diff --git a/3rdparty/3rdpartyDLL.vsprops b/3rdparty/3rdpartyDLL.vsprops new file mode 100644 index 0000000000..0c5392da35 --- /dev/null +++ b/3rdparty/3rdpartyDLL.vsprops @@ -0,0 +1,26 @@ + + + + + diff --git a/3rdparty/DefaultProjectRootDir.vsprops b/3rdparty/DefaultProjectRootDir.vsprops new file mode 100644 index 0000000000..7d8862f052 --- /dev/null +++ b/3rdparty/DefaultProjectRootDir.vsprops @@ -0,0 +1,15 @@ + + + + + diff --git a/3rdparty/SoundTouch/Makefile.am b/3rdparty/SoundTouch/Makefile.am index baf08c838f..eb39bcc96f 100644 --- a/3rdparty/SoundTouch/Makefile.am +++ b/3rdparty/SoundTouch/Makefile.am @@ -24,13 +24,8 @@ AUTOMAKE_OPTIONS = foreign noinst_HEADERS=AAFilter.h cpu_detect.h FIRFilter.h RateTransposer.h TDStretch.h cpu_detect_x86_gcc.cpp noinst_LIBRARIES = libSoundTouch.a -if X86_64 -libSoundTouch_a_CXXFLAGS = -fPIC -libSoundTouch_a_CFLAGS = -fPIC -else libSoundTouch_a_CXXFLAGS = -msse -mmmx libSoundTouch_a_CFLAGS = -msse -mmmx -endif #lib_LTLIBRARIES=libSoundTouch.la # the mmx_gcc.cpp and cpu_detect_x86_gcc.cpp may need to be conditionally included here from things discovered in configure.ac diff --git a/3rdparty/SoundTouch/SoundTouch.vcproj b/3rdparty/SoundTouch/SoundTouch.vcproj index b1cd6fa470..b7682bb958 100644 --- a/3rdparty/SoundTouch/SoundTouch.vcproj +++ b/3rdparty/SoundTouch/SoundTouch.vcproj @@ -18,7 +18,7 @@ @@ -95,12 +92,7 @@ /> @@ -154,12 +146,7 @@ /> @@ -96,17 +91,6 @@ /> @@ -160,17 +144,6 @@ /> _< Important: pthread_cond is an inherently flawed concept, and is quite incredibly slow on top of it. It's primarily meant for inter-process thread regulation, of which we do none. Therefore it has been excluded from the library builds. Don't use it! +I've also disabled rwlocks, since they use pthread_cond internally. Again, there should +be little or no reason to have to use those within the context of a high performance app +like Pcsx2. + diff --git a/3rdparty/w32pthreads/include/pthread.h b/3rdparty/w32pthreads/include/pthread.h index d33a9b14a8..12b4a169b5 100644 --- a/3rdparty/w32pthreads/include/pthread.h +++ b/3rdparty/w32pthreads/include/pthread.h @@ -1077,6 +1077,7 @@ PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * /* * Condition Variable Functions */ +#ifdef PCSX2_ALLOW_COND PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr); @@ -1092,6 +1093,7 @@ PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); +#endif /* * Scheduling diff --git a/3rdparty/w32pthreads/pthreads_2008.vcproj b/3rdparty/w32pthreads/pthreads_2008.vcproj index 5459698111..b18a1e9b32 100644 --- a/3rdparty/w32pthreads/pthreads_2008.vcproj +++ b/3rdparty/w32pthreads/pthreads_2008.vcproj @@ -2,7 +2,7 @@ + @@ -74,14 +74,18 @@ + @@ -102,23 +106,11 @@ /> + @@ -145,14 +141,17 @@ + @@ -173,22 +172,11 @@ /> + @@ -215,6 +207,9 @@ + @@ -439,6 +434,10 @@ /> + + @@ -754,6 +753,7 @@ > + + + diff --git a/3rdparty/wxWidgets/build/msw/ProjectRootDir.vsprops b/3rdparty/wxWidgets/build/msw/ProjectRootDir.vsprops new file mode 100644 index 0000000000..1bac222406 --- /dev/null +++ b/3rdparty/wxWidgets/build/msw/ProjectRootDir.vsprops @@ -0,0 +1,19 @@ + + + + + + diff --git a/3rdparty/wxWidgets/build/msw/wx_adv.vcproj b/3rdparty/wxWidgets/build/msw/wx_adv.vcproj deleted file mode 100644 index 1f0ee58a58..0000000000 --- a/3rdparty/wxWidgets/build/msw/wx_adv.vcproj +++ /dev/null @@ -1,2440 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/3rdparty/wxWidgets/build/msw/wx_base.vcproj b/3rdparty/wxWidgets/build/msw/wx_base.vcproj deleted file mode 100644 index cd86ff8b6e..0000000000 --- a/3rdparty/wxWidgets/build/msw/wx_base.vcproj +++ /dev/null @@ -1,6401 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/3rdparty/wxWidgets/build/msw/wx_base_2008.vcproj b/3rdparty/wxWidgets/build/msw/wx_base_2008.vcproj index ba94108894..d2d75db2e2 100644 --- a/3rdparty/wxWidgets/build/msw/wx_base_2008.vcproj +++ b/3rdparty/wxWidgets/build/msw/wx_base_2008.vcproj @@ -20,10 +20,8 @@ @@ -232,8 +198,6 @@ /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/3rdparty/wxWidgets/build/msw/wx_core_2008.vcproj b/3rdparty/wxWidgets/build/msw/wx_core_2008.vcproj index 2ca9b74a58..48d5ae7755 100644 --- a/3rdparty/wxWidgets/build/msw/wx_core_2008.vcproj +++ b/3rdparty/wxWidgets/build/msw/wx_core_2008.vcproj @@ -20,10 +20,8 @@ @@ -96,15 +92,7 @@ /> @@ -158,17 +146,7 @@ /> ] [dev,debug,release] [all, install, clean] +# If you don't specify pcsx2, plugins, or a plugin name, it will assume you want to rebuild everything. +# If you don't specify dev or debug, it assumes a release build. +# If it isn't all, install, or clean, it assumes install. + +# If you want other options, add them to $pcsx2_build_types. This is still a work in progress... +# --arcum42 + +require "fileutils.rb" +include FileUtils + +$main_dir = Dir.pwd +$pcsx2_install_dir = "#{$main_dir}/bin" +$plugin_install_dir = "#{$main_dir}/bin/plugins" + +$pcsx2_dir = "#{$main_dir}/pcsx2" +$plugins_dir = "#{$main_dir}/plugins" + +$pcsx2_prefix = " --prefix #{$main_dir}" +$plugins_prefix = " --prefix #{$plugin_install_dir}" + +$plugin_list=["CDVDnull", "dev9null", "FWnull", "USBnull", "SPU2null", "zerogs", "zzogl", "zeropad", "zerospu2", "PeopsSPU2", "CDVDiso", "CDVDisoEFP", "CDVDlinuz"] +$full_plugin_list=["CDVDnull", "dev9null", "FWnull", "USBnull", "SPU2null", "zerogs", "zzogl", "zeropad", "zerospu2", "PeopsSPU2", "CDVDiso", "CDVDisoEFP", "CDVDlinuz","GSnull","PadNull","wxpad"] + +$pcsx2_build_types = { + "dev" => " --enable-devbuild ", + "debug" => " --enable-debug ", + "release" => " " + } + +$pcsx2_release_params=["dev","debug","release"] +$make_params=["all", "clean","install"] + +$build_report ="" +$build_counter = 0 + +def plugin_src_dir(plugin_name) + name = "#{$plugins_dir}/#{plugin_name}/" + case plugin_name + when "CDVDiso" then + name += "src" + when "CDVDisoEFP" then + name += "src/Linux" + when "CDVDlinuz" + name += "Src/Linux" + when "zerogs", "zzogl" + name += "opengl" + end + + return name +end + +def announce(my_program) + print "---------------\n" + print "Building #{my_program}\n" + print "---------------\n" +end + +def make(options) + system("make #{options}") + ($? == 0) +end + +def rebuild(options) + system("aclocal") + system("automake") + system("autoconf") + system("chmod +x configure") + system("./configure #{options}") + make "clean" +end + +def install(build_name) + ret = make "install" + + case build_name + # If the package isn't inclined to obey simple instructions... + when "CDVDisoEFP" then + system("cp #{plugin_src_dir(build_name)}/cfgCDVDisoEFP #{$plugin_install_dir}") + system("cp #{plugin_src_dir(build_name)}/libCDVDisoEFP.so #{$plugin_install_dir}") + when "CDVDlinuz" then + system("cp #{plugin_src_dir(build_name)}/cfgCDVDlinuz #{$plugin_install_dir}") + system("cp #{plugin_src_dir(build_name)}/libCDVDlinuz.so #{$plugin_install_dir}") + when "PeopsSPU2" then + system("cp #{plugin_src_dir(build_name)}/libspu2Peops*.so* #{$plugin_install_dir}") + + # Copy the shaders over. Shouldn't the makefile do this? + when "zzogl","zerogs" then + system("cp #{plugin_src_dir(build_name)}/Win32/ps2hw.dat #{$plugin_install_dir}") + + #And while we have the opportunity... + when "pcsx2" then + svn_revision = `svn info | grep Revision:` + svn_revision = /[0-9]+/.match(svn_revision) + system("cp #{$pcsx2_install_dir}/pcsx2 #{$pcsx2_install_dir}/pcsx2-#{svn_revision}") + end + + ret +end + +def build(build_name, make_parameter) + completed = true + + announce "#{build_name.capitalize}" + + if build_name != "pcsx2" then + build_dir = plugin_src_dir(build_name) + else + build_dir = "#{$pcsx2_dir}" + end + + Dir.chdir build_dir + + case make_parameter + when "all" then + if build_name == "pcsx2" + rebuild($pcsx2_prefix) + else + rebuild($plugins_prefix) + end + completed = install(build_name) + + when "clean" then + make "clean" + + else + completed = install(build_name) + end + + Dir.chdir $main_dir + + if completed then + $build_report += "#{build_name} was built successfully.\n" + $build_counter += 1 + else + $build_report += "#{build_name} was not built successfully.\n" + end + +end + +build_parameter = "all" +make_parameter = "" +build_items = Array.new([]) + +ARGV.each do |x| + make_parameter = x if $make_params.include?(x) + + build_items.push(x) if $full_plugin_list.include?(x) or (x == "pcsx2") + $pcsx2_prefix = $pcsx2_build_types[x] + $pcsx2_prefix if $pcsx2_release_params.include?(x) + + if (x == "plugins") then + x = $plugin_list + build_items.push(x) + end +end + +if build_items.empty? then + build_items.push($plugin_list) + build_items.push("pcsx2") +end + +build_items.flatten! + +build_items.each do |x| + build(x,make_parameter) +end + +print "\n--\n" +print "Build Summary:\n" +print $build_report +print "\n" +print "#{$build_counter}/#{build_items.count} Successful.\n" \ No newline at end of file diff --git a/build.sh b/build.sh index a6aaa8710d..4da94673a5 100644 --- a/build.sh +++ b/build.sh @@ -11,8 +11,14 @@ #Optimized, but a devbuild export PCSX2OPTIONS="--enable-devbuild --prefix `pwd`" -#Debug / Devbuild version -#export PCSX2OPTIONS="--enable-debug --enable-devbuild --prefix `pwd`" +#Debug version (which now implies a devbuild) +#export PCSX2OPTIONS="--enable-debug --prefix `pwd`" + +#Normal, but unoptimized +#export PCSX2OPTIONS="--disable-optimization --prefix `pwd`" + +#Normal, with warnings +#export PCSX2OPTIONS="--enable-warnings --prefix `pwd`" #ZeroGS Normal mode export ZEROGSOPTIONS="--enable-sse2" @@ -23,12 +29,16 @@ export ZEROGSOPTIONS="--enable-sse2" #ZeroSPU2 Debug mode (Don't enable right now) #export ZEROSPU2OPTIONS="--enable-debug --enable-devbuild" +#GSnull debug options. +#export GSnullOPTIONS="--enable-debug" + option=$@ export PCSX2PLUGINS="`pwd`/bin/plugins" curdir=`pwd` +echo echo "Building the Pcsx2 Suite." -echo "Note: will not compile on Linux x64." +echo "Note: binaries generated are 32 bit, and require 32 bit versions of all dependencies." cd ${curdir}/plugins sh build.sh $option @@ -38,8 +48,9 @@ echo Error with building plugins exit 1 fi +echo echo "Building Pcsx2." -echo "Note: will not compile on Linux x64." +echo "Note: binaries generated are 32 bit, and require 32 bit versions of all dependencies." cd ${curdir}/pcsx2 sh build.sh $option diff --git a/common/build/Utilities/utilities.vcproj b/common/build/Utilities/utilities.vcproj new file mode 100644 index 0000000000..140df4fbe7 --- /dev/null +++ b/common/build/Utilities/utilities.vcproj @@ -0,0 +1,421 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/common/build/x86emitter/x86emitter.vcproj b/common/build/x86emitter/x86emitter.vcproj new file mode 100644 index 0000000000..c4e7a72a09 --- /dev/null +++ b/common/build/x86emitter/x86emitter.vcproj @@ -0,0 +1,366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/common/include/PS2Edefs.h b/common/include/PS2Edefs.h index eac022192b..6a231705ad 100644 --- a/common/include/PS2Edefs.h +++ b/common/include/PS2Edefs.h @@ -77,10 +77,18 @@ #define PS2E_SIO_VERSION 0x0001 #ifdef COMMONdefs +#ifdef __cplusplus +extern "C" { +#endif + u32 CALLBACK PS2EgetLibType(void); u32 CALLBACK PS2EgetLibVersion2(u32 type); char* CALLBACK PS2EgetLibName(void); +#ifdef __cplusplus +} +#endif + #endif // key values: diff --git a/common/include/Pcsx2Config.h b/common/include/Pcsx2Config.h index 4cde8671f7..fde95f4111 100644 --- a/common/include/Pcsx2Config.h +++ b/common/include/Pcsx2Config.h @@ -44,30 +44,34 @@ extern SessionOverrideFlags g_Session; ////////////////////////////////////////////////////////////////////////// // Pcsx2 User Configuration Options! -//#define PCSX2_MICROVU // Use Micro VU recs instead of Zero VU Recs -//#define PCSX2_MICROVU_ // Fully enable Micro VU recs (temporary option for now) -#define PCSX2_GSMULTITHREAD 1 // uses multi-threaded gs -#define PCSX2_EEREC 0x10 -#define PCSX2_VU0REC 0x20 -#define PCSX2_VU1REC 0x40 -#define PCSX2_FRAMELIMIT_MASK 0xc00 -#define PCSX2_FRAMELIMIT_NORMAL 0x000 -#define PCSX2_FRAMELIMIT_LIMIT 0x400 -#define PCSX2_FRAMELIMIT_SKIP 0x800 +#define PCSX2_GSMULTITHREAD 0x0001 // Use Multi-Threaded GS +#define PCSX2_EEREC 0x0010 +#define PCSX2_VU0REC 0x0020 +#define PCSX2_VU1REC 0x0040 +#define PCSX2_FRAMELIMIT_MASK 0x0c00 +#define PCSX2_FRAMELIMIT_NORMAL 0x0000 +#define PCSX2_FRAMELIMIT_LIMIT 0x0400 +#define PCSX2_FRAMELIMIT_SKIP 0x0800 +#define PCSX2_MICROVU0 0x1000 // Use Micro VU0 recs instead of Zero VU0 Recs +#define PCSX2_MICROVU1 0x2000 // Use Micro VU1 recs instead of Zero VU1 Recs #define CHECK_FRAMELIMIT (Config.Options&PCSX2_FRAMELIMIT_MASK) //------------ CPU Options!!! --------------- -#define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD) +#define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD) +#define CHECK_MICROVU0 (Config.Options&PCSX2_MICROVU0) +#define CHECK_MICROVU1 (Config.Options&PCSX2_MICROVU1) #define CHECK_EEREC (!g_Session.ForceDisableEErec && Config.Options&PCSX2_EEREC) #define CHECK_VU0REC (!g_Session.ForceDisableVU0rec && Config.Options&PCSX2_VU0REC) #define CHECK_VU1REC (!g_Session.ForceDisableVU1rec && (Config.Options&PCSX2_VU1REC)) //------------ SPECIAL GAME FIXES!!! --------------- -#define CHECK_VUADDSUBHACK (Config.GameFixes & 0x1) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate. -#define CHECK_FPUCOMPAREHACK (Config.GameFixes & 0x4) // Special Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu. -#define CHECK_VUCLIPFLAGHACK (Config.GameFixes & 0x2) // Special Fix for Persona games, maybe others. It's to do with the VU clip flag (again). -#define CHECK_FPUMULHACK (Config.GameFixes & 0x8) // Special Fix for Tales of Destiny hangs. +#define CHECK_VUADDSUBHACK (Config.GameFixes & 0x01) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate. +#define CHECK_FPUCOMPAREHACK (Config.GameFixes & 0x04) // Special Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu. +#define CHECK_VUCLIPFLAGHACK (Config.GameFixes & 0x02) // Special Fix for Persona games, maybe others. It's to do with the VU clip flag (again). +#define CHECK_FPUMULHACK (Config.GameFixes & 0x08) // Special Fix for Tales of Destiny hangs. +#define CHECK_DMAEXECHACK (Config.GameFixes & 0x10) // Special Fix for Fatal Frame; breaks Gust and Tri-Ace games. +#define CHECK_XGKICKHACK (Config.GameFixes & 0x20) // Special Fix for Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics. //------------ Advanced Options!!! --------------- #define CHECK_VU_OVERFLOW (Config.vuOptions & 0x1) @@ -161,12 +165,14 @@ public: int Patch; int CustomFps; struct Hacks_t { - int EECycleRate; + int EECycleRate; bool IOPCycleDouble; bool WaitCycleExt; bool INTCSTATSlow; - int VUCycleSteal; bool IdleLoopFF; + int VUCycleSteal; + bool vuFlagHack; + bool vuMinMax; bool ESCExits; // this is a hack!? } Hacks; int GameFixes; diff --git a/common/include/Pcsx2Defs.h b/common/include/Pcsx2Defs.h index 58c89c13a7..11e87f5d0d 100644 --- a/common/include/Pcsx2Defs.h +++ b/common/include/Pcsx2Defs.h @@ -1,120 +1,277 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2008 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __PCSX2DEFS_H__ -#define __PCSX2DEFS_H__ - -#ifndef __LINUX__ -# if defined (__linux__) // some distributions are lower case -# define __LINUX__ -# endif - -# ifdef __CYGWIN__ -# define __LINUX__ -# endif -#endif - -#include "Pcsx2Types.h" - -// Renamed ARRAYSIZE to ArraySize -- looks nice and gets rid of Windows.h conflicts (air) -#ifndef ArraySize -#define ArraySize(x) (sizeof(x)/sizeof((x)[0])) -#endif - -////////////////////////////////////////////////////////////////////////////////////////// -// jASSUME - give hints to the optimizer -// This is primarily useful for the default case switch optimizer, which enables VC to -// generate more compact switches. - -#ifdef NDEBUG -# define jBREAKPOINT() ((void) 0) -# ifdef _MSC_VER -# define jASSUME(exp) (__assume(exp)) -# else -# define jASSUME(exp) ((void) sizeof(exp)) -# endif -#else -# if defined(_MSC_VER) -# define jBREAKPOINT() do { __asm int 3 } while(0) -# else -# define jBREAKPOINT() ((void) *(volatile char *) 0) -# endif -# define jASSUME(exp) if(exp) ; else jBREAKPOINT() -#endif - -// disable the default case in a switch -#define jNO_DEFAULT \ -{ \ -default: \ - jASSUME(0); \ - break; \ -} - -/* common defines */ -#ifndef C_ASSERT -#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] -#endif - -#ifdef _MSC_VER -// Note: building the 'extern' into PCSX2_ALIGNED16_DECL fixes Visual Assist X's intellisense. - -#define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x -#define PCSX2_ALIGNED_EXTERN(alig,x) extern __declspec(align(alig)) x -#define PCSX2_ALIGNED16(x) __declspec(align(16)) x -#define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x - -#define __naked __declspec(naked) -#define __unused /*unused*/ -#define __noinline __declspec(noinline) -#define CALLBACK __stdcall - -#else - -// fixme - is this needed for recent versions of GCC? Or can we just use the first two macros -// instead for both definitions (implementations) and declarations (includes)? -- air -#define PCSX2_ALIGNED(alig,x) x __attribute((aligned(alig))) -#define PCSX2_ALIGNED16(x) x __attribute((aligned(16))) -#define PCSX2_ALIGNED_EXTERN(alig,x) extern x __attribute((aligned(alig))) -#define PCSX2_ALIGNED16_EXTERN(x) extern x __attribute((aligned(16))) - -#define __naked // GCC lacks the naked specifier -#define CALLBACK // CALLBACK is a win32-specific mess - -// GCC uses attributes for a lot of things that Visual C+ doesn't. -#define __fastcall __attribute__((fastcall)) -#define __unused __attribute__((unused)) -#define _inline __inline__ __attribute__((unused)) -#define __forceinline __attribute__((always_inline,unused)) -#define __noinline __attribute__((noinline)) -#endif - -typedef struct { - int size; - s8 *data; -} freezeData; - -// event values: -#define KEYPRESS 1 -#define KEYRELEASE 2 - -typedef struct _keyEvent { - u32 key; - u32 evt; -} keyEvent; - -#endif \ No newline at end of file +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __PCSX2DEFS_H__ +#define __PCSX2DEFS_H__ + +#if defined (__linux__) && !defined(__LINUX__) // some distributions are lower case +# define __LINUX__ +#endif + +#ifdef __CYGWIN__ +# define __LINUX__ +#endif + +#include "Pcsx2Types.h" + +////////////////////////////////////////////////////////////////////////////////////////// +// Microsoft specific STL extensions for bounds checking and stuff: Enabled in devbuilds, +// disabled in release builds. :) +// +#ifdef _MSC_VER +# pragma warning(disable:4244) // disable warning C4244: '=' : conversion from 'big' to 'small', possible loss of data +# ifdef PCSX2_DEVBUILD +# undef _SECURE_SCL +# define _SECURE_SCL 1 +# undef _SECURE_SCL_THROWS +# define _SECURE_SCL_THROWS 1 +# else +# undef _SECURE_SCL +# define _SECURE_SCL 0 +# undef _SECURE_SCL_THROWS +# define _SECURE_SCL_THROWS 0 +# endif +#endif + +#ifdef _MSC_VER +# include +#else +# include +#endif + +// Renamed ARRAYSIZE to ArraySize -- looks nice and gets rid of Windows.h conflicts (air) +// Notes: I'd have used ARRAY_SIZE instead but ran into cross-platform lib conflicts with +// that as well. >_< +#ifndef ArraySize +# define ArraySize(x) (sizeof(x)/sizeof((x)[0])) +#endif + +////////////////////////////////////////////////////////////////////////////////////////// +// __releaseinline -- a forceinline macro that is enabled for RELEASE/PUBLIC builds ONLY. +// This is useful because forceinline can make certain types of debugging problematic since +// functions that look like they should be called won't breakpoint since their code is +// inlined, and it can make stack traces confusing or near useless. +// +// Use __releaseinline for things which are generally large functions where trace debugging +// from Devel builds is likely useful; but which should be inlined in an optimized Release +// environment. +// +#ifdef PCSX2_DEVBUILD +# define __releaseinline +#else +# define __releaseinline __forceinline +#endif + +////////////////////////////////////////////////////////////////////////////////////////// +// jASSUME - give hints to the optimizer +// This is primarily useful for the default case switch optimizer, which enables VC to +// generate more compact switches. + +#ifndef jASSUME +# ifdef NDEBUG +# define jBREAKPOINT() ((void) 0) +# ifdef _MSC_VER +# define jASSUME(exp) (__assume(exp)) +# else +# define jASSUME(exp) ((void) sizeof(exp)) +# endif +# else +# define jBREAKPOINT() __debugbreak(); +# define jASSUME(exp) do { if(exp) ; else jBREAKPOINT(); } while(0); +# endif +#endif + +////////////////////////////////////////////////////////////////////////////////////////// +// jNO_DEFAULT -- disables the default case in a switch, which improves switch optimization +// under MSVC. +// +// How it Works: jASSUME turns into an __assume(0) under msvc compilers, which when specified +// in the 'default:' case of a switch tells the compiler that the case is unreachable, so +// that it will not generate any code, LUTs, or conditionals to handle it. +// +// * In debug builds the default case will cause an assertion. +// * In devel builds the default case will cause a LogicError exception (C++ only) +// (either meaning the jNO_DEFAULT has been used incorrectly, and that the default case is in +// fact used and needs to be handled). +// +// MSVC Note: To stacktrace LogicError exceptions, add Exception::LogicError to the C++ First- +// Chance Exception list (under Debug->Exceptions menu). +// +#ifndef jNO_DEFAULT +#if defined(__cplusplus) && defined(PCSX2_DEVBUILD) +# define jNO_DEFAULT \ + { \ + default: \ + assert(0); \ + if( !IsDebugBuild ) throw Exception::LogicError( "Incorrect usage of jNO_DEFAULT detected (default case is not unreachable!)" ); \ + break; \ + } +#else +# define jNO_DEFAULT \ + default: \ + { \ + jASSUME(0); \ + break; \ + } +#endif +#endif + +////////////////////////////////////////////////////////////////////////////////////////// +// compile-time assertion; usable at static variable define level. +// (typically used to confirm the correct sizeof() for struct types where size +// restaints must be enforced). +// +#ifndef C_ASSERT +# define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] +#endif + +////////////////////////////////////////////////////////////////////////////////////////// +// Dev / Debug conditionals - Consts for using if() statements instead of uglier #ifdef. +// +// Note: Using if() optimizes nicely in Devel and Release builds, but will generate extra +// code overhead in debug builds (since debug neither inlines, nor optimizes out const- +// level conditionals). Normally not a concern, but if you stick if( IsDevbuild ) in +// some tight loops it will likely make debug builds unusably slow. +// +#ifdef __cplusplus +# ifdef PCSX2_DEVBUILD + static const bool IsDevBuild = true; +# else + static const bool IsDevBuild = false; +# endif + +# ifdef PCSX2_DEBUG + static const bool IsDebugBuild = true; +# else + static const bool IsDebugBuild = false; +# endif + +#else + +# ifdef PCSX2_DEVBUILD + static const u8 IsDevBuild = 1; +# else + static const u8 IsDevBuild = 0; +# endif + +# ifdef PCSX2_DEBUG + static const u8 IsDebugBuild = 1; +# else + static const u8 IsDebugBuild = 0; +# endif +#endif + +////////////////////////////////////////////////////////////////////////////////////////// +// PCSX2_ALIGNED16 - helper macros for aligning variables in MSVC and GCC. +// +// GCC Warning! The GCC linker (LD) typically fails to assure alignment of class members. +// If you want alignment to be assured, the variable must either be a member of a struct +// or a static global. +// +// General Performance Warning: Any function that specifies alignment on a local (stack) +// variable will have to align the stack frame on enter, and restore it on exit (adds +// overhead). Furthermore, compilers cannot inline functions that have aligned local +// vars. So use local var alignment with much caution. +// +// Note: building the 'extern' into PCSX2_ALIGNED16 fixes Visual Assist X's intellisense. +// +#ifdef _MSC_VER + +# define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x +# define PCSX2_ALIGNED_EXTERN(alig,x) extern __declspec(align(alig)) x +# define PCSX2_ALIGNED16(x) __declspec(align(16)) x +# define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x + +# define __naked __declspec(naked) +# define __unused /*unused*/ +# define __noinline __declspec(noinline) + +// Don't know if there are Visual C++ equivalents of these. +# define __hot +# define __cold +# define likely(x) x +# define unlikely(x) x + +# define CALLBACK __stdcall + +#else + +// GCC 4.4.0 is a bit nutty, as compilers go. it gets a define to itself. +# define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +/* Test for GCC > 4.4.0; Should be adjusted when new versions come out */ +# if GCC_VERSION >= 40400 +# define THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0 +# define __nooptimization __attribute__((optimize("O0"))) +# endif + +/* +This theoretically unoptimizes. Not having much luck so far. +# ifdef THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0 +# pragma GCC optimize ("O0") +# endif + +# ifdef THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0 +# pragma GCC reset_options +# endif + +*/ + +// fixme - is this needed for recent versions of GCC? Or can we just use the first two macros +// instead for both definitions (implementations) and declarations (includes)? -- air +# define PCSX2_ALIGNED(alig,x) x __attribute((aligned(alig))) +# define PCSX2_ALIGNED16(x) x __attribute((aligned(16))) +# define PCSX2_ALIGNED_EXTERN(alig,x) extern x __attribute((aligned(alig))) +# define PCSX2_ALIGNED16_EXTERN(x) extern x __attribute((aligned(16))) + +# define __naked // GCC lacks the naked specifier +# define CALLBACK // CALLBACK is a win32-specific mess + +// GCC uses attributes for a lot of things that Visual C+ doesn't. +# define __fastcall __attribute__((fastcall)) +# define __unused __attribute__((unused)) +# define _inline __inline__ __attribute__((unused)) +# define __forceinline __attribute__((always_inline,unused)) +# define __noinline __attribute__((noinline)) +# define __hot __attribute__((hot)) +# define __cold __attribute__((cold)) +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +#endif + +#ifndef THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0 +# define __nooptimization +#endif + +typedef struct { + int size; + s8 *data; +} freezeData; + +// event values: +#define KEYPRESS 1 +#define KEYRELEASE 2 + +typedef struct _keyEvent { + u32 key; + u32 evt; +} keyEvent; + +#endif diff --git a/common/include/Pcsx2Types.h b/common/include/Pcsx2Types.h index 4c0e9fa23c..cc7ce30305 100644 --- a/common/include/Pcsx2Types.h +++ b/common/include/Pcsx2Types.h @@ -107,6 +107,7 @@ typedef s32 sptr; ////////////////////////////////////////////////////////////////////////////////////////// // A rough-and-ready cross platform 128-bit datatype, Non-SSE style. +// #ifdef __cplusplus struct u128 { diff --git a/common/include/Utilities/Console.h b/common/include/Utilities/Console.h new file mode 100644 index 0000000000..2b0e30f663 --- /dev/null +++ b/common/include/Utilities/Console.h @@ -0,0 +1,142 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +#include "StringHelpers.h" + +////////////////////////////////////////////////////////////////////////////////////////// +// Console Namespace -- For printing messages to the console. +// +// SysPrintf is depreciated; We should phase these in over time. +// +namespace Console +{ + enum Colors + { + Color_Black = 0, + Color_Red, + Color_Green, + Color_Yellow, + Color_Blue, + Color_Magenta, + Color_Cyan, + Color_White + }; + + // va_args version of WriteLn, mostly for internal use only. + extern void __fastcall _WriteLn( Colors color, const char* fmt, va_list args ); + + extern void __fastcall SetTitle( const wxString& title ); + + // Changes the active console color. + // This color will be unset by calls to colored text methods + // such as ErrorMsg and Notice. + extern void __fastcall SetColor( Colors color ); + + // Restores the console color to default (usually low-intensity white on Win32) + extern void ClearColor(); + + // The following Write functions return bool so that we can use macros to exclude + // them from different build types. The return values are always zero. + + // Writes a newline to the console. + extern bool Newline(); + + // Writes an unformatted string of text to the console (fast!) + // No newline is appended. + extern bool __fastcall Write( const char* text ); + + // Writes an unformatted string of text to the console (fast!) + // A newline is automatically appended, and the console color reset to default + // after the log is written. + extern bool __fastcall Write( Colors color, const char* text ); + + // Writes an unformatted string of text to the console (fast!) + // A newline is automatically appended. + extern bool __fastcall WriteLn( const char* text ); + + // Writes an unformatted string of text to the console (fast!) + // A newline is automatically appended, and the console color reset to default + // after the log is written. + extern bool __fastcall WriteLn( Colors color, const char* text ); + + // Writes a line of colored text to the console, with automatic newline appendage. + // The console color is reset to default when the operation is complete. + extern bool WriteLn( Colors color, const char* fmt, VARG_PARAM dummy, ... ); + + // Writes a formatted message to the console, with appended newline. + extern bool WriteLn( const char* fmt, VARG_PARAM dummy, ... ); + + // Writes a line of colored text to the console (no newline). + // The console color is reset to default when the operation is complete. + extern bool Write( Colors color, const char* fmt, VARG_PARAM dummy, ... ); + + // Writes a formatted message to the console (no newline) + extern bool Write( const char* fmt, VARG_PARAM dummy, ... ); + + // Displays a message in the console with red emphasis. + // Newline is automatically appended. + extern bool Error( const char* fmt, VARG_PARAM dummy, ... ); + extern bool __fastcall Error( const char* text ); + + // Displays a message in the console with yellow emphasis. + // Newline is automatically appended. + extern bool Notice( const char* fmt, VARG_PARAM dummy, ... ); + extern bool __fastcall Notice( const char* text ); + + // Displays a message in the console with yellow emphasis. + // Newline is automatically appended. + extern bool Status( const char* fmt, VARG_PARAM dummy, ... ); + extern bool __fastcall Status( const char* text ); + + + extern bool __fastcall Write( const wxString& text ); + extern bool __fastcall Write( Colors color, const wxString& text ); + extern bool __fastcall WriteLn( const wxString& text ); + extern bool __fastcall WriteLn( Colors color, const wxString& text ); + + extern bool __fastcall Error( const wxString& text ); + extern bool __fastcall Notice( const wxString& text ); + extern bool __fastcall Status( const wxString& text ); +} + +using Console::Color_Red; +using Console::Color_Green; +using Console::Color_Blue; +using Console::Color_Magenta; +using Console::Color_Cyan; +using Console::Color_Yellow; +using Console::Color_White; + +////////////////////////////////////////////////////////////////////////////////////////// +// DevCon / DbgCon + +#ifdef PCSX2_DEVBUILD +# define DevCon Console +# define DevMsg MsgBox +#else +# define DevCon 0&&Console +# define DevMsg +#endif + +#ifdef PCSX2_DEBUG +# define DbgCon Console +#else +# define DbgCon 0&&Console +#endif diff --git a/pcsx2/Decode_XA.h b/common/include/Utilities/Dependencies.h similarity index 59% rename from pcsx2/Decode_XA.h rename to common/include/Utilities/Dependencies.h index 0aeab19749..466e72996b 100644 --- a/pcsx2/Decode_XA.h +++ b/common/include/Utilities/Dependencies.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2008 Pcsx2 Team + * Copyright (C) 2002-2009 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,29 +15,20 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -//============================================ -//=== Audio XA decoding -//=== Kazzuya -//============================================ -#ifndef DECODEXA_H -#define DECODEXA_H +#pragma once -typedef struct { - long y0, y1; -} ADPCM_Decode_t; +#include "Pcsx2Defs.h" -typedef struct { - int freq; - int nbits; - int stereo; - int nsamples; - ADPCM_Decode_t left, right; - short pcm[16384]; -} xa_decode_t; +#include +#include +#include // for wxPoint/wxRect stuff +#include +#include -long xa_decode_sector( xa_decode_t *xdp, - unsigned char *sectorp, - int is_first_sector ); - -#endif +#include +#include +#include +#include // string.h under c++ +#include // stdio.h under c++ +#include diff --git a/pcsx2/Exceptions.h b/common/include/Utilities/Exceptions.h similarity index 97% rename from pcsx2/Exceptions.h rename to common/include/Utilities/Exceptions.h index 682456c932..c977e36d31 100644 --- a/pcsx2/Exceptions.h +++ b/common/include/Utilities/Exceptions.h @@ -18,6 +18,10 @@ #pragma once +#include "Dependencies.h" + +extern void DevAssert( bool condition, const char* msg ); + ////////////////////////////////////////////////////////////////////////////////////////// // This class provides an easy and clean method for ensuring objects are not copyable. class NoncopyableObject @@ -56,11 +60,6 @@ protected: // for every class that derives from it. #define Sealed private virtual __BaseSealed<__COUNTER__> -extern wxLocale* g_EnglishLocale; - -extern wxString GetEnglish( const char* msg ); -extern wxString GetTranslation( const char* msg ); - namespace Exception { ////////////////////////////////////////////////////////////////////////////////// @@ -104,7 +103,7 @@ namespace Exception ////////////////////////////////////////////////////////////////////////////////////////// // This class is used as a base exception for things tossed by PS2 cpus (EE, IOP, etc). // Translation Note: These exceptions are never translated, except to issue a general - // error message to the user (which is xspecified below). + // error message to the user (which is specified below). // class Ps2Generic : public BaseException { @@ -151,6 +150,18 @@ namespace Exception BaseException( msg_eng, msg_xlt ) { } }; + class AssertionFailure : public LogicError + { + public: + explicit AssertionFailure( const char* msg="Assertion Failure" ) : + LogicError( msg ) {} + + explicit AssertionFailure( const wxString& msg_eng, const wxString& msg_xlt ) : + LogicError( msg_eng, msg_xlt ) { } + + virtual ~AssertionFailure() throw() {} + }; + ////////////////////////////////////////////////////////////////////////////////// // class OutOfMemory : public RuntimeError diff --git a/common/include/Utilities/General.h b/common/include/Utilities/General.h new file mode 100644 index 0000000000..c7e608ef1f --- /dev/null +++ b/common/include/Utilities/General.h @@ -0,0 +1,57 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +enum PageProtectionMode +{ + Protect_NoAccess = 0, + Protect_ReadOnly, + Protect_ReadWrite +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// HostSys - Namespace housing general system-level implementations relating to loading +// plugins and allocating memory. For now, these functions are all accessed via Sys* +// versions defined in System.h/cpp. +// +namespace HostSys +{ + // Maps a block of memory for use as a recompiled code buffer. + // The allocated block has code execution privileges. + // Returns NULL on allocation failure. + extern void *Mmap(uptr base, u32 size); + + // Unmaps a block allocated by SysMmap + extern void Munmap(uptr base, u32 size); + + extern void MemProtect( void* baseaddr, size_t size, PageProtectionMode mode, bool allowExecution=false ); + + static __forceinline void Munmap( void* base, u32 size ) + { + Munmap( (uptr)base, size ); + } +} + + +////////////////////////////////////////////////////////////////////////////////////////// + + +extern void InitCPUTicks(); +extern u64 GetTickFrequency(); +extern u64 GetCPUTicks(); diff --git a/pcsx2/MemcpyFast.h b/common/include/Utilities/MemcpyFast.h similarity index 73% rename from pcsx2/MemcpyFast.h rename to common/include/Utilities/MemcpyFast.h index 1e7e1a7a4d..7536f84add 100644 --- a/pcsx2/MemcpyFast.h +++ b/common/include/Utilities/MemcpyFast.h @@ -18,28 +18,26 @@ #pragma once -#if defined(_WIN32) - #include "windows/memzero.h" -#else - #include "Linux/memzero.h" -#endif // WIN32 - - // Only used in the Windows version of memzero.h. But it's in Misc.cpp for some reason. - void _memset16_unaligned( void* dest, u16 data, size_t size ); - - // The new simplified memcpy_amd_ is now faster than memcpy_raz_. - // memcpy_amd_ also does mmx register saving, negating the need for freezeregs (code cleanup!) - // Additionally, using one single memcpy implementation keeps the code cache cleaner. - #ifdef __LINUX__ + +# include "lnx_memzero.h" + extern "C" void __fastcall memcpy_amd_(void *dest, const void *src, size_t bytes); extern "C" u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize); extern "C" void memxor_mmx(void* dst, const void* src1, int cmpsize); + #else + +# include "win_memzero.h" + extern void __fastcall memcpy_amd_(void *dest, const void *src, size_t bytes); extern u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize); extern void memxor_mmx(void* dst, const void* src1, int cmpsize); + #endif +// Only used in the Windows version of memzero.h. But it's in Misc.cpp for some reason. +void _memset16_unaligned( void* dest, u16 data, size_t size ); + #define memcpy_fast memcpy_amd_ #define memcpy_aligned memcpy_amd_ diff --git a/common/include/Utilities/RedtapeWindows.h b/common/include/Utilities/RedtapeWindows.h new file mode 100644 index 0000000000..c448869788 --- /dev/null +++ b/common/include/Utilities/RedtapeWindows.h @@ -0,0 +1,45 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +////////////////////////////////////////////////////////////////////////////////////////// +// Windows Redtape! No windows.h should be included without it! +// +// This header's purpose is to include windows.h with the correct OS version info, and +// to undefine some of windows.h's more evil macros (min/max). It also does a _WIN32 +// check, so that we don't have to do it explicitly in every instance where it might +// be needed from non-Win32-specific files + +#define NOMINMAX // Disables other libs inclusion of their own min/max macros (we use std instead) + +#ifdef _WIN32 + +// Force availability of to WinNT APIs (change to 0x600 to enable XP-specific APIs) +#ifndef WINVER +#define WINVER 0x0501 +#define _WIN32_WINNT 0x0501 +#endif + +#include + +// disable Windows versions of min/max -- we'll use the typesafe STL versions instead. +#undef min +#undef max + +#endif diff --git a/pcsx2/SafeArray.h b/common/include/Utilities/SafeArray.h similarity index 71% rename from pcsx2/SafeArray.h rename to common/include/Utilities/SafeArray.h index e95ec459c2..dfe7a9949a 100644 --- a/pcsx2/SafeArray.h +++ b/common/include/Utilities/SafeArray.h @@ -74,26 +74,24 @@ class SafeArray : public NoncopyableObject public: static const int DefaultChunkSize = 0x1000 * sizeof(T); -public: - const wxString Name; // user-assigned block name +public: + const wxChar* Name; // user-assigned block name int ChunkSize; protected: T* m_ptr; int m_size; // size of the allocation of memory - const static wxString m_str_Unnamed; - protected: // Internal constructor for use by derived classes. This allows a derived class to // use its own memory allocation (with an aligned memory, for example). // Throws: // Exception::OutOfMemory if the allocated_mem pointer is NULL. - explicit SafeArray( const wxString& name, T* allocated_mem, int initSize ) : - Name( name ) - , ChunkSize( DefaultChunkSize ) - , m_ptr( allocated_mem ) - , m_size( initSize ) + explicit SafeArray( const wxChar* name, T* allocated_mem, int initSize ) : + Name( name ) + , ChunkSize( DefaultChunkSize ) + , m_ptr( allocated_mem ) + , m_size( initSize ) { if( m_ptr == NULL ) throw Exception::OutOfMemory(); @@ -101,7 +99,10 @@ protected: virtual T* _virtual_realloc( int newsize ) { - return (T*)realloc( m_ptr, newsize * sizeof(T) ); + return (T*)((m_ptr == NULL) ? + malloc( newsize * sizeof(T) ) : + realloc( m_ptr, newsize * sizeof(T) ) + ); } public: @@ -110,67 +111,72 @@ public: safe_free( m_ptr ); } - explicit SafeArray( const wxString& name = L"Unnamed" ) : - Name( name ) - , ChunkSize( DefaultChunkSize ) - , m_ptr( NULL ) - , m_size( 0 ) + explicit SafeArray( const wxChar* name=L"Unnamed" ) : + Name( name ) + , ChunkSize( DefaultChunkSize ) + , m_ptr( NULL ) + , m_size( 0 ) { } - explicit SafeArray( const char* name ) : - Name( wxString::FromAscii(name) ) - , ChunkSize( DefaultChunkSize ) - , m_ptr( NULL ) - , m_size( 0 ) + explicit SafeArray( int initialSize, const wxChar* name=L"Unnamed" ) : + Name( name ) + , ChunkSize( DefaultChunkSize ) + , m_ptr( (initialSize==0) ? NULL : (T*)malloc( initialSize * sizeof(T) ) ) + , m_size( initialSize ) { - } - - explicit SafeArray( int initialSize, const wxString& name = L"Unnamed" ) : - Name( name ) - , ChunkSize( DefaultChunkSize ) - , m_ptr( (T*)malloc( initialSize * sizeof(T) ) ) - , m_size( initialSize ) - { - if( m_ptr == NULL ) + if( (initialSize != 0) && (m_ptr == NULL) ) throw Exception::OutOfMemory(); } - - explicit SafeArray( int initialSize, const char* name ) : - Name( wxString::FromAscii(name) ) - , ChunkSize( DefaultChunkSize ) - , m_ptr( (T*)malloc( initialSize * sizeof(T) ) ) - , m_size( initialSize ) + + // Clears the contents of the array to zero, and frees all memory allocations. + void Dispose() { - if( m_ptr == NULL ) - throw Exception::OutOfMemory(); + m_size = 0; + safe_free( m_ptr ); } + bool IsDisposed() const { return (m_ptr==NULL); } + // Returns the size of the memory allocation, as according to the array type. int GetLength() const { return m_size; } // Returns the size of the memory allocation in bytes. int GetSizeInBytes() const { return m_size * sizeof(T); } - // Ensures that the allocation is large enough to fit data of the - // amount requested. The memory allocation is not resized smaller. - void MakeRoomFor( int blockSize ) + // reallocates the array to the explicit size. Can be used to shrink or grow an + // array, and bypasses the internal threshold growth indicators. + void ExactAlloc( int newsize ) { - if( blockSize > m_size ) + if( newsize == m_size ) return; + + m_ptr = _virtual_realloc( newsize ); + if( m_ptr == NULL ) { - const uint newalloc = blockSize + ChunkSize; - m_ptr = _virtual_realloc( newalloc ); - if( m_ptr == NULL ) - { + throw Exception::OutOfMemory( wxsFormat( // english (for diagnostic) L"Out-of-memory on SafeArray block re-allocation.\n" L"Old size: %d bytes, New size: %d bytes.", - m_size, newalloc + m_size, newsize ) ); - } - m_size = newalloc; } + m_size = newsize; + } + + // Ensures that the allocation is large enough to fit data of the + // amount requested. The memory allocation is not resized smaller. + void MakeRoomFor( int newsize ) + { + if( newsize > m_size ) + ExactAlloc( newsize ); + } + + // Extends the containment area of the array. Extensions are performed + // in chunks. + void GrowBy( int items ) + { + MakeRoomFor( m_size + ChunkSize + items + 1 ); } // Gets a pointer to the requested allocation index. @@ -205,36 +211,40 @@ protected: #endif return &m_ptr[i]; } - }; ////////////////////////////////////////////////////////////////////////////////////////// +// SafeList - Simple growable container without all the mess or hassle of std containers. // +// This container is intended for reasonably simple class types only. Things which this +// container does not handle with desired robustness: +// +// * Classes with non-trivial constructors (such that construction creates much overhead) +// * Classes with copy constructors (copying is done using performance memcpy) +// * Classes with destructors (they're not called, sorry!) // template< typename T > -class SafeList +class SafeList : public NoncopyableObject { public: static const int DefaultChunkSize = 0x80 * sizeof(T); -public: - const wxString Name; // user-assigned block name - int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time. +public: + const wxChar* Name; // user-assigned block name + int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time. protected: T* m_ptr; int m_allocsize; // size of the allocation of memory uint m_length; // length of the array (active items, not buffer allocation) - const static wxString m_str_Unnamed; - protected: virtual T* _virtual_realloc( int newsize ) { return (T*)realloc( m_ptr, newsize * sizeof(T) ); } - - void _boundsCheck( uint i ) const + + void _boundsCheck( uint i ) const { if( IsDevBuild && i >= (uint)m_length ) throw Exception::IndexBoundsFault( Name, i, m_length ); @@ -243,9 +253,10 @@ protected: public: virtual ~SafeList() { + safe_free( m_ptr ); } - explicit SafeList( const wxString& name = L"Unnamed" ) : + explicit SafeList( const wxChar* name=L"Unnamed" ) : Name( name ) , ChunkSize( DefaultChunkSize ) , m_ptr( NULL ) @@ -254,16 +265,7 @@ public: { } - explicit SafeList( const char* name ) : - Name( wxString::FromAscii(name) ) - , ChunkSize( DefaultChunkSize ) - , m_ptr( NULL ) - , m_allocsize( 0 ) - , m_length( 0 ) - { - } - - explicit SafeList( int initialSize, const wxString& name = L"Unnamed" ) : + explicit SafeList( int initialSize, const wxChar* name=L"Unnamed" ) : Name( name ) , ChunkSize( DefaultChunkSize ) , m_ptr( (T*)malloc( initialSize * sizeof(T) ) ) @@ -272,17 +274,12 @@ public: { if( m_ptr == NULL ) throw Exception::OutOfMemory(); - } - explicit SafeList( int initialSize, const char* name ) : - Name( wxString::FromAscii(name) ) - , ChunkSize( DefaultChunkSize ) - , m_ptr( (T*)malloc( initialSize * sizeof(T) ) ) - , m_allocsize( initialSize ) - , m_length( 0 ) - { - if( m_ptr == NULL ) - throw Exception::OutOfMemory(); + for( int i=0; i m_allocsize ) { - const uint newalloc = blockSize + ChunkSize; + const int newalloc = blockSize + ChunkSize; m_ptr = _virtual_realloc( newalloc ); if( m_ptr == NULL ) { @@ -312,22 +309,58 @@ public: ) ); } - m_allocsize = newalloc; + + for( ; m_allocsize protected: T* _virtual_realloc( int newsize ) { - return (T*)_aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment ); + return (T*)( ( this->m_ptr == NULL ) ? + _aligned_malloc( newsize * sizeof(T), Alignment ) : + _aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment ) + ); } // Appends "(align: xx)" to the name of the allocation in devel builds. // Maybe useful,maybe not... no harm in attaching it. :D - wxString _getName( const wxString& src ) - { - if( IsDevBuild ) - return src + wxsFormat( L"(align: %d)", Alignment ); - else - return src; - } public: virtual ~SafeAlignedArray() @@ -391,28 +426,14 @@ public: // mptr is set to null, so the parent class's destructor won't re-free it. } - explicit SafeAlignedArray( const wxString& name = L"Unnamed") : + explicit SafeAlignedArray( const wxChar* name=L"Unnamed" ) : SafeArray::SafeArray( name ) { } - explicit SafeAlignedArray( const char* name ) : - SafeArray::SafeArray( name ) - { - } - - explicit SafeAlignedArray( int initialSize, const wxString& name = L"Unnamed") : + explicit SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" ) : SafeArray::SafeArray( - _getName(name), - (T*)_aligned_malloc( initialSize * sizeof(T), Alignment ), - initialSize - ) - { - } - - explicit SafeAlignedArray( int initialSize, const char* name ) : - SafeArray::SafeArray( - _getName(wxString::FromAscii(name)), + name, (T*)_aligned_malloc( initialSize * sizeof(T), Alignment ), initialSize ) diff --git a/common/include/Utilities/StringHelpers.h b/common/include/Utilities/StringHelpers.h new file mode 100644 index 0000000000..89229dd86d --- /dev/null +++ b/common/include/Utilities/StringHelpers.h @@ -0,0 +1,91 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +#include +#include +#include // for wxPoint/wxRect stuff + +////////////////////////////////////////////////////////////////////////////////////////// +// Helpers for wxWidgets stuff! +// + +// wxWidgets lacks one of its own... +extern const wxRect wxDefaultRect; + +// This should prove useful.... +#define wxsFormat wxString::Format + +extern wxString ToString( const wxPoint& src, const wxString& separator=L"," ); +extern wxString ToString( const wxSize& src, const wxString& separator=L"," ); +extern wxString ToString( const wxRect& src, const wxString& separator=L"," ); + +extern bool TryParse( wxPoint& dest, const wxStringTokenizer& parts ); +extern bool TryParse( wxSize& dest, const wxStringTokenizer& parts ); + +extern bool TryParse( wxPoint& dest, const wxString& src, const wxPoint& defval=wxDefaultPosition, const wxString& separators=L","); +extern bool TryParse( wxSize& dest, const wxString& src, const wxSize& defval=wxDefaultSize, const wxString& separators=L","); +extern bool TryParse( wxRect& dest, const wxString& src, const wxRect& defval=wxDefaultRect, const wxString& separators=L","); + + +////////////////////////////////////////////////////////////////////////////////////////// +// dummy structure used to type-guard the dummy parameter that's been inserted to +// allow us to use the va_list feature on references. +struct _VARG_PARAM +{ + // just some value to make the struct length 32bits instead of 8 bits, so that the + // compiler generates somewhat more efficient code. + uint someval; +}; + +#ifdef PCSX2_DEBUG + +#define params va_arg_dummy, +#define varg_assert() // jASSUME( dummy == &va_arg_dummy ); +// typedef the Va-Arg value to be a value type in debug builds. The value +// type requires a little more overhead in terms of code generation, but is always +// type-safe. The compiler will generate errors for any forgotten params value. +typedef _VARG_PARAM VARG_PARAM; + +#else + +#define params NULL, // using null is faster / more compact! +#define varg_assert() jASSUME( dummy == NULL ); +// typedef the Va-Arg value to be a pointer in release builds. Pointers +// generate more compact code by a small margin, but aren't entirely type safe since +// the compiler won't generate errors if you pass NULL or other values. +typedef _VARG_PARAM const * VARG_PARAM; + +#endif + +extern const _VARG_PARAM va_arg_dummy; + +////////////////////////////////////////////////////////////////////////////////////////// +// Custom internal sprintf functions, which are ASCII only (even in UNICODE builds) +// +// These functions are useful since they are ASCII always, even under Unicode. Typically +// even in a unicode app. + +extern void ssprintf(std::string& dest, const char* fmt, ...); +extern void ssappendf(std::string& dest, const char* format, ...); +extern void vssprintf(std::string& dest, const char* format, va_list args); +extern void vssappendf(std::string& dest, const char* format, va_list args); + +extern std::string fmt_string( const char* fmt, ... ); +extern std::string vfmt_string( const char* fmt, va_list args ); diff --git a/pcsx2/Threading.h b/common/include/Utilities/Threading.h similarity index 99% rename from pcsx2/Threading.h rename to common/include/Utilities/Threading.h index 8b1a7fcf00..3d4ae65137 100644 --- a/pcsx2/Threading.h +++ b/common/include/Utilities/Threading.h @@ -15,11 +15,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#ifndef _THREADING_H_ -#define _THREADING_H_ + + #pragma once #include // EBUSY +#include #include #include "Pcsx2Defs.h" @@ -276,4 +276,3 @@ namespace Threading } -#endif diff --git a/pcsx2/Linux/memzero.h b/common/include/Utilities/lnx_memzero.h similarity index 100% rename from pcsx2/Linux/memzero.h rename to common/include/Utilities/lnx_memzero.h diff --git a/pcsx2/windows/memzero.h b/common/include/Utilities/win_memzero.h similarity index 97% rename from pcsx2/windows/memzero.h rename to common/include/Utilities/win_memzero.h index c66d33ee57..4dddf64ea8 100644 --- a/pcsx2/windows/memzero.h +++ b/common/include/Utilities/win_memzero.h @@ -16,8 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef _WIN_MEMZERO_H_ -#define _WIN_MEMZERO_H_ +#pragma once // These functions are meant for memset operations of constant length only. // For dynamic length clears, use the C-compiler provided memset instead. @@ -36,6 +35,11 @@ // structures, which are constant in size, thus allowing us to generate optimal compile- // time code for each use of the function. +// Use of CLD (Clear Direction Flag): +// On Windows platforms the ABI declares that the direction flag should be cleared upon +// entry of *any* function. Therefore there is no need to have CLD prior to our use of +// rep strosd here. + // Notes on XMM0's "storage" area (_xmm_backup): // Unfortunately there's no way to guarantee alignment for this variable. If I use the // __declspec(aligned(16)) decorator, MSVC fails to inline the function since stack @@ -197,7 +201,6 @@ static __forceinline void memzero_ptr( void *dest ) case 3: __asm { - cld; mov edi, dest xor eax, eax stosd @@ -209,7 +212,6 @@ static __forceinline void memzero_ptr( void *dest ) case 4: __asm { - cld; mov edi, dest xor eax, eax stosd @@ -222,7 +224,6 @@ static __forceinline void memzero_ptr( void *dest ) case 5: __asm { - cld; mov edi, dest xor eax, eax stosd @@ -236,7 +237,6 @@ static __forceinline void memzero_ptr( void *dest ) default: __asm { - cld; mov ecx, remdat mov edi, dest xor eax, eax @@ -336,7 +336,6 @@ static __forceinline void memset_8( void *dest ) case 3: __asm { - cld; mov edi, dest; mov eax, data32; stosd; @@ -348,7 +347,6 @@ static __forceinline void memset_8( void *dest ) case 4: __asm { - cld; mov edi, dest; mov eax, data32; stosd; @@ -361,7 +359,6 @@ static __forceinline void memset_8( void *dest ) case 5: __asm { - cld; mov edi, dest; mov eax, data32; stosd; @@ -375,7 +372,6 @@ static __forceinline void memset_8( void *dest ) default: __asm { - cld; mov ecx, remdat; mov edi, dest; mov eax, data32; @@ -428,7 +424,6 @@ static __forceinline void memset_16( void *dest ) case 3: __asm { - cld; mov edi, dest; mov eax, data32; stosd; @@ -440,7 +435,6 @@ static __forceinline void memset_16( void *dest ) case 4: __asm { - cld; mov edi, dest; mov eax, data32; stosd; @@ -453,7 +447,6 @@ static __forceinline void memset_16( void *dest ) case 5: __asm { - cld; mov edi, dest; mov eax, data32; stosd; @@ -467,7 +460,6 @@ static __forceinline void memset_16( void *dest ) default: __asm { - cld; mov ecx, remdat; mov edi, dest; mov eax, data32; @@ -515,7 +507,6 @@ static __forceinline void memset_32( void *dest ) case 3: __asm { - cld; mov edi, dest; mov eax, data32; stosd; @@ -527,7 +518,6 @@ static __forceinline void memset_32( void *dest ) case 4: __asm { - cld; mov edi, dest; mov eax, data32; stosd; @@ -540,7 +530,6 @@ static __forceinline void memset_32( void *dest ) case 5: __asm { - cld; mov edi, dest; mov eax, data32; stosd; @@ -554,7 +543,6 @@ static __forceinline void memset_32( void *dest ) default: __asm { - cld; mov ecx, remdat; mov edi, dest; mov eax, data32; @@ -594,5 +582,3 @@ static __forceinline void memset32_obj( T& object ) memset_32( &object ); } -#endif - diff --git a/common/include/intrin_x86.h b/common/include/intrin_x86.h new file mode 100644 index 0000000000..7c04b795e0 --- /dev/null +++ b/common/include/intrin_x86.h @@ -0,0 +1,954 @@ +/* + Compatibility header for GCC -- GCC equivalents of intrinsic + Microsoft Visual C++ functions. Originally developed for the ReactOS + () and TinyKrnl () + projects. + + Copyright (c) 2006 KJK::Hyperion + + 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. +*/ + +#ifndef KJK_INTRIN_X86_H_ +#define KJK_INTRIN_X86_H_ + +/* + FIXME: review all "memory" clobbers, add/remove to match Visual C++ + behavior: some "obvious" memory barriers are not present in the Visual C++ + implementation - e.g. __stosX; on the other hand, some memory barriers that + *are* present could have been missed +*/ + +/* + NOTE: this is a *compatibility* header. Some functions may look wrong at + first, but they're only "as wrong" as they would be on Visual C++. Our + priority is compatibility + + NOTE: unlike most people who write inline asm for GCC, I didn't pull the + constraints and the uses of __volatile__ out of my... hat. Do not touch + them. I hate cargo cult programming + + NOTE: be very careful with declaring "memory" clobbers. Some "obvious" + barriers aren't there in Visual C++ (e.g. __stosX) + + NOTE: review all intrinsics with a return value, add/remove __volatile__ + where necessary. If an intrinsic whose value is ignored generates a no-op + under Visual C++, __volatile__ must be omitted; if it always generates code + (for example, if it has side effects), __volatile__ must be specified. GCC + will only optimize out non-volatile asm blocks with outputs, so input-only + blocks are safe. Oddities such as the non-volatile 'rdmsr' are intentional + and follow Visual C++ behavior + + NOTE: on GCC 4.1.0, please use the __sync_* built-ins for barriers and + atomic operations. Test the version like this: + + #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100 + ... + + Pay attention to the type of barrier. Make it match with what Visual C++ + would use in the same case +*/ + + +#ifndef __SIZE_T +#define __SIZE_T +typedef unsigned int size_t; +#endif + +/*** Stack frame juggling ***/ +#define _ReturnAddress() (__builtin_return_address(0)) +#define _AddressOfReturnAddress() (&(((void **)(__builtin_frame_address(0)))[1])) +/* TODO: __getcallerseflags but how??? */ + + +/*** Atomic operations ***/ + +#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100 +#define _ReadWriteBarrier() __sync_synchronize() +#else +static void __inline__ __attribute__((always_inline)) _MemoryBarrier(void) +{ + __asm__ __volatile__("" : : : "memory"); +} +#define _ReadWriteBarrier() _MemoryBarrier() +#endif + +/* BUGBUG: GCC only supports full barriers */ +#define _ReadBarrier _ReadWriteBarrier +#define _WriteBarrier _ReadWriteBarrier + +#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100 + +static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand) +{ + return __sync_val_compare_and_swap(Destination, Comperand, Exchange); +} + +static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand) +{ + return __sync_val_compare_and_swap(Destination, Comperand, Exchange); +} + +static __inline__ __attribute__((always_inline)) long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand) +{ + return __sync_val_compare_and_swap(Destination, Comperand, Exchange); +} + +static __inline__ __attribute__((always_inline)) long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand) +{ + return __sync_val_compare_and_swap(Destination, Comperand, Exchange); +} + +static __inline__ __attribute__((always_inline)) void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand) +{ + return __sync_val_compare_and_swap(Destination, Comperand, Exchange); +} + +static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volatile long * const Target, const long Value) +{ + /* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */ + __sync_synchronize(); + return __sync_lock_test_and_set(Target, Value); +} + +static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value) +{ + /* NOTE: ditto */ + __sync_synchronize(); + return __sync_lock_test_and_set(Target, Value); +} + +static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(volatile long * const Addend, const long Value) +{ + return __sync_fetch_and_add(Addend, Value); +} + +static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask) +{ + return __sync_fetch_and_and(value, mask); +} + +static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatile short * const value, const short mask) +{ + return __sync_fetch_and_and(value, mask); +} + +static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask) +{ + return __sync_fetch_and_and(value, mask); +} + +static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask) +{ + return __sync_fetch_and_or(value, mask); +} + +static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask) +{ + return __sync_fetch_and_or(value, mask); +} + +static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask) +{ + return __sync_fetch_and_or(value, mask); +} + +static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask) +{ + return __sync_fetch_and_xor(value, mask); +} + +static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask) +{ + return __sync_fetch_and_xor(value, mask); +} + +static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask) +{ + return __sync_fetch_and_xor(value, mask); +} + +#else + +static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand) +{ + char retval = Comperand; + __asm__("lock; cmpxchgb %b[Exchange], %[Destination]" : [retval] "+a" (retval) : [Destination] "m" (*Destination), [Exchange] "q" (Exchange) : "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand) +{ + short retval = Comperand; + __asm__("lock; cmpxchgw %w[Exchange], %[Destination]" : [retval] "+a" (retval) : [Destination] "m" (*Destination), [Exchange] "q" (Exchange): "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand) +{ + long retval = Comperand; + __asm__("lock; cmpxchgl %k[Exchange], %[Destination]" : [retval] "+a" (retval) : [Destination] "m" (*Destination), [Exchange] "q" (Exchange): "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand) +{ + long long retval = Comperand; + + __asm__ + ( + "cmpxchg8b %[Destination]" : + [retval] "+A" (retval) : + [Destination] "m" (*Destination), + "b" ((unsigned long)((Exchange >> 0) & 0xFFFFFFFF)), + "c" ((unsigned long)((Exchange >> 32) & 0xFFFFFFFF)) : + "memory" + ); + + return retval; +} + +static __inline__ __attribute__((always_inline)) void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand) +{ + void * retval = (void *)Comperand; + __asm__("lock; cmpxchgl %k[Exchange], %[Destination]" : [retval] "=a" (retval) : "[retval]" (retval), [Destination] "m" (*Destination), [Exchange] "q" (Exchange) : "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volatile long * const Target, const long Value) +{ + long retval = Value; + __asm__("xchgl %[retval], %[Target]" : [retval] "+r" (retval) : [Target] "m" (*Target) : "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value) +{ + void * retval = Value; + __asm__("xchgl %[retval], %[Target]" : [retval] "+r" (retval) : [Target] "m" (*Target) : "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(volatile long * const Addend, const long Value) +{ + long retval = Value; + __asm__("lock; xaddl %[retval], %[Addend]" : [retval] "+r" (retval) : [Addend] "m" (*Addend) : "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask) +{ + char x; + char y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange8(value, x & mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatile short * const value, const short mask) +{ + short x; + short y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange16(value, x & mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask) +{ + long x; + long y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange(value, x & mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask) +{ + char x; + char y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange8(value, x | mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask) +{ + short x; + short y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange16(value, x | mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask) +{ + long x; + long y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange(value, x | mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask) +{ + char x; + char y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange8(value, x ^ mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask) +{ + short x; + short y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange16(value, x ^ mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask) +{ + long x; + long y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange(value, x ^ mask, x); + } + while(y != x); + + return y; +} + +#endif + +static __inline__ __attribute__((always_inline)) long _InterlockedAddLargeStatistic(volatile long long * const Addend, const long Value) +{ + __asm__ + ( + "lock; add %[Value], %[Lo32];" + "jae LABEL%=;" + "lock; adc $0, %[Hi32];" + "LABEL%=:;" : + [Lo32] "=m" (*((volatile long *)(Addend) + 0)), [Hi32] "=m" (*((volatile long *)(Addend) + 1)) : + [Value] "ir" (Value) + ); + + return Value; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedDecrement(volatile long * const lpAddend) +{ + return _InterlockedExchangeAdd(lpAddend, -1) - 1; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedIncrement(volatile long * const lpAddend) +{ + return _InterlockedExchangeAdd(lpAddend, 1) + 1; +} + +static __inline__ __attribute__((always_inline)) unsigned char _interlockedbittestandreset(volatile long * a, const long b) +{ + unsigned char retval; + __asm__("lock; btrl %[b], %[a]; setb %b[retval]" : [retval] "=r" (retval), [a] "=m" (a) : [b] "Ir" (b) : "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned char _interlockedbittestandset(volatile long * a, const long b) +{ + unsigned char retval; + __asm__("lock; btsl %[b], %[a]; setc %b[retval]" : [retval] "=r" (retval), [a] "=m" (a) : [b] "Ir" (b) : "memory"); + return retval; +} + + +/*** String operations ***/ +/* NOTE: we don't set a memory clobber in the __stosX functions because Visual C++ doesn't */ +static __inline__ __attribute__((always_inline)) void __stosb(unsigned char * Dest, const unsigned char Data, size_t Count) +{ + __asm__ __volatile__ + ( + "rep; stosb" : + [Dest] "=D" (Dest), [Count] "=c" (Count) : + "[Dest]" (Dest), "a" (Data), "[Count]" (Count) + ); +} + +static __inline__ __attribute__((always_inline)) void __stosw(unsigned short * Dest, const unsigned short Data, size_t Count) +{ + __asm__ __volatile__ + ( + "rep; stosw" : + [Dest] "=D" (Dest), [Count] "=c" (Count) : + "[Dest]" (Dest), "a" (Data), "[Count]" (Count) + ); +} + +static __inline__ __attribute__((always_inline)) void __stosd(unsigned long * Dest, const unsigned long Data, size_t Count) +{ + __asm__ __volatile__ + ( + "rep; stosl" : + [Dest] "=D" (Dest), [Count] "=c" (Count) : + "[Dest]" (Dest), "a" (Data), "[Count]" (Count) + ); +} + +static __inline__ __attribute__((always_inline)) void __movsb(unsigned char * Destination, const unsigned char * Source, size_t Count) +{ + __asm__ __volatile__ + ( + "rep; movsb" : + [Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) : + "[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count) + ); +} + +static __inline__ __attribute__((always_inline)) void __movsw(unsigned short * Destination, const unsigned short * Source, size_t Count) +{ + __asm__ __volatile__ + ( + "rep; movsw" : + [Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) : + "[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count) + ); +} + +static __inline__ __attribute__((always_inline)) void __movsd(unsigned long * Destination, const unsigned long * Source, size_t Count) +{ + __asm__ __volatile__ + ( + "rep; movsd" : + [Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) : + "[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count) + ); +} + + +/*** FS segment addressing ***/ +static __inline__ __attribute__((always_inline)) void __writefsbyte(const unsigned long Offset, const unsigned char Data) +{ + __asm__("movb %b[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __writefsword(const unsigned long Offset, const unsigned short Data) +{ + __asm__("movw %w[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __writefsdword(const unsigned long Offset, const unsigned long Data) +{ + __asm__("movl %k[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + +static __inline__ __attribute__((always_inline)) unsigned char __readfsbyte(const unsigned long Offset) +{ + unsigned char value; + __asm__("movb %%fs:%a[Offset], %b[value]" : [value] "=q" (value) : [Offset] "irm" (Offset)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned short __readfsword(const unsigned long Offset) +{ + unsigned short value; + __asm__("movw %%fs:%a[Offset], %w[value]" : [value] "=q" (value) : [Offset] "irm" (Offset)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readfsdword(const unsigned long Offset) +{ + unsigned long value; + __asm__("movl %%fs:%a[Offset], %k[value]" : [value] "=q" (value) : [Offset] "irm" (Offset)); + return value; +} + +static __inline__ __attribute__((always_inline)) void __incfsbyte(const unsigned long Offset) +{ + __asm__("incb %%fs:%a[Offset]" : : [Offset] "ir" (Offset)); +} + +static __inline__ __attribute__((always_inline)) void __incfsword(const unsigned long Offset) +{ + __asm__("incw %%fs:%a[Offset]" : : [Offset] "ir" (Offset)); +} + +static __inline__ __attribute__((always_inline)) void __incfsdword(const unsigned long Offset) +{ + __asm__("incl %%fs:%a[Offset]" : : [Offset] "ir" (Offset)); +} + +/* NOTE: the bizarre implementation of __addfsxxx mimics the broken Visual C++ behavior */ +static __inline__ __attribute__((always_inline)) void __addfsbyte(const unsigned long Offset, const unsigned char Data) +{ + if(!__builtin_constant_p(Offset)) + __asm__("addb %k[Offset], %%fs:%a[Offset]" : : [Offset] "r" (Offset)); + else + __asm__("addb %b[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __addfsword(const unsigned long Offset, const unsigned short Data) +{ + if(!__builtin_constant_p(Offset)) + __asm__("addw %k[Offset], %%fs:%a[Offset]" : : [Offset] "r" (Offset)); + else + __asm__("addw %w[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __addfsdword(const unsigned long Offset, const unsigned int Data) +{ + if(!__builtin_constant_p(Offset)) + __asm__("addl %k[Offset], %%fs:%a[Offset]" : : [Offset] "r" (Offset)); + else + __asm__("addl %k[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + + +/*** Bit manipulation ***/ +static __inline__ __attribute__((always_inline)) unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask) +{ + __asm__("bsfl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask)); + return Mask ? 1 : 0; +} + +static __inline__ __attribute__((always_inline)) unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask) +{ + __asm__("bsrl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask)); + return Mask ? 1 : 0; +} + +/* NOTE: again, the bizarre implementation follows Visual C++ */ +static __inline__ __attribute__((always_inline)) unsigned char _bittest(const long * const a, const long b) +{ + unsigned char retval; + + if(__builtin_constant_p(b)) + __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32)); + else + __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b)); + + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned char _bittestandcomplement(long * const a, const long b) +{ + unsigned char retval; + + if(__builtin_constant_p(b)) + __asm__("btc %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32)); + else + __asm__("btc %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b)); + + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned char _bittestandreset(long * const a, const long b) +{ + unsigned char retval; + + if(__builtin_constant_p(b)) + __asm__("btr %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32)); + else + __asm__("btr %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b)); + + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned char _bittestandset(long * const a, const long b) +{ + unsigned char retval; + + if(__builtin_constant_p(b)) + __asm__("bts %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32)); + else + __asm__("bts %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b)); + + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned char _rotl8(const unsigned char value, const unsigned char shift) +{ + unsigned char retval; + __asm__("rolb %b[shift], %b[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned short _rotl16(const unsigned short value, const unsigned char shift) +{ + unsigned short retval; + __asm__("rolw %b[shift], %w[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned char _rotr8(const unsigned char value, const unsigned char shift) +{ + unsigned char retval; + __asm__("rorb %b[shift], %b[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned short _rotr16(const unsigned short value, const unsigned char shift) +{ + unsigned short retval; + __asm__("rorw %b[shift], %w[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); + return retval; +} + +/* + NOTE: in __ll_lshift, __ll_rshift and __ull_rshift we use the "A" + constraint (edx:eax) for the Mask argument, because it's the only way GCC + can pass 64-bit operands around - passing the two 32 bit parts separately + just confuses it. Also we declare Bit as an int and then truncate it to + match Visual C++ behavior +*/ +static __inline__ __attribute__((always_inline)) unsigned long long __ll_lshift(const unsigned long long Mask, const int Bit) +{ + unsigned long long retval = Mask; + + __asm__ + ( + "shldl %b[Bit], %%eax, %%edx; sall %b[Bit], %%eax" : + "+A" (retval) : + [Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF) + ); + + return retval; +} + +static __inline__ __attribute__((always_inline)) long long __ll_rshift(const long long Mask, const int Bit) +{ + unsigned long long retval = Mask; + + __asm__ + ( + "shldl %b[Bit], %%eax, %%edx; sarl %b[Bit], %%eax" : + "+A" (retval) : + [Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF) + ); + + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned long long __ull_rshift(const unsigned long long Mask, int Bit) +{ + unsigned long long retval = Mask; + + __asm__ + ( + "shrdl %b[Bit], %%eax, %%edx; shrl %b[Bit], %%eax" : + "+A" (retval) : + [Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF) + ); + + return retval; +} + + +/*** 64-bit math ***/ +static __inline__ __attribute__((always_inline)) long long __emul(const int a, const int b) +{ + long long retval; + __asm__("imull %[b]" : "=A" (retval) : [a] "a" (a), [b] "rm" (b)); + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned long long __emulu(const unsigned int a, const unsigned int b) +{ + unsigned long long retval; + __asm__("mull %[b]" : "=A" (retval) : [a] "a" (a), [b] "rm" (b)); + return retval; +} + + +/*** Port I/O ***/ +static __inline__ __attribute__((always_inline)) unsigned char __inbyte(const unsigned short Port) +{ + unsigned char byte; + __asm__ __volatile__("inb %w[Port], %b[byte]" : [byte] "=a" (byte) : [Port] "Nd" (Port)); + return byte; +} + +static __inline__ __attribute__((always_inline)) unsigned short __inword(const unsigned short Port) +{ + unsigned short word; + __asm__ __volatile__("inw %w[Port], %w[word]" : [word] "=a" (word) : [Port] "Nd" (Port)); + return word; +} + +static __inline__ __attribute__((always_inline)) unsigned long __indword(const unsigned short Port) +{ + unsigned long dword; + __asm__ __volatile__("inl %w[Port], %k[dword]" : [dword] "=a" (dword) : [Port] "Nd" (Port)); + return dword; +} + +static __inline__ __attribute__((always_inline)) void __inbytestring(unsigned short Port, unsigned char * Buffer, unsigned long Count) +{ + __asm__ __volatile__ + ( + "rep; insb" : + [Buffer] "=D" (Buffer), [Count] "=c" (Count) : + "d" (Port), "[Buffer]" (Buffer), "[Count]" (Count) : + "memory" + ); +} + +static __inline__ __attribute__((always_inline)) void __inwordstring(unsigned short Port, unsigned short * Buffer, unsigned long Count) +{ + __asm__ __volatile__ + ( + "rep; insw" : + [Buffer] "=D" (Buffer), [Count] "=c" (Count) : + "d" (Port), "[Buffer]" (Buffer), "[Count]" (Count) : + "memory" + ); +} + +static __inline__ __attribute__((always_inline)) void __indwordstring(unsigned short Port, unsigned long * Buffer, unsigned long Count) +{ + __asm__ __volatile__ + ( + "rep; insl" : + [Buffer] "=D" (Buffer), [Count] "=c" (Count) : + "d" (Port), "[Buffer]" (Buffer), "[Count]" (Count) : + "memory" + ); +} + +static __inline__ __attribute__((always_inline)) void __outbyte(unsigned short const Port, const unsigned char Data) +{ + __asm__ __volatile__("outb %b[Data], %w[Port]" : : [Port] "Nd" (Port), [Data] "a" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __outword(unsigned short const Port, const unsigned short Data) +{ + __asm__ __volatile__("outw %w[Data], %w[Port]" : : [Port] "Nd" (Port), [Data] "a" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __outdword(unsigned short const Port, const unsigned long Data) +{ + __asm__ __volatile__("outl %k[Data], %w[Port]" : : [Port] "Nd" (Port), [Data] "a" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __outbytestring(unsigned short const Port, const unsigned char * const Buffer, const unsigned long Count) +{ + __asm__ __volatile__("rep; outsb" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count)); +} + +static __inline__ __attribute__((always_inline)) void __outwordstring(unsigned short const Port, const unsigned short * const Buffer, const unsigned long Count) +{ + __asm__ __volatile__("rep; outsw" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count)); +} + +static __inline__ __attribute__((always_inline)) void __outdwordstring(unsigned short const Port, const unsigned long * const Buffer, const unsigned long Count) +{ + __asm__ __volatile__("rep; outsl" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count)); +} + + +/*** System information ***/ +static __inline__ __attribute__((always_inline)) void __cpuid(int CPUInfo[], const int InfoType) +{ + __asm__ __volatile__("cpuid" : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "a" (InfoType)); +} + +static __inline__ __attribute__((always_inline)) unsigned long long __rdtsc(void) +{ + unsigned long long retval; + __asm__ __volatile__("rdtsc" : "=A"(retval)); + return retval; +} + + +/*** Interrupts ***/ +static __inline__ __attribute__((always_inline)) void __debugbreak(void) +{ + __asm__("int $3"); +} + +static __inline__ __attribute__((always_inline)) void __int2c(void) +{ + __asm__("int $0x2c"); +} + +static __inline__ __attribute__((always_inline)) void _disable(void) +{ + __asm__("cli"); +} + +static __inline__ __attribute__((always_inline)) void _enable(void) +{ + __asm__("sti"); +} + + +/*** Protected memory management ***/ +static __inline__ __attribute__((always_inline)) unsigned long __readcr0(void) +{ + unsigned long value; + __asm__ __volatile__("mov %%cr0, %[value]" : [value] "=q" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readcr2(void) +{ + unsigned long value; + __asm__ __volatile__("mov %%cr2, %[value]" : [value] "=q" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readcr3(void) +{ + unsigned long value; + __asm__ __volatile__("mov %%cr3, %[value]" : [value] "=q" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readcr4(void) +{ + unsigned long value; + __asm__ __volatile__("mov %%cr4, %[value]" : [value] "=q" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) void __writecr0(const unsigned long long Data) +{ + __asm__("mov %[Data], %%cr0" : : [Data] "q" ((const unsigned long)(Data & 0xFFFFFFFF)) : "memory"); +} + +static __inline__ __attribute__((always_inline)) void __writecr3(const unsigned long long Data) +{ + __asm__("mov %[Data], %%cr3" : : [Data] "q" ((const unsigned long)(Data & 0xFFFFFFFF)) : "memory"); +} + +static __inline__ __attribute__((always_inline)) void __writecr4(const unsigned long long Data) +{ + __asm__("mov %[Data], %%cr4" : : [Data] "q" ((const unsigned long)(Data & 0xFFFFFFFF)) : "memory"); +} + +static __inline__ __attribute__((always_inline)) void __invlpg(void * const Address) +{ + __asm__("invlpg %[Address]" : : [Address] "m" (*((unsigned char *)(Address)))); +} + + +/*** System operations ***/ +static __inline__ __attribute__((always_inline)) unsigned long long __readmsr(const int reg) +{ + unsigned long long retval; + __asm__ __volatile__("rdmsr" : "=A" (retval) : "c" (reg)); + return retval; +} + +static __inline__ __attribute__((always_inline)) void __writemsr(const unsigned long Register, const unsigned long long Value) +{ + __asm__ __volatile__("wrmsr" : : "A" (Value), "c" (Register)); +} + +static __inline__ __attribute__((always_inline)) unsigned long long __readpmc(const int counter) +{ + unsigned long long retval; + __asm__ __volatile__("rdpmc" : "=A" (retval) : "c" (counter)); + return retval; +} + +/* NOTE: an immediate value for 'a' will raise an ICE in Visual C++ */ +static __inline__ __attribute__((always_inline)) unsigned long __segmentlimit(const unsigned long a) +{ + unsigned long retval; + __asm__ __volatile__("lsl %[a], %[retval]" : [retval] "=r" (retval) : [a] "rm" (a)); + return retval; +} + +static __inline__ __attribute__((always_inline)) void __wbinvd(void) +{ + __asm__ __volatile__("wbinvd"); +} + +#endif /* KJK_INTRIN_X86_H_ */ + +/* EOF */ diff --git a/pcsx2/x86/ix86/implement/dwshift.h b/common/include/x86emitter/implement/dwshift.h similarity index 100% rename from pcsx2/x86/ix86/implement/dwshift.h rename to common/include/x86emitter/implement/dwshift.h diff --git a/pcsx2/x86/ix86/implement/group1.h b/common/include/x86emitter/implement/group1.h similarity index 84% rename from pcsx2/x86/ix86/implement/group1.h rename to common/include/x86emitter/implement/group1.h index 2afdc40303..202ed53abf 100644 --- a/pcsx2/x86/ix86/implement/group1.h +++ b/common/include/x86emitter/implement/group1.h @@ -47,22 +47,6 @@ public: EmitSibMagic( from, to ); } - // ------------------------------------------------------------------------ - template< typename T > __forceinline void operator()( const xRegister& to, const void* src ) const - { - prefix16(); - xWrite8( (Is8BitOp() ? 2 : 3) | (InstType<<3) ); - EmitSibMagic( to, src ); - } - - // ------------------------------------------------------------------------ - template< typename T > __forceinline void operator()( void* dest, const xRegister& from ) const - { - prefix16(); - xWrite8( (Is8BitOp() ? 0 : 1) | (InstType<<3) ); - EmitSibMagic( from, dest ); - } - // ------------------------------------------------------------------------ template< typename T > __noinline void operator()( const ModSibBase& sibdest, const xRegister& from ) const { @@ -126,6 +110,37 @@ public: xWrite( imm ); } } + + // ------------------------------------------------------------------------ + template< typename T > __noinline void operator()( const ModSibBase& to, const xImmReg& immOrReg ) const + { + _DoI_helpermess( *this, to, immOrReg ); + } + + template< typename T > __noinline void operator()( const xDirectOrIndirect& to, const xImmReg& immOrReg ) const + { + _DoI_helpermess( *this, to, immOrReg ); + } + + template< typename T > __noinline void operator()( const xDirectOrIndirect& to, int imm ) const + { + _DoI_helpermess( *this, to, imm ); + } + + template< typename T > __noinline void operator()( const xDirectOrIndirect& to, const xDirectOrIndirect& from ) const + { + _DoI_helpermess( *this, to, from ); + } + + template< typename T > __noinline void operator()( const xRegister& to, const xDirectOrIndirect& from ) const + { + _DoI_helpermess( *this, xDirectOrIndirect( to ), from ); + } + + template< typename T > __noinline void operator()( const xDirectOrIndirect& to, const xRegister& from ) const + { + _DoI_helpermess( *this, to, xDirectOrIndirect( from ) ); + } xImpl_Group1() {} // Why does GCC need these? }; @@ -168,7 +183,6 @@ protected: template< u8 Prefix > struct Woot { __forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from, SSE2_ComparisonType cmptype ) const{ xOpWrite0F( Prefix, 0xc2, to, from, (u8)cmptype ); } - __forceinline void operator()( const xRegisterSSE& to, const void* from, SSE2_ComparisonType cmptype ) const { xOpWrite0F( Prefix, 0xc2, to, from, (u8)cmptype ); } __forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from, SSE2_ComparisonType cmptype ) const { xOpWrite0F( Prefix, 0xc2, to, from, (u8)cmptype ); } Woot() {} }; diff --git a/pcsx2/x86/ix86/implement/group2.h b/common/include/x86emitter/implement/group2.h similarity index 88% rename from pcsx2/x86/ix86/implement/group2.h rename to common/include/x86emitter/implement/group2.h index eab5bb2605..647124e19c 100644 --- a/pcsx2/x86/ix86/implement/group2.h +++ b/common/include/x86emitter/implement/group2.h @@ -94,5 +94,17 @@ public: } } + // ------------------------------------------------------------------------ + template< typename T > __noinline void operator()( const xDirectOrIndirect& to, u8 imm ) const + { + _DoI_helpermess( *this, to, imm ); + } + + template< typename T > __noinline void operator()( const xDirectOrIndirect& to, const xRegisterCL& from ) const + { + _DoI_helpermess( *this, to, from ); + } + + Group2ImplAll() {} // I am a class with no members, so I need an explicit constructor! Sense abounds. }; diff --git a/pcsx2/x86/ix86/implement/group3.h b/common/include/x86emitter/implement/group3.h similarity index 94% rename from pcsx2/x86/ix86/implement/group3.h rename to common/include/x86emitter/implement/group3.h index dc9bb169c2..5b5719ff66 100644 --- a/pcsx2/x86/ix86/implement/group3.h +++ b/common/include/x86emitter/implement/group3.h @@ -52,7 +52,11 @@ public: xWrite8( Is8BitOp() ? 0xf6 : 0xf7 ); EmitSibMagic( InstType, from ); } - + + template< typename T > __emitinline void operator()( const xDirectOrIndirect& from ) const + { + _DoI_helpermess( *this, from ); + } xImpl_Group3() {} }; @@ -97,13 +101,11 @@ public: using ImplMulDivBase::operator(); __forceinline void operator()( const xRegister32& to, const xRegister32& from ) const { xOpWrite0F( 0xaf, to, from ); } - __forceinline void operator()( const xRegister32& to, const void* src ) const { xOpWrite0F( 0xaf, to, src ); } __forceinline void operator()( const xRegister32& to, const ModSibBase& src ) const { xOpWrite0F( 0xaf, to, src ); } __forceinline void operator()( const xRegister32& to, const xRegister32& from, s32 imm ) const{ ImmStyle( to, from, imm ); } __forceinline void operator()( const xRegister32& to, const ModSibBase& from, s32 imm ) const { ImmStyle( to, from, imm ); } __forceinline void operator()( const xRegister16& to, const xRegister16& from ) const { xOpWrite0F( 0x66, 0xaf, to, from ); } - __forceinline void operator()( const xRegister16& to, const void* src ) const { xOpWrite0F( 0x66, 0xaf, to, src ); } __forceinline void operator()( const xRegister16& to, const ModSibBase& src ) const { xOpWrite0F( 0x66, 0xaf, to, src ); } __forceinline void operator()( const xRegister16& to, const xRegister16& from, s16 imm ) const{ ImmStyle( to, from, imm ); } __forceinline void operator()( const xRegister16& to, const ModSibBase& from, s16 imm ) const { ImmStyle( to, from, imm ); } diff --git a/common/include/x86emitter/implement/helpers.h b/common/include/x86emitter/implement/helpers.h new file mode 100644 index 0000000000..4f0e357e8e --- /dev/null +++ b/common/include/x86emitter/implement/helpers.h @@ -0,0 +1,157 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +// ------------------------------------------------------------------------ +// helpers.h -- Various universally helpful functions for emitter convenience! +// +// Note: Header file should be included from the x86Emitter::Internal namespace, such +// that all members contained within are in said namespace. +// ------------------------------------------------------------------------ + + +#pragma once + +extern void SimdPrefix( u8 prefix, u16 opcode ); +extern void EmitSibMagic( uint regfield, const void* address ); +extern void EmitSibMagic( uint regfield, const ModSibBase& info ); +extern void xJccKnownTarget( JccComparisonType comparison, const void* target, bool slideForward ); + +template< typename T > bool Is8BitOp() { return sizeof(T) == 1; } +template< typename T > void prefix16() { if( sizeof(T) == 2 ) xWrite8( 0x66 ); } + + +// Writes a ModRM byte for "Direct" register access forms, which is used for all +// instructions taking a form of [reg,reg]. +template< typename T > __emitinline +void EmitSibMagic( uint reg1, const xRegisterBase& reg2 ) +{ + xWrite8( (Mod_Direct << 6) | (reg1 << 3) | reg2.Id ); +} + +template< typename T1, typename T2 > __emitinline +void EmitSibMagic( const xRegisterBase reg1, const xRegisterBase& reg2 ) +{ + xWrite8( (Mod_Direct << 6) | (reg1.Id << 3) | reg2.Id ); +} + +template< typename T1 > __emitinline +void EmitSibMagic( const xRegisterBase reg1, const void* src ) { EmitSibMagic( reg1.Id, src ); } + +template< typename T1 > __emitinline +void EmitSibMagic( const xRegisterBase reg1, const ModSibBase& sib ) { EmitSibMagic( reg1.Id, sib ); } + +// ------------------------------------------------------------------------ +template< typename T1, typename T2 > __emitinline +void xOpWrite( u8 prefix, u8 opcode, const T1& param1, const T2& param2 ) +{ + if( prefix != 0 ) + xWrite16( (opcode<<8) | prefix ); + else + xWrite8( opcode ); + + EmitSibMagic( param1, param2 ); +} + +// ------------------------------------------------------------------------ +template< typename T1, typename T2 > __emitinline +void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2 ) +{ + SimdPrefix( prefix, opcode ); + EmitSibMagic( param1, param2 ); +} + +template< typename T1, typename T2 > __emitinline +void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2, u8 imm8 ) +{ + xOpWrite0F( prefix, opcode, param1, param2 ); + xWrite8( imm8 ); +} + +template< typename T1, typename T2 > __emitinline +void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2 ) { xOpWrite0F( 0, opcode, param1, param2 ); } + +template< typename T1, typename T2 > __emitinline +void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2, u8 imm8 ) { xOpWrite0F( 0, opcode, param1, param2, imm8 ); } + +// ------------------------------------------------------------------------ + +template< typename xImpl, typename T > +void _DoI_helpermess( const xImpl& helpme, const xDirectOrIndirect& to, const xImmReg& immOrReg ) +{ + if( to.IsDirect() ) + { + if( immOrReg.IsReg() ) + helpme( to.GetReg(), immOrReg.GetReg() ); + else + helpme( to.GetReg(), immOrReg.GetImm() ); + } + else + { + if( immOrReg.IsReg() ) + helpme( to.GetMem(), immOrReg.GetReg() ); + else + helpme( to.GetMem(), immOrReg.GetImm() ); + } +} + +template< typename xImpl, typename T > +void _DoI_helpermess( const xImpl& helpme, const ModSibBase& to, const xImmReg& immOrReg ) +{ + if( immOrReg.IsReg() ) + helpme( to, immOrReg.GetReg() ); + else + helpme( ModSibStrict(to), immOrReg.GetImm() ); +} + +template< typename xImpl, typename T > +void _DoI_helpermess( const xImpl& helpme, const xDirectOrIndirect& to, int imm ) +{ + if( to.IsDirect() ) + helpme( to.GetReg(), imm ); + else + helpme( to.GetMem(), imm ); +} + +template< typename xImpl, typename T > +void _DoI_helpermess( const xImpl& helpme, const xDirectOrIndirect& parm ) +{ + if( parm.IsDirect() ) + helpme( parm.GetReg() ); + else + helpme( parm.GetMem() ); +} + +template< typename xImpl, typename T > +void _DoI_helpermess( const xImpl& helpme, const xDirectOrIndirect& to, const xDirectOrIndirect& from ) +{ + if( to.IsDirect() && from.IsDirect() ) + helpme( to.GetReg(), from.GetReg() ); + + else if( to.IsDirect() ) + helpme( to.GetReg(), from.GetMem() ); + + else if( from.IsDirect() ) + helpme( to.GetMem(), from.GetReg() ); + + else + + // One of the fields needs to be direct, or else we cannot complete the operation. + // (intel doesn't support indirects in both fields) + + jASSUME( false ); +} diff --git a/pcsx2/x86/ix86/implement/incdec.h b/common/include/x86emitter/implement/incdec.h similarity index 100% rename from pcsx2/x86/ix86/implement/incdec.h rename to common/include/x86emitter/implement/incdec.h diff --git a/pcsx2/x86/ix86/implement/jmpcall.h b/common/include/x86emitter/implement/jmpcall.h similarity index 100% rename from pcsx2/x86/ix86/implement/jmpcall.h rename to common/include/x86emitter/implement/jmpcall.h diff --git a/common/include/x86emitter/implement/movs.h b/common/include/x86emitter/implement/movs.h new file mode 100644 index 0000000000..14ac196c31 --- /dev/null +++ b/common/include/x86emitter/implement/movs.h @@ -0,0 +1,239 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +// Header: ix86_impl_movs.h -- covers mov, cmov, movsx/movzx, and SETcc (which shares +// with cmov many similarities). + +// Note: This header is meant to be included from within the x86Emitter::Internal namespace. + +////////////////////////////////////////////////////////////////////////////////////////// +// MOV instruction Implementation + +class MovImplAll +{ +public: + // ------------------------------------------------------------------------ + template< typename T > __forceinline void operator()( const xRegister& to, const xRegister& from ) const + { + if( to == from ) return; // ignore redundant MOVs. + + prefix16(); + xWrite8( Is8BitOp() ? 0x88 : 0x89 ); + EmitSibMagic( from, to ); + } + + // ------------------------------------------------------------------------ + template< typename T > __noinline void operator()( const ModSibBase& dest, const xRegister& from ) const + { + prefix16(); + + // mov eax has a special from when writing directly to a DISP32 address + // (sans any register index/base registers). + + if( from.IsAccumulator() && dest.Index.IsEmpty() && dest.Base.IsEmpty() ) + { + xWrite8( Is8BitOp() ? 0xa2 : 0xa3 ); + xWrite32( dest.Displacement ); + } + else + { + xWrite8( Is8BitOp() ? 0x88 : 0x89 ); + EmitSibMagic( from.Id, dest ); + } + } + + // ------------------------------------------------------------------------ + template< typename T > __noinline void operator()( const xRegister& to, const ModSibBase& src ) const + { + prefix16(); + + // mov eax has a special from when reading directly from a DISP32 address + // (sans any register index/base registers). + + if( to.IsAccumulator() && src.Index.IsEmpty() && src.Base.IsEmpty() ) + { + xWrite8( Is8BitOp() ? 0xa0 : 0xa1 ); + xWrite32( src.Displacement ); + } + else + { + xWrite8( Is8BitOp() ? 0x8a : 0x8b ); + EmitSibMagic( to, src ); + } + } + + // ------------------------------------------------------------------------ + template< typename T > __noinline void operator()( const ModSibStrict& dest, int imm ) const + { + prefix16(); + xWrite8( Is8BitOp() ? 0xc6 : 0xc7 ); + EmitSibMagic( 0, dest ); + xWrite( imm ); + } + + // ------------------------------------------------------------------------ + // preserve_flags - set to true to disable optimizations which could alter the state of + // the flags (namely replacing mov reg,0 with xor). + template< typename T > __emitinline void operator()( const xRegister& to, int imm, bool preserve_flags=false ) const + { + if( !preserve_flags && (imm == 0) ) + xXOR( to, to ); + else + { + // Note: MOV does not have (reg16/32,imm8) forms. + + prefix16(); + xWrite8( (Is8BitOp() ? 0xb0 : 0xb8) | to.Id ); + xWrite( imm ); + } + } + + // ------------------------------------------------------------------------ + template< typename T > __noinline void operator()( const ModSibBase& to, const xImmReg& immOrReg ) const + { + _DoI_helpermess( *this, to, immOrReg ); + } + + template< typename T > __noinline void operator()( const xDirectOrIndirect& to, const xImmReg& immOrReg ) const + { + _DoI_helpermess( *this, to, immOrReg ); + } + + template< typename T > __noinline void operator()( const xDirectOrIndirect& to, int imm ) const + { + _DoI_helpermess( *this, to, imm ); + } + + template< typename T > __noinline void operator()( const xDirectOrIndirect& to, const xDirectOrIndirect& from ) const + { + if( to == from ) return; + _DoI_helpermess( *this, to, from ); + } + + template< typename T > __noinline void operator()( const xRegister& to, const xDirectOrIndirect& from ) const + { + _DoI_helpermess( *this, xDirectOrIndirect( to ), from ); + } + + template< typename T > __noinline void operator()( const xDirectOrIndirect& to, const xRegister& from ) const + { + _DoI_helpermess( *this, to, xDirectOrIndirect( from ) ); + } + + MovImplAll() {} // Satisfy GCC's whims. +}; + +#define ccSane() jASSUME( ccType >= 0 && ccType <= 0x0f ) + +////////////////////////////////////////////////////////////////////////////////////////// +// CMOV !! [in all of it's disappointing lack-of glory] .. and .. +// SETcc!! [more glory, less lack!] +// +// CMOV Disclaimer: Caution! This instruction can look exciting and cool, until you +// realize that it cannot load immediate values into registers. -_- +// +// I use explicit method declarations here instead of templates, in order to provide +// *only* 32 and 16 bit register operand forms (8 bit registers are not valid in CMOV). +// +class CMovImplGeneric +{ +public: + __forceinline void operator()( JccComparisonType ccType, const xRegister32& to, const xRegister32& from ) const { ccSane(); xOpWrite0F( 0x40 | ccType, to, from ); } + __noinline void operator()( JccComparisonType ccType, const xRegister32& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( 0x40 | ccType, to, sibsrc ); } + //__noinline void operator()( JccComparisonType ccType, const xDirectOrIndirect32& to, const xDirectOrIndirect32& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); } // too.. lazy.. to fix. + + __forceinline void operator()( JccComparisonType ccType, const xRegister16& to, const xRegister16& from ) const { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, from ); } + __noinline void operator()( JccComparisonType ccType, const xRegister16& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, sibsrc ); } + //__noinline void operator()( JccComparisonType ccType, const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); } + + CMovImplGeneric() {} // don't ask. +}; + +// ------------------------------------------------------------------------ +template< JccComparisonType ccType > +class CMovImplAll +{ + static const u16 Opcode = 0x40 | ccType; + +public: + __forceinline void operator()( const xRegister32& to, const xRegister32& from ) const { ccSane(); xOpWrite0F( Opcode, to, from ); } + __noinline void operator()( const xRegister32& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( Opcode, to, sibsrc ); } + __noinline void operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); } + + __forceinline void operator()( const xRegister16& to, const xRegister16& from ) const { ccSane(); xOpWrite0F( 0x66, Opcode, to, from ); } + __noinline void operator()( const xRegister16& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( 0x66, Opcode, to, sibsrc ); } + __noinline void operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); } + + CMovImplAll() {} // don't ask. +}; + +// ------------------------------------------------------------------------ +class SetImplGeneric +{ + // note: SETcc are 0x90, with 0 in the Reg field of ModRM. +public: + __forceinline void operator()( JccComparisonType ccType, const xRegister8& to ) const { ccSane(); xOpWrite0F( 0x90 | ccType, 0, to ); } + __noinline void operator()( JccComparisonType ccType, const ModSibStrict& dest ) const { ccSane(); xOpWrite0F( 0x90 | ccType, 0, dest ); } + + SetImplGeneric() {} // if you do, ask GCC. +}; + +// ------------------------------------------------------------------------ +template< JccComparisonType ccType > +class SetImplAll +{ + static const u16 Opcode = 0x90 | ccType; // SETcc are 0x90 base opcode, with 0 in the Reg field of ModRM. + +public: + __forceinline void operator()( const xRegister8& to ) const { ccSane(); xOpWrite0F( Opcode, 0, to ); } + __noinline void operator()( const ModSibStrict& dest ) const { ccSane(); xOpWrite0F( Opcode, 0, dest ); } + __noinline void operator()( const xDirectOrIndirect8& dest ) const { ccSane(); _DoI_helpermess( *this, dest ); } + + SetImplAll() {} // if you do, ask GCC. +}; + + +////////////////////////////////////////////////////////////////////////////////////////// +// Mov with sign/zero extension implementations (movsx / movzx) +// + +// ------------------------------------------------------------------------ +template< bool SignExtend > +class MovExtendImplAll +{ +protected: + static const u16 Opcode = 0xb6 | (SignExtend ? 8 : 0 ); + +public: + __forceinline void operator()( const xRegister32& to, const xRegister16& from ) const { xOpWrite0F( Opcode+1, to, from ); } + __noinline void operator()( const xRegister32& to, const ModSibStrict& sibsrc ) const { xOpWrite0F( Opcode+1, to, sibsrc ); } + __noinline void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const { _DoI_helpermess( *this, to, src ); } + + __forceinline void operator()( const xRegister32& to, const xRegister8& from ) const { xOpWrite0F( Opcode, to, from ); } + __noinline void operator()( const xRegister32& to, const ModSibStrict& sibsrc ) const { xOpWrite0F( Opcode, to, sibsrc ); } + __noinline void operator()( const xRegister32& to, const xDirectOrIndirect8& src ) const { _DoI_helpermess( *this, to, src ); } + + __forceinline void operator()( const xRegister16& to, const xRegister8& from ) const { xOpWrite0F( 0x66, Opcode, to, from ); } + __noinline void operator()( const xRegister16& to, const ModSibStrict& sibsrc ) const { xOpWrite0F( 0x66, Opcode, to, sibsrc ); } + __noinline void operator()( const xRegister16& to, const xDirectOrIndirect8& src ) const { _DoI_helpermess( *this, to, src ); } + + MovExtendImplAll() {} // don't ask. +}; + diff --git a/pcsx2/x86/ix86/implement/test.h b/common/include/x86emitter/implement/test.h similarity index 84% rename from pcsx2/x86/ix86/implement/test.h rename to common/include/x86emitter/implement/test.h index 4771d6ecf5..6e8ebc1783 100644 --- a/pcsx2/x86/ix86/implement/test.h +++ b/common/include/x86emitter/implement/test.h @@ -86,8 +86,6 @@ public: __forceinline void operator()( const xRegister32& to, const xRegister32& from ) const { xOpWrite0F( Opcode, to, from ); } __forceinline void operator()( const xRegister16& to, const xRegister16& from ) const { xOpWrite0F( 0x66, Opcode, to, from ); } - __forceinline void operator()( const xRegister32& to, const void* src ) const { xOpWrite0F( Opcode, to, src ); } - __forceinline void operator()( const xRegister16& to, const void* src ) const { xOpWrite0F( 0x66, Opcode, to, src ); } __forceinline void operator()( const xRegister32& to, const ModSibBase& sibsrc ) const { xOpWrite0F( Opcode, to, sibsrc ); } __forceinline void operator()( const xRegister16& to, const ModSibBase& sibsrc ) const { xOpWrite0F( 0x66, Opcode, to, sibsrc ); } }; @@ -104,13 +102,9 @@ public: __forceinline void operator()( const xRegister16& bitbase, const xRegister16& bitoffset ) const { xOpWrite0F( 0x66, RegFormOp, bitbase, bitoffset ); } __forceinline void operator()( const ModSibBase& bitbase, const xRegister32& bitoffset ) const { xOpWrite0F( RegFormOp, bitoffset, bitbase ); } __forceinline void operator()( const ModSibBase& bitbase, const xRegister16& bitoffset ) const { xOpWrite0F( 0x66, RegFormOp, bitoffset, bitbase ); } - __forceinline void operator()( const void* bitbase, const xRegister32& bitoffset ) const { xOpWrite0F( 0xab, bitoffset, bitbase ); } - __forceinline void operator()( const void* bitbase, const xRegister16& bitoffset ) const { xOpWrite0F( 0x66, RegFormOp, bitoffset, bitbase ); } __forceinline void operator()( const ModSibStrict& bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); } __forceinline void operator()( const ModSibStrict& bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); } - __forceinline void operator()( const u32* bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); } - __forceinline void operator()( const u16* bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); } __forceinline void operator()( const xRegister& bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); } __forceinline void operator()( const xRegister& bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); } diff --git a/pcsx2/x86/ix86/implement/xchg.h b/common/include/x86emitter/implement/xchg.h similarity index 100% rename from pcsx2/x86/ix86/implement/xchg.h rename to common/include/x86emitter/implement/xchg.h diff --git a/pcsx2/x86/ix86/implement/xmm/arithmetic.h b/common/include/x86emitter/implement/xmm/arithmetic.h similarity index 98% rename from pcsx2/x86/ix86/implement/xmm/arithmetic.h rename to common/include/x86emitter/implement/xmm/arithmetic.h index 328070ce2d..43a9209bf3 100644 --- a/pcsx2/x86/ix86/implement/xmm/arithmetic.h +++ b/common/include/x86emitter/implement/xmm/arithmetic.h @@ -29,11 +29,9 @@ public: _SimdShiftHelper() {} __forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( 0x66, Opcode1, to, from ); } - __forceinline void operator()( const xRegisterSSE& to, const void* from ) const { xOpWrite0F( 0x66, Opcode1, to, from ); } __forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( 0x66, Opcode1, to, from ); } __forceinline void operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const { xOpWrite0F( Opcode1, to, from ); } - __forceinline void operator()( const xRegisterMMX& to, const void* from ) const { xOpWrite0F( Opcode1, to, from ); } __forceinline void operator()( const xRegisterMMX& to, const ModSibBase& from ) const { xOpWrite0F( Opcode1, to, from ); } diff --git a/pcsx2/x86/ix86/implement/xmm/basehelpers.h b/common/include/x86emitter/implement/xmm/basehelpers.h similarity index 84% rename from pcsx2/x86/ix86/implement/xmm/basehelpers.h rename to common/include/x86emitter/implement/xmm/basehelpers.h index 05ef74d5a7..3af268793f 100644 --- a/pcsx2/x86/ix86/implement/xmm/basehelpers.h +++ b/common/include/x86emitter/implement/xmm/basehelpers.h @@ -30,7 +30,6 @@ class SimdImpl_DestRegSSE { public: __forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } - __forceinline void operator()( const xRegisterSSE& to, const void* from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } __forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } SimdImpl_DestRegSSE() {} //GCWho? @@ -45,7 +44,6 @@ class SimdImpl_DestRegImmSSE { public: __forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); } - __forceinline void operator()( const xRegisterSSE& to, const void* from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); } __forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); } SimdImpl_DestRegImmSSE() {} //GCWho? @@ -56,7 +54,6 @@ class SimdImpl_DestRegImmMMX { public: __forceinline void operator()( const xRegisterMMX& to, const xRegisterMMX& from, u8 imm ) const { xOpWrite0F( Opcode, to, from, imm ); } - __forceinline void operator()( const xRegisterMMX& to, const void* from, u8 imm ) const { xOpWrite0F( Opcode, to, from, imm ); } __forceinline void operator()( const xRegisterMMX& to, const ModSibBase& from, u8 imm ) const { xOpWrite0F( Opcode, to, from, imm ); } SimdImpl_DestRegImmMMX() {} //GCWho? @@ -71,11 +68,9 @@ class SimdImpl_DestRegEither { public: __forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } - __forceinline void operator()( const xRegisterSSE& to, const void* from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } __forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } __forceinline void operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const { xOpWrite0F( Opcode, to, from ); } - __forceinline void operator()( const xRegisterMMX& to, const void* from ) const { xOpWrite0F( Opcode, to, from ); } __forceinline void operator()( const xRegisterMMX& to, const ModSibBase& from ) const { xOpWrite0F( Opcode, to, from ); } SimdImpl_DestRegEither() {} //GCWho? @@ -95,7 +90,6 @@ class SimdImpl_DestRegStrict { public: __forceinline void operator()( const DestRegType& to, const SrcRegType& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } - __forceinline void operator()( const DestRegType& to, const SrcOperandType* from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } __forceinline void operator()( const DestRegType& to, const ModSibStrict& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } SimdImpl_DestRegStrict() {} //GCWho? diff --git a/pcsx2/x86/ix86/implement/xmm/comparisons.h b/common/include/x86emitter/implement/xmm/comparisons.h similarity index 92% rename from pcsx2/x86/ix86/implement/xmm/comparisons.h rename to common/include/x86emitter/implement/xmm/comparisons.h index e74d25b1f9..064d170bdc 100644 --- a/pcsx2/x86/ix86/implement/xmm/comparisons.h +++ b/common/include/x86emitter/implement/xmm/comparisons.h @@ -42,7 +42,6 @@ protected: template< u8 Prefix > struct Woot { __forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, 0xc2, to, from ); xWrite8( CType ); } - __forceinline void operator()( const xRegisterSSE& to, const void* from ) const { xOpWrite0F( Prefix, 0xc2, to, from ); xWrite8( CType ); } __forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( Prefix, 0xc2, to, from ); xWrite8( CType ); } Woot() {} }; @@ -55,6 +54,22 @@ public: SimdImpl_Compare() {} //GCWhat? }; +////////////////////////////////////////////////////////////////////////////////////////// +// Compare scalar floating point values and set EFLAGS (Ordered or Unordered) +// +template< bool Ordered > +class SimdImpl_COMI +{ +protected: + static const u16 OpcodeSSE = Ordered ? 0x2f : 0x2e; + +public: + const SimdImpl_DestRegSSE<0x00,OpcodeSSE> SS; + const SimdImpl_DestRegSSE<0x66,OpcodeSSE> SD; + + SimdImpl_COMI() {} +}; + ////////////////////////////////////////////////////////////////////////////////////////// // diff --git a/pcsx2/x86/ix86/implement/xmm/moremovs.h b/common/include/x86emitter/implement/xmm/moremovs.h similarity index 82% rename from pcsx2/x86/ix86/implement/xmm/moremovs.h rename to common/include/x86emitter/implement/xmm/moremovs.h index ce56078494..312d320bfd 100644 --- a/pcsx2/x86/ix86/implement/xmm/moremovs.h +++ b/common/include/x86emitter/implement/xmm/moremovs.h @@ -5,12 +5,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA @@ -30,8 +30,6 @@ protected: struct Woot { Woot() {} - __forceinline void operator()( const xRegisterSSE& to, const void* from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } - __forceinline void operator()( const void* to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, Opcode+1, from, to ); } __forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } __forceinline void operator()( const ModSibBase& to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, Opcode+1, from, to ); } }; @@ -63,12 +61,13 @@ public: // All implementations of Unaligned Movs will, when possible, use aligned movs instead. // This happens when using Mem,Reg or Reg,Mem forms where the address is simple displacement // which can be checked for alignment at runtime. -// +// + template< u8 Prefix, bool isAligned > class SimdImpl_MoveSSE { - static const uint OpcodeA = 0x28; // Aligned [aps] form - static const uint OpcodeU = 0x10; // unaligned [ups] form + static const u16 OpcodeA = 0x28; // Aligned [aps] form + static const u16 OpcodeU = 0x10; // unaligned [ups] form public: SimdImpl_MoveSSE() {} //GCC. @@ -78,21 +77,19 @@ public: if( to != from ) xOpWrite0F( Prefix, OpcodeA, to, from ); } - __forceinline void operator()( const xRegisterSSE& to, const void* from ) const - { - xOpWrite0F( Prefix, (isAligned || ((uptr)from & 0x0f) == 0) ? OpcodeA : OpcodeU, to, from ); - } - - __forceinline void operator()( void* to, const xRegisterSSE& from ) const - { - xOpWrite0F( Prefix, (isAligned || ((uptr)to & 0x0f) == 0) ? OpcodeA+1 : OpcodeU+1, from, to ); - } - __forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { // ModSib form is aligned if it's displacement-only and the displacement is aligned: bool isReallyAligned = isAligned || ( ((from.Displacement & 0x0f) == 0) && from.Index.IsEmpty() && from.Base.IsEmpty() ); - xOpWrite0F( Prefix, isReallyAligned ? OpcodeA : OpcodeU, to, from ); + u16 opcode; + + // See previous comment. + if (isReallyAligned) + opcode = OpcodeA; + else + opcode = OpcodeU; + + xOpWrite0F( Prefix, opcode, to, from ); } __forceinline void operator()( const ModSibBase& to, const xRegisterSSE& from ) const @@ -123,16 +120,6 @@ public: if( to != from ) xOpWrite0F( PrefixA, Opcode, to, from ); } - __forceinline void operator()( const xRegisterSSE& to, const void* from ) const - { - xOpWrite0F( (isAligned || ((uptr)from & 0x0f) == 0) ? PrefixA : PrefixU, Opcode, to, from ); - } - - __forceinline void operator()( const void* to, const xRegisterSSE& from ) const - { - xOpWrite0F( (isAligned || ((uptr)from & 0x0f) == 0) ? PrefixA : PrefixU, Opcode_Alt, to, from ); - } - __forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { // ModSib form is aligned if it's displacement-only and the displacement is aligned: @@ -148,18 +135,6 @@ public: } }; - -////////////////////////////////////////////////////////////////////////////////////////// -// -template< u8 AltPrefix, u16 OpcodeSSE > -class SimdImpl_UcomI -{ -public: - const SimdImpl_DestRegSSE<0x00,OpcodeSSE> SS; - const SimdImpl_DestRegSSE SD; - SimdImpl_UcomI() {} -}; - ////////////////////////////////////////////////////////////////////////////////////////// // Blend - Conditional copying of values in src into dest. // @@ -168,7 +143,7 @@ class SimdImpl_Blend public: // [SSE-4.1] Conditionally copies dword values from src to dest, depending on the // mask bits in the immediate operand (bits [3:0]). Each mask bit corresponds to a - // dword element in a 128-bit operand. + // dword element in a 128-bit operand. // // If a mask bit is 1, then the corresponding dword in the source operand is copied // to dest, else the dword element in dest is left unchanged. @@ -177,25 +152,25 @@ public: // [SSE-4.1] Conditionally copies quadword values from src to dest, depending on the // mask bits in the immediate operand (bits [1:0]). Each mask bit corresponds to a - // quadword element in a 128-bit operand. + // quadword element in a 128-bit operand. // // If a mask bit is 1, then the corresponding dword in the source operand is copied // to dest, else the dword element in dest is left unchanged. // SimdImpl_DestRegImmSSE<0x66,0x0d3a> PD; - + // [SSE-4.1] Conditionally copies dword values from src to dest, depending on the // mask (bits [3:0]) in XMM0 (yes, the fixed register). Each mask bit corresponds - // to a dword element in the 128-bit operand. + // to a dword element in the 128-bit operand. // // If a mask bit is 1, then the corresponding dword in the source operand is copied // to dest, else the dword element in dest is left unchanged. // SimdImpl_DestRegSSE<0x66,0x1438> VPS; - + // [SSE-4.1] Conditionally copies quadword values from src to dest, depending on the // mask (bits [1:0]) in XMM0 (yes, the fixed register). Each mask bit corresponds - // to a quadword element in the 128-bit operand. + // to a quadword element in the 128-bit operand. // // If a mask bit is 1, then the corresponding dword in the source operand is copied // to dest, else the dword element in dest is left unchanged. @@ -223,7 +198,7 @@ public: // [SSE-4.1] Zero/Sign-extend the low byte values in src into qword integers // and store them in dest. SimdImpl_DestRegStrict<0x66,OpcodeBase+0x200,xRegisterSSE,xRegisterSSE,u16> BQ; - + // [SSE-4.1] Zero/Sign-extend the low word values in src into dword integers // and store them in dest. SimdImpl_DestRegStrict<0x66,OpcodeBase+0x300,xRegisterSSE,xRegisterSSE,u64> WD; diff --git a/pcsx2/x86/ix86/implement/xmm/shufflepack.h b/common/include/x86emitter/implement/xmm/shufflepack.h similarity index 91% rename from pcsx2/x86/ix86/implement/xmm/shufflepack.h rename to common/include/x86emitter/implement/xmm/shufflepack.h index f251393056..e7ef281d64 100644 --- a/pcsx2/x86/ix86/implement/xmm/shufflepack.h +++ b/common/include/x86emitter/implement/xmm/shufflepack.h @@ -27,7 +27,6 @@ protected: template< u8 Prefix > struct Woot { __forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from, u8 cmptype ) const { xOpWrite0F( Prefix, OpcodeSSE, to, from ); xWrite8( cmptype ); } - __forceinline void operator()( const xRegisterSSE& to, const void* from, u8 cmptype ) const { xOpWrite0F( Prefix, OpcodeSSE, to, from ); xWrite8( cmptype ); } __forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from, u8 cmptype ) const { xOpWrite0F( Prefix, OpcodeSSE, to, from ); xWrite8( cmptype ); } Woot() {} }; @@ -185,11 +184,6 @@ protected: xOpWrite0F( 0x66, (Opcode<<8) | 0x3a, to, from, imm8 ); } - __forceinline void operator()( const xRegisterSSE& to, const void* from, u8 imm8 ) const - { - xOpWrite0F( 0x66, (Opcode<<8) | 0x3a, to, from, imm8 ); - } - __forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from, u8 imm8 ) const { xOpWrite0F( 0x66, (Opcode<<8) | 0x3a, to, from, imm8 ); @@ -201,11 +195,9 @@ public: // Operation can be performed on either MMX or SSE src operands. __forceinline void W( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); } - __forceinline void W( const xRegisterSSE& to, const void* from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); } __forceinline void W( const xRegisterSSE& to, const ModSibBase& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); } __forceinline void W( const xRegisterMMX& to, const xRegister32& from, u8 imm8 ) const { xOpWrite0F( 0xc4, to, from, imm8 ); } - __forceinline void W( const xRegisterMMX& to, const void* from, u8 imm8 ) const { xOpWrite0F( 0xc4, to, from, imm8 ); } __forceinline void W( const xRegisterMMX& to, const ModSibBase& from, u8 imm8 ) const { xOpWrite0F( 0xc4, to, from, imm8 ); } // [SSE-4.1] @@ -235,11 +227,6 @@ protected: xOpWrite0F( 0x66, (Opcode<<8) | 0x3a, to, from, imm8 ); } - __forceinline void operator()( void* dest, const xRegisterSSE& from, u8 imm8 ) const - { - xOpWrite0F( 0x66, (Opcode<<8) | 0x3a, from, dest, imm8 ); - } - __forceinline void operator()( const ModSibBase& dest, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, (Opcode<<8) | 0x3a, from, dest, imm8 ); @@ -258,7 +245,6 @@ public: __forceinline void W( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc5, to, from, imm8 ); } __forceinline void W( const xRegister32& to, const xRegisterMMX& from, u8 imm8 ) const { xOpWrite0F( 0xc5, to, from, imm8 ); } - __forceinline void W( void* dest, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0x153a, from, dest, imm8 ); } __forceinline void W( const ModSibBase& dest, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0x153a, from, dest, imm8 ); } // [SSE-4.1] Copies the byte element specified by imm8 from src to dest. The upper bits diff --git a/pcsx2/x86/ix86/ix86_inlines.inl b/common/include/x86emitter/inlines.inl similarity index 68% rename from pcsx2/x86/ix86/ix86_inlines.inl rename to common/include/x86emitter/inlines.inl index 9eedcb0b1a..424beec7b1 100644 --- a/pcsx2/x86/ix86/ix86_inlines.inl +++ b/common/include/x86emitter/inlines.inl @@ -46,35 +46,101 @@ // global optimization fails to resolve the externals and junk. // (score one for MSVC!) -#include "System.h" - namespace x86Emitter { + extern const char *const x86_regnames_gpr8[8]; + extern const char *const x86_regnames_gpr16[8]; + extern const char *const x86_regnames_gpr32[8]; + + extern const char *const x86_regnames_sse[8]; + extern const char *const x86_regnames_mmx[8]; + + ////////////////////////////////////////////////////////////////////////////////////////// + // Diagnostic -- returns a string representation of this register. + // + template< typename T > + const char* xGetRegName( const xRegister& src ) + { + if( src.IsEmpty() ) return "empty"; + + switch( sizeof(T) ) + { + case 1: return x86_regnames_gpr8[ src.Id ]; + case 2: return x86_regnames_gpr16[ src.Id ]; + case 4: return x86_regnames_gpr32[ src.Id ]; + + jNO_DEFAULT + } + + return "oops?"; + } + + template< typename T > + const char* xGetRegName( const xRegisterSIMD& src ) + { + if( src.IsEmpty() ) return "empty"; + + switch( sizeof(T) ) + { + case 8: return x86_regnames_mmx[ src.Id ]; + case 16: return x86_regnames_sse[ src.Id ]; + + jNO_DEFAULT + } + + return "oops?"; + } + ////////////////////////////////////////////////////////////////////////////////////////// // x86Register Method Implementations // __forceinline xAddressInfo xAddressReg::operator+( const xAddressReg& right ) const { + jASSUME( Id != -1 ); return xAddressInfo( *this, right ); } __forceinline xAddressInfo xAddressReg::operator+( const xAddressInfo& right ) const { + jASSUME( Id != -1 ); return right + *this; } __forceinline xAddressInfo xAddressReg::operator+( s32 right ) const { + jASSUME( Id != -1 ); return xAddressInfo( *this, right ); } + __forceinline xAddressInfo xAddressReg::operator+( const void* right ) const + { + jASSUME( Id != -1 ); + return xAddressInfo( *this, (s32)right ); + } + + // ------------------------------------------------------------------------ + __forceinline xAddressInfo xAddressReg::operator-( s32 right ) const + { + jASSUME( Id != -1 ); + return xAddressInfo( *this, -right ); + } + + __forceinline xAddressInfo xAddressReg::operator-( const void* right ) const + { + jASSUME( Id != -1 ); + return xAddressInfo( *this, -(s32)right ); + } + + // ------------------------------------------------------------------------ __forceinline xAddressInfo xAddressReg::operator*( u32 right ) const { + jASSUME( Id != -1 ); return xAddressInfo( Empty, *this, right ); } __forceinline xAddressInfo xAddressReg::operator<<( u32 shift ) const { + jASSUME( Id != -1 ); return xAddressInfo( Empty, *this, 1< xMOVSHDUP; extern void xINSERTPS( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 ); - extern void xINSERTPS( const xRegisterSSE& to, const u32* from, u8 imm8 ); extern void xINSERTPS( const xRegisterSSE& to, const ModSibStrict& from, u8 imm8 ); extern void xEXTRACTPS( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ); - extern void xEXTRACTPS( u32* dest, const xRegisterSSE& from, u8 imm8 ); extern void xEXTRACTPS( const ModSibStrict& dest, const xRegisterSSE& from, u8 imm8 ); // ------------------------------------------------------------------------ @@ -449,16 +430,17 @@ namespace x86Emitter extern const Internal::SimdImpl_DestRegEither<0x66,0xeb> xPOR; extern const Internal::SimdImpl_DestRegEither<0x66,0xef> xPXOR; - extern const Internal::SimdImpl_AndNot xANDN; + extern const Internal::SimdImpl_AndNot xANDN; - extern const Internal::SimdImpl_UcomI<0x66,0x2e> xUCOMI; - extern const Internal::SimdImpl_rSqrt<0x53> xRCP; - extern const Internal::SimdImpl_rSqrt<0x52> xRSQRT; - extern const Internal::SimdImpl_Sqrt<0x51> xSQRT; + extern const Internal::SimdImpl_COMI xCOMI; + extern const Internal::SimdImpl_COMI xUCOMI; + extern const Internal::SimdImpl_rSqrt<0x53> xRCP; + extern const Internal::SimdImpl_rSqrt<0x52> xRSQRT; + extern const Internal::SimdImpl_Sqrt<0x51> xSQRT; - extern const Internal::SimdImpl_MinMax<0x5f> xMAX; - extern const Internal::SimdImpl_MinMax<0x5d> xMIN; - extern const Internal::SimdImpl_Shuffle<0xc6> xSHUF; + extern const Internal::SimdImpl_MinMax<0x5f> xMAX; + extern const Internal::SimdImpl_MinMax<0x5d> xMIN; + extern const Internal::SimdImpl_Shuffle<0xc6> xSHUF; // ------------------------------------------------------------------------ @@ -508,35 +490,35 @@ namespace x86Emitter // ------------------------------------------------------------------------ - extern const Internal::SimdImpl_Shift<0xf0, 6> xPSLL; - extern const Internal::SimdImpl_Shift<0xd0, 2> xPSRL; + extern const Internal::SimdImpl_Shift<0xf0, 6> xPSLL; + extern const Internal::SimdImpl_Shift<0xd0, 2> xPSRL; extern const Internal::SimdImpl_ShiftWithoutQ<0xe0, 4> xPSRA; - extern const Internal::SimdImpl_AddSub<0xdc, 0xd4> xPADD; - extern const Internal::SimdImpl_AddSub<0xd8, 0xfb> xPSUB; - extern const Internal::SimdImpl_PMinMax<0xde,0x3c> xPMAX; - extern const Internal::SimdImpl_PMinMax<0xda,0x38> xPMIN; + extern const Internal::SimdImpl_AddSub<0xdc, 0xd4> xPADD; + extern const Internal::SimdImpl_AddSub<0xd8, 0xfb> xPSUB; + extern const Internal::SimdImpl_PMinMax<0xde,0x3c> xPMAX; + extern const Internal::SimdImpl_PMinMax<0xda,0x38> xPMIN; - extern const Internal::SimdImpl_PMul xPMUL; - extern const Internal::SimdImpl_PCompare xPCMP; - extern const Internal::SimdImpl_PShuffle xPSHUF; - extern const Internal::SimdImpl_PUnpack xPUNPCK; - extern const Internal::SimdImpl_Unpack xUNPCK; - extern const Internal::SimdImpl_Pack xPACK; + extern const Internal::SimdImpl_PMul xPMUL; + extern const Internal::SimdImpl_PCompare xPCMP; + extern const Internal::SimdImpl_PShuffle xPSHUF; + extern const Internal::SimdImpl_PUnpack xPUNPCK; + extern const Internal::SimdImpl_Unpack xUNPCK; + extern const Internal::SimdImpl_Pack xPACK; - extern const Internal::SimdImpl_PAbsolute xPABS; - extern const Internal::SimdImpl_PSign xPSIGN; - extern const Internal::SimdImpl_PInsert xPINSR; - extern const Internal::SimdImpl_PExtract xPEXTR; - extern const Internal::SimdImpl_PMultAdd xPMADD; - extern const Internal::SimdImpl_HorizAdd xHADD; + extern const Internal::SimdImpl_PAbsolute xPABS; + extern const Internal::SimdImpl_PSign xPSIGN; + extern const Internal::SimdImpl_PInsert xPINSR; + extern const Internal::SimdImpl_PExtract xPEXTR; + extern const Internal::SimdImpl_PMultAdd xPMADD; + extern const Internal::SimdImpl_HorizAdd xHADD; - extern const Internal::SimdImpl_Blend xBLEND; - extern const Internal::SimdImpl_DotProduct xDP; - extern const Internal::SimdImpl_Round xROUND; + extern const Internal::SimdImpl_Blend xBLEND; + extern const Internal::SimdImpl_DotProduct xDP; + extern const Internal::SimdImpl_Round xROUND; - extern const Internal::SimdImpl_PMove xPMOVSX; - extern const Internal::SimdImpl_PMove xPMOVZX; + extern const Internal::SimdImpl_PMove xPMOVSX; + extern const Internal::SimdImpl_PMove xPMOVZX; } diff --git a/pcsx2/x86/ix86/ix86_internal.h b/common/include/x86emitter/internal.h similarity index 93% rename from pcsx2/x86/ix86/ix86_internal.h rename to common/include/x86emitter/internal.h index b8ed9269ca..cda8d6a319 100644 --- a/pcsx2/x86/ix86/ix86_internal.h +++ b/common/include/x86emitter/internal.h @@ -18,5 +18,5 @@ #pragma once -#include "ix86_types.h" -#include "ix86_instructions.h" +#include "x86types.h" +#include "instructions.h" diff --git a/pcsx2/x86/ix86/ix86_legacy_instructions.h b/common/include/x86emitter/legacy_instructions.h similarity index 100% rename from pcsx2/x86/ix86/ix86_legacy_instructions.h rename to common/include/x86emitter/legacy_instructions.h diff --git a/pcsx2/x86/ix86/ix86_legacy_internal.h b/common/include/x86emitter/legacy_internal.h similarity index 93% rename from pcsx2/x86/ix86/ix86_legacy_internal.h rename to common/include/x86emitter/legacy_internal.h index 90ba4aef49..cdf025b038 100644 --- a/pcsx2/x86/ix86/ix86_legacy_internal.h +++ b/common/include/x86emitter/legacy_internal.h @@ -18,7 +18,7 @@ #pragma once -#include "ix86_internal.h" +#include "internal.h" //------------------------------------------------------------------ // Legacy Helper Macros and Functions (depreciated) @@ -31,8 +31,8 @@ using x86Emitter::xWrite16; using x86Emitter::xWrite32; using x86Emitter::xWrite64; -#include "ix86_legacy_types.h" -#include "ix86_legacy_instructions.h" +#include "legacy_types.h" +#include "legacy_instructions.h" #define MEMADDR(addr, oplen) (addr) @@ -49,5 +49,4 @@ extern void SibSB( uint ss, uint index, uint base ); extern void SET8R( int cc, int to ); extern u8* J8Rel( int cc, int to ); extern u32* J32Rel( int cc, u32 to ); -extern u64 GetCPUTick( void ); diff --git a/pcsx2/x86/ix86/ix86_legacy_types.h b/common/include/x86emitter/legacy_types.h similarity index 100% rename from pcsx2/x86/ix86/ix86_legacy_types.h rename to common/include/x86emitter/legacy_types.h diff --git a/pcsx2/x86/ix86/ix86_macros.h b/common/include/x86emitter/macros.h similarity index 98% rename from pcsx2/x86/ix86/ix86_macros.h rename to common/include/x86emitter/macros.h index 6179fc7e1d..27f56a450d 100644 --- a/pcsx2/x86/ix86/ix86_macros.h +++ b/common/include/x86emitter/macros.h @@ -1,965 +1,965 @@ -/* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2002-2009 Pcsx2 Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ -/* -* ix86 definitions v0.6.2 -* Authors: linuzappz -* alexey silinov -* goldfinger -* shadow < shadow@pcsx2.net > -* cottonvibes(@gmail.com) -*/ - -#pragma once - -//------------------------------------------------------------------ -// jump/align functions -//------------------------------------------------------------------ -#define x86SetPtr ex86SetPtr<_EmitterId_> -#define x86SetJ8 ex86SetJ8<_EmitterId_> -#define x86SetJ8A ex86SetJ8A<_EmitterId_> -#define x86SetJ16 ex86SetJ16<_EmitterId_> -#define x86SetJ16A ex86SetJ16A<_EmitterId_> -#define x86SetJ32 ex86SetJ32<_EmitterId_> -#define x86SetJ32A ex86SetJ32A<_EmitterId_> -#define x86Align ex86Align<_EmitterId_> -#define x86AlignExecutable ex86AlignExecutable<_EmitterId_> -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// *IX86 intructions* -//------------------------------------------------------------------ - -#define STC eSTC<_EmitterId_> -#define CLC eCLC<_EmitterId_> -#define NOP eNOP<_EmitterId_> - -//------------------------------------------------------------------ -// mov instructions -//------------------------------------------------------------------ -#define MOV32RtoR eMOV32RtoR<_EmitterId_> -#define MOV32RtoM eMOV32RtoM<_EmitterId_> -#define MOV32MtoR eMOV32MtoR<_EmitterId_> -#define MOV32RmtoR eMOV32RmtoR<_EmitterId_> -#define MOV32RmtoR eMOV32RmtoR<_EmitterId_> -#define MOV32RmStoR eMOV32RmStoR<_EmitterId_> -#define MOV32RmSOffsettoR eMOV32RmSOffsettoR<_EmitterId_> -#define MOV32RtoRm eMOV32RtoRm<_EmitterId_> -#define MOV32RtoRmS eMOV32RtoRmS<_EmitterId_> -#define MOV32ItoR eMOV32ItoR<_EmitterId_> -#define MOV32ItoM eMOV32ItoM<_EmitterId_> -#define MOV32ItoRm eMOV32ItoRm<_EmitterId_> -#define MOV32RtoRm eMOV32RtoRm<_EmitterId_> -#define MOV16RtoM eMOV16RtoM<_EmitterId_> -#define MOV16MtoR eMOV16MtoR<_EmitterId_> -#define MOV16RmtoR eMOV16RmtoR<_EmitterId_> -#define MOV16RmtoR eMOV16RmtoR<_EmitterId_> -#define MOV16RmSOffsettoR eMOV16RmSOffsettoR<_EmitterId_> -#define MOV16RtoRm eMOV16RtoRm<_EmitterId_> -#define MOV16ItoM eMOV16ItoM<_EmitterId_> -#define MOV16RtoRmS eMOV16RtoRmS<_EmitterId_> -#define MOV16ItoR eMOV16ItoR<_EmitterId_> -#define MOV16ItoRm eMOV16ItoRm<_EmitterId_> -#define MOV16RtoRm eMOV16RtoRm<_EmitterId_> -#define MOV8RtoM eMOV8RtoM<_EmitterId_> -#define MOV8MtoR eMOV8MtoR<_EmitterId_> -#define MOV8RmtoR eMOV8RmtoR<_EmitterId_> -#define MOV8RmtoR eMOV8RmtoR<_EmitterId_> -#define MOV8RmSOffsettoR eMOV8RmSOffsettoR<_EmitterId_> -#define MOV8RtoRm eMOV8RtoRm<_EmitterId_> -#define MOV8ItoM eMOV8ItoM<_EmitterId_> -#define MOV8ItoR eMOV8ItoR<_EmitterId_> -#define MOV8ItoRm eMOV8ItoRm<_EmitterId_> -#define MOV8RtoRm eMOV8RtoRm<_EmitterId_> -#define MOVSX32R8toR eMOVSX32R8toR<_EmitterId_> -#define MOVSX32Rm8toR eMOVSX32Rm8toR<_EmitterId_> -#define MOVSX32M8toR eMOVSX32M8toR<_EmitterId_> -#define MOVSX32R16toR eMOVSX32R16toR<_EmitterId_> -#define MOVSX32Rm16toR eMOVSX32Rm16toR<_EmitterId_> -#define MOVSX32M16toR eMOVSX32M16toR<_EmitterId_> -#define MOVZX32R8toR eMOVZX32R8toR<_EmitterId_> -#define MOVZX32Rm8toR eMOVZX32Rm8toR<_EmitterId_> -#define MOVZX32M8toR eMOVZX32M8toR<_EmitterId_> -#define MOVZX32R16toR eMOVZX32R16toR<_EmitterId_> -#define MOVZX32Rm16toR eMOVZX32Rm16toR<_EmitterId_> -#define MOVZX32M16toR eMOVZX32M16toR<_EmitterId_> -#define CMOVBE32RtoR eCMOVBE32RtoR<_EmitterId_> -#define CMOVBE32MtoR eCMOVBE32MtoR<_EmitterId_> -#define CMOVB32RtoR eCMOVB32RtoR<_EmitterId_> -#define CMOVB32MtoR eCMOVB32MtoR<_EmitterId_> -#define CMOVAE32RtoR eCMOVAE32RtoR<_EmitterId_> -#define CMOVAE32MtoR eCMOVAE32MtoR<_EmitterId_> -#define CMOVA32RtoR eCMOVA32RtoR<_EmitterId_> -#define CMOVA32MtoR eCMOVA32MtoR<_EmitterId_> -#define CMOVO32RtoR eCMOVO32RtoR<_EmitterId_> -#define CMOVO32MtoR eCMOVO32MtoR<_EmitterId_> -#define CMOVP32RtoR eCMOVP32RtoR<_EmitterId_> -#define CMOVP32MtoR eCMOVP32MtoR<_EmitterId_> -#define CMOVS32RtoR eCMOVS32RtoR<_EmitterId_> -#define CMOVS32MtoR eCMOVS32MtoR<_EmitterId_> -#define CMOVNO32RtoR eCMOVNO32RtoR<_EmitterId_> -#define CMOVNO32MtoR eCMOVNO32MtoR<_EmitterId_> -#define CMOVNP32RtoR eCMOVNP32RtoR<_EmitterId_> -#define CMOVNP32MtoR eCMOVNP32MtoR<_EmitterId_> -#define CMOVNS32RtoR eCMOVNS32RtoR<_EmitterId_> -#define CMOVNS32MtoR eCMOVNS32MtoR<_EmitterId_> -#define CMOVNE32RtoR eCMOVNE32RtoR<_EmitterId_> -#define CMOVNE32MtoR eCMOVNE32MtoR<_EmitterId_> -#define CMOVE32RtoR eCMOVE32RtoR<_EmitterId_> -#define CMOVE32MtoR eCMOVE32MtoR<_EmitterId_> -#define CMOVG32RtoR eCMOVG32RtoR<_EmitterId_> -#define CMOVG32MtoR eCMOVG32MtoR<_EmitterId_> -#define CMOVGE32RtoR eCMOVGE32RtoR<_EmitterId_> -#define CMOVGE32MtoR eCMOVGE32MtoR<_EmitterId_> -#define CMOVL32RtoR eCMOVL32RtoR<_EmitterId_> -#define CMOVL32MtoR eCMOVL32MtoR<_EmitterId_> -#define CMOVLE32RtoR eCMOVLE32RtoR<_EmitterId_> -#define CMOVLE32MtoR eCMOVLE32MtoR<_EmitterId_> -//------------------------------------------------------------------ -// arithmetic instructions -//------------------------------------------------------------------ -#define ADD32ItoEAX eADD32ItoEAX<_EmitterId_> -#define ADD32ItoR eADD32ItoR<_EmitterId_> -#define ADD32ItoM eADD32ItoM<_EmitterId_> -#define ADD32ItoRm eADD32ItoRm<_EmitterId_> -#define ADD32RtoR eADD32RtoR<_EmitterId_> -#define ADD32RtoM eADD32RtoM<_EmitterId_> -#define ADD32MtoR eADD32MtoR<_EmitterId_> -#define ADD16RtoR eADD16RtoR<_EmitterId_> -#define ADD16ItoR eADD16ItoR<_EmitterId_> -#define ADD16ItoM eADD16ItoM<_EmitterId_> -#define ADD16RtoM eADD16RtoM<_EmitterId_> -#define ADD16MtoR eADD16MtoR<_EmitterId_> -#define ADD8MtoR eADD8MtoR<_EmitterId_> -#define ADC32ItoR eADC32ItoR<_EmitterId_> -#define ADC32ItoM eADC32ItoM<_EmitterId_> -#define ADC32RtoR eADC32RtoR<_EmitterId_> -#define ADC32MtoR eADC32MtoR<_EmitterId_> -#define ADC32RtoM eADC32RtoM<_EmitterId_> -#define INC32R eINC32R<_EmitterId_> -#define INC32M eINC32M<_EmitterId_> -#define INC16R eINC16R<_EmitterId_> -#define INC16M eINC16M<_EmitterId_> -#define SUB32ItoR eSUB32ItoR<_EmitterId_> -#define SUB32ItoM eSUB32ItoM<_EmitterId_> -#define SUB32RtoR eSUB32RtoR<_EmitterId_> -#define SUB32MtoR eSUB32MtoR<_EmitterId_> -#define SUB32RtoM eSUB32RtoM<_EmitterId_> -#define SUB16RtoR eSUB16RtoR<_EmitterId_> -#define SUB16ItoR eSUB16ItoR<_EmitterId_> -#define SUB16ItoM eSUB16ItoM<_EmitterId_> -#define SUB16MtoR eSUB16MtoR<_EmitterId_> -#define SBB32ItoR eSBB32ItoR<_EmitterId_> -#define SBB32ItoM eSBB32ItoM<_EmitterId_> -#define SBB32RtoR eSBB32RtoR<_EmitterId_> -#define SBB32MtoR eSBB32MtoR<_EmitterId_> -#define SBB32RtoM eSBB32RtoM<_EmitterId_> -#define DEC32R eDEC32R<_EmitterId_> -#define DEC32M eDEC32M<_EmitterId_> -#define DEC16R eDEC16R<_EmitterId_> -#define DEC16M eDEC16M<_EmitterId_> -#define MUL32R eMUL32R<_EmitterId_> -#define MUL32M eMUL32M<_EmitterId_> -#define IMUL32R eIMUL32R<_EmitterId_> -#define IMUL32M eIMUL32M<_EmitterId_> -#define IMUL32RtoR eIMUL32RtoR<_EmitterId_> -#define DIV32R eDIV32R<_EmitterId_> -#define DIV32M eDIV32M<_EmitterId_> -#define IDIV32R eIDIV32R<_EmitterId_> -#define IDIV32M eIDIV32M<_EmitterId_> -//------------------------------------------------------------------ -// shifting instructions -//------------------------------------------------------------------ -#define SHL32ItoR eSHL32ItoR<_EmitterId_> -#define SHL32ItoM eSHL32ItoM<_EmitterId_> -#define SHL32CLtoR eSHL32CLtoR<_EmitterId_> -#define SHL16ItoR eSHL16ItoR<_EmitterId_> -#define SHL8ItoR eSHL8ItoR<_EmitterId_> -#define SHR32ItoR eSHR32ItoR<_EmitterId_> -#define SHR32ItoM eSHR32ItoM<_EmitterId_> -#define SHR32CLtoR eSHR32CLtoR<_EmitterId_> -#define SHR16ItoR eSHR16ItoR<_EmitterId_> -#define SHR8ItoR eSHR8ItoR<_EmitterId_> -#define SAR32ItoR eSAR32ItoR<_EmitterId_> -#define SAR32ItoM eSAR32ItoM<_EmitterId_> -#define SAR32CLtoR eSAR32CLtoR<_EmitterId_> -#define SAR16ItoR eSAR16ItoR<_EmitterId_> -#define ROR32ItoR eROR32ItoR<_EmitterId_> -#define RCR32ItoR eRCR32ItoR<_EmitterId_> -#define RCR32ItoM eRCR32ItoM<_EmitterId_> -#define SHLD32ItoR eSHLD32ItoR<_EmitterId_> -#define SHRD32ItoR eSHRD32ItoR<_EmitterId_> -//------------------------------------------------------------------ -// logical instructions -//------------------------------------------------------------------ -#define OR32ItoR eOR32ItoR<_EmitterId_> -#define OR32ItoM eOR32ItoM<_EmitterId_> -#define OR32RtoR eOR32RtoR<_EmitterId_> -#define OR32RtoM eOR32RtoM<_EmitterId_> -#define OR32MtoR eOR32MtoR<_EmitterId_> -#define OR16RtoR eOR16RtoR<_EmitterId_> -#define OR16ItoR eOR16ItoR<_EmitterId_> -#define OR16ItoM eOR16ItoM<_EmitterId_> -#define OR16MtoR eOR16MtoR<_EmitterId_> -#define OR16RtoM eOR16RtoM<_EmitterId_> -#define OR8RtoR eOR8RtoR<_EmitterId_> -#define OR8RtoM eOR8RtoM<_EmitterId_> -#define OR8ItoM eOR8ItoM<_EmitterId_> -#define OR8MtoR eOR8MtoR<_EmitterId_> -#define XOR32ItoR eXOR32ItoR<_EmitterId_> -#define XOR32ItoM eXOR32ItoM<_EmitterId_> -#define XOR32RtoR eXOR32RtoR<_EmitterId_> -#define XOR16RtoR eXOR16RtoR<_EmitterId_> -#define XOR32RtoM eXOR32RtoM<_EmitterId_> -#define XOR32MtoR eXOR32MtoR<_EmitterId_> -#define XOR16RtoM eXOR16RtoM<_EmitterId_> -#define XOR16ItoR eXOR16ItoR<_EmitterId_> -#define AND32ItoR eAND32ItoR<_EmitterId_> -#define AND32I8toR eAND32I8toR<_EmitterId_> -#define AND32ItoM eAND32ItoM<_EmitterId_> -#define AND32I8toM eAND32I8toM<_EmitterId_> -#define AND32RtoR eAND32RtoR<_EmitterId_> -#define AND32RtoM eAND32RtoM<_EmitterId_> -#define AND32MtoR eAND32MtoR<_EmitterId_> -#define AND32RmtoR eAND32RmtoR<_EmitterId_> -#define AND32RmtoR eAND32RmtoR<_EmitterId_> -#define AND16RtoR eAND16RtoR<_EmitterId_> -#define AND16ItoR eAND16ItoR<_EmitterId_> -#define AND16ItoM eAND16ItoM<_EmitterId_> -#define AND16RtoM eAND16RtoM<_EmitterId_> -#define AND16MtoR eAND16MtoR<_EmitterId_> -#define AND8ItoR eAND8ItoR<_EmitterId_> -#define AND8ItoM eAND8ItoM<_EmitterId_> -#define AND8RtoM eAND8RtoM<_EmitterId_> -#define AND8MtoR eAND8MtoR<_EmitterId_> -#define AND8RtoR eAND8RtoR<_EmitterId_> -#define NOT32R eNOT32R<_EmitterId_> -#define NOT32M eNOT32M<_EmitterId_> -#define NEG32R eNEG32R<_EmitterId_> -#define NEG32M eNEG32M<_EmitterId_> -#define NEG16R eNEG16R<_EmitterId_> -//------------------------------------------------------------------ -// jump/call instructions -//------------------------------------------------------------------ -#define JMP8 eJMP8<_EmitterId_> -#define JP8 eJP8<_EmitterId_> -#define JNP8 eJNP8<_EmitterId_> -#define JE8 eJE8<_EmitterId_> -#define JZ8 eJZ8<_EmitterId_> -#define JG8 eJG8<_EmitterId_> -#define JGE8 eJGE8<_EmitterId_> -#define JS8 eJS8<_EmitterId_> -#define JNS8 eJNS8<_EmitterId_> -#define JL8 eJL8<_EmitterId_> -#define JA8 eJA8<_EmitterId_> -#define JAE8 eJAE8<_EmitterId_> -#define JB8 eJB8<_EmitterId_> -#define JBE8 eJBE8<_EmitterId_> -#define JLE8 eJLE8<_EmitterId_> -#define JNE8 eJNE8<_EmitterId_> -#define JNZ8 eJNZ8<_EmitterId_> -#define JNG8 eJNG8<_EmitterId_> -#define JNGE8 eJNGE8<_EmitterId_> -#define JNL8 eJNL8<_EmitterId_> -#define JNLE8 eJNLE8<_EmitterId_> -#define JO8 eJO8<_EmitterId_> -#define JNO8 eJNO8<_EmitterId_> -#define JMP32 eJMP32<_EmitterId_> -#define JNS32 eJNS32<_EmitterId_> -#define JS32 eJS32<_EmitterId_> -#define JB32 eJB32<_EmitterId_> -#define JE32 eJE32<_EmitterId_> -#define JZ32 eJZ32<_EmitterId_> -#define JG32 eJG32<_EmitterId_> -#define JGE32 eJGE32<_EmitterId_> -#define JL32 eJL32<_EmitterId_> -#define JLE32 eJLE32<_EmitterId_> -#define JA32 eJA32<_EmitterId_> -#define JAE32 eJAE32<_EmitterId_> -#define JNE32 eJNE32<_EmitterId_> -#define JNZ32 eJNZ32<_EmitterId_> -#define JNG32 eJNG32<_EmitterId_> -#define JNGE32 eJNGE32<_EmitterId_> -#define JNL32 eJNL32<_EmitterId_> -#define JNLE32 eJNLE32<_EmitterId_> -#define JO32 eJO32<_EmitterId_> -#define JNO32 eJNO32<_EmitterId_> -#define JS32 eJS32<_EmitterId_> -#define JMPR eJMPR<_EmitterId_> -#define JMP32M eJMP32M<_EmitterId_> -#define CALLFunc eCALLFunc<_EmitterId_> -#define CALL32 eCALL32<_EmitterId_> -#define CALL32R eCALL32R<_EmitterId_> -#define CALL32M eCALL32M<_EmitterId_> -//------------------------------------------------------------------ -// misc instructions -//------------------------------------------------------------------ -#define CMP32ItoR eCMP32ItoR<_EmitterId_> -#define CMP32ItoM eCMP32ItoM<_EmitterId_> -#define CMP32RtoR eCMP32RtoR<_EmitterId_> -#define CMP32MtoR eCMP32MtoR<_EmitterId_> -#define CMP32ItoRm eCMP32ItoRm<_EmitterId_> -#define CMP8I8toRm eCMP8I8toRm<_EmitterId_> -#define CMP32I8toRm eCMP32I8toRm<_EmitterId_> -#define CMP32I8toM eCMP32I8toM<_EmitterId_> -#define CMP16ItoR eCMP16ItoR<_EmitterId_> -#define CMP16ItoM eCMP16ItoM<_EmitterId_> -#define CMP16RtoR eCMP16RtoR<_EmitterId_> -#define CMP16MtoR eCMP16MtoR<_EmitterId_> -#define CMP8ItoR eCMP8ItoR<_EmitterId_> -#define CMP8MtoR eCMP8MtoR<_EmitterId_> -#define TEST32ItoR eTEST32ItoR<_EmitterId_> -#define TEST32ItoM eTEST32ItoM<_EmitterId_> -#define TEST32RtoR eTEST32RtoR<_EmitterId_> -#define TEST32ItoRm eTEST32ItoRm<_EmitterId_> -#define TEST16ItoR eTEST16ItoR<_EmitterId_> -#define TEST16RtoR eTEST16RtoR<_EmitterId_> -#define TEST8RtoR eTEST8RtoR<_EmitterId_> -#define TEST8ItoR eTEST8ItoR<_EmitterId_> -#define TEST8ItoM eTEST8ItoM<_EmitterId_> -#define SETS8R eSETS8R<_EmitterId_> -#define SETL8R eSETL8R<_EmitterId_> -#define SETGE8R eSETGE8R<_EmitterId_> -#define SETG8R eSETG8R<_EmitterId_> -#define SETA8R eSETA8R<_EmitterId_> -#define SETAE8R eSETAE8R<_EmitterId_> -#define SETB8R eSETB8R<_EmitterId_> -#define SETNZ8R eSETNZ8R<_EmitterId_> -#define SETZ8R eSETZ8R<_EmitterId_> -#define SETE8R eSETE8R<_EmitterId_> -#define PUSH32I ePUSH32I<_EmitterId_> -#define PUSH32R ePUSH32R<_EmitterId_> -#define PUSH32M ePUSH32M<_EmitterId_> -#define PUSH32I ePUSH32I<_EmitterId_> -#define POP32R ePOP32R<_EmitterId_> -#define PUSHA32 ePUSHA32<_EmitterId_> -#define POPA32 ePOPA32<_EmitterId_> -#define PUSHR ePUSHR<_EmitterId_> -#define POPR ePOPR<_EmitterId_> -#define PUSHFD ePUSHFD<_EmitterId_> -#define POPFD ePOPFD<_EmitterId_> -#define RET eRET<_EmitterId_> -#define CBW eCBW<_EmitterId_> -#define CWDE eCWDE<_EmitterId_> -#define CWD eCWD<_EmitterId_> -#define CDQ eCDQ<_EmitterId_> -#define CDQE eCDQE<_EmitterId_> -#define LAHF eLAHF<_EmitterId_> -#define SAHF eSAHF<_EmitterId_> -#define BT32ItoR eBT32ItoR<_EmitterId_> -#define BTR32ItoR eBTR32ItoR<_EmitterId_> -#define BSRRtoR eBSRRtoR<_EmitterId_> -#define BSWAP32R eBSWAP32R<_EmitterId_> -#define LEA16RtoR eLEA16RtoR<_EmitterId_> -#define LEA32RtoR eLEA32RtoR<_EmitterId_> -#define LEA16RRtoR eLEA16RRtoR<_EmitterId_> -#define LEA32RRtoR eLEA32RRtoR<_EmitterId_> -#define LEA16RStoR eLEA16RStoR<_EmitterId_> -#define LEA32RStoR eLEA32RStoR<_EmitterId_> -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// FPU instructions -//------------------------------------------------------------------ -#define FILD32 eFILD32<_EmitterId_> -#define FISTP32 eFISTP32<_EmitterId_> -#define FLD32 eFLD32<_EmitterId_> -#define FLD eFLD<_EmitterId_> -#define FLD1 eFLD1<_EmitterId_> -#define FLDL2E eFLDL2E<_EmitterId_> -#define FST32 eFST32<_EmitterId_> -#define FSTP32 eFSTP32<_EmitterId_> -#define FSTP eFSTP<_EmitterId_> -#define FLDCW eFLDCW<_EmitterId_> -#define FNSTCW eFNSTCW<_EmitterId_> -#define FADD32Rto0 eFADD32Rto0<_EmitterId_> -#define FADD320toR eFADD320toR<_EmitterId_> -#define FSUB32Rto0 eFSUB32Rto0<_EmitterId_> -#define FSUB320toR eFSUB320toR<_EmitterId_> -#define FSUBP eFSUBP<_EmitterId_> -#define FMUL32Rto0 eFMUL32Rto0<_EmitterId_> -#define FMUL320toR eFMUL320toR<_EmitterId_> -#define FDIV32Rto0 eFDIV32Rto0<_EmitterId_> -#define FDIV320toR eFDIV320toR<_EmitterId_> -#define FDIV320toRP eFDIV320toRP<_EmitterId_> -#define FADD32 eFADD32<_EmitterId_> -#define FSUB32 eFSUB32<_EmitterId_> -#define FMUL32 eFMUL32<_EmitterId_> -#define FDIV32 eFDIV32<_EmitterId_> -#define FCOMI eFCOMI<_EmitterId_> -#define FCOMIP eFCOMIP<_EmitterId_> -#define FUCOMI eFUCOMI<_EmitterId_> -#define FUCOMIP eFUCOMIP<_EmitterId_> -#define FCOM32 eFCOM32<_EmitterId_> -#define FABS eFABS<_EmitterId_> -#define FSQRT eFSQRT<_EmitterId_> -#define FPATAN eFPATAN<_EmitterId_> -#define FSIN eFSIN<_EmitterId_> -#define FCHS eFCHS<_EmitterId_> -#define FCMOVB32 eFCMOVB32<_EmitterId_> -#define FCMOVE32 eFCMOVE32<_EmitterId_> -#define FCMOVBE32 eFCMOVBE32<_EmitterId_> -#define FCMOVU32 eFCMOVU32<_EmitterId_> -#define FCMOVNB32 eFCMOVNB32<_EmitterId_> -#define FCMOVNE32 eFCMOVNE32<_EmitterId_> -#define FCMOVNBE32 eFCMOVNBE32<_EmitterId_> -#define FCMOVNU32 eFCMOVNU32<_EmitterId_> -#define FCOMP32 eFCOMP32<_EmitterId_> -#define FNSTSWtoAX eFNSTSWtoAX<_EmitterId_> -#define FXAM eFXAM<_EmitterId_> -#define FDECSTP eFDECSTP<_EmitterId_> -#define FRNDINT eFRNDINT<_EmitterId_> -#define FXCH eFXCH<_EmitterId_> -#define F2XM1 eF2XM1<_EmitterId_> -#define FSCALE eFSCALE<_EmitterId_> -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// MMX instructions -//------------------------------------------------------------------ -#define EMMS eEMMS<_EmitterId_> -#define MOVQMtoR eMOVQMtoR<_EmitterId_> -#define MOVQRtoM eMOVQRtoM<_EmitterId_> -#define PANDRtoR ePANDRtoR<_EmitterId_> -#define PANDNRtoR ePANDNRtoR<_EmitterId_> -#define PANDMtoR ePANDMtoR<_EmitterId_> -#define PANDNRtoR ePANDNRtoR<_EmitterId_> -#define PANDNMtoR ePANDNMtoR<_EmitterId_> -#define PORRtoR ePORRtoR<_EmitterId_> -#define PORMtoR ePORMtoR<_EmitterId_> -#define PXORRtoR ePXORRtoR<_EmitterId_> -#define PXORMtoR ePXORMtoR<_EmitterId_> -#define PSLLQRtoR ePSLLQRtoR<_EmitterId_> -#define PSLLQMtoR ePSLLQMtoR<_EmitterId_> -#define PSLLQItoR ePSLLQItoR<_EmitterId_> -#define PSRLQRtoR ePSRLQRtoR<_EmitterId_> -#define PSRLQMtoR ePSRLQMtoR<_EmitterId_> -#define PSRLQItoR ePSRLQItoR<_EmitterId_> -#define PADDUSBRtoR ePADDUSBRtoR<_EmitterId_> -#define PADDUSBMtoR ePADDUSBMtoR<_EmitterId_> -#define PADDUSWRtoR ePADDUSWRtoR<_EmitterId_> -#define PADDUSWMtoR ePADDUSWMtoR<_EmitterId_> -#define PADDBRtoR ePADDBRtoR<_EmitterId_> -#define PADDBMtoR ePADDBMtoR<_EmitterId_> -#define PADDWRtoR ePADDWRtoR<_EmitterId_> -#define PADDWMtoR ePADDWMtoR<_EmitterId_> -#define PADDDRtoR ePADDDRtoR<_EmitterId_> -#define PADDDMtoR ePADDDMtoR<_EmitterId_> -#define PADDSBRtoR ePADDSBRtoR<_EmitterId_> -#define PADDSWRtoR ePADDSWRtoR<_EmitterId_> -#define PADDQMtoR ePADDQMtoR<_EmitterId_> -#define PADDQRtoR ePADDQRtoR<_EmitterId_> -#define PSUBSBRtoR ePSUBSBRtoR<_EmitterId_> -#define PSUBSWRtoR ePSUBSWRtoR<_EmitterId_> -#define PSUBBRtoR ePSUBBRtoR<_EmitterId_> -#define PSUBWRtoR ePSUBWRtoR<_EmitterId_> -#define PSUBDRtoR ePSUBDRtoR<_EmitterId_> -#define PSUBDMtoR ePSUBDMtoR<_EmitterId_> -#define PSUBQMtoR ePSUBQMtoR<_EmitterId_> -#define PSUBQRtoR ePSUBQRtoR<_EmitterId_> -#define PMULUDQMtoR ePMULUDQMtoR<_EmitterId_> -#define PMULUDQRtoR ePMULUDQRtoR<_EmitterId_> -#define PCMPEQBRtoR ePCMPEQBRtoR<_EmitterId_> -#define PCMPEQWRtoR ePCMPEQWRtoR<_EmitterId_> -#define PCMPEQDRtoR ePCMPEQDRtoR<_EmitterId_> -#define PCMPEQDMtoR ePCMPEQDMtoR<_EmitterId_> -#define PCMPGTBRtoR ePCMPGTBRtoR<_EmitterId_> -#define PCMPGTWRtoR ePCMPGTWRtoR<_EmitterId_> -#define PCMPGTDRtoR ePCMPGTDRtoR<_EmitterId_> -#define PCMPGTDMtoR ePCMPGTDMtoR<_EmitterId_> -#define PSRLWItoR ePSRLWItoR<_EmitterId_> -#define PSRLDItoR ePSRLDItoR<_EmitterId_> -#define PSRLDRtoR ePSRLDRtoR<_EmitterId_> -#define PSLLWItoR ePSLLWItoR<_EmitterId_> -#define PSLLDItoR ePSLLDItoR<_EmitterId_> -#define PSLLDRtoR ePSLLDRtoR<_EmitterId_> -#define PSRAWItoR ePSRAWItoR<_EmitterId_> -#define PSRADItoR ePSRADItoR<_EmitterId_> -#define PSRADRtoR ePSRADRtoR<_EmitterId_> -#define PUNPCKLDQRtoR ePUNPCKLDQRtoR<_EmitterId_> -#define PUNPCKLDQMtoR ePUNPCKLDQMtoR<_EmitterId_> -#define PUNPCKHDQRtoR ePUNPCKHDQRtoR<_EmitterId_> -#define PUNPCKHDQMtoR ePUNPCKHDQMtoR<_EmitterId_> -#define MOVQ64ItoR eMOVQ64ItoR<_EmitterId_> -#define MOVQRtoR eMOVQRtoR<_EmitterId_> -#define MOVQRmtoR eMOVQRmtoR<_EmitterId_> -#define MOVQRtoRm eMOVQRtoRm<_EmitterId_> -#define MOVDMtoMMX eMOVDMtoMMX<_EmitterId_> -#define MOVDMMXtoM eMOVDMMXtoM<_EmitterId_> -#define MOVD32RtoMMX eMOVD32RtoMMX<_EmitterId_> -#define MOVD32RmtoMMX eMOVD32RmtoMMX<_EmitterId_> -#define MOVD32RmtoMMX eMOVD32RmtoMMX<_EmitterId_> -#define MOVD32MMXtoR eMOVD32MMXtoR<_EmitterId_> -#define MOVD32MMXtoRm eMOVD32MMXtoRm<_EmitterId_> -#define MOVD32MMXtoRm eMOVD32MMXtoRm<_EmitterId_> -#define PINSRWRtoMMX ePINSRWRtoMMX<_EmitterId_> -#define PSHUFWRtoR ePSHUFWRtoR<_EmitterId_> -#define PSHUFWMtoR ePSHUFWMtoR<_EmitterId_> -#define MASKMOVQRtoR eMASKMOVQRtoR<_EmitterId_> -#define PMOVMSKBMMXtoR ePMOVMSKBMMXtoR<_EmitterId_> -//------------------------------------------------------------------ -// PACKSSWB,PACKSSDW: Pack Saturate Signed Word 64bits -//------------------------------------------------------------------ -#define PACKSSWBMMXtoMMX ePACKSSWBMMXtoMMX<_EmitterId_> -#define PACKSSDWMMXtoMMX ePACKSSDWMMXtoMMX<_EmitterId_> -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// *SSE instructions* -//------------------------------------------------------------------ -#define SSE_STMXCSR eSSE_STMXCSR<_EmitterId_> -#define SSE_LDMXCSR eSSE_LDMXCSR<_EmitterId_> -#define SSE_MOVAPS_M128_to_XMM eSSE_MOVAPS_M128_to_XMM<_EmitterId_> -#define SSE_MOVAPS_XMM_to_M128 eSSE_MOVAPS_XMM_to_M128<_EmitterId_> -#define SSE_MOVAPS_XMM_to_XMM eSSE_MOVAPS_XMM_to_XMM<_EmitterId_> -#define SSE_MOVUPS_M128_to_XMM eSSE_MOVUPS_M128_to_XMM<_EmitterId_> -#define SSE_MOVUPS_XMM_to_M128 eSSE_MOVUPS_XMM_to_M128<_EmitterId_> -#define SSE_MOVSS_M32_to_XMM eSSE_MOVSS_M32_to_XMM<_EmitterId_> -#define SSE_MOVSS_XMM_to_M32 eSSE_MOVSS_XMM_to_M32<_EmitterId_> -#define SSE_MOVSS_XMM_to_Rm eSSE_MOVSS_XMM_to_Rm<_EmitterId_> -#define SSE_MOVSS_XMM_to_XMM eSSE_MOVSS_XMM_to_XMM<_EmitterId_> -#define SSE_MOVSS_Rm_to_XMM eSSE_MOVSS_Rm_to_XMM<_EmitterId_> -#define SSE_MOVSS_XMM_to_Rm eSSE_MOVSS_XMM_to_Rm<_EmitterId_> -#define SSE_MASKMOVDQU_XMM_to_XMM eSSE_MASKMOVDQU_XMM_to_XMM<_EmitterId_> -#define SSE_MOVLPS_M64_to_XMM eSSE_MOVLPS_M64_to_XMM<_EmitterId_> -#define SSE_MOVLPS_XMM_to_M64 eSSE_MOVLPS_XMM_to_M64<_EmitterId_> -#define SSE_MOVLPS_Rm_to_XMM eSSE_MOVLPS_Rm_to_XMM<_EmitterId_> -#define SSE_MOVLPS_XMM_to_Rm eSSE_MOVLPS_XMM_to_Rm<_EmitterId_> -#define SSE_MOVHPS_M64_to_XMM eSSE_MOVHPS_M64_to_XMM<_EmitterId_> -#define SSE_MOVHPS_XMM_to_M64 eSSE_MOVHPS_XMM_to_M64<_EmitterId_> -#define SSE_MOVHPS_Rm_to_XMM eSSE_MOVHPS_Rm_to_XMM<_EmitterId_> -#define SSE_MOVHPS_XMM_to_Rm eSSE_MOVHPS_XMM_to_Rm<_EmitterId_> -#define SSE_MOVLHPS_XMM_to_XMM eSSE_MOVLHPS_XMM_to_XMM<_EmitterId_> -#define SSE_MOVHLPS_XMM_to_XMM eSSE_MOVHLPS_XMM_to_XMM<_EmitterId_> -#define SSE_MOVLPSRmtoR eSSE_MOVLPSRmtoR<_EmitterId_> -#define SSE_MOVLPSRtoRm eSSE_MOVLPSRtoRm<_EmitterId_> -#define SSE_MOVAPSRmStoR eSSE_MOVAPSRmStoR<_EmitterId_> -#define SSE_MOVAPSRtoRmS eSSE_MOVAPSRtoRmS<_EmitterId_> -#define SSE_MOVAPSRtoRm eSSE_MOVAPSRtoRm<_EmitterId_> -#define SSE_MOVAPSRmtoR eSSE_MOVAPSRmtoR<_EmitterId_> -#define SSE_MOVUPSRmStoR eSSE_MOVUPSRmStoR<_EmitterId_> -#define SSE_MOVUPSRtoRmS eSSE_MOVUPSRtoRmS<_EmitterId_> -#define SSE_MOVUPSRtoRm eSSE_MOVUPSRtoRm<_EmitterId_> -#define SSE_MOVUPSRmtoR eSSE_MOVUPSRmtoR<_EmitterId_> -#define SSE_MOVUPSRmtoR eSSE_MOVUPSRmtoR<_EmitterId_> -#define SSE_MOVUPSRtoRm eSSE_MOVUPSRtoRm<_EmitterId_> -#define SSE_RCPPS_XMM_to_XMM eSSE_RCPPS_XMM_to_XMM<_EmitterId_> -#define SSE_RCPPS_M128_to_XMM eSSE_RCPPS_M128_to_XMM<_EmitterId_> -#define SSE_RCPSS_XMM_to_XMM eSSE_RCPSS_XMM_to_XMM<_EmitterId_> -#define SSE_RCPSS_M32_to_XMM eSSE_RCPSS_M32_to_XMM<_EmitterId_> -#define SSE_ORPS_M128_to_XMM eSSE_ORPS_M128_to_XMM<_EmitterId_> -#define SSE_ORPS_XMM_to_XMM eSSE_ORPS_XMM_to_XMM<_EmitterId_> -#define SSE_XORPS_M128_to_XMM eSSE_XORPS_M128_to_XMM<_EmitterId_> -#define SSE_XORPS_XMM_to_XMM eSSE_XORPS_XMM_to_XMM<_EmitterId_> -#define SSE_ANDPS_M128_to_XMM eSSE_ANDPS_M128_to_XMM<_EmitterId_> -#define SSE_ANDPS_XMM_to_XMM eSSE_ANDPS_XMM_to_XMM<_EmitterId_> -#define SSE_ANDNPS_M128_to_XMM eSSE_ANDNPS_M128_to_XMM<_EmitterId_> -#define SSE_ANDNPS_XMM_to_XMM eSSE_ANDNPS_XMM_to_XMM<_EmitterId_> -#define SSE_ADDPS_M128_to_XMM eSSE_ADDPS_M128_to_XMM<_EmitterId_> -#define SSE_ADDPS_XMM_to_XMM eSSE_ADDPS_XMM_to_XMM<_EmitterId_> -#define SSE_ADDSS_M32_to_XMM eSSE_ADDSS_M32_to_XMM<_EmitterId_> -#define SSE_ADDSS_XMM_to_XMM eSSE_ADDSS_XMM_to_XMM<_EmitterId_> -#define SSE_SUBPS_M128_to_XMM eSSE_SUBPS_M128_to_XMM<_EmitterId_> -#define SSE_SUBPS_XMM_to_XMM eSSE_SUBPS_XMM_to_XMM<_EmitterId_> -#define SSE_SUBSS_M32_to_XMM eSSE_SUBSS_M32_to_XMM<_EmitterId_> -#define SSE_SUBSS_XMM_to_XMM eSSE_SUBSS_XMM_to_XMM<_EmitterId_> -#define SSE_MULPS_M128_to_XMM eSSE_MULPS_M128_to_XMM<_EmitterId_> -#define SSE_MULPS_XMM_to_XMM eSSE_MULPS_XMM_to_XMM<_EmitterId_> -#define SSE_MULSS_M32_to_XMM eSSE_MULSS_M32_to_XMM<_EmitterId_> -#define SSE_MULSS_XMM_to_XMM eSSE_MULSS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPEQSS_M32_to_XMM eSSE_CMPEQSS_M32_to_XMM<_EmitterId_> -#define SSE_CMPEQSS_XMM_to_XMM eSSE_CMPEQSS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPLTSS_M32_to_XMM eSSE_CMPLTSS_M32_to_XMM<_EmitterId_> -#define SSE_CMPLTSS_XMM_to_XMM eSSE_CMPLTSS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPLESS_M32_to_XMM eSSE_CMPLESS_M32_to_XMM<_EmitterId_> -#define SSE_CMPLESS_XMM_to_XMM eSSE_CMPLESS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPUNORDSS_M32_to_XMM eSSE_CMPUNORDSS_M32_to_XMM<_EmitterId_> -#define SSE_CMPUNORDSS_XMM_to_XMM eSSE_CMPUNORDSS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPNESS_M32_to_XMM eSSE_CMPNESS_M32_to_XMM<_EmitterId_> -#define SSE_CMPNESS_XMM_to_XMM eSSE_CMPNESS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPNLTSS_M32_to_XMM eSSE_CMPNLTSS_M32_to_XMM<_EmitterId_> -#define SSE_CMPNLTSS_XMM_to_XMM eSSE_CMPNLTSS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPNLESS_M32_to_XMM eSSE_CMPNLESS_M32_to_XMM<_EmitterId_> -#define SSE_CMPNLESS_XMM_to_XMM eSSE_CMPNLESS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPORDSS_M32_to_XMM eSSE_CMPORDSS_M32_to_XMM<_EmitterId_> -#define SSE_CMPORDSS_XMM_to_XMM eSSE_CMPORDSS_XMM_to_XMM<_EmitterId_> -#define SSE_UCOMISS_M32_to_XMM eSSE_UCOMISS_M32_to_XMM<_EmitterId_> -#define SSE_UCOMISS_XMM_to_XMM eSSE_UCOMISS_XMM_to_XMM<_EmitterId_> -#define SSE_PMAXSW_MM_to_MM eSSE_PMAXSW_MM_to_MM<_EmitterId_> -#define SSE_PMINSW_MM_to_MM eSSE_PMINSW_MM_to_MM<_EmitterId_> -#define SSE_CVTPI2PS_MM_to_XMM eSSE_CVTPI2PS_MM_to_XMM<_EmitterId_> -#define SSE_CVTPS2PI_M64_to_MM eSSE_CVTPS2PI_M64_to_MM<_EmitterId_> -#define SSE_CVTPS2PI_XMM_to_MM eSSE_CVTPS2PI_XMM_to_MM<_EmitterId_> -#define SSE_CVTPI2PS_M64_to_XMM eSSE_CVTPI2PS_M64_to_XMM<_EmitterId_> -#define SSE_CVTTSS2SI_M32_to_R32 eSSE_CVTTSS2SI_M32_to_R32<_EmitterId_> -#define SSE_CVTTSS2SI_XMM_to_R32 eSSE_CVTTSS2SI_XMM_to_R32<_EmitterId_> -#define SSE_CVTSI2SS_M32_to_XMM eSSE_CVTSI2SS_M32_to_XMM<_EmitterId_> -#define SSE_CVTSI2SS_R_to_XMM eSSE_CVTSI2SS_R_to_XMM<_EmitterId_> -#define SSE_MAXPS_M128_to_XMM eSSE_MAXPS_M128_to_XMM<_EmitterId_> -#define SSE_MAXPS_XMM_to_XMM eSSE_MAXPS_XMM_to_XMM<_EmitterId_> -#define SSE_MAXSS_M32_to_XMM eSSE_MAXSS_M32_to_XMM<_EmitterId_> -#define SSE_MAXSS_XMM_to_XMM eSSE_MAXSS_XMM_to_XMM<_EmitterId_> -#define SSE_MINPS_M128_to_XMM eSSE_MINPS_M128_to_XMM<_EmitterId_> -#define SSE_MINPS_XMM_to_XMM eSSE_MINPS_XMM_to_XMM<_EmitterId_> -#define SSE_MINSS_M32_to_XMM eSSE_MINSS_M32_to_XMM<_EmitterId_> -#define SSE_MINSS_XMM_to_XMM eSSE_MINSS_XMM_to_XMM<_EmitterId_> -#define SSE_RSQRTPS_M128_to_XMM eSSE_RSQRTPS_M128_to_XMM<_EmitterId_> -#define SSE_RSQRTPS_XMM_to_XMM eSSE_RSQRTPS_XMM_to_XMM<_EmitterId_> -#define SSE_RSQRTSS_M32_to_XMM eSSE_RSQRTSS_M32_to_XMM<_EmitterId_> -#define SSE_RSQRTSS_XMM_to_XMM eSSE_RSQRTSS_XMM_to_XMM<_EmitterId_> -#define SSE_SQRTPS_M128_to_XMM eSSE_SQRTPS_M128_to_XMM<_EmitterId_> -#define SSE_SQRTPS_XMM_to_XMM eSSE_SQRTPS_XMM_to_XMM<_EmitterId_> -#define SSE_SQRTSS_M32_to_XMM eSSE_SQRTSS_M32_to_XMM<_EmitterId_> -#define SSE_SQRTSS_XMM_to_XMM eSSE_SQRTSS_XMM_to_XMM<_EmitterId_> -#define SSE_UNPCKLPS_M128_to_XMM eSSE_UNPCKLPS_M128_to_XMM<_EmitterId_> -#define SSE_UNPCKLPS_XMM_to_XMM eSSE_UNPCKLPS_XMM_to_XMM<_EmitterId_> -#define SSE_UNPCKHPS_M128_to_XMM eSSE_UNPCKHPS_M128_to_XMM<_EmitterId_> -#define SSE_UNPCKHPS_XMM_to_XMM eSSE_UNPCKHPS_XMM_to_XMM<_EmitterId_> -#define SSE_SHUFPS_XMM_to_XMM eSSE_SHUFPS_XMM_to_XMM<_EmitterId_> -#define SSE_SHUFPS_M128_to_XMM eSSE_SHUFPS_M128_to_XMM<_EmitterId_> -#define SSE_SHUFPS_Rm_to_XMM eSSE_SHUFPS_Rm_to_XMM<_EmitterId_> -#define SSE_CMPEQPS_M128_to_XMM eSSE_CMPEQPS_M128_to_XMM<_EmitterId_> -#define SSE_CMPEQPS_XMM_to_XMM eSSE_CMPEQPS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPLTPS_M128_to_XMM eSSE_CMPLTPS_M128_to_XMM<_EmitterId_> -#define SSE_CMPLTPS_XMM_to_XMM eSSE_CMPLTPS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPLEPS_M128_to_XMM eSSE_CMPLEPS_M128_to_XMM<_EmitterId_> -#define SSE_CMPLEPS_XMM_to_XMM eSSE_CMPLEPS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPUNORDPS_M128_to_XMM eSSE_CMPUNORDPS_M128_to_XMM<_EmitterId_> -#define SSE_CMPUNORDPS_XMM_to_XMM eSSE_CMPUNORDPS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPNEPS_M128_to_XMM eSSE_CMPNEPS_M128_to_XMM<_EmitterId_> -#define SSE_CMPNEPS_XMM_to_XMM eSSE_CMPNEPS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPNLTPS_M128_to_XMM eSSE_CMPNLTPS_M128_to_XMM<_EmitterId_> -#define SSE_CMPNLTPS_XMM_to_XMM eSSE_CMPNLTPS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPNLEPS_M128_to_XMM eSSE_CMPNLEPS_M128_to_XMM<_EmitterId_> -#define SSE_CMPNLEPS_XMM_to_XMM eSSE_CMPNLEPS_XMM_to_XMM<_EmitterId_> -#define SSE_CMPORDPS_M128_to_XMM eSSE_CMPORDPS_M128_to_XMM<_EmitterId_> -#define SSE_CMPORDPS_XMM_to_XMM eSSE_CMPORDPS_XMM_to_XMM<_EmitterId_> -#define SSE_DIVPS_M128_to_XMM eSSE_DIVPS_M128_to_XMM<_EmitterId_> -#define SSE_DIVPS_XMM_to_XMM eSSE_DIVPS_XMM_to_XMM<_EmitterId_> -#define SSE_DIVSS_M32_to_XMM eSSE_DIVSS_M32_to_XMM<_EmitterId_> -#define SSE_DIVSS_XMM_to_XMM eSSE_DIVSS_XMM_to_XMM<_EmitterId_> -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// *SSE 2 Instructions* -//------------------------------------------------------------------ - -#define SSE2_MOVDQA_M128_to_XMM eSSE2_MOVDQA_M128_to_XMM<_EmitterId_> -#define SSE2_MOVDQA_XMM_to_M128 eSSE2_MOVDQA_XMM_to_M128<_EmitterId_> -#define SSE2_MOVDQA_XMM_to_XMM eSSE2_MOVDQA_XMM_to_XMM<_EmitterId_> -#define SSE2_MOVDQU_M128_to_XMM eSSE2_MOVDQU_M128_to_XMM<_EmitterId_> -#define SSE2_MOVDQU_XMM_to_M128 eSSE2_MOVDQU_XMM_to_M128<_EmitterId_> -#define SSE2_MOVDQU_XMM_to_XMM eSSE2_MOVDQA_XMM_to_XMM<_EmitterId_> -#define SSE2_PSRLW_XMM_to_XMM eSSE2_PSRLW_XMM_to_XMM<_EmitterId_> -#define SSE2_PSRLW_M128_to_XMM eSSE2_PSRLW_M128_to_XMM<_EmitterId_> -#define SSE2_PSRLW_I8_to_XMM eSSE2_PSRLW_I8_to_XMM<_EmitterId_> -#define SSE2_PSRLD_XMM_to_XMM eSSE2_PSRLD_XMM_to_XMM<_EmitterId_> -#define SSE2_PSRLD_M128_to_XMM eSSE2_PSRLD_M128_to_XMM<_EmitterId_> -#define SSE2_PSRLD_I8_to_XMM eSSE2_PSRLD_I8_to_XMM<_EmitterId_> -#define SSE2_PSRLQ_XMM_to_XMM eSSE2_PSRLQ_XMM_to_XMM<_EmitterId_> -#define SSE2_PSRLQ_M128_to_XMM eSSE2_PSRLQ_M128_to_XMM<_EmitterId_> -#define SSE2_PSRLQ_I8_to_XMM eSSE2_PSRLQ_I8_to_XMM<_EmitterId_> -#define SSE2_PSRLDQ_I8_to_XMM eSSE2_PSRLDQ_I8_to_XMM<_EmitterId_> -#define SSE2_PSRAW_XMM_to_XMM eSSE2_PSRAW_XMM_to_XMM<_EmitterId_> -#define SSE2_PSRAW_M128_to_XMM eSSE2_PSRAW_M128_to_XMM<_EmitterId_> -#define SSE2_PSRAW_I8_to_XMM eSSE2_PSRAW_I8_to_XMM<_EmitterId_> -#define SSE2_PSRAD_XMM_to_XMM eSSE2_PSRAD_XMM_to_XMM<_EmitterId_> -#define SSE2_PSRAD_M128_to_XMM eSSE2_PSRAD_M128_to_XMM<_EmitterId_> -#define SSE2_PSRAD_I8_to_XMM eSSE2_PSRAD_I8_to_XMM<_EmitterId_> -#define SSE2_PSLLW_XMM_to_XMM eSSE2_PSLLW_XMM_to_XMM<_EmitterId_> -#define SSE2_PSLLW_M128_to_XMM eSSE2_PSLLW_M128_to_XMM<_EmitterId_> -#define SSE2_PSLLW_I8_to_XMM eSSE2_PSLLW_I8_to_XMM<_EmitterId_> -#define SSE2_PSLLD_XMM_to_XMM eSSE2_PSLLD_XMM_to_XMM<_EmitterId_> -#define SSE2_PSLLD_M128_to_XMM eSSE2_PSLLD_M128_to_XMM<_EmitterId_> -#define SSE2_PSLLD_I8_to_XMM eSSE2_PSLLD_I8_to_XMM<_EmitterId_> -#define SSE2_PSLLQ_XMM_to_XMM eSSE2_PSLLQ_XMM_to_XMM<_EmitterId_> -#define SSE2_PSLLQ_M128_to_XMM eSSE2_PSLLQ_M128_to_XMM<_EmitterId_> -#define SSE2_PSLLQ_I8_to_XMM eSSE2_PSLLQ_I8_to_XMM<_EmitterId_> -#define SSE2_PSLLDQ_I8_to_XMM eSSE2_PSLLDQ_I8_to_XMM<_EmitterId_> -#define SSE2_PMAXSW_XMM_to_XMM eSSE2_PMAXSW_XMM_to_XMM<_EmitterId_> -#define SSE2_PMAXSW_M128_to_XMM eSSE2_PMAXSW_M128_to_XMM<_EmitterId_> -#define SSE2_PMAXUB_XMM_to_XMM eSSE2_PMAXUB_XMM_to_XMM<_EmitterId_> -#define SSE2_PMAXUB_M128_to_XMM eSSE2_PMAXUB_M128_to_XMM<_EmitterId_> -#define SSE2_PMINSW_XMM_to_XMM eSSE2_PMINSW_XMM_to_XMM<_EmitterId_> -#define SSE2_PMINSW_M128_to_XMM eSSE2_PMINSW_M128_to_XMM<_EmitterId_> -#define SSE2_PMINUB_XMM_to_XMM eSSE2_PMINUB_XMM_to_XMM<_EmitterId_> -#define SSE2_PMINUB_M128_to_XMM eSSE2_PMINUB_M128_to_XMM<_EmitterId_> -#define SSE2_PADDSB_XMM_to_XMM eSSE2_PADDSB_XMM_to_XMM<_EmitterId_> -#define SSE2_PADDSB_M128_to_XMM eSSE2_PADDSB_M128_to_XMM<_EmitterId_> -#define SSE2_PADDSW_XMM_to_XMM eSSE2_PADDSW_XMM_to_XMM<_EmitterId_> -#define SSE2_PADDSW_M128_to_XMM eSSE2_PADDSW_M128_to_XMM<_EmitterId_> -#define SSE2_PSUBSB_XMM_to_XMM eSSE2_PSUBSB_XMM_to_XMM<_EmitterId_> -#define SSE2_PSUBSB_M128_to_XMM eSSE2_PSUBSB_M128_to_XMM<_EmitterId_> -#define SSE2_PSUBSW_XMM_to_XMM eSSE2_PSUBSW_XMM_to_XMM<_EmitterId_> -#define SSE2_PSUBSW_M128_to_XMM eSSE2_PSUBSW_M128_to_XMM<_EmitterId_> -#define SSE2_PSUBUSB_XMM_to_XMM eSSE2_PSUBUSB_XMM_to_XMM<_EmitterId_> -#define SSE2_PSUBUSB_M128_to_XMM eSSE2_PSUBUSB_M128_to_XMM<_EmitterId_> -#define SSE2_PSUBUSW_XMM_to_XMM eSSE2_PSUBUSW_XMM_to_XMM<_EmitterId_> -#define SSE2_PSUBUSW_M128_to_XMM eSSE2_PSUBUSW_M128_to_XMM<_EmitterId_> -#define SSE2_PAND_XMM_to_XMM eSSE2_PAND_XMM_to_XMM<_EmitterId_> -#define SSE2_PAND_M128_to_XMM eSSE2_PAND_M128_to_XMM<_EmitterId_> -#define SSE2_PANDN_XMM_to_XMM eSSE2_PANDN_XMM_to_XMM<_EmitterId_> -#define SSE2_PANDN_M128_to_XMM eSSE2_PANDN_M128_to_XMM<_EmitterId_> -#define SSE2_PXOR_XMM_to_XMM eSSE2_PXOR_XMM_to_XMM<_EmitterId_> -#define SSE2_PXOR_M128_to_XMM eSSE2_PXOR_M128_to_XMM<_EmitterId_> -#define SSE2_PADDW_XMM_to_XMM eSSE2_PADDW_XMM_to_XMM<_EmitterId_> -#define SSE2_PADDW_M128_to_XMM eSSE2_PADDW_M128_to_XMM<_EmitterId_> -#define SSE2_PADDUSB_XMM_to_XMM eSSE2_PADDUSB_XMM_to_XMM<_EmitterId_> -#define SSE2_PADDUSB_M128_to_XMM eSSE2_PADDUSB_M128_to_XMM<_EmitterId_> -#define SSE2_PADDUSW_XMM_to_XMM eSSE2_PADDUSW_XMM_to_XMM<_EmitterId_> -#define SSE2_PADDUSW_M128_to_XMM eSSE2_PADDUSW_M128_to_XMM<_EmitterId_> -#define SSE2_PADDB_XMM_to_XMM eSSE2_PADDB_XMM_to_XMM<_EmitterId_> -#define SSE2_PADDB_M128_to_XMM eSSE2_PADDB_M128_to_XMM<_EmitterId_> -#define SSE2_PADDD_XMM_to_XMM eSSE2_PADDD_XMM_to_XMM<_EmitterId_> -#define SSE2_PADDD_M128_to_XMM eSSE2_PADDD_M128_to_XMM<_EmitterId_> -#define SSE2_PADDQ_XMM_to_XMM eSSE2_PADDQ_XMM_to_XMM<_EmitterId_> -#define SSE2_PADDQ_M128_to_XMM eSSE2_PADDQ_M128_to_XMM<_EmitterId_> -#define SSE2_PMADDWD_XMM_to_XMM eSSE2_PMADDWD_XMM_to_XMM<_EmitterId_> -#define SSE2_MOVSD_XMM_to_XMM eSSE2_MOVSD_XMM_to_XMM<_EmitterId_> -#define SSE2_MOVQ_M64_to_XMM eSSE2_MOVQ_M64_to_XMM<_EmitterId_> -#define SSE2_MOVQ_XMM_to_XMM eSSE2_MOVQ_XMM_to_XMM<_EmitterId_> -#define SSE2_MOVQ_XMM_to_M64 eSSE2_MOVQ_XMM_to_M64<_EmitterId_> -#define SSE2_MOVDQ2Q_XMM_to_MM eSSE2_MOVDQ2Q_XMM_to_MM<_EmitterId_> -#define SSE2_MOVQ2DQ_MM_to_XMM eSSE2_MOVQ2DQ_MM_to_XMM<_EmitterId_> -#define SSE2_MOVDQARtoRm eSSE2_MOVDQARtoRm<_EmitterId_> -#define SSE2_MOVDQARmtoR eSSE2_MOVDQARmtoR<_EmitterId_> -#define SSE2_CVTDQ2PS_M128_to_XMM eSSE2_CVTDQ2PS_M128_to_XMM<_EmitterId_> -#define SSE2_CVTDQ2PS_XMM_to_XMM eSSE2_CVTDQ2PS_XMM_to_XMM<_EmitterId_> -#define SSE2_CVTPS2DQ_M128_to_XMM eSSE2_CVTPS2DQ_M128_to_XMM<_EmitterId_> -#define SSE2_CVTPS2DQ_XMM_to_XMM eSSE2_CVTPS2DQ_XMM_to_XMM<_EmitterId_> -#define SSE2_CVTTPS2DQ_XMM_to_XMM eSSE2_CVTTPS2DQ_XMM_to_XMM<_EmitterId_> -#define SSE2_MAXPD_M128_to_XMM eSSE2_MAXPD_M128_to_XMM<_EmitterId_> -#define SSE2_MAXPD_XMM_to_XMM eSSE2_MAXPD_XMM_to_XMM<_EmitterId_> -#define SSE2_MINPD_M128_to_XMM eSSE2_MINPD_M128_to_XMM<_EmitterId_> -#define SSE2_MINPD_XMM_to_XMM eSSE2_MINPD_XMM_to_XMM<_EmitterId_> -#define SSE2_PSHUFD_XMM_to_XMM eSSE2_PSHUFD_XMM_to_XMM<_EmitterId_> -#define SSE2_PSHUFD_M128_to_XMM eSSE2_PSHUFD_M128_to_XMM<_EmitterId_> -#define SSE2_PSHUFLW_XMM_to_XMM eSSE2_PSHUFLW_XMM_to_XMM<_EmitterId_> -#define SSE2_PSHUFLW_M128_to_XMM eSSE2_PSHUFLW_M128_to_XMM<_EmitterId_> -#define SSE2_PSHUFHW_XMM_to_XMM eSSE2_PSHUFHW_XMM_to_XMM<_EmitterId_> -#define SSE2_PSHUFHW_M128_to_XMM eSSE2_PSHUFHW_M128_to_XMM<_EmitterId_> -#define SSE2_SHUFPD_XMM_to_XMM eSSE2_SHUFPD_XMM_to_XMM<_EmitterId_> -#define SSE2_SHUFPD_M128_to_XMM eSSE2_SHUFPD_M128_to_XMM<_EmitterId_> -#define SSE2_ORPD_M128_to_XMM eSSE2_ORPD_M128_to_XMM<_EmitterId_> -#define SSE2_ORPD_XMM_to_XMM eSSE2_ORPD_XMM_to_XMM<_EmitterId_> -#define SSE2_XORPD_M128_to_XMM eSSE2_XORPD_M128_to_XMM<_EmitterId_> -#define SSE2_XORPD_XMM_to_XMM eSSE2_XORPD_XMM_to_XMM<_EmitterId_> -#define SSE2_ANDPD_M128_to_XMM eSSE2_ANDPD_M128_to_XMM<_EmitterId_> -#define SSE2_ANDPD_XMM_to_XMM eSSE2_ANDPD_XMM_to_XMM<_EmitterId_> -#define SSE2_ANDNPD_M128_to_XMM eSSE2_ANDNPD_M128_to_XMM<_EmitterId_> -#define SSE2_ANDNPD_XMM_to_XMM eSSE2_ANDNPD_XMM_to_XMM<_EmitterId_> -#define SSE2_ADDSD_M64_to_XMM eSSE2_ADDSD_M64_to_XMM<_EmitterId_> -#define SSE2_ADDSD_XMM_to_XMM eSSE2_ADDSD_XMM_to_XMM<_EmitterId_> -#define SSE2_SUBSD_M64_to_XMM eSSE2_SUBSD_M64_to_XMM<_EmitterId_> -#define SSE2_SUBSD_XMM_to_XMM eSSE2_SUBSD_XMM_to_XMM<_EmitterId_> -#define SSE2_MULSD_M64_to_XMM eSSE2_MULSD_M64_to_XMM<_EmitterId_> -#define SSE2_MULSD_XMM_to_XMM eSSE2_MULSD_XMM_to_XMM<_EmitterId_> -#define SSE2_CMPEQSD_M64_to_XMM eSSE2_CMPEQSD_M64_to_XMM<_EmitterId_> -#define SSE2_CMPEQSD_XMM_to_XMM eSSE2_CMPEQSD_XMM_to_XMM<_EmitterId_> -#define SSE2_CMPLTSD_M64_to_XMM eSSE2_CMPLTSD_M64_to_XMM<_EmitterId_> -#define SSE2_CMPLTSD_XMM_to_XMM eSSE2_CMPLTSD_XMM_to_XMM<_EmitterId_> -#define SSE2_CMPLESD_M64_to_XMM eSSE2_CMPLESD_M64_to_XMM<_EmitterId_> -#define SSE2_CMPLESD_XMM_to_XMM eSSE2_CMPLESD_XMM_to_XMM<_EmitterId_> -#define SSE2_CMPUNORDSD_M64_to_XMM eSSE2_CMPUNORDSD_M64_to_XMM<_EmitterId_> -#define SSE2_CMPUNORDSD_XMM_to_XMM eSSE2_CMPUNORDSD_XMM_to_XMM<_EmitterId_> -#define SSE2_CMPNESD_M64_to_XMM eSSE2_CMPNESD_M64_to_XMM<_EmitterId_> -#define SSE2_CMPNESD_XMM_to_XMM eSSE2_CMPNESD_XMM_to_XMM<_EmitterId_> -#define SSE2_CMPNLTSD_M64_to_XMM eSSE2_CMPNLTSD_M64_to_XMM<_EmitterId_> -#define SSE2_CMPNLTSD_XMM_to_XMM eSSE2_CMPNLTSD_XMM_to_XMM<_EmitterId_> -#define SSE2_CMPNLESD_M64_to_XMM eSSE2_CMPNLESD_M64_to_XMM<_EmitterId_> -#define SSE2_CMPNLESD_XMM_to_XMM eSSE2_CMPNLESD_XMM_to_XMM<_EmitterId_> -#define SSE2_CMPORDSD_M64_to_XMM eSSE2_CMPORDSD_M64_to_XMM<_EmitterId_> -#define SSE2_CMPORDSD_XMM_to_XMM eSSE2_CMPORDSD_XMM_to_XMM<_EmitterId_> -#define SSE2_UCOMISD_M64_to_XMM eSSE2_UCOMISD_M64_to_XMM<_EmitterId_> -#define SSE2_UCOMISD_XMM_to_XMM eSSE2_UCOMISD_XMM_to_XMM<_EmitterId_> -#define SSE2_CVTSS2SD_M32_to_XMM eSSE2_CVTSS2SD_M32_to_XMM<_EmitterId_> -#define SSE2_CVTSS2SD_XMM_to_XMM eSSE2_CVTSS2SD_XMM_to_XMM<_EmitterId_> -#define SSE2_CVTSD2SS_M64_to_XMM eSSE2_CVTSD2SS_M64_to_XMM<_EmitterId_> -#define SSE2_CVTSD2SS_XMM_to_XMM eSSE2_CVTSD2SS_XMM_to_XMM<_EmitterId_> -#define SSE2_MAXSD_M64_to_XMM eSSE2_MAXSD_M64_to_XMM<_EmitterId_> -#define SSE2_MAXSD_XMM_to_XMM eSSE2_MAXSD_XMM_to_XMM<_EmitterId_> -#define SSE2_MINSD_M64_to_XMM eSSE2_MINSD_M64_to_XMM<_EmitterId_> -#define SSE2_MINSD_XMM_to_XMM eSSE2_MINSD_XMM_to_XMM<_EmitterId_> -#define SSE2_SQRTSD_M64_to_XMM eSSE2_SQRTSD_M64_to_XMM<_EmitterId_> -#define SSE2_SQRTSD_XMM_to_XMM eSSE2_SQRTSD_XMM_to_XMM<_EmitterId_> -#define SSE2_DIVSD_M64_to_XMM eSSE2_DIVSD_M64_to_XMM<_EmitterId_> -#define SSE2_DIVSD_XMM_to_XMM eSSE2_DIVSD_XMM_to_XMM<_EmitterId_> -//------------------------------------------------------------------ -// PACKSSWB,PACKSSDW: Pack Saturate Signed Word -//------------------------------------------------------------------ -#define SSE2_PACKSSWB_XMM_to_XMM eSSE2_PACKSSWB_XMM_to_XMM<_EmitterId_> -#define SSE2_PACKSSWB_M128_to_XMM eSSE2_PACKSSWB_M128_to_XMM<_EmitterId_> -#define SSE2_PACKSSDW_XMM_to_XMM eSSE2_PACKSSDW_XMM_to_XMM<_EmitterId_> -#define SSE2_PACKSSDW_M128_to_XMM eSSE2_PACKSSDW_M128_to_XMM<_EmitterId_> -#define SSE2_PACKUSWB_XMM_to_XMM eSSE2_PACKUSWB_XMM_to_XMM<_EmitterId_> -#define SSE2_PACKUSWB_M128_to_XMM eSSE2_PACKUSWB_M128_to_XMM<_EmitterId_> -//------------------------------------------------------------------ -// PUNPCKHWD: Unpack 16bit high -//------------------------------------------------------------------ -#define SSE2_PUNPCKLBW_XMM_to_XMM eSSE2_PUNPCKLBW_XMM_to_XMM<_EmitterId_> -#define SSE2_PUNPCKLBW_M128_to_XMM eSSE2_PUNPCKLBW_M128_to_XMM<_EmitterId_> -#define SSE2_PUNPCKHBW_XMM_to_XMM eSSE2_PUNPCKHBW_XMM_to_XMM<_EmitterId_> -#define SSE2_PUNPCKHBW_M128_to_XMM eSSE2_PUNPCKHBW_M128_to_XMM<_EmitterId_> -#define SSE2_PUNPCKLWD_XMM_to_XMM eSSE2_PUNPCKLWD_XMM_to_XMM<_EmitterId_> -#define SSE2_PUNPCKLWD_M128_to_XMM eSSE2_PUNPCKLWD_M128_to_XMM<_EmitterId_> -#define SSE2_PUNPCKHWD_XMM_to_XMM eSSE2_PUNPCKHWD_XMM_to_XMM<_EmitterId_> -#define SSE2_PUNPCKHWD_M128_to_XMM eSSE2_PUNPCKHWD_M128_to_XMM<_EmitterId_> -#define SSE2_PUNPCKLDQ_XMM_to_XMM eSSE2_PUNPCKLDQ_XMM_to_XMM<_EmitterId_> -#define SSE2_PUNPCKLDQ_M128_to_XMM eSSE2_PUNPCKLDQ_M128_to_XMM<_EmitterId_> -#define SSE2_PUNPCKHDQ_XMM_to_XMM eSSE2_PUNPCKHDQ_XMM_to_XMM<_EmitterId_> -#define SSE2_PUNPCKHDQ_M128_to_XMM eSSE2_PUNPCKHDQ_M128_to_XMM<_EmitterId_> -#define SSE2_PUNPCKLQDQ_XMM_to_XMM eSSE2_PUNPCKLQDQ_XMM_to_XMM<_EmitterId_> -#define SSE2_PUNPCKLQDQ_M128_to_XMM eSSE2_PUNPCKLQDQ_M128_to_XMM<_EmitterId_> -#define SSE2_PUNPCKHQDQ_XMM_to_XMM eSSE2_PUNPCKHQDQ_XMM_to_XMM<_EmitterId_> -#define SSE2_PUNPCKHQDQ_M128_to_XMM eSSE2_PUNPCKHQDQ_M128_to_XMM<_EmitterId_> -#define SSE2_PMULLW_XMM_to_XMM eSSE2_PMULLW_XMM_to_XMM<_EmitterId_> -#define SSE2_PMULLW_M128_to_XMM eSSE2_PMULLW_M128_to_XMM<_EmitterId_> -#define SSE2_PMULHW_XMM_to_XMM eSSE2_PMULHW_XMM_to_XMM<_EmitterId_> -#define SSE2_PMULHW_M128_to_XMM eSSE2_PMULHW_M128_to_XMM<_EmitterId_> -#define SSE2_PMULUDQ_XMM_to_XMM eSSE2_PMULUDQ_XMM_to_XMM<_EmitterId_> -#define SSE2_PMULUDQ_M128_to_XMM eSSE2_PMULUDQ_M128_to_XMM<_EmitterId_> -//------------------------------------------------------------------ -// PMOVMSKB: Create 16bit mask from signs of 8bit integers -//------------------------------------------------------------------ -#define SSE_MOVMSKPS_XMM_to_R32 eSSE_MOVMSKPS_XMM_to_R32<_EmitterId_> -#define SSE2_PMOVMSKB_XMM_to_R32 eSSE2_PMOVMSKB_XMM_to_R32<_EmitterId_> -#define SSE2_MOVMSKPD_XMM_to_R32 eSSE2_MOVMSKPD_XMM_to_R32<_EmitterId_> -//------------------------------------------------------------------ -// PEXTRW,PINSRW: Packed Extract/Insert Word -//------------------------------------------------------------------ -#define SSE_PEXTRW_XMM_to_R32 eSSE_PEXTRW_XMM_to_R32<_EmitterId_> -#define SSE_PINSRW_R32_to_XMM eSSE_PINSRW_R32_to_XMM<_EmitterId_> -//------------------------------------------------------------------ -// PSUBx: Subtract Packed Integers -//------------------------------------------------------------------ -#define SSE2_PSUBB_XMM_to_XMM eSSE2_PSUBB_XMM_to_XMM<_EmitterId_> -#define SSE2_PSUBB_M128_to_XMM eSSE2_PSUBB_M128_to_XMM<_EmitterId_> -#define SSE2_PSUBW_XMM_to_XMM eSSE2_PSUBW_XMM_to_XMM<_EmitterId_> -#define SSE2_PSUBW_M128_to_XMM eSSE2_PSUBW_M128_to_XMM<_EmitterId_> -#define SSE2_PSUBD_XMM_to_XMM eSSE2_PSUBD_XMM_to_XMM<_EmitterId_> -#define SSE2_PSUBD_M128_to_XMM eSSE2_PSUBD_M128_to_XMM<_EmitterId_> -#define SSE2_PSUBQ_XMM_to_XMM eSSE2_PSUBQ_XMM_to_XMM<_EmitterId_> -#define SSE2_PSUBQ_M128_to_XMM eSSE2_PSUBQ_M128_to_XMM<_EmitterId_> -//------------------------------------------------------------------ -// PCMPxx: Compare Packed Integers -//------------------------------------------------------------------ -#define SSE2_PCMPGTB_XMM_to_XMM eSSE2_PCMPGTB_XMM_to_XMM<_EmitterId_> -#define SSE2_PCMPGTB_M128_to_XMM eSSE2_PCMPGTB_M128_to_XMM<_EmitterId_> -#define SSE2_PCMPGTW_XMM_to_XMM eSSE2_PCMPGTW_XMM_to_XMM<_EmitterId_> -#define SSE2_PCMPGTW_M128_to_XMM eSSE2_PCMPGTW_M128_to_XMM<_EmitterId_> -#define SSE2_PCMPGTD_XMM_to_XMM eSSE2_PCMPGTD_XMM_to_XMM<_EmitterId_> -#define SSE2_PCMPGTD_M128_to_XMM eSSE2_PCMPGTD_M128_to_XMM<_EmitterId_> -#define SSE2_PCMPEQB_XMM_to_XMM eSSE2_PCMPEQB_XMM_to_XMM<_EmitterId_> -#define SSE2_PCMPEQB_M128_to_XMM eSSE2_PCMPEQB_M128_to_XMM<_EmitterId_> -#define SSE2_PCMPEQW_XMM_to_XMM eSSE2_PCMPEQW_XMM_to_XMM<_EmitterId_> -#define SSE2_PCMPEQW_M128_to_XMM eSSE2_PCMPEQW_M128_to_XMM<_EmitterId_> -#define SSE2_PCMPEQD_XMM_to_XMM eSSE2_PCMPEQD_XMM_to_XMM<_EmitterId_> -#define SSE2_PCMPEQD_M128_to_XMM eSSE2_PCMPEQD_M128_to_XMM<_EmitterId_> -//------------------------------------------------------------------ -// MOVD: Move Dword(32bit) to /from XMM reg -//------------------------------------------------------------------ -#define SSE2_MOVD_M32_to_XMM eSSE2_MOVD_M32_to_XMM<_EmitterId_> -#define SSE2_MOVD_R_to_XMM eSSE2_MOVD_R_to_XMM<_EmitterId_> -#define SSE2_MOVD_Rm_to_XMM eSSE2_MOVD_Rm_to_XMM<_EmitterId_> -#define SSE2_MOVD_Rm_to_XMM eSSE2_MOVD_Rm_to_XMM<_EmitterId_> -#define SSE2_MOVD_XMM_to_M32 eSSE2_MOVD_XMM_to_M32<_EmitterId_> -#define SSE2_MOVD_XMM_to_R eSSE2_MOVD_XMM_to_R<_EmitterId_> -#define SSE2_MOVD_XMM_to_Rm eSSE2_MOVD_XMM_to_Rm<_EmitterId_> -#define SSE2_MOVD_XMM_to_Rm eSSE2_MOVD_XMM_to_Rm<_EmitterId_> -#define SSE2_MOVQ_XMM_to_R eSSE2_MOVQ_XMM_to_R<_EmitterId_> -#define SSE2_MOVQ_R_to_XMM eSSE2_MOVQ_R_to_XMM<_EmitterId_> -//------------------------------------------------------------------ -// POR : SSE Bitwise OR -//------------------------------------------------------------------ -#define SSE2_POR_XMM_to_XMM eSSE2_POR_XMM_to_XMM<_EmitterId_> -#define SSE2_POR_M128_to_XMM eSSE2_POR_M128_to_XMM<_EmitterId_> -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// SSE3 -//------------------------------------------------------------------ -#define SSE3_HADDPS_XMM_to_XMM eSSE3_HADDPS_XMM_to_XMM<_EmitterId_> -#define SSE3_HADDPS_M128_to_XMM eSSE3_HADDPS_M128_to_XMM<_EmitterId_> -#define SSE3_MOVSLDUP_XMM_to_XMM eSSE3_MOVSLDUP_XMM_to_XMM<_EmitterId_> -#define SSE3_MOVSLDUP_M128_to_XMM eSSE3_MOVSLDUP_M128_to_XMM<_EmitterId_> -#define SSE3_MOVSHDUP_XMM_to_XMM eSSE3_MOVSHDUP_XMM_to_XMM<_EmitterId_> -#define SSE3_MOVSHDUP_M128_to_XMM eSSE3_MOVSHDUP_M128_to_XMM<_EmitterId_> -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// SSSE3 -//------------------------------------------------------------------ -#define SSSE3_PABSB_XMM_to_XMM eSSSE3_PABSB_XMM_to_XMM<_EmitterId_> -#define SSSE3_PABSW_XMM_to_XMM eSSSE3_PABSW_XMM_to_XMM<_EmitterId_> -#define SSSE3_PABSD_XMM_to_XMM eSSSE3_PABSD_XMM_to_XMM<_EmitterId_> -#define SSSE3_PALIGNR_XMM_to_XMM eSSSE3_PALIGNR_XMM_to_XMM<_EmitterId_> -#define SSSE3_PSIGNB_XMM_to_XMM eSSSE3_PSIGNB_XMM_to_XMM<_EmitterId_> -#define SSSE3_PSIGNW_XMM_to_XMM eSSSE3_PSIGNW_XMM_to_XMM<_EmitterId_> -#define SSSE3_PSIGND_XMM_to_XMM eSSSE3_PSIGND_XMM_to_XMM<_EmitterId_> -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// SSE4.1 -//------------------------------------------------------------------ -#define SSE4_DPPS_XMM_to_XMM eSSE4_DPPS_XMM_to_XMM<_EmitterId_> -#define SSE4_DPPS_M128_to_XMM eSSE4_DPPS_M128_to_XMM<_EmitterId_> -#define SSE4_INSERTPS_XMM_to_XMM eSSE4_INSERTPS_XMM_to_XMM<_EmitterId_> -#define SSE4_EXTRACTPS_XMM_to_R32 eSSE4_EXTRACTPS_XMM_to_R32<_EmitterId_> -#define SSE4_BLENDPS_XMM_to_XMM eSSE4_BLENDPS_XMM_to_XMM<_EmitterId_> -#define SSE4_BLENDVPS_XMM_to_XMM eSSE4_BLENDVPS_XMM_to_XMM<_EmitterId_> -#define SSE4_BLENDVPS_M128_to_XMM eSSE4_BLENDVPS_M128_to_XMM<_EmitterId_> -#define SSE4_PMOVSXDQ_XMM_to_XMM eSSE4_PMOVSXDQ_XMM_to_XMM<_EmitterId_> -#define SSE4_PMOVZXDQ_XMM_to_XMM eSSE4_PMOVZXDQ_XMM_to_XMM<_EmitterId_> -#define SSE4_PINSRD_R32_to_XMM eSSE4_PINSRD_R32_to_XMM<_EmitterId_> -#define SSE4_PMAXSD_XMM_to_XMM eSSE4_PMAXSD_XMM_to_XMM<_EmitterId_> -#define SSE4_PMINSD_XMM_to_XMM eSSE4_PMINSD_XMM_to_XMM<_EmitterId_> -#define SSE4_PMAXUD_XMM_to_XMM eSSE4_PMAXUD_XMM_to_XMM<_EmitterId_> -#define SSE4_PMINUD_XMM_to_XMM eSSE4_PMINUD_XMM_to_XMM<_EmitterId_> -#define SSE4_PMAXSD_M128_to_XMM eSSE4_PMAXSD_M128_to_XMM<_EmitterId_> -#define SSE4_PMINSD_M128_to_XMM eSSE4_PMINSD_M128_to_XMM<_EmitterId_> -#define SSE4_PMAXUD_M128_to_XMM eSSE4_PMAXUD_M128_to_XMM<_EmitterId_> -#define SSE4_PMINUD_M128_to_XMM eSSE4_PMINUD_M128_to_XMM<_EmitterId_> -#define SSE4_PMULDQ_XMM_to_XMM eSSE4_PMULDQ_XMM_to_XMM<_EmitterId_> -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// 3DNOW instructions -//------------------------------------------------------------------ -#define FEMMS eFEMMS<_EmitterId_> -#define PFCMPEQMtoR ePFCMPEQMtoR<_EmitterId_> -#define PFCMPGTMtoR ePFCMPGTMtoR<_EmitterId_> -#define PFCMPGEMtoR ePFCMPGEMtoR<_EmitterId_> -#define PFADDMtoR ePFADDMtoR<_EmitterId_> -#define PFADDRtoR ePFADDRtoR<_EmitterId_> -#define PFSUBMtoR ePFSUBMtoR<_EmitterId_> -#define PFSUBRtoR ePFSUBRtoR<_EmitterId_> -#define PFMULMtoR ePFMULMtoR<_EmitterId_> -#define PFMULRtoR ePFMULRtoR<_EmitterId_> -#define PFRCPMtoR ePFRCPMtoR<_EmitterId_> -#define PFRCPRtoR ePFRCPRtoR<_EmitterId_> -#define PFRCPIT1RtoR ePFRCPIT1RtoR<_EmitterId_> -#define PFRCPIT2RtoR ePFRCPIT2RtoR<_EmitterId_> -#define PFRSQRTRtoR ePFRSQRTRtoR<_EmitterId_> -#define PFRSQIT1RtoR ePFRSQIT1RtoR<_EmitterId_> -#define PF2IDMtoR ePF2IDMtoR<_EmitterId_> -#define PI2FDMtoR ePI2FDMtoR<_EmitterId_> -#define PI2FDRtoR ePI2FDRtoR<_EmitterId_> -#define PFMAXMtoR ePFMAXMtoR<_EmitterId_> -#define PFMAXRtoR ePFMAXRtoR<_EmitterId_> -#define PFMINMtoR ePFMINMtoR<_EmitterId_> -#define PFMINRtoR ePFMINRtoR<_EmitterId_> -//------------------------------------------------------------------ +/* Pcsx2 - Pc Ps2 Emulator +* Copyright (C) 2002-2009 Pcsx2 Team +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ +/* +* ix86 definitions v0.6.2 +* Authors: linuzappz +* alexey silinov +* goldfinger +* shadow < shadow@pcsx2.net > +* cottonvibes(@gmail.com) +*/ + +#pragma once + +//------------------------------------------------------------------ +// jump/align functions +//------------------------------------------------------------------ +#define x86SetPtr ex86SetPtr<_EmitterId_> +#define x86SetJ8 ex86SetJ8<_EmitterId_> +#define x86SetJ8A ex86SetJ8A<_EmitterId_> +#define x86SetJ16 ex86SetJ16<_EmitterId_> +#define x86SetJ16A ex86SetJ16A<_EmitterId_> +#define x86SetJ32 ex86SetJ32<_EmitterId_> +#define x86SetJ32A ex86SetJ32A<_EmitterId_> +#define x86Align ex86Align<_EmitterId_> +#define x86AlignExecutable ex86AlignExecutable<_EmitterId_> +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// *IX86 intructions* +//------------------------------------------------------------------ + +#define STC eSTC<_EmitterId_> +#define CLC eCLC<_EmitterId_> +#define NOP eNOP<_EmitterId_> + +//------------------------------------------------------------------ +// mov instructions +//------------------------------------------------------------------ +#define MOV32RtoR eMOV32RtoR<_EmitterId_> +#define MOV32RtoM eMOV32RtoM<_EmitterId_> +#define MOV32MtoR eMOV32MtoR<_EmitterId_> +#define MOV32RmtoR eMOV32RmtoR<_EmitterId_> +#define MOV32RmtoR eMOV32RmtoR<_EmitterId_> +#define MOV32RmStoR eMOV32RmStoR<_EmitterId_> +#define MOV32RmSOffsettoR eMOV32RmSOffsettoR<_EmitterId_> +#define MOV32RtoRm eMOV32RtoRm<_EmitterId_> +#define MOV32RtoRmS eMOV32RtoRmS<_EmitterId_> +#define MOV32ItoR eMOV32ItoR<_EmitterId_> +#define MOV32ItoM eMOV32ItoM<_EmitterId_> +#define MOV32ItoRm eMOV32ItoRm<_EmitterId_> +#define MOV32RtoRm eMOV32RtoRm<_EmitterId_> +#define MOV16RtoM eMOV16RtoM<_EmitterId_> +#define MOV16MtoR eMOV16MtoR<_EmitterId_> +#define MOV16RmtoR eMOV16RmtoR<_EmitterId_> +#define MOV16RmtoR eMOV16RmtoR<_EmitterId_> +#define MOV16RmSOffsettoR eMOV16RmSOffsettoR<_EmitterId_> +#define MOV16RtoRm eMOV16RtoRm<_EmitterId_> +#define MOV16ItoM eMOV16ItoM<_EmitterId_> +#define MOV16RtoRmS eMOV16RtoRmS<_EmitterId_> +#define MOV16ItoR eMOV16ItoR<_EmitterId_> +#define MOV16ItoRm eMOV16ItoRm<_EmitterId_> +#define MOV16RtoRm eMOV16RtoRm<_EmitterId_> +#define MOV8RtoM eMOV8RtoM<_EmitterId_> +#define MOV8MtoR eMOV8MtoR<_EmitterId_> +#define MOV8RmtoR eMOV8RmtoR<_EmitterId_> +#define MOV8RmtoR eMOV8RmtoR<_EmitterId_> +#define MOV8RmSOffsettoR eMOV8RmSOffsettoR<_EmitterId_> +#define MOV8RtoRm eMOV8RtoRm<_EmitterId_> +#define MOV8ItoM eMOV8ItoM<_EmitterId_> +#define MOV8ItoR eMOV8ItoR<_EmitterId_> +#define MOV8ItoRm eMOV8ItoRm<_EmitterId_> +#define MOV8RtoRm eMOV8RtoRm<_EmitterId_> +#define MOVSX32R8toR eMOVSX32R8toR<_EmitterId_> +#define MOVSX32Rm8toR eMOVSX32Rm8toR<_EmitterId_> +#define MOVSX32M8toR eMOVSX32M8toR<_EmitterId_> +#define MOVSX32R16toR eMOVSX32R16toR<_EmitterId_> +#define MOVSX32Rm16toR eMOVSX32Rm16toR<_EmitterId_> +#define MOVSX32M16toR eMOVSX32M16toR<_EmitterId_> +#define MOVZX32R8toR eMOVZX32R8toR<_EmitterId_> +#define MOVZX32Rm8toR eMOVZX32Rm8toR<_EmitterId_> +#define MOVZX32M8toR eMOVZX32M8toR<_EmitterId_> +#define MOVZX32R16toR eMOVZX32R16toR<_EmitterId_> +#define MOVZX32Rm16toR eMOVZX32Rm16toR<_EmitterId_> +#define MOVZX32M16toR eMOVZX32M16toR<_EmitterId_> +#define CMOVBE32RtoR eCMOVBE32RtoR<_EmitterId_> +#define CMOVBE32MtoR eCMOVBE32MtoR<_EmitterId_> +#define CMOVB32RtoR eCMOVB32RtoR<_EmitterId_> +#define CMOVB32MtoR eCMOVB32MtoR<_EmitterId_> +#define CMOVAE32RtoR eCMOVAE32RtoR<_EmitterId_> +#define CMOVAE32MtoR eCMOVAE32MtoR<_EmitterId_> +#define CMOVA32RtoR eCMOVA32RtoR<_EmitterId_> +#define CMOVA32MtoR eCMOVA32MtoR<_EmitterId_> +#define CMOVO32RtoR eCMOVO32RtoR<_EmitterId_> +#define CMOVO32MtoR eCMOVO32MtoR<_EmitterId_> +#define CMOVP32RtoR eCMOVP32RtoR<_EmitterId_> +#define CMOVP32MtoR eCMOVP32MtoR<_EmitterId_> +#define CMOVS32RtoR eCMOVS32RtoR<_EmitterId_> +#define CMOVS32MtoR eCMOVS32MtoR<_EmitterId_> +#define CMOVNO32RtoR eCMOVNO32RtoR<_EmitterId_> +#define CMOVNO32MtoR eCMOVNO32MtoR<_EmitterId_> +#define CMOVNP32RtoR eCMOVNP32RtoR<_EmitterId_> +#define CMOVNP32MtoR eCMOVNP32MtoR<_EmitterId_> +#define CMOVNS32RtoR eCMOVNS32RtoR<_EmitterId_> +#define CMOVNS32MtoR eCMOVNS32MtoR<_EmitterId_> +#define CMOVNE32RtoR eCMOVNE32RtoR<_EmitterId_> +#define CMOVNE32MtoR eCMOVNE32MtoR<_EmitterId_> +#define CMOVE32RtoR eCMOVE32RtoR<_EmitterId_> +#define CMOVE32MtoR eCMOVE32MtoR<_EmitterId_> +#define CMOVG32RtoR eCMOVG32RtoR<_EmitterId_> +#define CMOVG32MtoR eCMOVG32MtoR<_EmitterId_> +#define CMOVGE32RtoR eCMOVGE32RtoR<_EmitterId_> +#define CMOVGE32MtoR eCMOVGE32MtoR<_EmitterId_> +#define CMOVL32RtoR eCMOVL32RtoR<_EmitterId_> +#define CMOVL32MtoR eCMOVL32MtoR<_EmitterId_> +#define CMOVLE32RtoR eCMOVLE32RtoR<_EmitterId_> +#define CMOVLE32MtoR eCMOVLE32MtoR<_EmitterId_> +//------------------------------------------------------------------ +// arithmetic instructions +//------------------------------------------------------------------ +#define ADD32ItoEAX eADD32ItoEAX<_EmitterId_> +#define ADD32ItoR eADD32ItoR<_EmitterId_> +#define ADD32ItoM eADD32ItoM<_EmitterId_> +#define ADD32ItoRm eADD32ItoRm<_EmitterId_> +#define ADD32RtoR eADD32RtoR<_EmitterId_> +#define ADD32RtoM eADD32RtoM<_EmitterId_> +#define ADD32MtoR eADD32MtoR<_EmitterId_> +#define ADD16RtoR eADD16RtoR<_EmitterId_> +#define ADD16ItoR eADD16ItoR<_EmitterId_> +#define ADD16ItoM eADD16ItoM<_EmitterId_> +#define ADD16RtoM eADD16RtoM<_EmitterId_> +#define ADD16MtoR eADD16MtoR<_EmitterId_> +#define ADD8MtoR eADD8MtoR<_EmitterId_> +#define ADC32ItoR eADC32ItoR<_EmitterId_> +#define ADC32ItoM eADC32ItoM<_EmitterId_> +#define ADC32RtoR eADC32RtoR<_EmitterId_> +#define ADC32MtoR eADC32MtoR<_EmitterId_> +#define ADC32RtoM eADC32RtoM<_EmitterId_> +#define INC32R eINC32R<_EmitterId_> +#define INC32M eINC32M<_EmitterId_> +#define INC16R eINC16R<_EmitterId_> +#define INC16M eINC16M<_EmitterId_> +#define SUB32ItoR eSUB32ItoR<_EmitterId_> +#define SUB32ItoM eSUB32ItoM<_EmitterId_> +#define SUB32RtoR eSUB32RtoR<_EmitterId_> +#define SUB32MtoR eSUB32MtoR<_EmitterId_> +#define SUB32RtoM eSUB32RtoM<_EmitterId_> +#define SUB16RtoR eSUB16RtoR<_EmitterId_> +#define SUB16ItoR eSUB16ItoR<_EmitterId_> +#define SUB16ItoM eSUB16ItoM<_EmitterId_> +#define SUB16MtoR eSUB16MtoR<_EmitterId_> +#define SBB32ItoR eSBB32ItoR<_EmitterId_> +#define SBB32ItoM eSBB32ItoM<_EmitterId_> +#define SBB32RtoR eSBB32RtoR<_EmitterId_> +#define SBB32MtoR eSBB32MtoR<_EmitterId_> +#define SBB32RtoM eSBB32RtoM<_EmitterId_> +#define DEC32R eDEC32R<_EmitterId_> +#define DEC32M eDEC32M<_EmitterId_> +#define DEC16R eDEC16R<_EmitterId_> +#define DEC16M eDEC16M<_EmitterId_> +#define MUL32R eMUL32R<_EmitterId_> +#define MUL32M eMUL32M<_EmitterId_> +#define IMUL32R eIMUL32R<_EmitterId_> +#define IMUL32M eIMUL32M<_EmitterId_> +#define IMUL32RtoR eIMUL32RtoR<_EmitterId_> +#define DIV32R eDIV32R<_EmitterId_> +#define DIV32M eDIV32M<_EmitterId_> +#define IDIV32R eIDIV32R<_EmitterId_> +#define IDIV32M eIDIV32M<_EmitterId_> +//------------------------------------------------------------------ +// shifting instructions +//------------------------------------------------------------------ +#define SHL32ItoR eSHL32ItoR<_EmitterId_> +#define SHL32ItoM eSHL32ItoM<_EmitterId_> +#define SHL32CLtoR eSHL32CLtoR<_EmitterId_> +#define SHL16ItoR eSHL16ItoR<_EmitterId_> +#define SHL8ItoR eSHL8ItoR<_EmitterId_> +#define SHR32ItoR eSHR32ItoR<_EmitterId_> +#define SHR32ItoM eSHR32ItoM<_EmitterId_> +#define SHR32CLtoR eSHR32CLtoR<_EmitterId_> +#define SHR16ItoR eSHR16ItoR<_EmitterId_> +#define SHR8ItoR eSHR8ItoR<_EmitterId_> +#define SAR32ItoR eSAR32ItoR<_EmitterId_> +#define SAR32ItoM eSAR32ItoM<_EmitterId_> +#define SAR32CLtoR eSAR32CLtoR<_EmitterId_> +#define SAR16ItoR eSAR16ItoR<_EmitterId_> +#define ROR32ItoR eROR32ItoR<_EmitterId_> +#define RCR32ItoR eRCR32ItoR<_EmitterId_> +#define RCR32ItoM eRCR32ItoM<_EmitterId_> +#define SHLD32ItoR eSHLD32ItoR<_EmitterId_> +#define SHRD32ItoR eSHRD32ItoR<_EmitterId_> +//------------------------------------------------------------------ +// logical instructions +//------------------------------------------------------------------ +#define OR32ItoR eOR32ItoR<_EmitterId_> +#define OR32ItoM eOR32ItoM<_EmitterId_> +#define OR32RtoR eOR32RtoR<_EmitterId_> +#define OR32RtoM eOR32RtoM<_EmitterId_> +#define OR32MtoR eOR32MtoR<_EmitterId_> +#define OR16RtoR eOR16RtoR<_EmitterId_> +#define OR16ItoR eOR16ItoR<_EmitterId_> +#define OR16ItoM eOR16ItoM<_EmitterId_> +#define OR16MtoR eOR16MtoR<_EmitterId_> +#define OR16RtoM eOR16RtoM<_EmitterId_> +#define OR8RtoR eOR8RtoR<_EmitterId_> +#define OR8RtoM eOR8RtoM<_EmitterId_> +#define OR8ItoM eOR8ItoM<_EmitterId_> +#define OR8MtoR eOR8MtoR<_EmitterId_> +#define XOR32ItoR eXOR32ItoR<_EmitterId_> +#define XOR32ItoM eXOR32ItoM<_EmitterId_> +#define XOR32RtoR eXOR32RtoR<_EmitterId_> +#define XOR16RtoR eXOR16RtoR<_EmitterId_> +#define XOR32RtoM eXOR32RtoM<_EmitterId_> +#define XOR32MtoR eXOR32MtoR<_EmitterId_> +#define XOR16RtoM eXOR16RtoM<_EmitterId_> +#define XOR16ItoR eXOR16ItoR<_EmitterId_> +#define AND32ItoR eAND32ItoR<_EmitterId_> +#define AND32I8toR eAND32I8toR<_EmitterId_> +#define AND32ItoM eAND32ItoM<_EmitterId_> +#define AND32I8toM eAND32I8toM<_EmitterId_> +#define AND32RtoR eAND32RtoR<_EmitterId_> +#define AND32RtoM eAND32RtoM<_EmitterId_> +#define AND32MtoR eAND32MtoR<_EmitterId_> +#define AND32RmtoR eAND32RmtoR<_EmitterId_> +#define AND32RmtoR eAND32RmtoR<_EmitterId_> +#define AND16RtoR eAND16RtoR<_EmitterId_> +#define AND16ItoR eAND16ItoR<_EmitterId_> +#define AND16ItoM eAND16ItoM<_EmitterId_> +#define AND16RtoM eAND16RtoM<_EmitterId_> +#define AND16MtoR eAND16MtoR<_EmitterId_> +#define AND8ItoR eAND8ItoR<_EmitterId_> +#define AND8ItoM eAND8ItoM<_EmitterId_> +#define AND8RtoM eAND8RtoM<_EmitterId_> +#define AND8MtoR eAND8MtoR<_EmitterId_> +#define AND8RtoR eAND8RtoR<_EmitterId_> +#define NOT32R eNOT32R<_EmitterId_> +#define NOT32M eNOT32M<_EmitterId_> +#define NEG32R eNEG32R<_EmitterId_> +#define NEG32M eNEG32M<_EmitterId_> +#define NEG16R eNEG16R<_EmitterId_> +//------------------------------------------------------------------ +// jump/call instructions +//------------------------------------------------------------------ +#define JMP8 eJMP8<_EmitterId_> +#define JP8 eJP8<_EmitterId_> +#define JNP8 eJNP8<_EmitterId_> +#define JE8 eJE8<_EmitterId_> +#define JZ8 eJZ8<_EmitterId_> +#define JG8 eJG8<_EmitterId_> +#define JGE8 eJGE8<_EmitterId_> +#define JS8 eJS8<_EmitterId_> +#define JNS8 eJNS8<_EmitterId_> +#define JL8 eJL8<_EmitterId_> +#define JA8 eJA8<_EmitterId_> +#define JAE8 eJAE8<_EmitterId_> +#define JB8 eJB8<_EmitterId_> +#define JBE8 eJBE8<_EmitterId_> +#define JLE8 eJLE8<_EmitterId_> +#define JNE8 eJNE8<_EmitterId_> +#define JNZ8 eJNZ8<_EmitterId_> +#define JNG8 eJNG8<_EmitterId_> +#define JNGE8 eJNGE8<_EmitterId_> +#define JNL8 eJNL8<_EmitterId_> +#define JNLE8 eJNLE8<_EmitterId_> +#define JO8 eJO8<_EmitterId_> +#define JNO8 eJNO8<_EmitterId_> +#define JMP32 eJMP32<_EmitterId_> +#define JNS32 eJNS32<_EmitterId_> +#define JS32 eJS32<_EmitterId_> +#define JB32 eJB32<_EmitterId_> +#define JE32 eJE32<_EmitterId_> +#define JZ32 eJZ32<_EmitterId_> +#define JG32 eJG32<_EmitterId_> +#define JGE32 eJGE32<_EmitterId_> +#define JL32 eJL32<_EmitterId_> +#define JLE32 eJLE32<_EmitterId_> +#define JA32 eJA32<_EmitterId_> +#define JAE32 eJAE32<_EmitterId_> +#define JNE32 eJNE32<_EmitterId_> +#define JNZ32 eJNZ32<_EmitterId_> +#define JNG32 eJNG32<_EmitterId_> +#define JNGE32 eJNGE32<_EmitterId_> +#define JNL32 eJNL32<_EmitterId_> +#define JNLE32 eJNLE32<_EmitterId_> +#define JO32 eJO32<_EmitterId_> +#define JNO32 eJNO32<_EmitterId_> +#define JS32 eJS32<_EmitterId_> +#define JMPR eJMPR<_EmitterId_> +#define JMP32M eJMP32M<_EmitterId_> +#define CALLFunc eCALLFunc<_EmitterId_> +#define CALL32 eCALL32<_EmitterId_> +#define CALL32R eCALL32R<_EmitterId_> +#define CALL32M eCALL32M<_EmitterId_> +//------------------------------------------------------------------ +// misc instructions +//------------------------------------------------------------------ +#define CMP32ItoR eCMP32ItoR<_EmitterId_> +#define CMP32ItoM eCMP32ItoM<_EmitterId_> +#define CMP32RtoR eCMP32RtoR<_EmitterId_> +#define CMP32MtoR eCMP32MtoR<_EmitterId_> +#define CMP32ItoRm eCMP32ItoRm<_EmitterId_> +#define CMP8I8toRm eCMP8I8toRm<_EmitterId_> +#define CMP32I8toRm eCMP32I8toRm<_EmitterId_> +#define CMP32I8toM eCMP32I8toM<_EmitterId_> +#define CMP16ItoR eCMP16ItoR<_EmitterId_> +#define CMP16ItoM eCMP16ItoM<_EmitterId_> +#define CMP16RtoR eCMP16RtoR<_EmitterId_> +#define CMP16MtoR eCMP16MtoR<_EmitterId_> +#define CMP8ItoR eCMP8ItoR<_EmitterId_> +#define CMP8MtoR eCMP8MtoR<_EmitterId_> +#define TEST32ItoR eTEST32ItoR<_EmitterId_> +#define TEST32ItoM eTEST32ItoM<_EmitterId_> +#define TEST32RtoR eTEST32RtoR<_EmitterId_> +#define TEST32ItoRm eTEST32ItoRm<_EmitterId_> +#define TEST16ItoR eTEST16ItoR<_EmitterId_> +#define TEST16RtoR eTEST16RtoR<_EmitterId_> +#define TEST8RtoR eTEST8RtoR<_EmitterId_> +#define TEST8ItoR eTEST8ItoR<_EmitterId_> +#define TEST8ItoM eTEST8ItoM<_EmitterId_> +#define SETS8R eSETS8R<_EmitterId_> +#define SETL8R eSETL8R<_EmitterId_> +#define SETGE8R eSETGE8R<_EmitterId_> +#define SETG8R eSETG8R<_EmitterId_> +#define SETA8R eSETA8R<_EmitterId_> +#define SETAE8R eSETAE8R<_EmitterId_> +#define SETB8R eSETB8R<_EmitterId_> +#define SETNZ8R eSETNZ8R<_EmitterId_> +#define SETZ8R eSETZ8R<_EmitterId_> +#define SETE8R eSETE8R<_EmitterId_> +#define PUSH32I ePUSH32I<_EmitterId_> +#define PUSH32R ePUSH32R<_EmitterId_> +#define PUSH32M ePUSH32M<_EmitterId_> +#define PUSH32I ePUSH32I<_EmitterId_> +#define POP32R ePOP32R<_EmitterId_> +#define PUSHA32 ePUSHA32<_EmitterId_> +#define POPA32 ePOPA32<_EmitterId_> +#define PUSHR ePUSHR<_EmitterId_> +#define POPR ePOPR<_EmitterId_> +#define PUSHFD ePUSHFD<_EmitterId_> +#define POPFD ePOPFD<_EmitterId_> +#define RET eRET<_EmitterId_> +#define CBW eCBW<_EmitterId_> +#define CWDE eCWDE<_EmitterId_> +#define CWD eCWD<_EmitterId_> +#define CDQ eCDQ<_EmitterId_> +#define CDQE eCDQE<_EmitterId_> +#define LAHF eLAHF<_EmitterId_> +#define SAHF eSAHF<_EmitterId_> +#define BT32ItoR eBT32ItoR<_EmitterId_> +#define BTR32ItoR eBTR32ItoR<_EmitterId_> +#define BSRRtoR eBSRRtoR<_EmitterId_> +#define BSWAP32R eBSWAP32R<_EmitterId_> +#define LEA16RtoR eLEA16RtoR<_EmitterId_> +#define LEA32RtoR eLEA32RtoR<_EmitterId_> +#define LEA16RRtoR eLEA16RRtoR<_EmitterId_> +#define LEA32RRtoR eLEA32RRtoR<_EmitterId_> +#define LEA16RStoR eLEA16RStoR<_EmitterId_> +#define LEA32RStoR eLEA32RStoR<_EmitterId_> +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// FPU instructions +//------------------------------------------------------------------ +#define FILD32 eFILD32<_EmitterId_> +#define FISTP32 eFISTP32<_EmitterId_> +#define FLD32 eFLD32<_EmitterId_> +#define FLD eFLD<_EmitterId_> +#define FLD1 eFLD1<_EmitterId_> +#define FLDL2E eFLDL2E<_EmitterId_> +#define FST32 eFST32<_EmitterId_> +#define FSTP32 eFSTP32<_EmitterId_> +#define FSTP eFSTP<_EmitterId_> +#define FLDCW eFLDCW<_EmitterId_> +#define FNSTCW eFNSTCW<_EmitterId_> +#define FADD32Rto0 eFADD32Rto0<_EmitterId_> +#define FADD320toR eFADD320toR<_EmitterId_> +#define FSUB32Rto0 eFSUB32Rto0<_EmitterId_> +#define FSUB320toR eFSUB320toR<_EmitterId_> +#define FSUBP eFSUBP<_EmitterId_> +#define FMUL32Rto0 eFMUL32Rto0<_EmitterId_> +#define FMUL320toR eFMUL320toR<_EmitterId_> +#define FDIV32Rto0 eFDIV32Rto0<_EmitterId_> +#define FDIV320toR eFDIV320toR<_EmitterId_> +#define FDIV320toRP eFDIV320toRP<_EmitterId_> +#define FADD32 eFADD32<_EmitterId_> +#define FSUB32 eFSUB32<_EmitterId_> +#define FMUL32 eFMUL32<_EmitterId_> +#define FDIV32 eFDIV32<_EmitterId_> +#define FCOMI eFCOMI<_EmitterId_> +#define FCOMIP eFCOMIP<_EmitterId_> +#define FUCOMI eFUCOMI<_EmitterId_> +#define FUCOMIP eFUCOMIP<_EmitterId_> +#define FCOM32 eFCOM32<_EmitterId_> +#define FABS eFABS<_EmitterId_> +#define FSQRT eFSQRT<_EmitterId_> +#define FPATAN eFPATAN<_EmitterId_> +#define FSIN eFSIN<_EmitterId_> +#define FCHS eFCHS<_EmitterId_> +#define FCMOVB32 eFCMOVB32<_EmitterId_> +#define FCMOVE32 eFCMOVE32<_EmitterId_> +#define FCMOVBE32 eFCMOVBE32<_EmitterId_> +#define FCMOVU32 eFCMOVU32<_EmitterId_> +#define FCMOVNB32 eFCMOVNB32<_EmitterId_> +#define FCMOVNE32 eFCMOVNE32<_EmitterId_> +#define FCMOVNBE32 eFCMOVNBE32<_EmitterId_> +#define FCMOVNU32 eFCMOVNU32<_EmitterId_> +#define FCOMP32 eFCOMP32<_EmitterId_> +#define FNSTSWtoAX eFNSTSWtoAX<_EmitterId_> +#define FXAM eFXAM<_EmitterId_> +#define FDECSTP eFDECSTP<_EmitterId_> +#define FRNDINT eFRNDINT<_EmitterId_> +#define FXCH eFXCH<_EmitterId_> +#define F2XM1 eF2XM1<_EmitterId_> +#define FSCALE eFSCALE<_EmitterId_> +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// MMX instructions +//------------------------------------------------------------------ +#define EMMS eEMMS<_EmitterId_> +#define MOVQMtoR eMOVQMtoR<_EmitterId_> +#define MOVQRtoM eMOVQRtoM<_EmitterId_> +#define PANDRtoR ePANDRtoR<_EmitterId_> +#define PANDNRtoR ePANDNRtoR<_EmitterId_> +#define PANDMtoR ePANDMtoR<_EmitterId_> +#define PANDNRtoR ePANDNRtoR<_EmitterId_> +#define PANDNMtoR ePANDNMtoR<_EmitterId_> +#define PORRtoR ePORRtoR<_EmitterId_> +#define PORMtoR ePORMtoR<_EmitterId_> +#define PXORRtoR ePXORRtoR<_EmitterId_> +#define PXORMtoR ePXORMtoR<_EmitterId_> +#define PSLLQRtoR ePSLLQRtoR<_EmitterId_> +#define PSLLQMtoR ePSLLQMtoR<_EmitterId_> +#define PSLLQItoR ePSLLQItoR<_EmitterId_> +#define PSRLQRtoR ePSRLQRtoR<_EmitterId_> +#define PSRLQMtoR ePSRLQMtoR<_EmitterId_> +#define PSRLQItoR ePSRLQItoR<_EmitterId_> +#define PADDUSBRtoR ePADDUSBRtoR<_EmitterId_> +#define PADDUSBMtoR ePADDUSBMtoR<_EmitterId_> +#define PADDUSWRtoR ePADDUSWRtoR<_EmitterId_> +#define PADDUSWMtoR ePADDUSWMtoR<_EmitterId_> +#define PADDBRtoR ePADDBRtoR<_EmitterId_> +#define PADDBMtoR ePADDBMtoR<_EmitterId_> +#define PADDWRtoR ePADDWRtoR<_EmitterId_> +#define PADDWMtoR ePADDWMtoR<_EmitterId_> +#define PADDDRtoR ePADDDRtoR<_EmitterId_> +#define PADDDMtoR ePADDDMtoR<_EmitterId_> +#define PADDSBRtoR ePADDSBRtoR<_EmitterId_> +#define PADDSWRtoR ePADDSWRtoR<_EmitterId_> +#define PADDQMtoR ePADDQMtoR<_EmitterId_> +#define PADDQRtoR ePADDQRtoR<_EmitterId_> +#define PSUBSBRtoR ePSUBSBRtoR<_EmitterId_> +#define PSUBSWRtoR ePSUBSWRtoR<_EmitterId_> +#define PSUBBRtoR ePSUBBRtoR<_EmitterId_> +#define PSUBWRtoR ePSUBWRtoR<_EmitterId_> +#define PSUBDRtoR ePSUBDRtoR<_EmitterId_> +#define PSUBDMtoR ePSUBDMtoR<_EmitterId_> +#define PSUBQMtoR ePSUBQMtoR<_EmitterId_> +#define PSUBQRtoR ePSUBQRtoR<_EmitterId_> +#define PMULUDQMtoR ePMULUDQMtoR<_EmitterId_> +#define PMULUDQRtoR ePMULUDQRtoR<_EmitterId_> +#define PCMPEQBRtoR ePCMPEQBRtoR<_EmitterId_> +#define PCMPEQWRtoR ePCMPEQWRtoR<_EmitterId_> +#define PCMPEQDRtoR ePCMPEQDRtoR<_EmitterId_> +#define PCMPEQDMtoR ePCMPEQDMtoR<_EmitterId_> +#define PCMPGTBRtoR ePCMPGTBRtoR<_EmitterId_> +#define PCMPGTWRtoR ePCMPGTWRtoR<_EmitterId_> +#define PCMPGTDRtoR ePCMPGTDRtoR<_EmitterId_> +#define PCMPGTDMtoR ePCMPGTDMtoR<_EmitterId_> +#define PSRLWItoR ePSRLWItoR<_EmitterId_> +#define PSRLDItoR ePSRLDItoR<_EmitterId_> +#define PSRLDRtoR ePSRLDRtoR<_EmitterId_> +#define PSLLWItoR ePSLLWItoR<_EmitterId_> +#define PSLLDItoR ePSLLDItoR<_EmitterId_> +#define PSLLDRtoR ePSLLDRtoR<_EmitterId_> +#define PSRAWItoR ePSRAWItoR<_EmitterId_> +#define PSRADItoR ePSRADItoR<_EmitterId_> +#define PSRADRtoR ePSRADRtoR<_EmitterId_> +#define PUNPCKLDQRtoR ePUNPCKLDQRtoR<_EmitterId_> +#define PUNPCKLDQMtoR ePUNPCKLDQMtoR<_EmitterId_> +#define PUNPCKHDQRtoR ePUNPCKHDQRtoR<_EmitterId_> +#define PUNPCKHDQMtoR ePUNPCKHDQMtoR<_EmitterId_> +#define MOVQ64ItoR eMOVQ64ItoR<_EmitterId_> +#define MOVQRtoR eMOVQRtoR<_EmitterId_> +#define MOVQRmtoR eMOVQRmtoR<_EmitterId_> +#define MOVQRtoRm eMOVQRtoRm<_EmitterId_> +#define MOVDMtoMMX eMOVDMtoMMX<_EmitterId_> +#define MOVDMMXtoM eMOVDMMXtoM<_EmitterId_> +#define MOVD32RtoMMX eMOVD32RtoMMX<_EmitterId_> +#define MOVD32RmtoMMX eMOVD32RmtoMMX<_EmitterId_> +#define MOVD32RmtoMMX eMOVD32RmtoMMX<_EmitterId_> +#define MOVD32MMXtoR eMOVD32MMXtoR<_EmitterId_> +#define MOVD32MMXtoRm eMOVD32MMXtoRm<_EmitterId_> +#define MOVD32MMXtoRm eMOVD32MMXtoRm<_EmitterId_> +#define PINSRWRtoMMX ePINSRWRtoMMX<_EmitterId_> +#define PSHUFWRtoR ePSHUFWRtoR<_EmitterId_> +#define PSHUFWMtoR ePSHUFWMtoR<_EmitterId_> +#define MASKMOVQRtoR eMASKMOVQRtoR<_EmitterId_> +#define PMOVMSKBMMXtoR ePMOVMSKBMMXtoR<_EmitterId_> +//------------------------------------------------------------------ +// PACKSSWB,PACKSSDW: Pack Saturate Signed Word 64bits +//------------------------------------------------------------------ +#define PACKSSWBMMXtoMMX ePACKSSWBMMXtoMMX<_EmitterId_> +#define PACKSSDWMMXtoMMX ePACKSSDWMMXtoMMX<_EmitterId_> +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// *SSE instructions* +//------------------------------------------------------------------ +#define SSE_STMXCSR eSSE_STMXCSR<_EmitterId_> +#define SSE_LDMXCSR eSSE_LDMXCSR<_EmitterId_> +#define SSE_MOVAPS_M128_to_XMM eSSE_MOVAPS_M128_to_XMM<_EmitterId_> +#define SSE_MOVAPS_XMM_to_M128 eSSE_MOVAPS_XMM_to_M128<_EmitterId_> +#define SSE_MOVAPS_XMM_to_XMM eSSE_MOVAPS_XMM_to_XMM<_EmitterId_> +#define SSE_MOVUPS_M128_to_XMM eSSE_MOVUPS_M128_to_XMM<_EmitterId_> +#define SSE_MOVUPS_XMM_to_M128 eSSE_MOVUPS_XMM_to_M128<_EmitterId_> +#define SSE_MOVSS_M32_to_XMM eSSE_MOVSS_M32_to_XMM<_EmitterId_> +#define SSE_MOVSS_XMM_to_M32 eSSE_MOVSS_XMM_to_M32<_EmitterId_> +#define SSE_MOVSS_XMM_to_Rm eSSE_MOVSS_XMM_to_Rm<_EmitterId_> +#define SSE_MOVSS_XMM_to_XMM eSSE_MOVSS_XMM_to_XMM<_EmitterId_> +#define SSE_MOVSS_Rm_to_XMM eSSE_MOVSS_Rm_to_XMM<_EmitterId_> +#define SSE_MOVSS_XMM_to_Rm eSSE_MOVSS_XMM_to_Rm<_EmitterId_> +#define SSE_MASKMOVDQU_XMM_to_XMM eSSE_MASKMOVDQU_XMM_to_XMM<_EmitterId_> +#define SSE_MOVLPS_M64_to_XMM eSSE_MOVLPS_M64_to_XMM<_EmitterId_> +#define SSE_MOVLPS_XMM_to_M64 eSSE_MOVLPS_XMM_to_M64<_EmitterId_> +#define SSE_MOVLPS_Rm_to_XMM eSSE_MOVLPS_Rm_to_XMM<_EmitterId_> +#define SSE_MOVLPS_XMM_to_Rm eSSE_MOVLPS_XMM_to_Rm<_EmitterId_> +#define SSE_MOVHPS_M64_to_XMM eSSE_MOVHPS_M64_to_XMM<_EmitterId_> +#define SSE_MOVHPS_XMM_to_M64 eSSE_MOVHPS_XMM_to_M64<_EmitterId_> +#define SSE_MOVHPS_Rm_to_XMM eSSE_MOVHPS_Rm_to_XMM<_EmitterId_> +#define SSE_MOVHPS_XMM_to_Rm eSSE_MOVHPS_XMM_to_Rm<_EmitterId_> +#define SSE_MOVLHPS_XMM_to_XMM eSSE_MOVLHPS_XMM_to_XMM<_EmitterId_> +#define SSE_MOVHLPS_XMM_to_XMM eSSE_MOVHLPS_XMM_to_XMM<_EmitterId_> +#define SSE_MOVLPSRmtoR eSSE_MOVLPSRmtoR<_EmitterId_> +#define SSE_MOVLPSRtoRm eSSE_MOVLPSRtoRm<_EmitterId_> +#define SSE_MOVAPSRmStoR eSSE_MOVAPSRmStoR<_EmitterId_> +#define SSE_MOVAPSRtoRmS eSSE_MOVAPSRtoRmS<_EmitterId_> +#define SSE_MOVAPSRtoRm eSSE_MOVAPSRtoRm<_EmitterId_> +#define SSE_MOVAPSRmtoR eSSE_MOVAPSRmtoR<_EmitterId_> +#define SSE_MOVUPSRmStoR eSSE_MOVUPSRmStoR<_EmitterId_> +#define SSE_MOVUPSRtoRmS eSSE_MOVUPSRtoRmS<_EmitterId_> +#define SSE_MOVUPSRtoRm eSSE_MOVUPSRtoRm<_EmitterId_> +#define SSE_MOVUPSRmtoR eSSE_MOVUPSRmtoR<_EmitterId_> +#define SSE_MOVUPSRmtoR eSSE_MOVUPSRmtoR<_EmitterId_> +#define SSE_MOVUPSRtoRm eSSE_MOVUPSRtoRm<_EmitterId_> +#define SSE_RCPPS_XMM_to_XMM eSSE_RCPPS_XMM_to_XMM<_EmitterId_> +#define SSE_RCPPS_M128_to_XMM eSSE_RCPPS_M128_to_XMM<_EmitterId_> +#define SSE_RCPSS_XMM_to_XMM eSSE_RCPSS_XMM_to_XMM<_EmitterId_> +#define SSE_RCPSS_M32_to_XMM eSSE_RCPSS_M32_to_XMM<_EmitterId_> +#define SSE_ORPS_M128_to_XMM eSSE_ORPS_M128_to_XMM<_EmitterId_> +#define SSE_ORPS_XMM_to_XMM eSSE_ORPS_XMM_to_XMM<_EmitterId_> +#define SSE_XORPS_M128_to_XMM eSSE_XORPS_M128_to_XMM<_EmitterId_> +#define SSE_XORPS_XMM_to_XMM eSSE_XORPS_XMM_to_XMM<_EmitterId_> +#define SSE_ANDPS_M128_to_XMM eSSE_ANDPS_M128_to_XMM<_EmitterId_> +#define SSE_ANDPS_XMM_to_XMM eSSE_ANDPS_XMM_to_XMM<_EmitterId_> +#define SSE_ANDNPS_M128_to_XMM eSSE_ANDNPS_M128_to_XMM<_EmitterId_> +#define SSE_ANDNPS_XMM_to_XMM eSSE_ANDNPS_XMM_to_XMM<_EmitterId_> +#define SSE_ADDPS_M128_to_XMM eSSE_ADDPS_M128_to_XMM<_EmitterId_> +#define SSE_ADDPS_XMM_to_XMM eSSE_ADDPS_XMM_to_XMM<_EmitterId_> +#define SSE_ADDSS_M32_to_XMM eSSE_ADDSS_M32_to_XMM<_EmitterId_> +#define SSE_ADDSS_XMM_to_XMM eSSE_ADDSS_XMM_to_XMM<_EmitterId_> +#define SSE_SUBPS_M128_to_XMM eSSE_SUBPS_M128_to_XMM<_EmitterId_> +#define SSE_SUBPS_XMM_to_XMM eSSE_SUBPS_XMM_to_XMM<_EmitterId_> +#define SSE_SUBSS_M32_to_XMM eSSE_SUBSS_M32_to_XMM<_EmitterId_> +#define SSE_SUBSS_XMM_to_XMM eSSE_SUBSS_XMM_to_XMM<_EmitterId_> +#define SSE_MULPS_M128_to_XMM eSSE_MULPS_M128_to_XMM<_EmitterId_> +#define SSE_MULPS_XMM_to_XMM eSSE_MULPS_XMM_to_XMM<_EmitterId_> +#define SSE_MULSS_M32_to_XMM eSSE_MULSS_M32_to_XMM<_EmitterId_> +#define SSE_MULSS_XMM_to_XMM eSSE_MULSS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPEQSS_M32_to_XMM eSSE_CMPEQSS_M32_to_XMM<_EmitterId_> +#define SSE_CMPEQSS_XMM_to_XMM eSSE_CMPEQSS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPLTSS_M32_to_XMM eSSE_CMPLTSS_M32_to_XMM<_EmitterId_> +#define SSE_CMPLTSS_XMM_to_XMM eSSE_CMPLTSS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPLESS_M32_to_XMM eSSE_CMPLESS_M32_to_XMM<_EmitterId_> +#define SSE_CMPLESS_XMM_to_XMM eSSE_CMPLESS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPUNORDSS_M32_to_XMM eSSE_CMPUNORDSS_M32_to_XMM<_EmitterId_> +#define SSE_CMPUNORDSS_XMM_to_XMM eSSE_CMPUNORDSS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPNESS_M32_to_XMM eSSE_CMPNESS_M32_to_XMM<_EmitterId_> +#define SSE_CMPNESS_XMM_to_XMM eSSE_CMPNESS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPNLTSS_M32_to_XMM eSSE_CMPNLTSS_M32_to_XMM<_EmitterId_> +#define SSE_CMPNLTSS_XMM_to_XMM eSSE_CMPNLTSS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPNLESS_M32_to_XMM eSSE_CMPNLESS_M32_to_XMM<_EmitterId_> +#define SSE_CMPNLESS_XMM_to_XMM eSSE_CMPNLESS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPORDSS_M32_to_XMM eSSE_CMPORDSS_M32_to_XMM<_EmitterId_> +#define SSE_CMPORDSS_XMM_to_XMM eSSE_CMPORDSS_XMM_to_XMM<_EmitterId_> +#define SSE_UCOMISS_M32_to_XMM eSSE_UCOMISS_M32_to_XMM<_EmitterId_> +#define SSE_UCOMISS_XMM_to_XMM eSSE_UCOMISS_XMM_to_XMM<_EmitterId_> +#define SSE_PMAXSW_MM_to_MM eSSE_PMAXSW_MM_to_MM<_EmitterId_> +#define SSE_PMINSW_MM_to_MM eSSE_PMINSW_MM_to_MM<_EmitterId_> +#define SSE_CVTPI2PS_MM_to_XMM eSSE_CVTPI2PS_MM_to_XMM<_EmitterId_> +#define SSE_CVTPS2PI_M64_to_MM eSSE_CVTPS2PI_M64_to_MM<_EmitterId_> +#define SSE_CVTPS2PI_XMM_to_MM eSSE_CVTPS2PI_XMM_to_MM<_EmitterId_> +#define SSE_CVTPI2PS_M64_to_XMM eSSE_CVTPI2PS_M64_to_XMM<_EmitterId_> +#define SSE_CVTTSS2SI_M32_to_R32 eSSE_CVTTSS2SI_M32_to_R32<_EmitterId_> +#define SSE_CVTTSS2SI_XMM_to_R32 eSSE_CVTTSS2SI_XMM_to_R32<_EmitterId_> +#define SSE_CVTSI2SS_M32_to_XMM eSSE_CVTSI2SS_M32_to_XMM<_EmitterId_> +#define SSE_CVTSI2SS_R_to_XMM eSSE_CVTSI2SS_R_to_XMM<_EmitterId_> +#define SSE_MAXPS_M128_to_XMM eSSE_MAXPS_M128_to_XMM<_EmitterId_> +#define SSE_MAXPS_XMM_to_XMM eSSE_MAXPS_XMM_to_XMM<_EmitterId_> +#define SSE_MAXSS_M32_to_XMM eSSE_MAXSS_M32_to_XMM<_EmitterId_> +#define SSE_MAXSS_XMM_to_XMM eSSE_MAXSS_XMM_to_XMM<_EmitterId_> +#define SSE_MINPS_M128_to_XMM eSSE_MINPS_M128_to_XMM<_EmitterId_> +#define SSE_MINPS_XMM_to_XMM eSSE_MINPS_XMM_to_XMM<_EmitterId_> +#define SSE_MINSS_M32_to_XMM eSSE_MINSS_M32_to_XMM<_EmitterId_> +#define SSE_MINSS_XMM_to_XMM eSSE_MINSS_XMM_to_XMM<_EmitterId_> +#define SSE_RSQRTPS_M128_to_XMM eSSE_RSQRTPS_M128_to_XMM<_EmitterId_> +#define SSE_RSQRTPS_XMM_to_XMM eSSE_RSQRTPS_XMM_to_XMM<_EmitterId_> +#define SSE_RSQRTSS_M32_to_XMM eSSE_RSQRTSS_M32_to_XMM<_EmitterId_> +#define SSE_RSQRTSS_XMM_to_XMM eSSE_RSQRTSS_XMM_to_XMM<_EmitterId_> +#define SSE_SQRTPS_M128_to_XMM eSSE_SQRTPS_M128_to_XMM<_EmitterId_> +#define SSE_SQRTPS_XMM_to_XMM eSSE_SQRTPS_XMM_to_XMM<_EmitterId_> +#define SSE_SQRTSS_M32_to_XMM eSSE_SQRTSS_M32_to_XMM<_EmitterId_> +#define SSE_SQRTSS_XMM_to_XMM eSSE_SQRTSS_XMM_to_XMM<_EmitterId_> +#define SSE_UNPCKLPS_M128_to_XMM eSSE_UNPCKLPS_M128_to_XMM<_EmitterId_> +#define SSE_UNPCKLPS_XMM_to_XMM eSSE_UNPCKLPS_XMM_to_XMM<_EmitterId_> +#define SSE_UNPCKHPS_M128_to_XMM eSSE_UNPCKHPS_M128_to_XMM<_EmitterId_> +#define SSE_UNPCKHPS_XMM_to_XMM eSSE_UNPCKHPS_XMM_to_XMM<_EmitterId_> +#define SSE_SHUFPS_XMM_to_XMM eSSE_SHUFPS_XMM_to_XMM<_EmitterId_> +#define SSE_SHUFPS_M128_to_XMM eSSE_SHUFPS_M128_to_XMM<_EmitterId_> +#define SSE_SHUFPS_Rm_to_XMM eSSE_SHUFPS_Rm_to_XMM<_EmitterId_> +#define SSE_CMPEQPS_M128_to_XMM eSSE_CMPEQPS_M128_to_XMM<_EmitterId_> +#define SSE_CMPEQPS_XMM_to_XMM eSSE_CMPEQPS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPLTPS_M128_to_XMM eSSE_CMPLTPS_M128_to_XMM<_EmitterId_> +#define SSE_CMPLTPS_XMM_to_XMM eSSE_CMPLTPS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPLEPS_M128_to_XMM eSSE_CMPLEPS_M128_to_XMM<_EmitterId_> +#define SSE_CMPLEPS_XMM_to_XMM eSSE_CMPLEPS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPUNORDPS_M128_to_XMM eSSE_CMPUNORDPS_M128_to_XMM<_EmitterId_> +#define SSE_CMPUNORDPS_XMM_to_XMM eSSE_CMPUNORDPS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPNEPS_M128_to_XMM eSSE_CMPNEPS_M128_to_XMM<_EmitterId_> +#define SSE_CMPNEPS_XMM_to_XMM eSSE_CMPNEPS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPNLTPS_M128_to_XMM eSSE_CMPNLTPS_M128_to_XMM<_EmitterId_> +#define SSE_CMPNLTPS_XMM_to_XMM eSSE_CMPNLTPS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPNLEPS_M128_to_XMM eSSE_CMPNLEPS_M128_to_XMM<_EmitterId_> +#define SSE_CMPNLEPS_XMM_to_XMM eSSE_CMPNLEPS_XMM_to_XMM<_EmitterId_> +#define SSE_CMPORDPS_M128_to_XMM eSSE_CMPORDPS_M128_to_XMM<_EmitterId_> +#define SSE_CMPORDPS_XMM_to_XMM eSSE_CMPORDPS_XMM_to_XMM<_EmitterId_> +#define SSE_DIVPS_M128_to_XMM eSSE_DIVPS_M128_to_XMM<_EmitterId_> +#define SSE_DIVPS_XMM_to_XMM eSSE_DIVPS_XMM_to_XMM<_EmitterId_> +#define SSE_DIVSS_M32_to_XMM eSSE_DIVSS_M32_to_XMM<_EmitterId_> +#define SSE_DIVSS_XMM_to_XMM eSSE_DIVSS_XMM_to_XMM<_EmitterId_> +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// *SSE 2 Instructions* +//------------------------------------------------------------------ + +#define SSE2_MOVDQA_M128_to_XMM eSSE2_MOVDQA_M128_to_XMM<_EmitterId_> +#define SSE2_MOVDQA_XMM_to_M128 eSSE2_MOVDQA_XMM_to_M128<_EmitterId_> +#define SSE2_MOVDQA_XMM_to_XMM eSSE2_MOVDQA_XMM_to_XMM<_EmitterId_> +#define SSE2_MOVDQU_M128_to_XMM eSSE2_MOVDQU_M128_to_XMM<_EmitterId_> +#define SSE2_MOVDQU_XMM_to_M128 eSSE2_MOVDQU_XMM_to_M128<_EmitterId_> +#define SSE2_MOVDQU_XMM_to_XMM eSSE2_MOVDQA_XMM_to_XMM<_EmitterId_> +#define SSE2_PSRLW_XMM_to_XMM eSSE2_PSRLW_XMM_to_XMM<_EmitterId_> +#define SSE2_PSRLW_M128_to_XMM eSSE2_PSRLW_M128_to_XMM<_EmitterId_> +#define SSE2_PSRLW_I8_to_XMM eSSE2_PSRLW_I8_to_XMM<_EmitterId_> +#define SSE2_PSRLD_XMM_to_XMM eSSE2_PSRLD_XMM_to_XMM<_EmitterId_> +#define SSE2_PSRLD_M128_to_XMM eSSE2_PSRLD_M128_to_XMM<_EmitterId_> +#define SSE2_PSRLD_I8_to_XMM eSSE2_PSRLD_I8_to_XMM<_EmitterId_> +#define SSE2_PSRLQ_XMM_to_XMM eSSE2_PSRLQ_XMM_to_XMM<_EmitterId_> +#define SSE2_PSRLQ_M128_to_XMM eSSE2_PSRLQ_M128_to_XMM<_EmitterId_> +#define SSE2_PSRLQ_I8_to_XMM eSSE2_PSRLQ_I8_to_XMM<_EmitterId_> +#define SSE2_PSRLDQ_I8_to_XMM eSSE2_PSRLDQ_I8_to_XMM<_EmitterId_> +#define SSE2_PSRAW_XMM_to_XMM eSSE2_PSRAW_XMM_to_XMM<_EmitterId_> +#define SSE2_PSRAW_M128_to_XMM eSSE2_PSRAW_M128_to_XMM<_EmitterId_> +#define SSE2_PSRAW_I8_to_XMM eSSE2_PSRAW_I8_to_XMM<_EmitterId_> +#define SSE2_PSRAD_XMM_to_XMM eSSE2_PSRAD_XMM_to_XMM<_EmitterId_> +#define SSE2_PSRAD_M128_to_XMM eSSE2_PSRAD_M128_to_XMM<_EmitterId_> +#define SSE2_PSRAD_I8_to_XMM eSSE2_PSRAD_I8_to_XMM<_EmitterId_> +#define SSE2_PSLLW_XMM_to_XMM eSSE2_PSLLW_XMM_to_XMM<_EmitterId_> +#define SSE2_PSLLW_M128_to_XMM eSSE2_PSLLW_M128_to_XMM<_EmitterId_> +#define SSE2_PSLLW_I8_to_XMM eSSE2_PSLLW_I8_to_XMM<_EmitterId_> +#define SSE2_PSLLD_XMM_to_XMM eSSE2_PSLLD_XMM_to_XMM<_EmitterId_> +#define SSE2_PSLLD_M128_to_XMM eSSE2_PSLLD_M128_to_XMM<_EmitterId_> +#define SSE2_PSLLD_I8_to_XMM eSSE2_PSLLD_I8_to_XMM<_EmitterId_> +#define SSE2_PSLLQ_XMM_to_XMM eSSE2_PSLLQ_XMM_to_XMM<_EmitterId_> +#define SSE2_PSLLQ_M128_to_XMM eSSE2_PSLLQ_M128_to_XMM<_EmitterId_> +#define SSE2_PSLLQ_I8_to_XMM eSSE2_PSLLQ_I8_to_XMM<_EmitterId_> +#define SSE2_PSLLDQ_I8_to_XMM eSSE2_PSLLDQ_I8_to_XMM<_EmitterId_> +#define SSE2_PMAXSW_XMM_to_XMM eSSE2_PMAXSW_XMM_to_XMM<_EmitterId_> +#define SSE2_PMAXSW_M128_to_XMM eSSE2_PMAXSW_M128_to_XMM<_EmitterId_> +#define SSE2_PMAXUB_XMM_to_XMM eSSE2_PMAXUB_XMM_to_XMM<_EmitterId_> +#define SSE2_PMAXUB_M128_to_XMM eSSE2_PMAXUB_M128_to_XMM<_EmitterId_> +#define SSE2_PMINSW_XMM_to_XMM eSSE2_PMINSW_XMM_to_XMM<_EmitterId_> +#define SSE2_PMINSW_M128_to_XMM eSSE2_PMINSW_M128_to_XMM<_EmitterId_> +#define SSE2_PMINUB_XMM_to_XMM eSSE2_PMINUB_XMM_to_XMM<_EmitterId_> +#define SSE2_PMINUB_M128_to_XMM eSSE2_PMINUB_M128_to_XMM<_EmitterId_> +#define SSE2_PADDSB_XMM_to_XMM eSSE2_PADDSB_XMM_to_XMM<_EmitterId_> +#define SSE2_PADDSB_M128_to_XMM eSSE2_PADDSB_M128_to_XMM<_EmitterId_> +#define SSE2_PADDSW_XMM_to_XMM eSSE2_PADDSW_XMM_to_XMM<_EmitterId_> +#define SSE2_PADDSW_M128_to_XMM eSSE2_PADDSW_M128_to_XMM<_EmitterId_> +#define SSE2_PSUBSB_XMM_to_XMM eSSE2_PSUBSB_XMM_to_XMM<_EmitterId_> +#define SSE2_PSUBSB_M128_to_XMM eSSE2_PSUBSB_M128_to_XMM<_EmitterId_> +#define SSE2_PSUBSW_XMM_to_XMM eSSE2_PSUBSW_XMM_to_XMM<_EmitterId_> +#define SSE2_PSUBSW_M128_to_XMM eSSE2_PSUBSW_M128_to_XMM<_EmitterId_> +#define SSE2_PSUBUSB_XMM_to_XMM eSSE2_PSUBUSB_XMM_to_XMM<_EmitterId_> +#define SSE2_PSUBUSB_M128_to_XMM eSSE2_PSUBUSB_M128_to_XMM<_EmitterId_> +#define SSE2_PSUBUSW_XMM_to_XMM eSSE2_PSUBUSW_XMM_to_XMM<_EmitterId_> +#define SSE2_PSUBUSW_M128_to_XMM eSSE2_PSUBUSW_M128_to_XMM<_EmitterId_> +#define SSE2_PAND_XMM_to_XMM eSSE2_PAND_XMM_to_XMM<_EmitterId_> +#define SSE2_PAND_M128_to_XMM eSSE2_PAND_M128_to_XMM<_EmitterId_> +#define SSE2_PANDN_XMM_to_XMM eSSE2_PANDN_XMM_to_XMM<_EmitterId_> +#define SSE2_PANDN_M128_to_XMM eSSE2_PANDN_M128_to_XMM<_EmitterId_> +#define SSE2_PXOR_XMM_to_XMM eSSE2_PXOR_XMM_to_XMM<_EmitterId_> +#define SSE2_PXOR_M128_to_XMM eSSE2_PXOR_M128_to_XMM<_EmitterId_> +#define SSE2_PADDW_XMM_to_XMM eSSE2_PADDW_XMM_to_XMM<_EmitterId_> +#define SSE2_PADDW_M128_to_XMM eSSE2_PADDW_M128_to_XMM<_EmitterId_> +#define SSE2_PADDUSB_XMM_to_XMM eSSE2_PADDUSB_XMM_to_XMM<_EmitterId_> +#define SSE2_PADDUSB_M128_to_XMM eSSE2_PADDUSB_M128_to_XMM<_EmitterId_> +#define SSE2_PADDUSW_XMM_to_XMM eSSE2_PADDUSW_XMM_to_XMM<_EmitterId_> +#define SSE2_PADDUSW_M128_to_XMM eSSE2_PADDUSW_M128_to_XMM<_EmitterId_> +#define SSE2_PADDB_XMM_to_XMM eSSE2_PADDB_XMM_to_XMM<_EmitterId_> +#define SSE2_PADDB_M128_to_XMM eSSE2_PADDB_M128_to_XMM<_EmitterId_> +#define SSE2_PADDD_XMM_to_XMM eSSE2_PADDD_XMM_to_XMM<_EmitterId_> +#define SSE2_PADDD_M128_to_XMM eSSE2_PADDD_M128_to_XMM<_EmitterId_> +#define SSE2_PADDQ_XMM_to_XMM eSSE2_PADDQ_XMM_to_XMM<_EmitterId_> +#define SSE2_PADDQ_M128_to_XMM eSSE2_PADDQ_M128_to_XMM<_EmitterId_> +#define SSE2_PMADDWD_XMM_to_XMM eSSE2_PMADDWD_XMM_to_XMM<_EmitterId_> +#define SSE2_MOVSD_XMM_to_XMM eSSE2_MOVSD_XMM_to_XMM<_EmitterId_> +#define SSE2_MOVQ_M64_to_XMM eSSE2_MOVQ_M64_to_XMM<_EmitterId_> +#define SSE2_MOVQ_XMM_to_XMM eSSE2_MOVQ_XMM_to_XMM<_EmitterId_> +#define SSE2_MOVQ_XMM_to_M64 eSSE2_MOVQ_XMM_to_M64<_EmitterId_> +#define SSE2_MOVDQ2Q_XMM_to_MM eSSE2_MOVDQ2Q_XMM_to_MM<_EmitterId_> +#define SSE2_MOVQ2DQ_MM_to_XMM eSSE2_MOVQ2DQ_MM_to_XMM<_EmitterId_> +#define SSE2_MOVDQARtoRm eSSE2_MOVDQARtoRm<_EmitterId_> +#define SSE2_MOVDQARmtoR eSSE2_MOVDQARmtoR<_EmitterId_> +#define SSE2_CVTDQ2PS_M128_to_XMM eSSE2_CVTDQ2PS_M128_to_XMM<_EmitterId_> +#define SSE2_CVTDQ2PS_XMM_to_XMM eSSE2_CVTDQ2PS_XMM_to_XMM<_EmitterId_> +#define SSE2_CVTPS2DQ_M128_to_XMM eSSE2_CVTPS2DQ_M128_to_XMM<_EmitterId_> +#define SSE2_CVTPS2DQ_XMM_to_XMM eSSE2_CVTPS2DQ_XMM_to_XMM<_EmitterId_> +#define SSE2_CVTTPS2DQ_XMM_to_XMM eSSE2_CVTTPS2DQ_XMM_to_XMM<_EmitterId_> +#define SSE2_MAXPD_M128_to_XMM eSSE2_MAXPD_M128_to_XMM<_EmitterId_> +#define SSE2_MAXPD_XMM_to_XMM eSSE2_MAXPD_XMM_to_XMM<_EmitterId_> +#define SSE2_MINPD_M128_to_XMM eSSE2_MINPD_M128_to_XMM<_EmitterId_> +#define SSE2_MINPD_XMM_to_XMM eSSE2_MINPD_XMM_to_XMM<_EmitterId_> +#define SSE2_PSHUFD_XMM_to_XMM eSSE2_PSHUFD_XMM_to_XMM<_EmitterId_> +#define SSE2_PSHUFD_M128_to_XMM eSSE2_PSHUFD_M128_to_XMM<_EmitterId_> +#define SSE2_PSHUFLW_XMM_to_XMM eSSE2_PSHUFLW_XMM_to_XMM<_EmitterId_> +#define SSE2_PSHUFLW_M128_to_XMM eSSE2_PSHUFLW_M128_to_XMM<_EmitterId_> +#define SSE2_PSHUFHW_XMM_to_XMM eSSE2_PSHUFHW_XMM_to_XMM<_EmitterId_> +#define SSE2_PSHUFHW_M128_to_XMM eSSE2_PSHUFHW_M128_to_XMM<_EmitterId_> +#define SSE2_SHUFPD_XMM_to_XMM eSSE2_SHUFPD_XMM_to_XMM<_EmitterId_> +#define SSE2_SHUFPD_M128_to_XMM eSSE2_SHUFPD_M128_to_XMM<_EmitterId_> +#define SSE2_ORPD_M128_to_XMM eSSE2_ORPD_M128_to_XMM<_EmitterId_> +#define SSE2_ORPD_XMM_to_XMM eSSE2_ORPD_XMM_to_XMM<_EmitterId_> +#define SSE2_XORPD_M128_to_XMM eSSE2_XORPD_M128_to_XMM<_EmitterId_> +#define SSE2_XORPD_XMM_to_XMM eSSE2_XORPD_XMM_to_XMM<_EmitterId_> +#define SSE2_ANDPD_M128_to_XMM eSSE2_ANDPD_M128_to_XMM<_EmitterId_> +#define SSE2_ANDPD_XMM_to_XMM eSSE2_ANDPD_XMM_to_XMM<_EmitterId_> +#define SSE2_ANDNPD_M128_to_XMM eSSE2_ANDNPD_M128_to_XMM<_EmitterId_> +#define SSE2_ANDNPD_XMM_to_XMM eSSE2_ANDNPD_XMM_to_XMM<_EmitterId_> +#define SSE2_ADDSD_M64_to_XMM eSSE2_ADDSD_M64_to_XMM<_EmitterId_> +#define SSE2_ADDSD_XMM_to_XMM eSSE2_ADDSD_XMM_to_XMM<_EmitterId_> +#define SSE2_SUBSD_M64_to_XMM eSSE2_SUBSD_M64_to_XMM<_EmitterId_> +#define SSE2_SUBSD_XMM_to_XMM eSSE2_SUBSD_XMM_to_XMM<_EmitterId_> +#define SSE2_MULSD_M64_to_XMM eSSE2_MULSD_M64_to_XMM<_EmitterId_> +#define SSE2_MULSD_XMM_to_XMM eSSE2_MULSD_XMM_to_XMM<_EmitterId_> +#define SSE2_CMPEQSD_M64_to_XMM eSSE2_CMPEQSD_M64_to_XMM<_EmitterId_> +#define SSE2_CMPEQSD_XMM_to_XMM eSSE2_CMPEQSD_XMM_to_XMM<_EmitterId_> +#define SSE2_CMPLTSD_M64_to_XMM eSSE2_CMPLTSD_M64_to_XMM<_EmitterId_> +#define SSE2_CMPLTSD_XMM_to_XMM eSSE2_CMPLTSD_XMM_to_XMM<_EmitterId_> +#define SSE2_CMPLESD_M64_to_XMM eSSE2_CMPLESD_M64_to_XMM<_EmitterId_> +#define SSE2_CMPLESD_XMM_to_XMM eSSE2_CMPLESD_XMM_to_XMM<_EmitterId_> +#define SSE2_CMPUNORDSD_M64_to_XMM eSSE2_CMPUNORDSD_M64_to_XMM<_EmitterId_> +#define SSE2_CMPUNORDSD_XMM_to_XMM eSSE2_CMPUNORDSD_XMM_to_XMM<_EmitterId_> +#define SSE2_CMPNESD_M64_to_XMM eSSE2_CMPNESD_M64_to_XMM<_EmitterId_> +#define SSE2_CMPNESD_XMM_to_XMM eSSE2_CMPNESD_XMM_to_XMM<_EmitterId_> +#define SSE2_CMPNLTSD_M64_to_XMM eSSE2_CMPNLTSD_M64_to_XMM<_EmitterId_> +#define SSE2_CMPNLTSD_XMM_to_XMM eSSE2_CMPNLTSD_XMM_to_XMM<_EmitterId_> +#define SSE2_CMPNLESD_M64_to_XMM eSSE2_CMPNLESD_M64_to_XMM<_EmitterId_> +#define SSE2_CMPNLESD_XMM_to_XMM eSSE2_CMPNLESD_XMM_to_XMM<_EmitterId_> +#define SSE2_CMPORDSD_M64_to_XMM eSSE2_CMPORDSD_M64_to_XMM<_EmitterId_> +#define SSE2_CMPORDSD_XMM_to_XMM eSSE2_CMPORDSD_XMM_to_XMM<_EmitterId_> +#define SSE2_UCOMISD_M64_to_XMM eSSE2_UCOMISD_M64_to_XMM<_EmitterId_> +#define SSE2_UCOMISD_XMM_to_XMM eSSE2_UCOMISD_XMM_to_XMM<_EmitterId_> +#define SSE2_CVTSS2SD_M32_to_XMM eSSE2_CVTSS2SD_M32_to_XMM<_EmitterId_> +#define SSE2_CVTSS2SD_XMM_to_XMM eSSE2_CVTSS2SD_XMM_to_XMM<_EmitterId_> +#define SSE2_CVTSD2SS_M64_to_XMM eSSE2_CVTSD2SS_M64_to_XMM<_EmitterId_> +#define SSE2_CVTSD2SS_XMM_to_XMM eSSE2_CVTSD2SS_XMM_to_XMM<_EmitterId_> +#define SSE2_MAXSD_M64_to_XMM eSSE2_MAXSD_M64_to_XMM<_EmitterId_> +#define SSE2_MAXSD_XMM_to_XMM eSSE2_MAXSD_XMM_to_XMM<_EmitterId_> +#define SSE2_MINSD_M64_to_XMM eSSE2_MINSD_M64_to_XMM<_EmitterId_> +#define SSE2_MINSD_XMM_to_XMM eSSE2_MINSD_XMM_to_XMM<_EmitterId_> +#define SSE2_SQRTSD_M64_to_XMM eSSE2_SQRTSD_M64_to_XMM<_EmitterId_> +#define SSE2_SQRTSD_XMM_to_XMM eSSE2_SQRTSD_XMM_to_XMM<_EmitterId_> +#define SSE2_DIVSD_M64_to_XMM eSSE2_DIVSD_M64_to_XMM<_EmitterId_> +#define SSE2_DIVSD_XMM_to_XMM eSSE2_DIVSD_XMM_to_XMM<_EmitterId_> +//------------------------------------------------------------------ +// PACKSSWB,PACKSSDW: Pack Saturate Signed Word +//------------------------------------------------------------------ +#define SSE2_PACKSSWB_XMM_to_XMM eSSE2_PACKSSWB_XMM_to_XMM<_EmitterId_> +#define SSE2_PACKSSWB_M128_to_XMM eSSE2_PACKSSWB_M128_to_XMM<_EmitterId_> +#define SSE2_PACKSSDW_XMM_to_XMM eSSE2_PACKSSDW_XMM_to_XMM<_EmitterId_> +#define SSE2_PACKSSDW_M128_to_XMM eSSE2_PACKSSDW_M128_to_XMM<_EmitterId_> +#define SSE2_PACKUSWB_XMM_to_XMM eSSE2_PACKUSWB_XMM_to_XMM<_EmitterId_> +#define SSE2_PACKUSWB_M128_to_XMM eSSE2_PACKUSWB_M128_to_XMM<_EmitterId_> +//------------------------------------------------------------------ +// PUNPCKHWD: Unpack 16bit high +//------------------------------------------------------------------ +#define SSE2_PUNPCKLBW_XMM_to_XMM eSSE2_PUNPCKLBW_XMM_to_XMM<_EmitterId_> +#define SSE2_PUNPCKLBW_M128_to_XMM eSSE2_PUNPCKLBW_M128_to_XMM<_EmitterId_> +#define SSE2_PUNPCKHBW_XMM_to_XMM eSSE2_PUNPCKHBW_XMM_to_XMM<_EmitterId_> +#define SSE2_PUNPCKHBW_M128_to_XMM eSSE2_PUNPCKHBW_M128_to_XMM<_EmitterId_> +#define SSE2_PUNPCKLWD_XMM_to_XMM eSSE2_PUNPCKLWD_XMM_to_XMM<_EmitterId_> +#define SSE2_PUNPCKLWD_M128_to_XMM eSSE2_PUNPCKLWD_M128_to_XMM<_EmitterId_> +#define SSE2_PUNPCKHWD_XMM_to_XMM eSSE2_PUNPCKHWD_XMM_to_XMM<_EmitterId_> +#define SSE2_PUNPCKHWD_M128_to_XMM eSSE2_PUNPCKHWD_M128_to_XMM<_EmitterId_> +#define SSE2_PUNPCKLDQ_XMM_to_XMM eSSE2_PUNPCKLDQ_XMM_to_XMM<_EmitterId_> +#define SSE2_PUNPCKLDQ_M128_to_XMM eSSE2_PUNPCKLDQ_M128_to_XMM<_EmitterId_> +#define SSE2_PUNPCKHDQ_XMM_to_XMM eSSE2_PUNPCKHDQ_XMM_to_XMM<_EmitterId_> +#define SSE2_PUNPCKHDQ_M128_to_XMM eSSE2_PUNPCKHDQ_M128_to_XMM<_EmitterId_> +#define SSE2_PUNPCKLQDQ_XMM_to_XMM eSSE2_PUNPCKLQDQ_XMM_to_XMM<_EmitterId_> +#define SSE2_PUNPCKLQDQ_M128_to_XMM eSSE2_PUNPCKLQDQ_M128_to_XMM<_EmitterId_> +#define SSE2_PUNPCKHQDQ_XMM_to_XMM eSSE2_PUNPCKHQDQ_XMM_to_XMM<_EmitterId_> +#define SSE2_PUNPCKHQDQ_M128_to_XMM eSSE2_PUNPCKHQDQ_M128_to_XMM<_EmitterId_> +#define SSE2_PMULLW_XMM_to_XMM eSSE2_PMULLW_XMM_to_XMM<_EmitterId_> +#define SSE2_PMULLW_M128_to_XMM eSSE2_PMULLW_M128_to_XMM<_EmitterId_> +#define SSE2_PMULHW_XMM_to_XMM eSSE2_PMULHW_XMM_to_XMM<_EmitterId_> +#define SSE2_PMULHW_M128_to_XMM eSSE2_PMULHW_M128_to_XMM<_EmitterId_> +#define SSE2_PMULUDQ_XMM_to_XMM eSSE2_PMULUDQ_XMM_to_XMM<_EmitterId_> +#define SSE2_PMULUDQ_M128_to_XMM eSSE2_PMULUDQ_M128_to_XMM<_EmitterId_> +//------------------------------------------------------------------ +// PMOVMSKB: Create 16bit mask from signs of 8bit integers +//------------------------------------------------------------------ +#define SSE_MOVMSKPS_XMM_to_R32 eSSE_MOVMSKPS_XMM_to_R32<_EmitterId_> +#define SSE2_PMOVMSKB_XMM_to_R32 eSSE2_PMOVMSKB_XMM_to_R32<_EmitterId_> +#define SSE2_MOVMSKPD_XMM_to_R32 eSSE2_MOVMSKPD_XMM_to_R32<_EmitterId_> +//------------------------------------------------------------------ +// PEXTRW,PINSRW: Packed Extract/Insert Word +//------------------------------------------------------------------ +#define SSE_PEXTRW_XMM_to_R32 eSSE_PEXTRW_XMM_to_R32<_EmitterId_> +#define SSE_PINSRW_R32_to_XMM eSSE_PINSRW_R32_to_XMM<_EmitterId_> +//------------------------------------------------------------------ +// PSUBx: Subtract Packed Integers +//------------------------------------------------------------------ +#define SSE2_PSUBB_XMM_to_XMM eSSE2_PSUBB_XMM_to_XMM<_EmitterId_> +#define SSE2_PSUBB_M128_to_XMM eSSE2_PSUBB_M128_to_XMM<_EmitterId_> +#define SSE2_PSUBW_XMM_to_XMM eSSE2_PSUBW_XMM_to_XMM<_EmitterId_> +#define SSE2_PSUBW_M128_to_XMM eSSE2_PSUBW_M128_to_XMM<_EmitterId_> +#define SSE2_PSUBD_XMM_to_XMM eSSE2_PSUBD_XMM_to_XMM<_EmitterId_> +#define SSE2_PSUBD_M128_to_XMM eSSE2_PSUBD_M128_to_XMM<_EmitterId_> +#define SSE2_PSUBQ_XMM_to_XMM eSSE2_PSUBQ_XMM_to_XMM<_EmitterId_> +#define SSE2_PSUBQ_M128_to_XMM eSSE2_PSUBQ_M128_to_XMM<_EmitterId_> +//------------------------------------------------------------------ +// PCMPxx: Compare Packed Integers +//------------------------------------------------------------------ +#define SSE2_PCMPGTB_XMM_to_XMM eSSE2_PCMPGTB_XMM_to_XMM<_EmitterId_> +#define SSE2_PCMPGTB_M128_to_XMM eSSE2_PCMPGTB_M128_to_XMM<_EmitterId_> +#define SSE2_PCMPGTW_XMM_to_XMM eSSE2_PCMPGTW_XMM_to_XMM<_EmitterId_> +#define SSE2_PCMPGTW_M128_to_XMM eSSE2_PCMPGTW_M128_to_XMM<_EmitterId_> +#define SSE2_PCMPGTD_XMM_to_XMM eSSE2_PCMPGTD_XMM_to_XMM<_EmitterId_> +#define SSE2_PCMPGTD_M128_to_XMM eSSE2_PCMPGTD_M128_to_XMM<_EmitterId_> +#define SSE2_PCMPEQB_XMM_to_XMM eSSE2_PCMPEQB_XMM_to_XMM<_EmitterId_> +#define SSE2_PCMPEQB_M128_to_XMM eSSE2_PCMPEQB_M128_to_XMM<_EmitterId_> +#define SSE2_PCMPEQW_XMM_to_XMM eSSE2_PCMPEQW_XMM_to_XMM<_EmitterId_> +#define SSE2_PCMPEQW_M128_to_XMM eSSE2_PCMPEQW_M128_to_XMM<_EmitterId_> +#define SSE2_PCMPEQD_XMM_to_XMM eSSE2_PCMPEQD_XMM_to_XMM<_EmitterId_> +#define SSE2_PCMPEQD_M128_to_XMM eSSE2_PCMPEQD_M128_to_XMM<_EmitterId_> +//------------------------------------------------------------------ +// MOVD: Move Dword(32bit) to /from XMM reg +//------------------------------------------------------------------ +#define SSE2_MOVD_M32_to_XMM eSSE2_MOVD_M32_to_XMM<_EmitterId_> +#define SSE2_MOVD_R_to_XMM eSSE2_MOVD_R_to_XMM<_EmitterId_> +#define SSE2_MOVD_Rm_to_XMM eSSE2_MOVD_Rm_to_XMM<_EmitterId_> +#define SSE2_MOVD_Rm_to_XMM eSSE2_MOVD_Rm_to_XMM<_EmitterId_> +#define SSE2_MOVD_XMM_to_M32 eSSE2_MOVD_XMM_to_M32<_EmitterId_> +#define SSE2_MOVD_XMM_to_R eSSE2_MOVD_XMM_to_R<_EmitterId_> +#define SSE2_MOVD_XMM_to_Rm eSSE2_MOVD_XMM_to_Rm<_EmitterId_> +#define SSE2_MOVD_XMM_to_Rm eSSE2_MOVD_XMM_to_Rm<_EmitterId_> +#define SSE2_MOVQ_XMM_to_R eSSE2_MOVQ_XMM_to_R<_EmitterId_> +#define SSE2_MOVQ_R_to_XMM eSSE2_MOVQ_R_to_XMM<_EmitterId_> +//------------------------------------------------------------------ +// POR : SSE Bitwise OR +//------------------------------------------------------------------ +#define SSE2_POR_XMM_to_XMM eSSE2_POR_XMM_to_XMM<_EmitterId_> +#define SSE2_POR_M128_to_XMM eSSE2_POR_M128_to_XMM<_EmitterId_> +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// SSE3 +//------------------------------------------------------------------ +#define SSE3_HADDPS_XMM_to_XMM eSSE3_HADDPS_XMM_to_XMM<_EmitterId_> +#define SSE3_HADDPS_M128_to_XMM eSSE3_HADDPS_M128_to_XMM<_EmitterId_> +#define SSE3_MOVSLDUP_XMM_to_XMM eSSE3_MOVSLDUP_XMM_to_XMM<_EmitterId_> +#define SSE3_MOVSLDUP_M128_to_XMM eSSE3_MOVSLDUP_M128_to_XMM<_EmitterId_> +#define SSE3_MOVSHDUP_XMM_to_XMM eSSE3_MOVSHDUP_XMM_to_XMM<_EmitterId_> +#define SSE3_MOVSHDUP_M128_to_XMM eSSE3_MOVSHDUP_M128_to_XMM<_EmitterId_> +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// SSSE3 +//------------------------------------------------------------------ +#define SSSE3_PABSB_XMM_to_XMM eSSSE3_PABSB_XMM_to_XMM<_EmitterId_> +#define SSSE3_PABSW_XMM_to_XMM eSSSE3_PABSW_XMM_to_XMM<_EmitterId_> +#define SSSE3_PABSD_XMM_to_XMM eSSSE3_PABSD_XMM_to_XMM<_EmitterId_> +#define SSSE3_PALIGNR_XMM_to_XMM eSSSE3_PALIGNR_XMM_to_XMM<_EmitterId_> +#define SSSE3_PSIGNB_XMM_to_XMM eSSSE3_PSIGNB_XMM_to_XMM<_EmitterId_> +#define SSSE3_PSIGNW_XMM_to_XMM eSSSE3_PSIGNW_XMM_to_XMM<_EmitterId_> +#define SSSE3_PSIGND_XMM_to_XMM eSSSE3_PSIGND_XMM_to_XMM<_EmitterId_> +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// SSE4.1 +//------------------------------------------------------------------ +#define SSE4_DPPS_XMM_to_XMM eSSE4_DPPS_XMM_to_XMM<_EmitterId_> +#define SSE4_DPPS_M128_to_XMM eSSE4_DPPS_M128_to_XMM<_EmitterId_> +#define SSE4_INSERTPS_XMM_to_XMM eSSE4_INSERTPS_XMM_to_XMM<_EmitterId_> +#define SSE4_EXTRACTPS_XMM_to_R32 eSSE4_EXTRACTPS_XMM_to_R32<_EmitterId_> +#define SSE4_BLENDPS_XMM_to_XMM eSSE4_BLENDPS_XMM_to_XMM<_EmitterId_> +#define SSE4_BLENDVPS_XMM_to_XMM eSSE4_BLENDVPS_XMM_to_XMM<_EmitterId_> +#define SSE4_BLENDVPS_M128_to_XMM eSSE4_BLENDVPS_M128_to_XMM<_EmitterId_> +#define SSE4_PMOVSXDQ_XMM_to_XMM eSSE4_PMOVSXDQ_XMM_to_XMM<_EmitterId_> +#define SSE4_PMOVZXDQ_XMM_to_XMM eSSE4_PMOVZXDQ_XMM_to_XMM<_EmitterId_> +#define SSE4_PINSRD_R32_to_XMM eSSE4_PINSRD_R32_to_XMM<_EmitterId_> +#define SSE4_PMAXSD_XMM_to_XMM eSSE4_PMAXSD_XMM_to_XMM<_EmitterId_> +#define SSE4_PMINSD_XMM_to_XMM eSSE4_PMINSD_XMM_to_XMM<_EmitterId_> +#define SSE4_PMAXUD_XMM_to_XMM eSSE4_PMAXUD_XMM_to_XMM<_EmitterId_> +#define SSE4_PMINUD_XMM_to_XMM eSSE4_PMINUD_XMM_to_XMM<_EmitterId_> +#define SSE4_PMAXSD_M128_to_XMM eSSE4_PMAXSD_M128_to_XMM<_EmitterId_> +#define SSE4_PMINSD_M128_to_XMM eSSE4_PMINSD_M128_to_XMM<_EmitterId_> +#define SSE4_PMAXUD_M128_to_XMM eSSE4_PMAXUD_M128_to_XMM<_EmitterId_> +#define SSE4_PMINUD_M128_to_XMM eSSE4_PMINUD_M128_to_XMM<_EmitterId_> +#define SSE4_PMULDQ_XMM_to_XMM eSSE4_PMULDQ_XMM_to_XMM<_EmitterId_> +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// 3DNOW instructions +//------------------------------------------------------------------ +#define FEMMS eFEMMS<_EmitterId_> +#define PFCMPEQMtoR ePFCMPEQMtoR<_EmitterId_> +#define PFCMPGTMtoR ePFCMPGTMtoR<_EmitterId_> +#define PFCMPGEMtoR ePFCMPGEMtoR<_EmitterId_> +#define PFADDMtoR ePFADDMtoR<_EmitterId_> +#define PFADDRtoR ePFADDRtoR<_EmitterId_> +#define PFSUBMtoR ePFSUBMtoR<_EmitterId_> +#define PFSUBRtoR ePFSUBRtoR<_EmitterId_> +#define PFMULMtoR ePFMULMtoR<_EmitterId_> +#define PFMULRtoR ePFMULRtoR<_EmitterId_> +#define PFRCPMtoR ePFRCPMtoR<_EmitterId_> +#define PFRCPRtoR ePFRCPRtoR<_EmitterId_> +#define PFRCPIT1RtoR ePFRCPIT1RtoR<_EmitterId_> +#define PFRCPIT2RtoR ePFRCPIT2RtoR<_EmitterId_> +#define PFRSQRTRtoR ePFRSQRTRtoR<_EmitterId_> +#define PFRSQIT1RtoR ePFRSQIT1RtoR<_EmitterId_> +#define PF2IDMtoR ePF2IDMtoR<_EmitterId_> +#define PI2FDMtoR ePI2FDMtoR<_EmitterId_> +#define PI2FDRtoR ePI2FDRtoR<_EmitterId_> +#define PFMAXMtoR ePFMAXMtoR<_EmitterId_> +#define PFMAXRtoR ePFMAXRtoR<_EmitterId_> +#define PFMINMtoR ePFMINMtoR<_EmitterId_> +#define PFMINRtoR ePFMINRtoR<_EmitterId_> +//------------------------------------------------------------------ diff --git a/pcsx2/x86/ix86/ix86_sse_helpers.h b/common/include/x86emitter/sse_helpers.h similarity index 100% rename from pcsx2/x86/ix86/ix86_sse_helpers.h rename to common/include/x86emitter/sse_helpers.h diff --git a/common/include/x86emitter/tools.h b/common/include/x86emitter/tools.h new file mode 100644 index 0000000000..49792cf184 --- /dev/null +++ b/common/include/x86emitter/tools.h @@ -0,0 +1,106 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +// this is all that needs to be called and will fill up the below structs +extern void cpudetectInit(); + +////////////////////////////////////////////////////////////////////////////////////////// +// cpu capabilities structure +// +struct CAPABILITIES +{ + u32 hasFloatingPointUnit; + u32 hasVirtual8086ModeEnhancements; + u32 hasDebuggingExtensions; + u32 hasPageSizeExtensions; + u32 hasTimeStampCounter; + u32 hasModelSpecificRegisters; + u32 hasPhysicalAddressExtension; + u32 hasCOMPXCHG8BInstruction; + u32 hasAdvancedProgrammableInterruptController; + u32 hasSEPFastSystemCall; + u32 hasMemoryTypeRangeRegisters; + u32 hasPTEGlobalFlag; + u32 hasMachineCheckArchitecture; + u32 hasConditionalMoveAndCompareInstructions; + u32 hasFGPageAttributeTable; + u32 has36bitPageSizeExtension; + u32 hasProcessorSerialNumber; + u32 hasCFLUSHInstruction; + u32 hasDebugStore; + u32 hasACPIThermalMonitorAndClockControl; + u32 hasMultimediaExtensions; + u32 hasFastStreamingSIMDExtensionsSaveRestore; + u32 hasStreamingSIMDExtensions; + u32 hasStreamingSIMD2Extensions; + u32 hasSelfSnoop; + u32 hasMultiThreading; // is TRUE for both mutli-core and Hyperthreaded CPUs. + u32 hasThermalMonitor; + u32 hasIntel64BitArchitecture; + u32 hasStreamingSIMD3Extensions; + u32 hasSupplementalStreamingSIMD3Extensions; + u32 hasStreamingSIMD4Extensions; + u32 hasStreamingSIMD4Extensions2; + + // AMD-specific CPU Features + u32 hasMultimediaExtensionsExt; + u32 hasAMD64BitArchitecture; + u32 has3DNOWInstructionExtensionsExt; + u32 has3DNOWInstructionExtensions; + u32 hasStreamingSIMD4ExtensionsA; +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// +struct CPUINFO +{ + u32 x86Family; // Processor Family + u32 x86Model; // Processor Model + u32 x86PType; // Processor Type + u32 x86StepID; // Stepping ID + u32 x86Flags; // Feature Flags + u32 x86Flags2; // More Feature Flags + u32 x86EFlags; // Extended Feature Flags + u32 x86EFlags2; // Extended Feature Flags pg2 + + u32 PhysicalCores; + u32 LogicalCores; + + char x86ID[16]; // Vendor ID //the vendor creator (in %s) + char x86Type[20]; //cpu type in char format //the cpu type (in %s) + char x86Fam[50]; // family in char format //the original cpu name string (in %s) + u32 cpuspeed; // speed of cpu //this will give cpu speed (in %d) +}; + + +////////////////////////////////////////////////////////////////////////////////////////// + + +extern CAPABILITIES cpucaps; +extern CPUINFO cpuinfo; + +extern u8 g_globalMMXSaved, g_globalXMMSaved; +extern bool g_EEFreezeRegs; + +// when using mmx/xmm regs, use; 0 is load +// freezes no matter the state +extern void FreezeXMMRegs(int save); +extern void FreezeMMXRegs(int save); +extern void FreezeRegs(int save); diff --git a/pcsx2/x86/ix86/ix86.h b/common/include/x86emitter/x86emitter.h similarity index 92% rename from pcsx2/x86/ix86/ix86.h rename to common/include/x86emitter/x86emitter.h index c2b0eaf7d7..5c72b516b5 100644 --- a/pcsx2/x86/ix86/ix86.h +++ b/common/include/x86emitter/x86emitter.h @@ -5,12 +5,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA @@ -45,10 +45,11 @@ #pragma once -#include "ix86_types.h" -#include "ix86_instructions.h" +#include "x86types.h" +#include "tools.h" +#include "instructions.h" // Including legacy items for now, but these should be removed eventually, // once most code is no longer dependent on them. -#include "ix86_legacy_types.h" -#include "ix86_legacy_instructions.h" +#include "legacy_types.h" +#include "legacy_instructions.h" diff --git a/pcsx2/x86/ix86/ix86_types.h b/common/include/x86emitter/x86types.h similarity index 78% rename from pcsx2/x86/ix86/ix86_types.h rename to common/include/x86emitter/x86types.h index 95a6a3b3cd..ae85f27f00 100644 --- a/pcsx2/x86/ix86/ix86_types.h +++ b/common/include/x86emitter/x86types.h @@ -18,76 +18,6 @@ #pragma once -extern void cpudetectInit();//this is all that needs to be called and will fill up the below structs - -//cpu capabilities structure -struct CAPABILITIES -{ - u32 hasFloatingPointUnit; - u32 hasVirtual8086ModeEnhancements; - u32 hasDebuggingExtensions; - u32 hasPageSizeExtensions; - u32 hasTimeStampCounter; - u32 hasModelSpecificRegisters; - u32 hasPhysicalAddressExtension; - u32 hasCOMPXCHG8BInstruction; - u32 hasAdvancedProgrammableInterruptController; - u32 hasSEPFastSystemCall; - u32 hasMemoryTypeRangeRegisters; - u32 hasPTEGlobalFlag; - u32 hasMachineCheckArchitecture; - u32 hasConditionalMoveAndCompareInstructions; - u32 hasFGPageAttributeTable; - u32 has36bitPageSizeExtension; - u32 hasProcessorSerialNumber; - u32 hasCFLUSHInstruction; - u32 hasDebugStore; - u32 hasACPIThermalMonitorAndClockControl; - u32 hasMultimediaExtensions; - u32 hasFastStreamingSIMDExtensionsSaveRestore; - u32 hasStreamingSIMDExtensions; - u32 hasStreamingSIMD2Extensions; - u32 hasSelfSnoop; - u32 hasMultiThreading; // is TRUE for both mutli-core and Hyperthreaded CPUs. - u32 hasThermalMonitor; - u32 hasIntel64BitArchitecture; - u32 hasStreamingSIMD3Extensions; - u32 hasSupplementalStreamingSIMD3Extensions; - u32 hasStreamingSIMD4Extensions; - u32 hasStreamingSIMD4Extensions2; - - // AMD-specific CPU Features - u32 hasMultimediaExtensionsExt; - u32 hasAMD64BitArchitecture; - u32 has3DNOWInstructionExtensionsExt; - u32 has3DNOWInstructionExtensions; - u32 hasStreamingSIMD4ExtensionsA; -}; - -extern CAPABILITIES cpucaps; - -struct CPUINFO -{ - u32 x86Family; // Processor Family - u32 x86Model; // Processor Model - u32 x86PType; // Processor Type - u32 x86StepID; // Stepping ID - u32 x86Flags; // Feature Flags - u32 x86Flags2; // More Feature Flags - u32 x86EFlags; // Extended Feature Flags - u32 x86EFlags2; // Extended Feature Flags pg2 - - u32 PhysicalCores; - u32 LogicalCores; - - char x86ID[16]; // Vendor ID //the vendor creator (in %s) - char x86Type[20]; //cpu type in char format //the cpu type (in %s) - char x86Fam[50]; // family in char format //the original cpu name string (in %s) - u32 cpuspeed; // speed of cpu //this will give cpu speed (in %d) -}; - -extern CPUINFO cpuinfo; - //------------------------------------------------------------------ #ifdef _MSC_VER #define __threadlocal __declspec(thread) @@ -206,9 +136,8 @@ __forceinline void xWrite( T val ) int Id; - xRegisterBase( const xRegisterBase& src ) : Id( src.Id ) {} xRegisterBase(): Id( -1 ) {} - explicit xRegisterBase( int regId ) : Id( regId ) { jASSUME( Id >= -1 && Id < 8 ); } + explicit xRegisterBase( int regId ) : Id( regId ) { jASSUME( Id >= -2 && Id < 8 ); } // allow -2 for user-custom identifiers. bool IsEmpty() const { return Id < 0; } @@ -220,12 +149,6 @@ __forceinline void xWrite( T val ) bool operator==( const xRegisterBase& src ) const { return (Id == src.Id); } bool operator!=( const xRegisterBase& src ) const { return (Id != src.Id); } - - xRegisterBase& operator=( const xRegisterBase& src ) - { - Id = src.Id; - return *this; - } }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -233,19 +156,15 @@ __forceinline void xWrite( T val ) template< typename OperandType > class xRegister : public xRegisterBase { - public: - static const xRegister Empty; // defined as an empty/unused value (-1) - public: xRegister(): xRegisterBase() {} - xRegister( const xRegister& src ) : xRegisterBase( src.Id ) {} - explicit xRegister( const xRegisterBase& src ) : xRegisterBase( src ) {} + xRegister( const xRegisterBase& src ) : xRegisterBase( src ) {} explicit xRegister( int regId ) : xRegisterBase( regId ) {} bool operator==( const xRegister& src ) const { return this->Id == src.Id; } bool operator!=( const xRegister& src ) const { return this->Id != src.Id; } - xRegister& operator=( const xRegister& src ) + xRegister& operator=( const xRegisterBase& src ) { this->Id = src.Id; return *this; @@ -262,14 +181,13 @@ __forceinline void xWrite( T val ) public: xRegisterSIMD(): xRegisterBase() {} - xRegisterSIMD( const xRegisterSIMD& src ) : xRegisterBase( src.Id ) {} explicit xRegisterSIMD( const xRegisterBase& src ) : xRegisterBase( src ) {} explicit xRegisterSIMD( int regId ) : xRegisterBase( regId ) {} bool operator==( const xRegisterSIMD& src ) const { return this->Id == src.Id; } bool operator!=( const xRegisterSIMD& src ) const { return this->Id != src.Id; } - xRegisterSIMD& operator=( const xRegisterSIMD& src ) + xRegisterSIMD& operator=( const xRegisterBase& src ) { this->Id = src.Id; return *this; @@ -317,6 +235,10 @@ __forceinline void xWrite( T val ) xAddressInfo operator+( const xAddressReg& right ) const; xAddressInfo operator+( const xAddressInfo& right ) const; xAddressInfo operator+( s32 right ) const; + xAddressInfo operator+( const void* right ) const; + + xAddressInfo operator-( s32 right ) const; + xAddressInfo operator-( const void* right ) const; xAddressInfo operator*( u32 factor ) const; xAddressInfo operator<<( u32 shift ) const; @@ -327,7 +249,7 @@ __forceinline void xWrite( T val ) return *this; } }; - + ////////////////////////////////////////////////////////////////////////////////////////// // class xAddressInfo @@ -381,6 +303,7 @@ __forceinline void xWrite( T val ) __forceinline xAddressInfo operator+( const xAddressInfo& right ) const { return xAddressInfo( *this ).Add( right ); } __forceinline xAddressInfo operator+( s32 imm ) const { return xAddressInfo( *this ).Add( imm ); } __forceinline xAddressInfo operator-( s32 imm ) const { return xAddressInfo( *this ).Add( -imm ); } + __forceinline xAddressInfo operator+( const void* addr ) const { return xAddressInfo( *this ).Add( (uptr)addr ); } }; extern const xRegisterSSE @@ -405,6 +328,33 @@ __forceinline void xWrite( T val ) extern const xRegisterCL cl; // I'm special! + ////////////////////////////////////////////////////////////////////////////////////////// + // xImmReg - used to represent an immediate value which can also be optimized to a register. + // Note that the immediate value represented by this structure is *always* legal. The + // register assignment is an optional optimization which can be implemented in cases where + // an immediate is used enough times to merit allocating it to a register. + // + // Note: not all instructions support this operand type (yet). You can always implement it + // manually by checking the status of IsReg() and generating the xOP conditionally. + // + template< typename OperandType > + class xImmReg + { + xRegister m_reg; + int m_imm; + + public: + xImmReg() : + m_reg(), m_imm( 0 ) { } + + xImmReg( int imm, const xRegister& reg=xRegister() ) : + m_reg( reg ), m_imm( imm ) { } + + const xRegister& GetReg() const { return m_reg; } + const int GetImm() const { return m_imm; } + bool IsReg() const { return !m_reg.IsEmpty(); } + }; + ////////////////////////////////////////////////////////////////////////////////////////// // ModSib - Internal low-level representation of the ModRM/SIB information. // @@ -429,6 +379,7 @@ __forceinline void xWrite( T val ) explicit ModSibBase( const xAddressInfo& src ); explicit ModSibBase( s32 disp ); ModSibBase( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 ); + ModSibBase( const void* target ); bool IsByteSizeDisp() const { return is_s8( Displacement ); } @@ -455,8 +406,10 @@ __forceinline void xWrite( T val ) public: static const uint OperandSize = sizeof( OperandType ); + __forceinline explicit ModSibStrict( const ModSibBase& src ) : ModSibBase( src ) {} __forceinline explicit ModSibStrict( const xAddressInfo& src ) : ModSibBase( src ) {} __forceinline explicit ModSibStrict( s32 disp ) : ModSibBase( disp ) {} + __forceinline ModSibStrict( const OperandType* target ) : ModSibBase( target ) {} __forceinline ModSibStrict( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 ) : ModSibBase( base, index, scale, displacement ) {} @@ -468,6 +421,18 @@ __forceinline void xWrite( T val ) __forceinline ModSibStrict operator+( const s32 imm ) const { return ModSibStrict( *this ).Add( imm ); } __forceinline ModSibStrict operator-( const s32 imm ) const { return ModSibStrict( *this ).Add( -imm ); } + + bool operator==( const ModSibStrict& src ) const + { + return + ( Base == src.Base ) && ( Index == src.Index ) && + ( Scale == src.Scale ) && ( Displacement == src.Displacement ); + } + + bool operator!=( const ModSibStrict& src ) const + { + return !operator==( src ); + } }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -540,12 +505,64 @@ __forceinline void xWrite( T val ) // ptr[] - use this form for instructions which can resolve the address operand size from // the other register operand sizes. - extern const xAddressIndexerBase ptr; - extern const xAddressIndexer ptr128; - extern const xAddressIndexer ptr64; - extern const xAddressIndexer ptr32; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms - extern const xAddressIndexer ptr16; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms - extern const xAddressIndexer ptr8; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms + extern const xAddressIndexerBase ptr; + extern const xAddressIndexer ptr128; + extern const xAddressIndexer ptr64; + extern const xAddressIndexer ptr32; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms + extern const xAddressIndexer ptr16; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms + extern const xAddressIndexer ptr8; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms + + ////////////////////////////////////////////////////////////////////////////////////////// + // + // [TODO] - make SSE version of thise, perhaps? + // + template< typename OperandType > + class xDirectOrIndirect + { + xRegister m_RegDirect; + ModSibStrict m_MemIndirect; + + public: + xDirectOrIndirect() : + m_RegDirect(), m_MemIndirect( 0 ) {} + + xDirectOrIndirect( const xRegister& srcreg ) : + m_RegDirect( srcreg ), m_MemIndirect( 0 ) {} + + xDirectOrIndirect( const ModSibBase& srcmem ) : + m_RegDirect(), m_MemIndirect( srcmem ) {} + + xDirectOrIndirect( const ModSibStrict& srcmem ) : + m_RegDirect(), m_MemIndirect( srcmem ) {} + + const xRegister& GetReg() const { return m_RegDirect; } + const ModSibStrict& GetMem() const { return m_MemIndirect; } + bool IsDirect() const { return !m_RegDirect.IsEmpty(); } + bool IsIndirect() const { return m_RegDirect.IsEmpty(); } + + bool operator==( const xDirectOrIndirect& src ) const + { + return IsDirect() ? + (m_RegDirect == src.m_RegDirect) : + (m_MemIndirect == src.m_MemIndirect); + } + + bool operator!=( const xDirectOrIndirect& src ) const + { + return !operator==( src ); + } + + bool operator==( const xRegister& src ) const { return (m_RegDirect == src); } + bool operator!=( const xRegister& src ) const { return (m_RegDirect == src); } + }; + + typedef xImmReg xImmOrReg8; + typedef xImmReg xImmOrReg16; + typedef xImmReg xImmOrReg32; + + typedef xDirectOrIndirect xDirectOrIndirect8; + typedef xDirectOrIndirect xDirectOrIndirect16; + typedef xDirectOrIndirect xDirectOrIndirect32; ////////////////////////////////////////////////////////////////////////////////////////// // JccComparisonType - enumerated possibilities for inspired code branching! @@ -633,7 +650,7 @@ __forceinline void xWrite( T val ) JccComparisonType m_cc; // comparison type of the instruction public: - const int GetMaxInstructionSize() const + int GetMaxInstructionSize() const { jASSUME( m_cc != Jcc_Unknown ); return ( m_cc == Jcc_Unconditional ) ? 5 : 6; @@ -686,70 +703,7 @@ __forceinline void xWrite( T val ) // namespace Internal { - extern void SimdPrefix( u8 prefix, u16 opcode ); - extern void EmitSibMagic( uint regfield, const void* address ); - extern void EmitSibMagic( uint regfield, const ModSibBase& info ); - extern void xJccKnownTarget( JccComparisonType comparison, const void* target, bool slideForward ); - - - // Writes a ModRM byte for "Direct" register access forms, which is used for all - // instructions taking a form of [reg,reg]. - template< typename T > __emitinline - void EmitSibMagic( uint reg1, const xRegisterBase& reg2 ) - { - xWrite8( (Mod_Direct << 6) | (reg1 << 3) | reg2.Id ); - } - - template< typename T1, typename T2 > __emitinline - void EmitSibMagic( const xRegisterBase reg1, const xRegisterBase& reg2 ) - { - xWrite8( (Mod_Direct << 6) | (reg1.Id << 3) | reg2.Id ); - } - - template< typename T1 > __emitinline - void EmitSibMagic( const xRegisterBase reg1, const void* src ) { EmitSibMagic( reg1.Id, src ); } - - template< typename T1 > __emitinline - void EmitSibMagic( const xRegisterBase reg1, const ModSibBase& sib ) { EmitSibMagic( reg1.Id, sib ); } - - // ------------------------------------------------------------------------ - template< typename T1, typename T2 > __emitinline - void xOpWrite( u8 prefix, u8 opcode, const T1& param1, const T2& param2 ) - { - if( prefix != 0 ) - xWrite16( (opcode<<8) | prefix ); - else - xWrite8( opcode ); - - EmitSibMagic( param1, param2 ); - } - - // ------------------------------------------------------------------------ - template< typename T1, typename T2 > __emitinline - void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2 ) - { - SimdPrefix( prefix, opcode ); - EmitSibMagic( param1, param2 ); - } - - template< typename T1, typename T2 > __emitinline - void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2, u8 imm8 ) - { - xOpWrite0F( prefix, opcode, param1, param2 ); - xWrite8( imm8 ); - } - - template< typename T1, typename T2 > __emitinline - void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2 ) { xOpWrite0F( 0, opcode, param1, param2 ); } - - template< typename T1, typename T2 > __emitinline - void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2, u8 imm8 ) { xOpWrite0F( 0, opcode, param1, param2, imm8 ); } - - // ------------------------------------------------------------------------ - - template< typename T > bool Is8BitOp() { return sizeof(T) == 1; } - template< typename T > void prefix16() { if( sizeof(T) == 2 ) xWrite8( 0x66 ); } - + #include "implement/helpers.h" #include "implement/xmm/basehelpers.h" #include "implement/xmm/moremovs.h" #include "implement/xmm/arithmetic.h" @@ -764,6 +718,26 @@ __forceinline void xWrite( T val ) #include "implement/test.h" #include "implement/jmpcall.h" } + + static __forceinline xAddressInfo operator+( const void* addr, const xAddressReg& reg ) + { + return xAddressInfo( reg, (sptr)addr ); + } + + static __forceinline xAddressInfo operator+( const void* addr, const xAddressInfo& reg ) + { + return xAddressInfo( (sptr)addr ).Add( reg ); + } + + static __forceinline xAddressInfo operator+( s32 addr, const xAddressReg& reg ) + { + return xAddressInfo( reg, (sptr)addr ); + } + + static __forceinline xAddressInfo operator+( s32 addr, const xAddressInfo& reg ) + { + return xAddressInfo( (sptr)addr ).Add( reg ); + } } -#include "ix86_inlines.inl" +#include "inlines.inl" diff --git a/pcsx2/AlignedMalloc.cpp b/common/src/Utilities/AlignedMalloc.cpp similarity index 99% rename from pcsx2/AlignedMalloc.cpp rename to common/src/Utilities/AlignedMalloc.cpp index 7b86160e50..8ff31f562d 100644 --- a/pcsx2/AlignedMalloc.cpp +++ b/common/src/Utilities/AlignedMalloc.cpp @@ -20,7 +20,6 @@ // it built into their CRT/libc. #include "PrecompiledHeader.h" -#include "System.h" struct AlignedMallocHeader diff --git a/common/src/Utilities/Console.cpp b/common/src/Utilities/Console.cpp new file mode 100644 index 0000000000..cb128ca4bb --- /dev/null +++ b/common/src/Utilities/Console.cpp @@ -0,0 +1,236 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" +#include "Threading.h" + +using namespace Threading; +using namespace std; + +const _VARG_PARAM va_arg_dummy = { 0 }; + +namespace Console +{ + MutexLock m_writelock; + std::string m_format_buffer; + + // ------------------------------------------------------------------------ + bool __fastcall Write( Colors color, const char* fmt ) + { + SetColor( color ); + Write( fmt ); + ClearColor(); + + return false; + } + + // ------------------------------------------------------------------------ + bool __fastcall Write( Colors color, const wxString& fmt ) + { + SetColor( color ); + Write( fmt ); + ClearColor(); + + return false; + } + + // ------------------------------------------------------------------------ + bool __fastcall WriteLn( const char* fmt ) + { + Write( fmt ); + Newline(); + return false; + } + + bool __fastcall WriteLn( Colors color, const char* fmt ) + { + SetColor( color ); + Write( fmt ); + Newline(); + ClearColor(); + + return false; + } + + // ------------------------------------------------------------------------ + bool __fastcall WriteLn( const wxString& fmt ) + { + Write( fmt ); + Newline(); + return false; + } + + bool __fastcall WriteLn( Colors color, const wxString& fmt ) + { + SetColor( color ); + Write( fmt ); + Newline(); + ClearColor(); + return false; + } + + // ------------------------------------------------------------------------ + __forceinline void __fastcall _Write( const char* fmt, va_list args ) + { + ScopedLock locker( m_writelock ); + vssprintf( m_format_buffer, fmt, args ); + const char* cstr = m_format_buffer.c_str(); + + Write( fmt ); + } + + __forceinline void __fastcall _WriteLn( const char* fmt, va_list args ) + { + _Write( fmt, args ); + Newline(); + } + + __forceinline void __fastcall _WriteLn( Colors color, const char* fmt, va_list args ) + { + SetColor( color ); + _WriteLn( fmt, args ); + ClearColor(); + } + + // ------------------------------------------------------------------------ + bool Write( const char* fmt, VARG_PARAM dummy, ... ) + { + varg_assert(); + + va_list args; + va_start(args,dummy); + _Write( fmt, args ); + va_end(args); + + return false; + } + + bool Write( Colors color, const char* fmt, VARG_PARAM dummy, ... ) + { + varg_assert(); + + va_list args; + va_start(args,dummy); + SetColor( color ); + _Write( fmt, args ); + ClearColor(); + va_end(args); + + return false; + } + + // ------------------------------------------------------------------------ + bool WriteLn( const char* fmt, VARG_PARAM dummy, ... ) + { + varg_assert(); + va_list args; + va_start(args,dummy); + _WriteLn( fmt, args ); + va_end(args); + + return false; + } + + // ------------------------------------------------------------------------ + bool WriteLn( Colors color, const char* fmt, VARG_PARAM dummy, ... ) + { + varg_assert(); + + va_list args; + va_start(args,dummy); + _WriteLn( color, fmt, args ); + va_end(args); + return false; + } + + // ------------------------------------------------------------------------ + bool Error( const char* fmt, VARG_PARAM dummy, ... ) + { + varg_assert(); + + va_list args; + va_start(args,dummy); + _WriteLn( Color_Red, fmt, args ); + va_end(args); + return false; + } + + // ------------------------------------------------------------------------ + bool Notice( const char* fmt, VARG_PARAM dummy, ... ) + { + varg_assert(); + + va_list list; + va_start(list,dummy); + _WriteLn( Color_Yellow, fmt, list ); + va_end(list); + return false; + } + + // ------------------------------------------------------------------------ + bool Status( const char* fmt, VARG_PARAM dummy, ... ) + { + varg_assert(); + + va_list list; + va_start(list,dummy); + _WriteLn( Color_Green, fmt, list ); + va_end(list); + return false; + } + + // ------------------------------------------------------------------------ + bool __fastcall Error( const char* fmt ) + { + WriteLn( Color_Red, fmt ); + return false; + } + + bool __fastcall Notice( const char* fmt ) + { + WriteLn( Color_Yellow, fmt ); + return false; + } + + bool __fastcall Status( const char* fmt ) + { + WriteLn( Color_Green, fmt ); + return false; + } + + // ------------------------------------------------------------------------ + bool __fastcall Error( const wxString& src ) + { + WriteLn( Color_Red, src ); + return false; + } + + bool __fastcall Notice( const wxString& src ) + { + WriteLn( Color_Yellow, src ); + return false; + } + + bool __fastcall Status( const wxString& src ) + { + WriteLn( Color_Green, src ); + return false; + } + +} + diff --git a/pcsx2/Exceptions.cpp b/common/src/Utilities/Exceptions.cpp similarity index 99% rename from pcsx2/Exceptions.cpp rename to common/src/Utilities/Exceptions.cpp index c19fc467b1..86cea1a41d 100644 --- a/pcsx2/Exceptions.cpp +++ b/common/src/Utilities/Exceptions.cpp @@ -163,4 +163,3 @@ namespace Exception return m_message; } } - diff --git a/common/src/Utilities/Linux/LnxHostSys.cpp b/common/src/Utilities/Linux/LnxHostSys.cpp new file mode 100644 index 0000000000..4a6aa81f4b --- /dev/null +++ b/common/src/Utilities/Linux/LnxHostSys.cpp @@ -0,0 +1,57 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" + +#include +#include + +namespace HostSys +{ + void *Mmap(uptr base, u32 size) + { + u8 *Mem; + Mem = (u8*)mmap((uptr*)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + if (Mem == MAP_FAILED) Console::Notice("Mmap Failed!"); + + return Mem; + } + + void Munmap(uptr base, u32 size) + { + munmap((uptr*)base, size); + } + + void MemProtect( void* baseaddr, size_t size, PageProtectionMode mode, bool allowExecution ) + { + int lnxmode = 0; + + // make sure size is aligned to the system page size: + size = (size + m_pagemask) & ~m_pagemask; + + switch( mode ) + { + case Protect_NoAccess: break; + case Protect_ReadOnly: lnxmode = PROT_READ; break; + case Protect_ReadWrite: lnxmode = PROT_READ | PROT_WRITE; break; + } + + if( allowExecution ) lnxmode |= PROT_EXEC; + mprotect( baseaddr, size, lnxmode ); + } +} diff --git a/pcsx2/Linux/LnxMisc.cpp b/common/src/Utilities/LnxMisc.cpp similarity index 98% rename from pcsx2/Linux/LnxMisc.cpp rename to common/src/Utilities/LnxMisc.cpp index 297c82ab9c..bca210e80b 100644 --- a/pcsx2/Linux/LnxMisc.cpp +++ b/common/src/Utilities/LnxMisc.cpp @@ -22,8 +22,6 @@ #include #include -#include "CDVD.h" - void InitCPUTicks() { } diff --git a/pcsx2/Linux/LnxThreads.cpp b/common/src/Utilities/LnxThreads.cpp similarity index 90% rename from pcsx2/Linux/LnxThreads.cpp rename to common/src/Utilities/LnxThreads.cpp index 02c04ba314..fe985ebcf1 100644 --- a/pcsx2/Linux/LnxThreads.cpp +++ b/common/src/Utilities/LnxThreads.cpp @@ -17,7 +17,7 @@ */ #include "PrecompiledHeader.h" -#include "ix86/ix86.h" +#include "Threading.h" // Note: assuming multicore is safer because it forces the interlocked routines to use // the LOCK prefix. The prefix works on single core CPUs fine (but is slow), but not @@ -169,28 +169,4 @@ namespace Threading return result; } - - #ifdef __x86_64__ - __forceinline void pcsx2_InterlockedExchange64(volatile s64* Target, s64 Value) - { - __asm__ __volatile__( - ".intel_syntax noprefix\n" - "lock xchg [%0], rax\n" - ".att_syntax\n" : : "r"(Target), "a"(Value) : "memory" - ); - return 0; - } - - __forceinline s64 pcsx2_InterlockedCompareExchange64(volatile s64* dest, s64 exch, s64 comp) - { - s64 old; - __asm__ __volatile__( - "lock; cmpxchgq %q2, %q1" - : "=a" (old) - : "r" (exch), "m" (*dest), "a" (comp) - ); - return old; - } -#endif - } diff --git a/common/src/Utilities/PrecompiledHeader.cpp b/common/src/Utilities/PrecompiledHeader.cpp new file mode 100644 index 0000000000..9e39fea4a2 --- /dev/null +++ b/common/src/Utilities/PrecompiledHeader.cpp @@ -0,0 +1,2 @@ + +#include "PrecompiledHeader.h" diff --git a/common/src/Utilities/PrecompiledHeader.h b/common/src/Utilities/PrecompiledHeader.h new file mode 100644 index 0000000000..05f0f62af8 --- /dev/null +++ b/common/src/Utilities/PrecompiledHeader.h @@ -0,0 +1,17 @@ +#ifndef UTILITIES_PRECOMPILED_HEADER +#define UTILITIES_PRECOMPILED_HEADER + +#include "Dependencies.h" + +using std::string; +using std::min; +using std::max; + +#include "MemcpyFast.h" +#include "Console.h" +#include "Exceptions.h" +#include "SafeArray.h" +#include "General.h" + +#endif + diff --git a/pcsx2/StringUtils.cpp b/common/src/Utilities/StringHelpers.cpp similarity index 98% rename from pcsx2/StringUtils.cpp rename to common/src/Utilities/StringHelpers.cpp index 6ac28715b1..f7ae2ec470 100644 --- a/pcsx2/StringUtils.cpp +++ b/common/src/Utilities/StringHelpers.cpp @@ -17,7 +17,8 @@ */ #include "PrecompiledHeader.h" -#include "SafeArray.h" + +const wxRect wxDefaultRect( wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord ); ////////////////////////////////////////////////////////////////////////////////////////// // Splits a string into parts and adds the parts into the given SafeList. diff --git a/pcsx2/ThreadTools.cpp b/common/src/Utilities/ThreadTools.cpp similarity index 100% rename from pcsx2/ThreadTools.cpp rename to common/src/Utilities/ThreadTools.cpp diff --git a/pcsx2/windows/WinMisc.cpp b/common/src/Utilities/WinMisc.cpp similarity index 98% rename from pcsx2/windows/WinMisc.cpp rename to common/src/Utilities/WinMisc.cpp index 94ab3b6fe2..285aeca4dc 100644 --- a/pcsx2/windows/WinMisc.cpp +++ b/common/src/Utilities/WinMisc.cpp @@ -18,7 +18,6 @@ #include "PrecompiledHeader.h" #include "RedtapeWindows.h" -#include "cdvd.h" static LARGE_INTEGER lfreq; diff --git a/pcsx2/windows/WinThreads.cpp b/common/src/Utilities/WinThreads.cpp similarity index 91% rename from pcsx2/windows/WinThreads.cpp rename to common/src/Utilities/WinThreads.cpp index d70781412a..0c1728b1d7 100644 --- a/pcsx2/windows/WinThreads.cpp +++ b/common/src/Utilities/WinThreads.cpp @@ -19,9 +19,9 @@ #include "PrecompiledHeader.h" #include "RedtapeWindows.h" +#include "x86emitter/tools.h" +#include "Threading.h" -#include "System.h" -#include "ix86/ix86_types.h" #ifdef _WIN32 #include "implement.h" // win32 pthreads implementations. @@ -53,7 +53,7 @@ namespace Threading LogicalCoresPerPhysicalCPU = CPUs; cpuinfo.PhysicalCores = ( CPUs / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU; - ptw32_smp_system = ( cpuinfo.LogicalCores > 1 ) ? TRUE : FALSE; + //ptw32_smp_system = ( cpuinfo.LogicalCores > 1 ) ? TRUE : FALSE; } __forceinline void Timeslice() @@ -77,13 +77,13 @@ namespace Threading { jASSUME( itsme != NULL ); - pthread_win32_thread_attach_np(); + //pthread_win32_thread_attach_np(); Thread& owner = *((Thread*)itsme); owner.m_returncode = owner.Callback(); owner.m_terminated = true; - pthread_win32_thread_detach_np(); + //pthread_win32_thread_detach_np(); return NULL; } @@ -98,14 +98,13 @@ namespace Threading __forceinline long pcsx2_InterlockedExchange( volatile long* target, long srcval ) { - // Use the pthreads-win32 implementation... - return ptw32_InterlockedExchange( target, srcval ); + return _InterlockedExchange( target, srcval ); } __forceinline long pcsx2_InterlockedCompareExchange( volatile long* target, long srcval, long comp ) { // Use the pthreads-win32 implementation... - return ptw32_InterlockedCompareExchange( target, srcval, comp ); + return _InterlockedCompareExchange( target, srcval, comp ); } __forceinline long pcsx2_InterlockedExchangeAdd( volatile long* target, long srcval ) diff --git a/pcsx2/windows/HostSys.cpp b/common/src/Utilities/Windows/WinHostSys.cpp similarity index 95% rename from pcsx2/windows/HostSys.cpp rename to common/src/Utilities/Windows/WinHostSys.cpp index 5f39743845..3024e6396c 100644 --- a/pcsx2/windows/HostSys.cpp +++ b/common/src/Utilities/Windows/WinHostSys.cpp @@ -16,8 +16,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "PrecompiledHeader.h" -#include "Win32.h" +#include "../PrecompiledHeader.h" +#include "Utilities/RedtapeWindows.h" #include namespace HostSys diff --git a/pcsx2/vssprintf.cpp b/common/src/Utilities/vssprintf.cpp similarity index 100% rename from pcsx2/vssprintf.cpp rename to common/src/Utilities/vssprintf.cpp diff --git a/pcsx2/x86/fast_routines.S b/common/src/Utilities/x86/MemcpyFast.S similarity index 93% rename from pcsx2/x86/fast_routines.S rename to common/src/Utilities/x86/MemcpyFast.S index 08cb90068a..e5e22793e6 100644 --- a/pcsx2/x86/fast_routines.S +++ b/common/src/Utilities/x86/MemcpyFast.S @@ -27,8 +27,6 @@ // zerofrog(@gmail.com) // and added to by arcum42@gmail.com .intel_syntax noprefix -.extern g_EEFreezeRegs -.extern FreezeMMXRegs_ .extern _mmx_backup // mmx memcmp implementation, size has to be a multiple of 8 @@ -227,20 +225,12 @@ memcmp_End: .global memxor_mmx memxor_mmx: - // make sure mmx regs are stored - // FreezeMMXRegs(1); - cmp dword ptr [g_EEFreezeRegs], 0 - je memxor_mmx_begin - push 1 - call FreezeMMXRegs_ - add esp, 4 -memxor_mmx_begin: - push esi - mov MEMXOR_SRC1, dword ptr [esp+8] - mov MEMXOR_SRC2, dword ptr [esp+12] - mov MEMXOR_SIZE, dword ptr [esp+16] - cmp MEMXOR_SIZE, 64 + push esi + mov MEMXOR_SRC1, dword ptr [esp+8] + mov MEMXOR_SRC2, dword ptr [esp+12] + mov MEMXOR_SIZE, dword ptr [esp+16] + cmp MEMXOR_SIZE, 64 jl memxor_Setup4 movq mm0, [MEMXOR_SRC2] diff --git a/pcsx2/x86/fast_routines.cpp b/common/src/Utilities/x86/MemcpyFast.cpp similarity index 99% rename from pcsx2/x86/fast_routines.cpp rename to common/src/Utilities/x86/MemcpyFast.cpp index d907cfaf03..cd1c77d12f 100644 --- a/pcsx2/x86/fast_routines.cpp +++ b/common/src/Utilities/x86/MemcpyFast.cpp @@ -31,7 +31,7 @@ 3dsdk.support@amd.com ******************************************************************************/ -#include "PrecompiledHeader.h" +#include "..\PrecompiledHeader.h" #ifdef _MSC_VER #pragma warning(disable:4414) @@ -72,19 +72,13 @@ MEMCPY_AMD.CPP // This is faster than using software prefetch. The technique is great for // getting maximum read bandwidth, especially in DDR memory systems. -#include "Misc.h" - // Inline assembly syntax for use with Visual C++ #if defined(_MSC_VER) -#ifdef _DEBUG +#ifdef PCSX2_DEBUG extern u8 g_globalMMXSaved; -void checkregs() -{ - if( g_EEFreezeRegs ) assert( g_globalMMXSaved ); -} #endif @@ -772,7 +766,6 @@ End: // returns the xor of all elements, cmpsize has to be mult of 8 void memxor_mmx(void* dst, const void* src1, int cmpsize) { - FreezeMMXRegs(1); assert( (cmpsize&7) == 0 ); __asm { @@ -875,7 +868,6 @@ Setup1: End: emms } - FreezeMMXRegs(0); } #endif diff --git a/pcsx2/x86/ix86/ix86_3dnow.cpp b/common/src/x86emitter/3dnow.cpp similarity index 94% rename from pcsx2/x86/ix86/ix86_3dnow.cpp rename to common/src/x86emitter/3dnow.cpp index 0dc600d1be..df7307d34b 100644 --- a/pcsx2/x86/ix86/ix86_3dnow.cpp +++ b/common/src/x86emitter/3dnow.cpp @@ -1,202 +1,202 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "PrecompiledHeader.h" -#include "ix86_legacy_internal.h" - -//------------------------------------------------------------------ -// 3DNOW instructions [Anyone caught dead using these will be re-killed] -//------------------------------------------------------------------ - -/* femms */ -emitterT void FEMMS( void ) -{ - xWrite16( 0x0E0F ); -} - -emitterT void PFCMPEQMtoR( x86IntRegType to, uptr from ) -{ - xWrite16( 0x0F0F ); - ModRM( 0, to, DISP32 ); - xWrite32( from ); - xWrite8( 0xB0 ); -} - -emitterT void PFCMPGTMtoR( x86IntRegType to, uptr from ) -{ - xWrite16( 0x0F0F ); - ModRM( 0, to, DISP32 ); - xWrite32( from ); - xWrite8( 0xA0 ); -} - -emitterT void PFCMPGEMtoR( x86IntRegType to, uptr from ) -{ - xWrite16( 0x0F0F ); - ModRM( 0, to, DISP32 ); - xWrite32( from ); - xWrite8( 0x90 ); -} - -emitterT void PFADDMtoR( x86IntRegType to, uptr from ) -{ - xWrite16( 0x0F0F ); - ModRM( 0, to, DISP32 ); - xWrite32( from ); - xWrite8( 0x9E ); -} - -emitterT void PFADDRtoR( x86IntRegType to, x86IntRegType from ) -{ - xWrite16( 0x0F0F ); - ModRM( 3, to, from ); - xWrite8( 0x9E ); -} - -emitterT void PFSUBMtoR( x86IntRegType to, uptr from ) -{ - xWrite16( 0x0F0F ); - ModRM( 0, to, DISP32 ); - xWrite32( from ); - xWrite8( 0x9A ); -} - -emitterT void PFSUBRtoR( x86IntRegType to, x86IntRegType from ) -{ - xWrite16( 0x0F0F ); - ModRM( 3, to, from ); - xWrite8( 0x9A ); -} - -emitterT void PFMULMtoR( x86IntRegType to, uptr from ) -{ - xWrite16( 0x0F0F ); - ModRM( 0, to, DISP32 ); - xWrite32( from ); - xWrite8( 0xB4 ); -} - -emitterT void PFMULRtoR( x86IntRegType to, x86IntRegType from ) -{ - xWrite16( 0x0F0F ); - ModRM( 3, to, from ); - xWrite8( 0xB4 ); -} - -emitterT void PFRCPMtoR( x86IntRegType to, uptr from ) -{ - xWrite16( 0x0F0F ); - ModRM( 0, to, DISP32 ); - xWrite32( from ); - xWrite8( 0x96 ); -} - -emitterT void PFRCPRtoR( x86IntRegType to, x86IntRegType from ) -{ - xWrite16( 0x0F0F ); - ModRM( 3, to, from ); - xWrite8( 0x96 ); -} - -emitterT void PFRCPIT1RtoR( x86IntRegType to, x86IntRegType from ) -{ - xWrite16( 0x0F0F ); - ModRM( 3, to, from ); - xWrite8( 0xA6 ); -} - -emitterT void PFRCPIT2RtoR( x86IntRegType to, x86IntRegType from ) -{ - xWrite16( 0x0F0F ); - ModRM( 3, to, from ); - xWrite8( 0xB6 ); -} - -emitterT void PFRSQRTRtoR( x86IntRegType to, x86IntRegType from ) -{ - xWrite16( 0x0F0F ); - ModRM( 3, to, from ); - xWrite8( 0x97 ); -} - -emitterT void PFRSQIT1RtoR( x86IntRegType to, x86IntRegType from ) -{ - xWrite16( 0x0F0F ); - ModRM( 3, to, from ); - xWrite8( 0xA7 ); -} - -emitterT void PF2IDMtoR( x86IntRegType to, uptr from ) -{ - xWrite16( 0x0F0F ); - ModRM( 0, to, DISP32 ); - xWrite32( from ); - xWrite8( 0x1D ); -} - -emitterT void PF2IDRtoR( x86IntRegType to, x86IntRegType from ) -{ - xWrite16( 0x0F0F ); - ModRM( 3, to, from ); - xWrite8( 0x1D ); -} - -emitterT void PI2FDMtoR( x86IntRegType to, uptr from ) -{ - xWrite16( 0x0F0F ); - ModRM( 0, to, DISP32 ); - xWrite32( from ); - xWrite8( 0x0D ); -} - -emitterT void PI2FDRtoR( x86IntRegType to, x86IntRegType from ) -{ - xWrite16( 0x0F0F ); - ModRM( 3, to, from ); - xWrite8( 0x0D ); -} - -emitterT void PFMAXMtoR( x86IntRegType to, uptr from ) -{ - xWrite16( 0x0F0F ); - ModRM( 0, to, DISP32 ); - xWrite32( from ); - xWrite8( 0xA4 ); -} - -emitterT void PFMAXRtoR( x86IntRegType to, x86IntRegType from ) -{ - xWrite16( 0x0F0F ); - ModRM( 3, to, from ); - xWrite8( 0xA4 ); -} - -emitterT void PFMINMtoR( x86IntRegType to, uptr from ) -{ - xWrite16( 0x0F0F ); - ModRM( 0, to, DISP32 ); - xWrite32( from ); - xWrite8( 0x94 ); -} - -emitterT void PFMINRtoR( x86IntRegType to, x86IntRegType from ) -{ - xWrite16( 0x0F0F ); - ModRM( 3, to, from ); - xWrite8( 0x94 ); -} +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" +#include "legacy_internal.h" + +//------------------------------------------------------------------ +// 3DNOW instructions [Anyone caught dead using these will be re-killed] +//------------------------------------------------------------------ + +/* femms */ +emitterT void FEMMS( void ) +{ + xWrite16( 0x0E0F ); +} + +emitterT void PFCMPEQMtoR( x86IntRegType to, uptr from ) +{ + xWrite16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + xWrite32( from ); + xWrite8( 0xB0 ); +} + +emitterT void PFCMPGTMtoR( x86IntRegType to, uptr from ) +{ + xWrite16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + xWrite32( from ); + xWrite8( 0xA0 ); +} + +emitterT void PFCMPGEMtoR( x86IntRegType to, uptr from ) +{ + xWrite16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + xWrite32( from ); + xWrite8( 0x90 ); +} + +emitterT void PFADDMtoR( x86IntRegType to, uptr from ) +{ + xWrite16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + xWrite32( from ); + xWrite8( 0x9E ); +} + +emitterT void PFADDRtoR( x86IntRegType to, x86IntRegType from ) +{ + xWrite16( 0x0F0F ); + ModRM( 3, to, from ); + xWrite8( 0x9E ); +} + +emitterT void PFSUBMtoR( x86IntRegType to, uptr from ) +{ + xWrite16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + xWrite32( from ); + xWrite8( 0x9A ); +} + +emitterT void PFSUBRtoR( x86IntRegType to, x86IntRegType from ) +{ + xWrite16( 0x0F0F ); + ModRM( 3, to, from ); + xWrite8( 0x9A ); +} + +emitterT void PFMULMtoR( x86IntRegType to, uptr from ) +{ + xWrite16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + xWrite32( from ); + xWrite8( 0xB4 ); +} + +emitterT void PFMULRtoR( x86IntRegType to, x86IntRegType from ) +{ + xWrite16( 0x0F0F ); + ModRM( 3, to, from ); + xWrite8( 0xB4 ); +} + +emitterT void PFRCPMtoR( x86IntRegType to, uptr from ) +{ + xWrite16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + xWrite32( from ); + xWrite8( 0x96 ); +} + +emitterT void PFRCPRtoR( x86IntRegType to, x86IntRegType from ) +{ + xWrite16( 0x0F0F ); + ModRM( 3, to, from ); + xWrite8( 0x96 ); +} + +emitterT void PFRCPIT1RtoR( x86IntRegType to, x86IntRegType from ) +{ + xWrite16( 0x0F0F ); + ModRM( 3, to, from ); + xWrite8( 0xA6 ); +} + +emitterT void PFRCPIT2RtoR( x86IntRegType to, x86IntRegType from ) +{ + xWrite16( 0x0F0F ); + ModRM( 3, to, from ); + xWrite8( 0xB6 ); +} + +emitterT void PFRSQRTRtoR( x86IntRegType to, x86IntRegType from ) +{ + xWrite16( 0x0F0F ); + ModRM( 3, to, from ); + xWrite8( 0x97 ); +} + +emitterT void PFRSQIT1RtoR( x86IntRegType to, x86IntRegType from ) +{ + xWrite16( 0x0F0F ); + ModRM( 3, to, from ); + xWrite8( 0xA7 ); +} + +emitterT void PF2IDMtoR( x86IntRegType to, uptr from ) +{ + xWrite16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + xWrite32( from ); + xWrite8( 0x1D ); +} + +emitterT void PF2IDRtoR( x86IntRegType to, x86IntRegType from ) +{ + xWrite16( 0x0F0F ); + ModRM( 3, to, from ); + xWrite8( 0x1D ); +} + +emitterT void PI2FDMtoR( x86IntRegType to, uptr from ) +{ + xWrite16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + xWrite32( from ); + xWrite8( 0x0D ); +} + +emitterT void PI2FDRtoR( x86IntRegType to, x86IntRegType from ) +{ + xWrite16( 0x0F0F ); + ModRM( 3, to, from ); + xWrite8( 0x0D ); +} + +emitterT void PFMAXMtoR( x86IntRegType to, uptr from ) +{ + xWrite16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + xWrite32( from ); + xWrite8( 0xA4 ); +} + +emitterT void PFMAXRtoR( x86IntRegType to, x86IntRegType from ) +{ + xWrite16( 0x0F0F ); + ModRM( 3, to, from ); + xWrite8( 0xA4 ); +} + +emitterT void PFMINMtoR( x86IntRegType to, uptr from ) +{ + xWrite16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + xWrite32( from ); + xWrite8( 0x94 ); +} + +emitterT void PFMINRtoR( x86IntRegType to, x86IntRegType from ) +{ + xWrite16( 0x0F0F ); + ModRM( 3, to, from ); + xWrite8( 0x94 ); +} diff --git a/common/src/x86emitter/PrecompiledHeader.cpp b/common/src/x86emitter/PrecompiledHeader.cpp new file mode 100644 index 0000000000..9e39fea4a2 --- /dev/null +++ b/common/src/x86emitter/PrecompiledHeader.cpp @@ -0,0 +1,2 @@ + +#include "PrecompiledHeader.h" diff --git a/common/src/x86emitter/PrecompiledHeader.h b/common/src/x86emitter/PrecompiledHeader.h new file mode 100644 index 0000000000..6a2d726aa1 --- /dev/null +++ b/common/src/x86emitter/PrecompiledHeader.h @@ -0,0 +1,29 @@ +#ifndef EMITTER_PRECOMPILED_HEADER +#define EMITTER_PRECOMPILED_HEADER + +#include "Pcsx2Defs.h" + +#include +#include +#include // for wxPoint/wxRect stuff +#include +#include + +#include +#include +#include +#include // string.h under c++ +#include // stdio.h under c++ +#include + +using std::string; +using std::min; +using std::max; + +#include "Utilities/Console.h" +#include "Utilities/Exceptions.h" +#include "Utilities/General.h" +#include "Utilities/MemcpyFast.h" + +#endif + diff --git a/pcsx2/x86/ix86/ix86_cpudetect.cpp b/common/src/x86emitter/cpudetect.cpp similarity index 73% rename from pcsx2/x86/ix86/ix86_cpudetect.cpp rename to common/src/x86emitter/cpudetect.cpp index 6e211619f3..2d210ffc52 100644 --- a/pcsx2/x86/ix86/ix86_cpudetect.cpp +++ b/common/src/x86emitter/cpudetect.cpp @@ -1,450 +1,401 @@ -/* Cpudetection lib - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "PrecompiledHeader.h" - -#include "System.h" -#include "ix86_legacy_internal.h" - -#include "RedtapeWindows.h" - -using namespace x86Emitter; - -#if defined (_MSC_VER) && _MSC_VER >= 1400 - - extern "C" - { - void __cpuid(int* CPUInfo, int InfoType); - unsigned __int64 __rdtsc(); -#ifndef __INTEL_COMPILER -# pragma intrinsic(__cpuid) -# pragma intrinsic(__rdtsc) -#endif - } - -#endif - -CAPABILITIES cpucaps; -CPUINFO cpuinfo; - -#define cpuid(cmd,a,b,c,d) \ - __asm__ __volatile__("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \ - : "=a" (a), "=r" (b), "=c" (c), "=d" (d) : "0" (cmd), "c" (0)) - -extern s32 iCpuId( u32 cmd, u32 *regs ) -{ - int flag=1; - -#if defined (_MSC_VER) && _MSC_VER >= 1400 - - __asm - { - xor ecx, ecx; /* ecx should be zero for CPUID(4) */ - } - __cpuid( (int*)regs, cmd ); - - return 0; - -#elif defined (_MSC_VER) - __asm - { - push ebx; - push edi; - - pushfd; - pop eax; - mov edx, eax; - xor eax, 1 << 21; - push eax; - popfd; - pushfd; - pop eax; - xor eax, edx; - mov flag, eax; - } - if ( ! flag ) - { - return -1; - } - - __asm - { - mov eax, cmd; - xor ecx, ecx; /* ecx should be zero for CPUID(4) */ - cpuid; - mov edi, [regs] - mov [edi], eax; - mov [edi+4], ebx; - mov [edi+8], ecx; - mov [edi+12], edx; - - pop edi; - pop ebx; - } - return 0; - -#else - - // GCC Assembly Code --> - - // see if we can use cpuid - __asm__ __volatile__ ( - "sub $0x18, %%esp\n" - "pushf\n" - "pop %%eax\n" - "mov %%eax, %%edx\n" - "xor $0x200000, %%eax\n" - "push %%eax\n" - "popf\n" - "pushf\n" - "pop %%eax\n" - "xor %%edx, %%eax\n" - "mov %%eax, %[flag]\n" - "add $0x18, %%esp\n" - "cmpl $0x0,%%eax\n" - "jne 1f\n" - "mov $0xffffffff, %%eax\n" - "leave\n" - "ret\n" - "1:\n" - : [flag]"=r"(flag) : - ); - - cpuid(cmd, regs[0], regs[1], regs[2], regs[3]); - return 0; - -#endif // _MSC_VER -} - -u64 GetCPUTick( void ) -{ -#if defined (_MSC_VER) && _MSC_VER >= 1400 - - return __rdtsc(); - -#elif defined(_WIN32) - - __asm rdtsc; - -#else - - u32 _a, _d; - __asm__ __volatile__ ("rdtsc" : "=a"(_a), "=d"(_d)); - return (u64)_a | ((u64)_d << 32); - -#endif -} - -////////////////////////////////////////////////////////////////////////////////////////// -// Note: This function doesn't support GCC/Linux. Looking online it seems the only -// way to simulate the Micrsoft SEH model is to use unix signals, and the 'sigaction' -// function specifically. Maybe a project for a linux developer at a later date. :) -#ifdef _MSC_VER -static bool _test_instruction( void* pfnCall ) -{ - __try { - ((void (*)())pfnCall)(); - } - __except(EXCEPTION_EXECUTE_HANDLER) { - return false; - } - return true; -} - -static char* bool_to_char( bool testcond ) -{ - return testcond ? "true" : "false"; -} - -#endif - -#if defined __LINUX__ - -#include -#include - -#endif - -////////////////////////////////////////////////////////////////////////////////////////// -// -s64 CPUSpeedHz( int time ) -{ - int timeStart, - timeStop; - s64 startTick, - endTick; - - if( ! cpucaps.hasTimeStampCounter ) - { - return 0; //check if function is supported - } - - // Align the cpu execution to a timeGetTime boundary. - // Without this the result could be skewed by up to several milliseconds. - - do { timeStart = timeGetTime( ); - } while( timeGetTime( ) == timeStart ); - - do - { - timeStop = timeGetTime( ); - startTick = GetCPUTick( ); - } while( ( timeStop - timeStart ) < 1 ); - - timeStart = timeStop; - do - { - timeStop = timeGetTime(); - endTick = GetCPUTick(); - } - while( ( timeStop - timeStart ) < time ); - - return (s64)( endTick - startTick ); -} - -//////////////////////////////////////////////////// -int arr[] = { - 0x65746e49, 0x2952286c, 0x726f4320, 0x4d542865, - 0x51203229,0x20646175,0x20555043,0x20202020 , - 0x20202020,0x20402020,0x36362e32,0x7a4847 -}; - -void cpudetectInit() -{ - u32 regs[ 4 ]; - u32 cmds; - int cputype=0; // Cpu type - //AMD 64 STUFF - u32 x86_64_8BITBRANDID; - u32 x86_64_12BITBRANDID; - int num; - char str[50]; - - memzero_obj( cpuinfo.x86ID ); - cpuinfo.x86Family = 0; - cpuinfo.x86Model = 0; - cpuinfo.x86PType = 0; - cpuinfo.x86StepID = 0; - cpuinfo.x86Flags = 0; - cpuinfo.x86EFlags = 0; - - if ( iCpuId( 0, regs ) == -1 ) return; - - cmds = regs[ 0 ]; - ((u32*)cpuinfo.x86ID)[ 0 ] = regs[ 1 ]; - ((u32*)cpuinfo.x86ID)[ 1 ] = regs[ 3 ]; - ((u32*)cpuinfo.x86ID)[ 2 ] = regs[ 2 ]; - - // Hack - prevents reg[2] & reg[3] from being optimized out of existance! - num = sprintf(str, "\tx86Flags = %8.8x %8.8x\n", regs[3], regs[2]); - - u32 LogicalCoresPerPhysicalCPU = 0; - u32 PhysicalCoresPerPhysicalCPU = 1; - - if ( cmds >= 0x00000001 ) - { - if ( iCpuId( 0x00000001, regs ) != -1 ) - { - cpuinfo.x86StepID = regs[ 0 ] & 0xf; - cpuinfo.x86Model = (regs[ 0 ] >> 4) & 0xf; - cpuinfo.x86Family = (regs[ 0 ] >> 8) & 0xf; - cpuinfo.x86PType = (regs[ 0 ] >> 12) & 0x3; - LogicalCoresPerPhysicalCPU = ( regs[1] >> 16 ) & 0xff; - x86_64_8BITBRANDID = regs[1] & 0xff; - cpuinfo.x86Flags = regs[ 3 ]; - cpuinfo.x86Flags2 = regs[ 2 ]; - } - } - /* detect multicore for intel cpu */ - if ((cmds >= 0x00000004) && !strcmp("GenuineIntel",cpuinfo.x86ID)) - { - if ( iCpuId( 0x00000004, regs ) != -1 ) - { - PhysicalCoresPerPhysicalCPU += ( regs[0] >> 26) & 0x3f; - } - } - - if ( iCpuId( 0x80000000, regs ) != -1 ) - { - cmds = regs[ 0 ]; - if ( cmds >= 0x80000001 ) - { - if ( iCpuId( 0x80000001, regs ) != -1 ) - { - x86_64_12BITBRANDID = regs[1] & 0xfff; - cpuinfo.x86EFlags2 = regs[ 2 ]; - cpuinfo.x86EFlags = regs[ 3 ]; - - } - } - /* detect multicore for amd cpu */ - if ((cmds >= 0x80000008) && !strcmp("AuthenticAMD",cpuinfo.x86ID)) - { - if ( iCpuId( 0x80000008, regs ) != -1 ) - { - PhysicalCoresPerPhysicalCPU += ( regs[2] ) & 0xff; - } - } - } - - switch(cpuinfo.x86PType) - { - case 0: - strcpy( cpuinfo.x86Type, "Standard OEM"); - break; - case 1: - strcpy( cpuinfo.x86Type, "Overdrive"); - break; - case 2: - strcpy( cpuinfo.x86Type, "Dual"); - break; - case 3: - strcpy( cpuinfo.x86Type, "Reserved"); - break; - default: - strcpy( cpuinfo.x86Type, "Unknown"); - break; - } - if ( cpuinfo.x86ID[ 0 ] == 'G' ){ cputype=0;}//trick lines but if you know a way better ;p - if ( cpuinfo.x86ID[ 0 ] == 'A' ){ cputype=1;} - - memzero_obj( cpuinfo.x86Fam ); - iCpuId( 0x80000002, (u32*)cpuinfo.x86Fam); - iCpuId( 0x80000003, (u32*)(cpuinfo.x86Fam+16)); - iCpuId( 0x80000004, (u32*)(cpuinfo.x86Fam+32)); - - //capabilities - cpucaps.hasFloatingPointUnit = ( cpuinfo.x86Flags >> 0 ) & 1; - cpucaps.hasVirtual8086ModeEnhancements = ( cpuinfo.x86Flags >> 1 ) & 1; - cpucaps.hasDebuggingExtensions = ( cpuinfo.x86Flags >> 2 ) & 1; - cpucaps.hasPageSizeExtensions = ( cpuinfo.x86Flags >> 3 ) & 1; - cpucaps.hasTimeStampCounter = ( cpuinfo.x86Flags >> 4 ) & 1; - cpucaps.hasModelSpecificRegisters = ( cpuinfo.x86Flags >> 5 ) & 1; - cpucaps.hasPhysicalAddressExtension = ( cpuinfo.x86Flags >> 6 ) & 1; - cpucaps.hasMachineCheckArchitecture = ( cpuinfo.x86Flags >> 7 ) & 1; - cpucaps.hasCOMPXCHG8BInstruction = ( cpuinfo.x86Flags >> 8 ) & 1; - cpucaps.hasAdvancedProgrammableInterruptController = ( cpuinfo.x86Flags >> 9 ) & 1; - cpucaps.hasSEPFastSystemCall = ( cpuinfo.x86Flags >> 11 ) & 1; - cpucaps.hasMemoryTypeRangeRegisters = ( cpuinfo.x86Flags >> 12 ) & 1; - cpucaps.hasPTEGlobalFlag = ( cpuinfo.x86Flags >> 13 ) & 1; - cpucaps.hasMachineCheckArchitecture = ( cpuinfo.x86Flags >> 14 ) & 1; - cpucaps.hasConditionalMoveAndCompareInstructions = ( cpuinfo.x86Flags >> 15 ) & 1; - cpucaps.hasFGPageAttributeTable = ( cpuinfo.x86Flags >> 16 ) & 1; - cpucaps.has36bitPageSizeExtension = ( cpuinfo.x86Flags >> 17 ) & 1; - cpucaps.hasProcessorSerialNumber = ( cpuinfo.x86Flags >> 18 ) & 1; - cpucaps.hasCFLUSHInstruction = ( cpuinfo.x86Flags >> 19 ) & 1; - cpucaps.hasDebugStore = ( cpuinfo.x86Flags >> 21 ) & 1; - cpucaps.hasACPIThermalMonitorAndClockControl = ( cpuinfo.x86Flags >> 22 ) & 1; - cpucaps.hasMultimediaExtensions = ( cpuinfo.x86Flags >> 23 ) & 1; //mmx - cpucaps.hasFastStreamingSIMDExtensionsSaveRestore = ( cpuinfo.x86Flags >> 24 ) & 1; - cpucaps.hasStreamingSIMDExtensions = ( cpuinfo.x86Flags >> 25 ) & 1; //sse - cpucaps.hasStreamingSIMD2Extensions = ( cpuinfo.x86Flags >> 26 ) & 1; //sse2 - cpucaps.hasSelfSnoop = ( cpuinfo.x86Flags >> 27 ) & 1; - cpucaps.hasMultiThreading = ( cpuinfo.x86Flags >> 28 ) & 1; - cpucaps.hasThermalMonitor = ( cpuinfo.x86Flags >> 29 ) & 1; - cpucaps.hasIntel64BitArchitecture = ( cpuinfo.x86Flags >> 30 ) & 1; - - //that is only for AMDs - cpucaps.hasMultimediaExtensionsExt = ( cpuinfo.x86EFlags >> 22 ) & 1; //mmx2 - cpucaps.hasAMD64BitArchitecture = ( cpuinfo.x86EFlags >> 29 ) & 1; //64bit cpu - cpucaps.has3DNOWInstructionExtensionsExt = ( cpuinfo.x86EFlags >> 30 ) & 1; //3dnow+ - cpucaps.has3DNOWInstructionExtensions = ( cpuinfo.x86EFlags >> 31 ) & 1; //3dnow - cpucaps.hasStreamingSIMD4ExtensionsA = ( cpuinfo.x86EFlags2 >> 6 ) & 1; //INSERTQ / EXTRQ / MOVNT - - - cpuinfo.cpuspeed = (u32)(CPUSpeedHz( 400 ) / 400000 ); - - // --> SSE3 / SSSE3 / SSE4.1 / SSE 4.2 detection <-- - - cpucaps.hasStreamingSIMD3Extensions = ( cpuinfo.x86Flags2 >> 0 ) & 1; //sse3 - cpucaps.hasSupplementalStreamingSIMD3Extensions = ( cpuinfo.x86Flags2 >> 9 ) & 1; //ssse3 - cpucaps.hasStreamingSIMD4Extensions = ( cpuinfo.x86Flags2 >> 19 ) & 1; //sse4.1 - cpucaps.hasStreamingSIMD4Extensions2 = ( cpuinfo.x86Flags2 >> 20 ) & 1; //sse4.2 - - // Can the SSE3 / SSE4.1 bits be trusted? Using an instruction test is a very "complete" - // approach to ensuring the bit is accurate, and at least one reported case of a Q9550 not - // having SSE 4.1 set but still supporting it properly is fixed by this --air - - #ifdef _MSC_VER - u8* recSSE = (u8*)HostSys::Mmap( NULL, 0x1000 ); - if( recSSE != NULL ) - { - xSetPtr( recSSE ); - xMOVSLDUP( xmm1, xmm0 ); - RET(); - - u8* funcSSSE3 = xGetPtr(); - xPABS.W( xmm0, xmm1 ); - RET(); - - u8* funcSSE41 = xGetPtr(); - xBLEND.VPD( xmm1, xmm0 ); - RET(); - - bool sse3_result = _test_instruction( recSSE ); // sse3 - bool ssse3_result = _test_instruction( funcSSSE3 ); - bool sse41_result = _test_instruction( funcSSE41 ); - - HostSys::Munmap( recSSE, 0x1000 ); - - // Test for and log any irregularities here. - // We take the instruction test result over cpuid since (in theory) it should be a - // more reliable gauge of the cpu's actual ability. - - if( sse3_result != !!cpucaps.hasStreamingSIMD3Extensions ) - { - Console::Notice( "SSE3 Detection Inconsistency: cpuid=%s, test_result=%s", - params bool_to_char( !!cpucaps.hasStreamingSIMD3Extensions ), bool_to_char( sse3_result ) ); - - cpucaps.hasStreamingSIMD3Extensions = sse3_result; - } - - if( ssse3_result != !!cpucaps.hasSupplementalStreamingSIMD3Extensions ) - { - Console::Notice( "SSSE3 Detection Inconsistency: cpuid=%s, test_result=%s", - params bool_to_char( !!cpucaps.hasSupplementalStreamingSIMD3Extensions ), bool_to_char( ssse3_result ) ); - - cpucaps.hasSupplementalStreamingSIMD3Extensions = ssse3_result; - } - - if( sse41_result != !!cpucaps.hasStreamingSIMD4Extensions ) - { - Console::Notice( "SSE4 Detection Inconsistency: cpuid=%s, test_result=%s", - params bool_to_char( !!cpucaps.hasStreamingSIMD4Extensions ), bool_to_char( sse41_result ) ); - - cpucaps.hasStreamingSIMD4Extensions = sse41_result; - } - - } - else - Console::Notice( - "Notice: Could not allocate memory for SSE3/4 detection.\n" - "\tRelying on CPUID results. [this is not an error]" - ); - #endif - - ////////////////////////////////////// - // Core Counting! - - if( !cpucaps.hasMultiThreading || LogicalCoresPerPhysicalCPU == 0 ) - LogicalCoresPerPhysicalCPU = 1; - - // This will assign values into cpuinfo.LogicalCores and PhysicalCores - Threading::CountLogicalCores( LogicalCoresPerPhysicalCPU, PhysicalCoresPerPhysicalCPU ); -} - +/* Cpudetection lib + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" +#include "internal.h" +#include "tools.h" +#include "Utilities/RedtapeWindows.h" +#include "Utilities/Threading.h" + +using namespace x86Emitter; + +CAPABILITIES cpucaps; +CPUINFO cpuinfo; + +static s32 iCpuId( u32 cmd, u32 *regs ) +{ +#ifdef _MSC_VER + __asm + { + xor ecx, ecx; // ecx should be zero for CPUID(4) + } +#else + __asm__ ( "xor ecx, ecx" ); +#endif + + __cpuid( (int*)regs, cmd ); + return 0; +} + +static u64 GetRdtsc( void ) +{ + return __rdtsc(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// Note: This function doesn't support GCC/Linux. Looking online it seems the only +// way to simulate the Microsoft SEH model is to use unix signals, and the 'sigaction' +// function specifically. Maybe a project for a linux developer at a later date. :) +// +#ifdef _MSC_VER +static bool _test_instruction( void* pfnCall ) +{ + __try { + ((void (*)())pfnCall)(); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + return false; + } + return true; +} + +static char* bool_to_char( bool testcond ) +{ + return testcond ? "true" : "false"; +} + +#endif + +#ifdef __LINUX__ +# include +# include +#endif + +#ifdef _WINDOWS_ +static HANDLE s_threadId = NULL; +static DWORD s_oldmask = ERROR_INVALID_PARAMETER; +#endif + +static void SetSingleAffinity() +{ +#ifdef _WINDOWS_ + // Assign a single CPU thread affinity to ensure rdtsc() accuracy. + // (rdtsc for each CPU/core can differ, causing skewed results) + + DWORD_PTR availProcCpus, availSysCpus; + if( !GetProcessAffinityMask( GetCurrentProcess(), &availProcCpus, &availSysCpus ) ) return; + + int i; + for( i=0; i<32; ++i ) + { + if( availProcCpus & (1<= 0x00000001 ) + { + if ( iCpuId( 0x00000001, regs ) != -1 ) + { + cpuinfo.x86StepID = regs[ 0 ] & 0xf; + cpuinfo.x86Model = (regs[ 0 ] >> 4) & 0xf; + cpuinfo.x86Family = (regs[ 0 ] >> 8) & 0xf; + cpuinfo.x86PType = (regs[ 0 ] >> 12) & 0x3; + LogicalCoresPerPhysicalCPU = ( regs[1] >> 16 ) & 0xff; + x86_64_8BITBRANDID = regs[ 1 ] & 0xff; + cpuinfo.x86Flags = regs[ 3 ]; + cpuinfo.x86Flags2 = regs[ 2 ]; + } + } + /* detect multicore for intel cpu */ + if ((cmds >= 0x00000004) && !strcmp("GenuineIntel",cpuinfo.x86ID)) + { + if ( iCpuId( 0x00000004, regs ) != -1 ) + { + PhysicalCoresPerPhysicalCPU += ( regs[0] >> 26) & 0x3f; + } + } + + if ( iCpuId( 0x80000000, regs ) != -1 ) + { + cmds = regs[ 0 ]; + if ( cmds >= 0x80000001 ) + { + if ( iCpuId( 0x80000001, regs ) != -1 ) + { + x86_64_12BITBRANDID = regs[1] & 0xfff; + cpuinfo.x86EFlags2 = regs[ 2 ]; + cpuinfo.x86EFlags = regs[ 3 ]; + + } + } + /* detect multicore for amd cpu */ + if ((cmds >= 0x80000008) && !strcmp("AuthenticAMD",cpuinfo.x86ID)) + { + if ( iCpuId( 0x80000008, regs ) != -1 ) + { + PhysicalCoresPerPhysicalCPU += ( regs[2] ) & 0xff; + } + } + } + + switch(cpuinfo.x86PType) + { + case 0: + strcpy( cpuinfo.x86Type, "Standard OEM"); + break; + case 1: + strcpy( cpuinfo.x86Type, "Overdrive"); + break; + case 2: + strcpy( cpuinfo.x86Type, "Dual"); + break; + case 3: + strcpy( cpuinfo.x86Type, "Reserved"); + break; + default: + strcpy( cpuinfo.x86Type, "Unknown"); + break; + } + if ( cpuinfo.x86ID[ 0 ] == 'G' ){ cputype=0;}//trick lines but if you know a way better ;p + if ( cpuinfo.x86ID[ 0 ] == 'A' ){ cputype=1;} + + memzero_obj( cpuinfo.x86Fam ); + iCpuId( 0x80000002, (u32*)cpuinfo.x86Fam); + iCpuId( 0x80000003, (u32*)(cpuinfo.x86Fam+16)); + iCpuId( 0x80000004, (u32*)(cpuinfo.x86Fam+32)); + + //capabilities + cpucaps.hasFloatingPointUnit = ( cpuinfo.x86Flags >> 0 ) & 1; + cpucaps.hasVirtual8086ModeEnhancements = ( cpuinfo.x86Flags >> 1 ) & 1; + cpucaps.hasDebuggingExtensions = ( cpuinfo.x86Flags >> 2 ) & 1; + cpucaps.hasPageSizeExtensions = ( cpuinfo.x86Flags >> 3 ) & 1; + cpucaps.hasTimeStampCounter = ( cpuinfo.x86Flags >> 4 ) & 1; + cpucaps.hasModelSpecificRegisters = ( cpuinfo.x86Flags >> 5 ) & 1; + cpucaps.hasPhysicalAddressExtension = ( cpuinfo.x86Flags >> 6 ) & 1; + cpucaps.hasMachineCheckArchitecture = ( cpuinfo.x86Flags >> 7 ) & 1; + cpucaps.hasCOMPXCHG8BInstruction = ( cpuinfo.x86Flags >> 8 ) & 1; + cpucaps.hasAdvancedProgrammableInterruptController = ( cpuinfo.x86Flags >> 9 ) & 1; + cpucaps.hasSEPFastSystemCall = ( cpuinfo.x86Flags >> 11 ) & 1; + cpucaps.hasMemoryTypeRangeRegisters = ( cpuinfo.x86Flags >> 12 ) & 1; + cpucaps.hasPTEGlobalFlag = ( cpuinfo.x86Flags >> 13 ) & 1; + cpucaps.hasMachineCheckArchitecture = ( cpuinfo.x86Flags >> 14 ) & 1; + cpucaps.hasConditionalMoveAndCompareInstructions = ( cpuinfo.x86Flags >> 15 ) & 1; + cpucaps.hasFGPageAttributeTable = ( cpuinfo.x86Flags >> 16 ) & 1; + cpucaps.has36bitPageSizeExtension = ( cpuinfo.x86Flags >> 17 ) & 1; + cpucaps.hasProcessorSerialNumber = ( cpuinfo.x86Flags >> 18 ) & 1; + cpucaps.hasCFLUSHInstruction = ( cpuinfo.x86Flags >> 19 ) & 1; + cpucaps.hasDebugStore = ( cpuinfo.x86Flags >> 21 ) & 1; + cpucaps.hasACPIThermalMonitorAndClockControl = ( cpuinfo.x86Flags >> 22 ) & 1; + cpucaps.hasMultimediaExtensions = ( cpuinfo.x86Flags >> 23 ) & 1; //mmx + cpucaps.hasFastStreamingSIMDExtensionsSaveRestore = ( cpuinfo.x86Flags >> 24 ) & 1; + cpucaps.hasStreamingSIMDExtensions = ( cpuinfo.x86Flags >> 25 ) & 1; //sse + cpucaps.hasStreamingSIMD2Extensions = ( cpuinfo.x86Flags >> 26 ) & 1; //sse2 + cpucaps.hasSelfSnoop = ( cpuinfo.x86Flags >> 27 ) & 1; + cpucaps.hasMultiThreading = ( cpuinfo.x86Flags >> 28 ) & 1; + cpucaps.hasThermalMonitor = ( cpuinfo.x86Flags >> 29 ) & 1; + cpucaps.hasIntel64BitArchitecture = ( cpuinfo.x86Flags >> 30 ) & 1; + + //that is only for AMDs + cpucaps.hasMultimediaExtensionsExt = ( cpuinfo.x86EFlags >> 22 ) & 1; //mmx2 + cpucaps.hasAMD64BitArchitecture = ( cpuinfo.x86EFlags >> 29 ) & 1; //64bit cpu + cpucaps.has3DNOWInstructionExtensionsExt = ( cpuinfo.x86EFlags >> 30 ) & 1; //3dnow+ + cpucaps.has3DNOWInstructionExtensions = ( cpuinfo.x86EFlags >> 31 ) & 1; //3dnow + cpucaps.hasStreamingSIMD4ExtensionsA = ( cpuinfo.x86EFlags2 >> 6 ) & 1; //INSERTQ / EXTRQ / MOVNT + + InitCPUTicks(); + u64 span = GetTickFrequency(); + + if( (span % 1000) < 400 ) // helps minimize rounding errors + cpuinfo.cpuspeed = (u32)( CPUSpeedHz( span / 1000 ) / 1000 ); + else + cpuinfo.cpuspeed = (u32)( CPUSpeedHz( span / 500 ) / 2000 ); + + // --> SSE3 / SSSE3 / SSE4.1 / SSE 4.2 detection <-- + + cpucaps.hasStreamingSIMD3Extensions = ( cpuinfo.x86Flags2 >> 0 ) & 1; //sse3 + cpucaps.hasSupplementalStreamingSIMD3Extensions = ( cpuinfo.x86Flags2 >> 9 ) & 1; //ssse3 + cpucaps.hasStreamingSIMD4Extensions = ( cpuinfo.x86Flags2 >> 19 ) & 1; //sse4.1 + cpucaps.hasStreamingSIMD4Extensions2 = ( cpuinfo.x86Flags2 >> 20 ) & 1; //sse4.2 + + ////////////////////////////////////////////////////////////////////////////////////////// + // SIMD Instruction Support Detection + // + // Can the SSE3 / SSE4.1 bits be trusted? Using an instruction test is a very "complete" + // approach to ensuring the instruction set is supported, and at least one reported case + // of a Q9550 not having it's SSE 4.1 bit set but still supporting it properly is fixed + // by this --air + // (note: the user who reported the case later fixed the problem by doing a CMOS reset) + // + // Linux support note: Linux/GCC doesn't have SEH-style exceptions which allow handling of + // CPU-level exceptions (__try/__except in msvc) so this code is disabled on GCC, and + // detection relies on the CPUID bits alone. + + #ifdef _MSC_VER + u8* recSSE = (u8*)HostSys::Mmap( NULL, 0x1000 ); + if( recSSE != NULL ) + { + xSetPtr( recSSE ); + xMOVSLDUP( xmm1, xmm0 ); + xRET(); + + u8* funcSSSE3 = xGetPtr(); + xPABS.W( xmm0, xmm1 ); + xRET(); + + u8* funcSSE41 = xGetPtr(); + xBLEND.VPD( xmm1, xmm0 ); + xRET(); + + bool sse3_result = _test_instruction( recSSE ); // sse3 + bool ssse3_result = _test_instruction( funcSSSE3 ); + bool sse41_result = _test_instruction( funcSSE41 ); + + HostSys::Munmap( recSSE, 0x1000 ); + + // Test for and log any irregularities here. + // We take the instruction test result over cpuid since (in theory) it should be a + // more reliable gauge of the cpu's actual ability. But since a difference in bit + // and actual ability may represent a cmos/bios problem, we report it to the user. + + if( sse3_result != !!cpucaps.hasStreamingSIMD3Extensions ) + { + Console::Notice( "SSE3 Detection Inconsistency: cpuid=%s, test_result=%s", + params bool_to_char( !!cpucaps.hasStreamingSIMD3Extensions ), bool_to_char( sse3_result ) ); + + cpucaps.hasStreamingSIMD3Extensions = sse3_result; + } + + if( ssse3_result != !!cpucaps.hasSupplementalStreamingSIMD3Extensions ) + { + Console::Notice( "SSSE3 Detection Inconsistency: cpuid=%s, test_result=%s", + params bool_to_char( !!cpucaps.hasSupplementalStreamingSIMD3Extensions ), bool_to_char( ssse3_result ) ); + + cpucaps.hasSupplementalStreamingSIMD3Extensions = ssse3_result; + } + + if( sse41_result != !!cpucaps.hasStreamingSIMD4Extensions ) + { + Console::Notice( "SSE4 Detection Inconsistency: cpuid=%s, test_result=%s", + params bool_to_char( !!cpucaps.hasStreamingSIMD4Extensions ), bool_to_char( sse41_result ) ); + + cpucaps.hasStreamingSIMD4Extensions = sse41_result; + } + + } + else + { + Console::Notice( + "Notice: Could not allocate memory for SSE3/4 detection.\n" + "\tRelying on CPUID results. [this is not an error]" + ); + } + #endif + + //////////////////////////////////////////////////////////////////////////////////////////// + // Core Counting! + + if( !cpucaps.hasMultiThreading || LogicalCoresPerPhysicalCPU == 0 ) + LogicalCoresPerPhysicalCPU = 1; + + // This will assign values into cpuinfo.LogicalCores and PhysicalCores + Threading::CountLogicalCores( LogicalCoresPerPhysicalCPU, PhysicalCoresPerPhysicalCPU ); +} + diff --git a/pcsx2/x86/ix86/ix86_fpu.cpp b/common/src/x86emitter/fpu.cpp similarity index 95% rename from pcsx2/x86/ix86/ix86_fpu.cpp rename to common/src/x86emitter/fpu.cpp index 9394fc2156..9a16483815 100644 --- a/pcsx2/x86/ix86/ix86_fpu.cpp +++ b/common/src/x86emitter/fpu.cpp @@ -1,276 +1,276 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "PrecompiledHeader.h" -#include "ix86_legacy_internal.h" - -//------------------------------------------------------------------ -// FPU instructions -//------------------------------------------------------------------ - -/* fild m32 to fpu reg stack */ -emitterT void FILD32( u32 from ) -{ - xWrite8( 0xDB ); - ModRM( 0, 0x0, DISP32 ); - xWrite32( MEMADDR(from, 4) ); -} - -/* fistp m32 from fpu reg stack */ -emitterT void FISTP32( u32 from ) -{ - xWrite8( 0xDB ); - ModRM( 0, 0x3, DISP32 ); - xWrite32( MEMADDR(from, 4) ); -} - -/* fld m32 to fpu reg stack */ -emitterT void FLD32( u32 from ) -{ - xWrite8( 0xD9 ); - ModRM( 0, 0x0, DISP32 ); - xWrite32( MEMADDR(from, 4) ); -} - -// fld st(i) -emitterT void FLD(int st) { xWrite16(0xc0d9+(st<<8)); } -emitterT void FLD1() { xWrite16(0xe8d9); } -emitterT void FLDL2E() { xWrite16(0xead9); } - -/* fst m32 from fpu reg stack */ -emitterT void FST32( u32 to ) -{ - xWrite8( 0xD9 ); - ModRM( 0, 0x2, DISP32 ); - xWrite32( MEMADDR(to, 4) ); -} - -/* fstp m32 from fpu reg stack */ -emitterT void FSTP32( u32 to ) -{ - xWrite8( 0xD9 ); - ModRM( 0, 0x3, DISP32 ); - xWrite32( MEMADDR(to, 4) ); -} - -// fstp st(i) -emitterT void FSTP(int st) { xWrite16(0xd8dd+(st<<8)); } - -/* fldcw fpu control word from m16 */ -emitterT void FLDCW( u32 from ) -{ - xWrite8( 0xD9 ); - ModRM( 0, 0x5, DISP32 ); - xWrite32( MEMADDR(from, 4) ); -} - -/* fnstcw fpu control word to m16 */ -emitterT void FNSTCW( u32 to ) -{ - xWrite8( 0xD9 ); - ModRM( 0, 0x7, DISP32 ); - xWrite32( MEMADDR(to, 4) ); -} - -emitterT void FNSTSWtoAX() { xWrite16(0xE0DF); } -emitterT void FXAM() { xWrite16(0xe5d9); } -emitterT void FDECSTP() { xWrite16(0xf6d9); } -emitterT void FRNDINT() { xWrite16(0xfcd9); } -emitterT void FXCH(int st) { xWrite16(0xc8d9+(st<<8)); } -emitterT void F2XM1() { xWrite16(0xf0d9); } -emitterT void FSCALE() { xWrite16(0xfdd9); } -emitterT void FPATAN(void) { xWrite16(0xf3d9); } -emitterT void FSIN(void) { xWrite16(0xfed9); } - -/* fadd ST(src) to fpu reg stack ST(0) */ -emitterT void FADD32Rto0( x86IntRegType src ) -{ - xWrite8( 0xD8 ); - xWrite8( 0xC0 + src ); -} - -/* fadd ST(0) to fpu reg stack ST(src) */ -emitterT void FADD320toR( x86IntRegType src ) -{ - xWrite8( 0xDC ); - xWrite8( 0xC0 + src ); -} - -/* fsub ST(src) to fpu reg stack ST(0) */ -emitterT void FSUB32Rto0( x86IntRegType src ) -{ - xWrite8( 0xD8 ); - xWrite8( 0xE0 + src ); -} - -/* fsub ST(0) to fpu reg stack ST(src) */ -emitterT void FSUB320toR( x86IntRegType src ) -{ - xWrite8( 0xDC ); - xWrite8( 0xE8 + src ); -} - -/* fsubp -> substract ST(0) from ST(1), store in ST(1) and POP stack */ -emitterT void FSUBP( void ) -{ - xWrite8( 0xDE ); - xWrite8( 0xE9 ); -} - -/* fmul ST(src) to fpu reg stack ST(0) */ -emitterT void FMUL32Rto0( x86IntRegType src ) -{ - xWrite8( 0xD8 ); - xWrite8( 0xC8 + src ); -} - -/* fmul ST(0) to fpu reg stack ST(src) */ -emitterT void FMUL320toR( x86IntRegType src ) -{ - xWrite8( 0xDC ); - xWrite8( 0xC8 + src ); -} - -/* fdiv ST(src) to fpu reg stack ST(0) */ -emitterT void FDIV32Rto0( x86IntRegType src ) -{ - xWrite8( 0xD8 ); - xWrite8( 0xF0 + src ); -} - -/* fdiv ST(0) to fpu reg stack ST(src) */ -emitterT void FDIV320toR( x86IntRegType src ) -{ - xWrite8( 0xDC ); - xWrite8( 0xF8 + src ); -} - -emitterT void FDIV320toRP( x86IntRegType src ) -{ - xWrite8( 0xDE ); - xWrite8( 0xF8 + src ); -} - -/* fadd m32 to fpu reg stack */ -emitterT void FADD32( u32 from ) -{ - xWrite8( 0xD8 ); - ModRM( 0, 0x0, DISP32 ); - xWrite32( MEMADDR(from, 4) ); -} - -/* fsub m32 to fpu reg stack */ -emitterT void FSUB32( u32 from ) -{ - xWrite8( 0xD8 ); - ModRM( 0, 0x4, DISP32 ); - xWrite32( MEMADDR(from, 4) ); -} - -/* fmul m32 to fpu reg stack */ -emitterT void FMUL32( u32 from ) -{ - xWrite8( 0xD8 ); - ModRM( 0, 0x1, DISP32 ); - xWrite32( MEMADDR(from, 4) ); -} - -/* fdiv m32 to fpu reg stack */ -emitterT void FDIV32( u32 from ) -{ - xWrite8( 0xD8 ); - ModRM( 0, 0x6, DISP32 ); - xWrite32( MEMADDR(from, 4) ); -} - -/* fabs fpu reg stack */ -emitterT void FABS( void ) -{ - xWrite16( 0xE1D9 ); -} - -/* fsqrt fpu reg stack */ -emitterT void FSQRT( void ) -{ - xWrite16( 0xFAD9 ); -} - -/* fchs fpu reg stack */ -emitterT void FCHS( void ) -{ - xWrite16( 0xE0D9 ); -} - -/* fcomi st, st(i) */ -emitterT void FCOMI( x86IntRegType src ) -{ - xWrite8( 0xDB ); - xWrite8( 0xF0 + src ); -} - -/* fcomip st, st(i) */ -emitterT void FCOMIP( x86IntRegType src ) -{ - xWrite8( 0xDF ); - xWrite8( 0xF0 + src ); -} - -/* fucomi st, st(i) */ -emitterT void FUCOMI( x86IntRegType src ) -{ - xWrite8( 0xDB ); - xWrite8( 0xE8 + src ); -} - -/* fucomip st, st(i) */ -emitterT void FUCOMIP( x86IntRegType src ) -{ - xWrite8( 0xDF ); - xWrite8( 0xE8 + src ); -} - -/* fcom m32 to fpu reg stack */ -emitterT void FCOM32( u32 from ) -{ - xWrite8( 0xD8 ); - ModRM( 0, 0x2, DISP32 ); - xWrite32( MEMADDR(from, 4) ); -} - -/* fcomp m32 to fpu reg stack */ -emitterT void FCOMP32( u32 from ) -{ - xWrite8( 0xD8 ); - ModRM( 0, 0x3, DISP32 ); - xWrite32( MEMADDR(from, 4) ); -} - -#define FCMOV32( low, high ) \ - { \ - xWrite8( low ); \ - xWrite8( high + from ); \ - } - -emitterT void FCMOVB32( x86IntRegType from ) { FCMOV32( 0xDA, 0xC0 ); } -emitterT void FCMOVE32( x86IntRegType from ) { FCMOV32( 0xDA, 0xC8 ); } -emitterT void FCMOVBE32( x86IntRegType from ) { FCMOV32( 0xDA, 0xD0 ); } -emitterT void FCMOVU32( x86IntRegType from ) { FCMOV32( 0xDA, 0xD8 ); } -emitterT void FCMOVNB32( x86IntRegType from ) { FCMOV32( 0xDB, 0xC0 ); } -emitterT void FCMOVNE32( x86IntRegType from ) { FCMOV32( 0xDB, 0xC8 ); } -emitterT void FCMOVNBE32( x86IntRegType from ) { FCMOV32( 0xDB, 0xD0 ); } -emitterT void FCMOVNU32( x86IntRegType from ) { FCMOV32( 0xDB, 0xD8 ); } +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" +#include "legacy_internal.h" + +//------------------------------------------------------------------ +// FPU instructions +//------------------------------------------------------------------ + +/* fild m32 to fpu reg stack */ +emitterT void FILD32( u32 from ) +{ + xWrite8( 0xDB ); + ModRM( 0, 0x0, DISP32 ); + xWrite32( MEMADDR(from, 4) ); +} + +/* fistp m32 from fpu reg stack */ +emitterT void FISTP32( u32 from ) +{ + xWrite8( 0xDB ); + ModRM( 0, 0x3, DISP32 ); + xWrite32( MEMADDR(from, 4) ); +} + +/* fld m32 to fpu reg stack */ +emitterT void FLD32( u32 from ) +{ + xWrite8( 0xD9 ); + ModRM( 0, 0x0, DISP32 ); + xWrite32( MEMADDR(from, 4) ); +} + +// fld st(i) +emitterT void FLD(int st) { xWrite16(0xc0d9+(st<<8)); } +emitterT void FLD1() { xWrite16(0xe8d9); } +emitterT void FLDL2E() { xWrite16(0xead9); } + +/* fst m32 from fpu reg stack */ +emitterT void FST32( u32 to ) +{ + xWrite8( 0xD9 ); + ModRM( 0, 0x2, DISP32 ); + xWrite32( MEMADDR(to, 4) ); +} + +/* fstp m32 from fpu reg stack */ +emitterT void FSTP32( u32 to ) +{ + xWrite8( 0xD9 ); + ModRM( 0, 0x3, DISP32 ); + xWrite32( MEMADDR(to, 4) ); +} + +// fstp st(i) +emitterT void FSTP(int st) { xWrite16(0xd8dd+(st<<8)); } + +/* fldcw fpu control word from m16 */ +emitterT void FLDCW( u32 from ) +{ + xWrite8( 0xD9 ); + ModRM( 0, 0x5, DISP32 ); + xWrite32( MEMADDR(from, 4) ); +} + +/* fnstcw fpu control word to m16 */ +emitterT void FNSTCW( u32 to ) +{ + xWrite8( 0xD9 ); + ModRM( 0, 0x7, DISP32 ); + xWrite32( MEMADDR(to, 4) ); +} + +emitterT void FNSTSWtoAX() { xWrite16(0xE0DF); } +emitterT void FXAM() { xWrite16(0xe5d9); } +emitterT void FDECSTP() { xWrite16(0xf6d9); } +emitterT void FRNDINT() { xWrite16(0xfcd9); } +emitterT void FXCH(int st) { xWrite16(0xc8d9+(st<<8)); } +emitterT void F2XM1() { xWrite16(0xf0d9); } +emitterT void FSCALE() { xWrite16(0xfdd9); } +emitterT void FPATAN(void) { xWrite16(0xf3d9); } +emitterT void FSIN(void) { xWrite16(0xfed9); } + +/* fadd ST(src) to fpu reg stack ST(0) */ +emitterT void FADD32Rto0( x86IntRegType src ) +{ + xWrite8( 0xD8 ); + xWrite8( 0xC0 + src ); +} + +/* fadd ST(0) to fpu reg stack ST(src) */ +emitterT void FADD320toR( x86IntRegType src ) +{ + xWrite8( 0xDC ); + xWrite8( 0xC0 + src ); +} + +/* fsub ST(src) to fpu reg stack ST(0) */ +emitterT void FSUB32Rto0( x86IntRegType src ) +{ + xWrite8( 0xD8 ); + xWrite8( 0xE0 + src ); +} + +/* fsub ST(0) to fpu reg stack ST(src) */ +emitterT void FSUB320toR( x86IntRegType src ) +{ + xWrite8( 0xDC ); + xWrite8( 0xE8 + src ); +} + +/* fsubp -> substract ST(0) from ST(1), store in ST(1) and POP stack */ +emitterT void FSUBP( void ) +{ + xWrite8( 0xDE ); + xWrite8( 0xE9 ); +} + +/* fmul ST(src) to fpu reg stack ST(0) */ +emitterT void FMUL32Rto0( x86IntRegType src ) +{ + xWrite8( 0xD8 ); + xWrite8( 0xC8 + src ); +} + +/* fmul ST(0) to fpu reg stack ST(src) */ +emitterT void FMUL320toR( x86IntRegType src ) +{ + xWrite8( 0xDC ); + xWrite8( 0xC8 + src ); +} + +/* fdiv ST(src) to fpu reg stack ST(0) */ +emitterT void FDIV32Rto0( x86IntRegType src ) +{ + xWrite8( 0xD8 ); + xWrite8( 0xF0 + src ); +} + +/* fdiv ST(0) to fpu reg stack ST(src) */ +emitterT void FDIV320toR( x86IntRegType src ) +{ + xWrite8( 0xDC ); + xWrite8( 0xF8 + src ); +} + +emitterT void FDIV320toRP( x86IntRegType src ) +{ + xWrite8( 0xDE ); + xWrite8( 0xF8 + src ); +} + +/* fadd m32 to fpu reg stack */ +emitterT void FADD32( u32 from ) +{ + xWrite8( 0xD8 ); + ModRM( 0, 0x0, DISP32 ); + xWrite32( MEMADDR(from, 4) ); +} + +/* fsub m32 to fpu reg stack */ +emitterT void FSUB32( u32 from ) +{ + xWrite8( 0xD8 ); + ModRM( 0, 0x4, DISP32 ); + xWrite32( MEMADDR(from, 4) ); +} + +/* fmul m32 to fpu reg stack */ +emitterT void FMUL32( u32 from ) +{ + xWrite8( 0xD8 ); + ModRM( 0, 0x1, DISP32 ); + xWrite32( MEMADDR(from, 4) ); +} + +/* fdiv m32 to fpu reg stack */ +emitterT void FDIV32( u32 from ) +{ + xWrite8( 0xD8 ); + ModRM( 0, 0x6, DISP32 ); + xWrite32( MEMADDR(from, 4) ); +} + +/* fabs fpu reg stack */ +emitterT void FABS( void ) +{ + xWrite16( 0xE1D9 ); +} + +/* fsqrt fpu reg stack */ +emitterT void FSQRT( void ) +{ + xWrite16( 0xFAD9 ); +} + +/* fchs fpu reg stack */ +emitterT void FCHS( void ) +{ + xWrite16( 0xE0D9 ); +} + +/* fcomi st, st(i) */ +emitterT void FCOMI( x86IntRegType src ) +{ + xWrite8( 0xDB ); + xWrite8( 0xF0 + src ); +} + +/* fcomip st, st(i) */ +emitterT void FCOMIP( x86IntRegType src ) +{ + xWrite8( 0xDF ); + xWrite8( 0xF0 + src ); +} + +/* fucomi st, st(i) */ +emitterT void FUCOMI( x86IntRegType src ) +{ + xWrite8( 0xDB ); + xWrite8( 0xE8 + src ); +} + +/* fucomip st, st(i) */ +emitterT void FUCOMIP( x86IntRegType src ) +{ + xWrite8( 0xDF ); + xWrite8( 0xE8 + src ); +} + +/* fcom m32 to fpu reg stack */ +emitterT void FCOM32( u32 from ) +{ + xWrite8( 0xD8 ); + ModRM( 0, 0x2, DISP32 ); + xWrite32( MEMADDR(from, 4) ); +} + +/* fcomp m32 to fpu reg stack */ +emitterT void FCOMP32( u32 from ) +{ + xWrite8( 0xD8 ); + ModRM( 0, 0x3, DISP32 ); + xWrite32( MEMADDR(from, 4) ); +} + +#define FCMOV32( low, high ) \ + { \ + xWrite8( low ); \ + xWrite8( high + from ); \ + } + +emitterT void FCMOVB32( x86IntRegType from ) { FCMOV32( 0xDA, 0xC0 ); } +emitterT void FCMOVE32( x86IntRegType from ) { FCMOV32( 0xDA, 0xC8 ); } +emitterT void FCMOVBE32( x86IntRegType from ) { FCMOV32( 0xDA, 0xD0 ); } +emitterT void FCMOVU32( x86IntRegType from ) { FCMOV32( 0xDA, 0xD8 ); } +emitterT void FCMOVNB32( x86IntRegType from ) { FCMOV32( 0xDB, 0xC0 ); } +emitterT void FCMOVNE32( x86IntRegType from ) { FCMOV32( 0xDB, 0xC8 ); } +emitterT void FCMOVNBE32( x86IntRegType from ) { FCMOV32( 0xDB, 0xD0 ); } +emitterT void FCMOVNU32( x86IntRegType from ) { FCMOV32( 0xDB, 0xD8 ); } diff --git a/pcsx2/x86/ix86/ix86_jmp.cpp b/common/src/x86emitter/jmp.cpp similarity index 70% rename from pcsx2/x86/ix86/ix86_jmp.cpp rename to common/src/x86emitter/jmp.cpp index ab5611ce9e..4255d6a864 100644 --- a/pcsx2/x86/ix86/ix86_jmp.cpp +++ b/common/src/x86emitter/jmp.cpp @@ -32,9 +32,7 @@ */ #include "PrecompiledHeader.h" - -#include "System.h" -#include "ix86_internal.h" +#include "internal.h" namespace x86Emitter { @@ -73,6 +71,34 @@ xSmartJump::~xSmartJump() m_baseptr = NULL; // just in case (sometimes helps in debugging too) } +// ------------------------------------------------------------------------ +// Emits a 32 bit jump, and returns a pointer to the 32 bit displacement. +// (displacements should be assigned relative to the end of the jump instruction, +// or in other words *(retval+1) ) +__emitinline s32* xJcc32( JccComparisonType comparison, s32 displacement ) +{ + if( comparison == Jcc_Unconditional ) + xWrite8( 0xe9 ); + else + { + xWrite8( 0x0f ); + xWrite8( 0x80 | comparison ); + } + xWrite( displacement ); + + return ((s32*)xGetPtr()) - 1; +} + +// ------------------------------------------------------------------------ +// Emits a 32 bit jump, and returns a pointer to the 8 bit displacement. +// (displacements should be assigned relative to the end of the jump instruction, +// or in other words *(retval+1) ) +__emitinline s8* xJcc8( JccComparisonType comparison, s8 displacement ) +{ + xWrite8( (comparison == Jcc_Unconditional) ? 0xeb : (0x70 | comparison) ); + xWrite( displacement ); + return (s8*)xGetPtr() - 1; +} // ------------------------------------------------------------------------ // Writes a jump at the current x86Ptr, which targets a pre-established target address. @@ -84,32 +110,26 @@ xSmartJump::~xSmartJump() __emitinline void Internal::xJccKnownTarget( JccComparisonType comparison, const void* target, bool slideForward ) { // Calculate the potential j8 displacement first, assuming an instruction length of 2: - sptr displacement8 = (sptr)target - ((sptr)xGetPtr() + 2); + sptr displacement8 = (sptr)target - (sptr)(xGetPtr() + 2); const int slideVal = slideForward ? ((comparison == Jcc_Unconditional) ? 3 : 4) : 0; displacement8 -= slideVal; // if the following assert fails it means we accidentally used slideForard on a backward // jump (which is an invalid operation since there's nothing to slide forward). - if( slideForward ) jASSUME( displacement8 >= 0 ); + if( slideForward ) + { + // jASSUME has an else statement in it that would be abiguous without the brackets. + jASSUME( displacement8 >= 0 ); + } if( is_s8( displacement8 ) ) - { - xWrite8( (comparison == Jcc_Unconditional) ? 0xeb : (0x70 | comparison) ); - xWrite( displacement8 ); - } + xJcc8( comparison, displacement8 ); else { // Perform a 32 bit jump instead. :( - - if( comparison == Jcc_Unconditional ) - xWrite8( 0xe9 ); - else - { - xWrite8( 0x0f ); - xWrite8( 0x80 | comparison ); - } - xWrite( (sptr)target - ((sptr)xGetPtr() + 4) ); + s32* bah = xJcc32( comparison ); + *bah = (s32)target - (s32)xGetPtr(); } } diff --git a/pcsx2/x86/ix86/ix86_legacy.cpp b/common/src/x86emitter/legacy.cpp similarity index 96% rename from pcsx2/x86/ix86/ix86_legacy.cpp rename to common/src/x86emitter/legacy.cpp index 8bf4bd3c4a..e0a80caaed 100644 --- a/pcsx2/x86/ix86/ix86_legacy.cpp +++ b/common/src/x86emitter/legacy.cpp @@ -1,733 +1,732 @@ -/* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2002-2009 Pcsx2 Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ -/* -* ix86 core v0.6.2 -* Authors: linuzappz -* alexey silinov -* goldfinger -* zerofrog(@gmail.com) -* cottonvibes(@gmail.com) -*/ - -//------------------------------------------------------------------ -// ix86 legacy emitter functions -//------------------------------------------------------------------ - -#include "PrecompiledHeader.h" -#include "System.h" -#include "ix86_legacy_internal.h" - -////////////////////////////////////////////////////////////////////////////////////////// -// -emitterT void ModRM( uint mod, uint reg, uint rm ) -{ - // Note: Following ASSUMEs are for legacy support only. - // The new emitter performs these sanity checks during operand construction, so these - // assertions can probably be removed once all legacy emitter code has been removed. - jASSUME( mod < 4 ); - jASSUME( reg < 8 ); - jASSUME( rm < 8 ); - xWrite8( (mod << 6) | (reg << 3) | rm ); -} - -emitterT void SibSB( uint ss, uint index, uint base ) -{ - // Note: Following ASSUMEs are for legacy support only. - // The new emitter performs these sanity checks during operand construction, so these - // assertions can probably be removed once all legacy emitter code has been removed. - jASSUME( ss < 4 ); - jASSUME( index < 8 ); - jASSUME( base < 8 ); - xWrite8( (ss << 6) | (index << 3) | base ); -} - -using namespace x86Emitter; - -template< typename ImmType > -static __forceinline xRegister _reghlp( x86IntRegType src ) -{ - return xRegister( src ); -} - -static __forceinline ModSibBase _mrmhlp( x86IntRegType src ) -{ - return ptr[_reghlp(src)]; -} - -template< typename ImmType > -static __forceinline ModSibStrict _mhlp( x86IntRegType src ) -{ - return ModSibStrict( xAddressReg::Empty, xAddressReg(src) ); -} - -template< typename ImmType > -static __forceinline ModSibStrict _mhlp2( x86IntRegType src1, x86IntRegType src2 ) -{ - return ModSibStrict( xAddressReg(src2), xAddressReg(src1) ); -} - -////////////////////////////////////////////////////////////////////////////////////////// -// -#define DEFINE_LEGACY_HELPER( cod, bits ) \ - emitterT void cod##bits##RtoR( x86IntRegType to, x86IntRegType from ) { x##cod( _reghlp(to), _reghlp(from) ); } \ - emitterT void cod##bits##ItoR( x86IntRegType to, u##bits imm ) { x##cod( _reghlp(to), imm ); } \ - emitterT void cod##bits##MtoR( x86IntRegType to, uptr from ) { x##cod( _reghlp(to), (void*)from ); } \ - emitterT void cod##bits##RtoM( uptr to, x86IntRegType from ) { x##cod( (void*)to, _reghlp(from) ); } \ - emitterT void cod##bits##ItoM( uptr to, u##bits imm ) { x##cod( ptr##bits[to], imm ); } \ - emitterT void cod##bits##ItoRm( x86IntRegType to, u##bits imm, int offset ) { x##cod( _mhlp(to) + offset, imm ); } \ - emitterT void cod##bits##RmtoR( x86IntRegType to, x86IntRegType from, int offset ) { x##cod( _reghlp(to), _mhlp(from) + offset ); } \ - emitterT void cod##bits##RtoRm( x86IntRegType to, x86IntRegType from, int offset ) { x##cod( _mhlp(to) + offset, _reghlp(from) ); } \ - emitterT void cod##bits##RtoRmS( x86IntRegType to1, x86IntRegType to2, x86IntRegType from, int offset ) \ - { x##cod( _mhlp2(to1,to2) + offset, _reghlp(from) ); } \ - emitterT void cod##bits##RmStoR( x86IntRegType to, x86IntRegType from1, x86IntRegType from2, int offset ) \ - { x##cod( _reghlp(to), _mhlp2(from1,from2) + offset ); } - -#define DEFINE_LEGACY_SHIFT_HELPER( cod, bits ) \ - emitterT void cod##bits##CLtoR( x86IntRegType to ) { x##cod( _reghlp(to), cl ); } \ - emitterT void cod##bits##ItoR( x86IntRegType to, u8 imm ) { x##cod( _reghlp(to), imm ); } \ - emitterT void cod##bits##CLtoM( uptr to ) { x##cod( ptr##bits[to], cl ); } \ - emitterT void cod##bits##ItoM( uptr to, u8 imm ) { x##cod( ptr##bits[to], imm ); } \ - emitterT void cod##bits##ItoRm( x86IntRegType to, u8 imm, int offset ) { x##cod( _mhlp(to) + offset, imm ); } \ - emitterT void cod##bits##CLtoRm( x86IntRegType to, int offset ) { x##cod( _mhlp(to) + offset, cl ); } - -#define DEFINE_LEGACY_ONEREG_HELPER( cod, bits ) \ - emitterT void cod##bits##R( x86IntRegType to ) { x##cod( _reghlp(to) ); } \ - emitterT void cod##bits##M( uptr to ) { x##cod( ptr##bits[to] ); } \ - emitterT void cod##bits##Rm( x86IntRegType to, uptr offset ) { x##cod( _mhlp(to) + offset ); } - -//emitterT void cod##bits##RtoRmS( x86IntRegType to1, x86IntRegType to2, x86IntRegType from, int offset ) \ -// { cod( _mhlp2(to1,to2) + offset, _reghlp(from) ); } \ - -#define DEFINE_OPCODE_LEGACY( cod ) \ - DEFINE_LEGACY_HELPER( cod, 32 ) \ - DEFINE_LEGACY_HELPER( cod, 16 ) \ - DEFINE_LEGACY_HELPER( cod, 8 ) - -#define DEFINE_OPCODE_SHIFT_LEGACY( cod ) \ - DEFINE_LEGACY_SHIFT_HELPER( cod, 32 ) \ - DEFINE_LEGACY_SHIFT_HELPER( cod, 16 ) \ - DEFINE_LEGACY_SHIFT_HELPER( cod, 8 ) - -#define DEFINE_OPCODE_ONEREG_LEGACY( cod ) \ - DEFINE_LEGACY_ONEREG_HELPER( cod, 32 ) \ - DEFINE_LEGACY_ONEREG_HELPER( cod, 16 ) \ - DEFINE_LEGACY_ONEREG_HELPER( cod, 8 ) - -////////////////////////////////////////////////////////////////////////////////////////// -// -DEFINE_OPCODE_LEGACY( ADD ) -DEFINE_OPCODE_LEGACY( CMP ) -DEFINE_OPCODE_LEGACY( OR ) -DEFINE_OPCODE_LEGACY( ADC ) -DEFINE_OPCODE_LEGACY( SBB ) -DEFINE_OPCODE_LEGACY( AND ) -DEFINE_OPCODE_LEGACY( SUB ) -DEFINE_OPCODE_LEGACY( XOR ) - -DEFINE_OPCODE_SHIFT_LEGACY( ROL ) -DEFINE_OPCODE_SHIFT_LEGACY( ROR ) -DEFINE_OPCODE_SHIFT_LEGACY( RCL ) -DEFINE_OPCODE_SHIFT_LEGACY( RCR ) -DEFINE_OPCODE_SHIFT_LEGACY( SHL ) -DEFINE_OPCODE_SHIFT_LEGACY( SHR ) -DEFINE_OPCODE_SHIFT_LEGACY( SAR ) - -DEFINE_OPCODE_LEGACY( MOV ) - -DEFINE_OPCODE_ONEREG_LEGACY( INC ) -DEFINE_OPCODE_ONEREG_LEGACY( DEC ) -DEFINE_OPCODE_ONEREG_LEGACY( NOT ) -DEFINE_OPCODE_ONEREG_LEGACY( NEG ) - - -// ------------------------------------------------------------------------ -#define DEFINE_LEGACY_MOVEXTEND( form, destbits, srcbits ) \ - emitterT void MOV##form##destbits##R##srcbits##toR( x86IntRegType to, x86IntRegType from ) { xMOV##form( xRegister##destbits( to ), xRegister##srcbits( from ) ); } \ - emitterT void MOV##form##destbits##Rm##srcbits##toR( x86IntRegType to, x86IntRegType from, int offset ) { xMOV##form( xRegister##destbits( to ), ptr##srcbits[xAddressReg( from ) + offset] ); } \ - emitterT void MOV##form##destbits##M##srcbits##toR( x86IntRegType to, u32 from ) { xMOV##form( xRegister##destbits( to ), ptr##srcbits[from] ); } - -DEFINE_LEGACY_MOVEXTEND( SX, 32, 16 ) -DEFINE_LEGACY_MOVEXTEND( ZX, 32, 16 ) -DEFINE_LEGACY_MOVEXTEND( SX, 32, 8 ) -DEFINE_LEGACY_MOVEXTEND( ZX, 32, 8 ) - -DEFINE_LEGACY_MOVEXTEND( SX, 16, 8 ) -DEFINE_LEGACY_MOVEXTEND( ZX, 16, 8 ) - -emitterT void TEST32ItoR( x86IntRegType to, u32 from ) { xTEST( xRegister32(to), from ); } -emitterT void TEST32ItoM( uptr to, u32 from ) { xTEST( ptr32[to], from ); } -emitterT void TEST32RtoR( x86IntRegType to, x86IntRegType from ) { xTEST( xRegister32(to), xRegister32(from) ); } -emitterT void TEST32ItoRm( x86IntRegType to, u32 from ) { xTEST( ptr32[xAddressReg(to)], from ); } - -emitterT void TEST16ItoR( x86IntRegType to, u16 from ) { xTEST( xRegister16(to), from ); } -emitterT void TEST16ItoM( uptr to, u16 from ) { xTEST( ptr16[to], from ); } -emitterT void TEST16RtoR( x86IntRegType to, x86IntRegType from ) { xTEST( xRegister16(to), xRegister16(from) ); } -emitterT void TEST16ItoRm( x86IntRegType to, u16 from ) { xTEST( ptr16[xAddressReg(to)], from ); } - -emitterT void TEST8ItoR( x86IntRegType to, u8 from ) { xTEST( xRegister8(to), from ); } -emitterT void TEST8ItoM( uptr to, u8 from ) { xTEST( ptr8[to], from ); } -emitterT void TEST8RtoR( x86IntRegType to, x86IntRegType from ) { xTEST( xRegister8(to), xRegister8(from) ); } -emitterT void TEST8ItoRm( x86IntRegType to, u8 from ) { xTEST( ptr8[xAddressReg(to)], from ); } - -// mov r32 to [r32<(to), from ); -} - -emitterT void AND32I8toM( uptr to, s8 from ) -{ - xAND( ptr8[to], from ); -} - -/* cmove r32 to r32*/ -emitterT void CMOVE32RtoR( x86IntRegType to, x86IntRegType from ) -{ - xCMOVE( xRegister32(to), xRegister32(from) ); -} - -// shld imm8 to r32 -emitterT void SHLD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift ) -{ - xSHLD( xRegister32(to), xRegister32(from), shift ); -} - -// shrd imm8 to r32 -emitterT void SHRD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift ) -{ - xSHRD( xRegister32(to), xRegister32(from), shift ); -} - -/* mul eax by r32 to edx:eax */ -emitterT void MUL32R( x86IntRegType from ) { xUMUL( xRegister32(from) ); } -/* imul eax by r32 to edx:eax */ -emitterT void IMUL32R( x86IntRegType from ) { xMUL( xRegister32(from) ); } -/* mul eax by m32 to edx:eax */ -emitterT void MUL32M( u32 from ) { xUMUL( ptr32[from] ); } -/* imul eax by m32 to edx:eax */ -emitterT void IMUL32M( u32 from ) { xMUL( ptr32[from] ); } - -/* imul r32 by r32 to r32 */ -emitterT void IMUL32RtoR( x86IntRegType to, x86IntRegType from ) -{ - xMUL( xRegister32(to), xRegister32(from) ); -} - -/* div eax by r32 to edx:eax */ -emitterT void DIV32R( x86IntRegType from ) { xUDIV( xRegister32(from) ); } -/* idiv eax by r32 to edx:eax */ -emitterT void IDIV32R( x86IntRegType from ) { xDIV( xRegister32(from) ); } -/* div eax by m32 to edx:eax */ -emitterT void DIV32M( u32 from ) { xUDIV( ptr32[from] ); } -/* idiv eax by m32 to edx:eax */ -emitterT void IDIV32M( u32 from ) { xDIV( ptr32[from] ); } - - -emitterT void LEA32RtoR(x86IntRegType to, x86IntRegType from, s32 offset) -{ - xLEA( xRegister32( to ), ptr[xAddressReg(from)+offset] ); -} - -emitterT void LEA32RRtoR(x86IntRegType to, x86IntRegType from0, x86IntRegType from1) -{ - xLEA( xRegister32( to ), ptr[xAddressReg(from0)+xAddressReg(from1)] ); -} - -// Don't inline recursive functions -emitterT void LEA32RStoR(x86IntRegType to, x86IntRegType from, u32 scale) -{ - xLEA( xRegister32( to ), ptr[xAddressReg(from)*(1< 0x7f ) { - Console::Error( "j8 greater than 0x7f!!" ); - assert(0); - } - *j8 = (u8)jump; -} - -void x86SetJ8A( u8* j8 ) -{ - u32 jump = ( x86Ptr - j8 ) - 1; - - if ( jump > 0x7f ) { - Console::Error( "j8 greater than 0x7f!!" ); - assert(0); - } - - if( ((uptr)x86Ptr&0xf) > 4 ) { - - uptr newjump = jump + 16-((uptr)x86Ptr&0xf); - - if( newjump <= 0x7f ) { - jump = newjump; - while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90; - } - } - *j8 = (u8)jump; -} - -//////////////////////////////////////////////////// -emitterT void x86SetJ32( u32* j32 ) -{ - *j32 = ( x86Ptr - (u8*)j32 ) - 4; -} - -emitterT void x86SetJ32A( u32* j32 ) -{ - while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90; - x86SetJ32(j32); -} - -//////////////////////////////////////////////////// -emitterT void x86Align( int bytes ) -{ - // forward align - x86Ptr = (u8*)( ( (uptr)x86Ptr + bytes - 1) & ~( bytes - 1 ) ); -} - -/********************/ -/* IX86 instructions */ -/********************/ - -emitterT void STC( void ) { xSTC(); } -emitterT void CLC( void ) { xCLC(); } -emitterT void NOP( void ) { xNOP(); } - -//////////////////////////////////// -// jump instructions / -//////////////////////////////////// - -/* jmp rel8 */ -emitterT u8* JMP8( u8 to ) -{ - xWrite8( 0xEB ); - xWrite8( to ); - return x86Ptr - 1; -} - -/* jmp rel32 */ -emitterT u32* JMP32( uptr to ) -{ - assert( (sptr)to <= 0x7fffffff && (sptr)to >= -0x7fffffff ); - xWrite8( 0xE9 ); - xWrite32( to ); - return (u32*)(x86Ptr - 4 ); -} - -/* jmp r32/r64 */ -emitterT void JMPR( x86IntRegType to ) -{ - xJMP( xRegister32(to) ); -} - -// jmp m32 -emitterT void JMP32M( uptr to ) -{ - xJMP( ptr32[to] ); -} - -/* jp rel8 */ -emitterT u8* JP8( u8 to ) { - return J8Rel( 0x7A, to ); -} - -/* jnp rel8 */ -emitterT u8* JNP8( u8 to ) { - return J8Rel( 0x7B, to ); -} - -/* je rel8 */ -emitterT u8* JE8( u8 to ) { - return J8Rel( 0x74, to ); -} - -/* jz rel8 */ -emitterT u8* JZ8( u8 to ) -{ - return J8Rel( 0x74, to ); -} - -/* js rel8 */ -emitterT u8* JS8( u8 to ) -{ - return J8Rel( 0x78, to ); -} - -/* jns rel8 */ -emitterT u8* JNS8( u8 to ) -{ - return J8Rel( 0x79, to ); -} - -/* jg rel8 */ -emitterT u8* JG8( u8 to ) -{ - return J8Rel( 0x7F, to ); -} - -/* jge rel8 */ -emitterT u8* JGE8( u8 to ) -{ - return J8Rel( 0x7D, to ); -} - -/* jl rel8 */ -emitterT u8* JL8( u8 to ) -{ - return J8Rel( 0x7C, to ); -} - -/* ja rel8 */ -emitterT u8* JA8( u8 to ) -{ - return J8Rel( 0x77, to ); -} - -emitterT u8* JAE8( u8 to ) -{ - return J8Rel( 0x73, to ); -} - -/* jb rel8 */ -emitterT u8* JB8( u8 to ) -{ - return J8Rel( 0x72, to ); -} - -/* jbe rel8 */ -emitterT u8* JBE8( u8 to ) -{ - return J8Rel( 0x76, to ); -} - -/* jle rel8 */ -emitterT u8* JLE8( u8 to ) -{ - return J8Rel( 0x7E, to ); -} - -/* jne rel8 */ -emitterT u8* JNE8( u8 to ) -{ - return J8Rel( 0x75, to ); -} - -/* jnz rel8 */ -emitterT u8* JNZ8( u8 to ) -{ - return J8Rel( 0x75, to ); -} - -/* jng rel8 */ -emitterT u8* JNG8( u8 to ) -{ - return J8Rel( 0x7E, to ); -} - -/* jnge rel8 */ -emitterT u8* JNGE8( u8 to ) -{ - return J8Rel( 0x7C, to ); -} - -/* jnl rel8 */ -emitterT u8* JNL8( u8 to ) -{ - return J8Rel( 0x7D, to ); -} - -/* jnle rel8 */ -emitterT u8* JNLE8( u8 to ) -{ - return J8Rel( 0x7F, to ); -} - -/* jo rel8 */ -emitterT u8* JO8( u8 to ) -{ - return J8Rel( 0x70, to ); -} - -/* jno rel8 */ -emitterT u8* JNO8( u8 to ) -{ - return J8Rel( 0x71, to ); -} -// jb rel32 -emitterT u32* JB32( u32 to ) -{ - return J32Rel( 0x82, to ); -} - -/* je rel32 */ -emitterT u32* JE32( u32 to ) -{ - return J32Rel( 0x84, to ); -} - -/* jz rel32 */ -emitterT u32* JZ32( u32 to ) -{ - return J32Rel( 0x84, to ); -} - -/* js rel32 */ -emitterT u32* JS32( u32 to ) -{ - return J32Rel( 0x88, to ); -} - -/* jns rel32 */ -emitterT u32* JNS32( u32 to ) -{ - return J32Rel( 0x89, to ); -} - -/* jg rel32 */ -emitterT u32* JG32( u32 to ) -{ - return J32Rel( 0x8F, to ); -} - -/* jge rel32 */ -emitterT u32* JGE32( u32 to ) -{ - return J32Rel( 0x8D, to ); -} - -/* jl rel32 */ -emitterT u32* JL32( u32 to ) -{ - return J32Rel( 0x8C, to ); -} - -/* jle rel32 */ -emitterT u32* JLE32( u32 to ) -{ - return J32Rel( 0x8E, to ); -} - -/* ja rel32 */ -emitterT u32* JA32( u32 to ) -{ - return J32Rel( 0x87, to ); -} - -/* jae rel32 */ -emitterT u32* JAE32( u32 to ) -{ - return J32Rel( 0x83, to ); -} - -/* jne rel32 */ -emitterT u32* JNE32( u32 to ) -{ - return J32Rel( 0x85, to ); -} - -/* jnz rel32 */ -emitterT u32* JNZ32( u32 to ) -{ - return J32Rel( 0x85, to ); -} - -/* jng rel32 */ -emitterT u32* JNG32( u32 to ) -{ - return J32Rel( 0x8E, to ); -} - -/* jnge rel32 */ -emitterT u32* JNGE32( u32 to ) -{ - return J32Rel( 0x8C, to ); -} - -/* jnl rel32 */ -emitterT u32* JNL32( u32 to ) -{ - return J32Rel( 0x8D, to ); -} - -/* jnle rel32 */ -emitterT u32* JNLE32( u32 to ) -{ - return J32Rel( 0x8F, to ); -} - -/* jo rel32 */ -emitterT u32* JO32( u32 to ) -{ - return J32Rel( 0x80, to ); -} - -/* jno rel32 */ -emitterT u32* JNO32( u32 to ) -{ - return J32Rel( 0x81, to ); -} - - - -/* call func */ -emitterT void CALLFunc( uptr func ) -{ - xCALL( (void*)func ); -} - -/* call r32 */ -emitterT void CALL32R( x86IntRegType to ) -{ - xCALL( xRegister32( to ) ); -} - -/* call m32 */ -emitterT void CALL32M( u32 to ) -{ - xCALL( ptr32[to] ); -} - -emitterT void BSRRtoR(x86IntRegType to, x86IntRegType from) -{ - xBSR( xRegister32(to), xRegister32(from) ); -} - -emitterT void BSWAP32R( x86IntRegType to ) -{ - xBSWAP( xRegister32(to) ); -} +/* Pcsx2 - Pc Ps2 Emulator +* Copyright (C) 2002-2009 Pcsx2 Team +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ +/* +* ix86 core v0.6.2 +* Authors: linuzappz +* alexey silinov +* goldfinger +* zerofrog(@gmail.com) +* cottonvibes(@gmail.com) +*/ + +//------------------------------------------------------------------ +// ix86 legacy emitter functions +//------------------------------------------------------------------ + +#include "PrecompiledHeader.h" +#include "legacy_internal.h" + +////////////////////////////////////////////////////////////////////////////////////////// +// +emitterT void ModRM( uint mod, uint reg, uint rm ) +{ + // Note: Following ASSUMEs are for legacy support only. + // The new emitter performs these sanity checks during operand construction, so these + // assertions can probably be removed once all legacy emitter code has been removed. + jASSUME( mod < 4 ); + jASSUME( reg < 8 ); + jASSUME( rm < 8 ); + xWrite8( (mod << 6) | (reg << 3) | rm ); +} + +emitterT void SibSB( uint ss, uint index, uint base ) +{ + // Note: Following ASSUMEs are for legacy support only. + // The new emitter performs these sanity checks during operand construction, so these + // assertions can probably be removed once all legacy emitter code has been removed. + jASSUME( ss < 4 ); + jASSUME( index < 8 ); + jASSUME( base < 8 ); + xWrite8( (ss << 6) | (index << 3) | base ); +} + +using namespace x86Emitter; + +template< typename ImmType > +static __forceinline xRegister _reghlp( x86IntRegType src ) +{ + return xRegister( src ); +} + +static __forceinline ModSibBase _mrmhlp( x86IntRegType src ) +{ + return ptr[_reghlp(src)]; +} + +template< typename ImmType > +static __forceinline ModSibStrict _mhlp( x86IntRegType src ) +{ + return ModSibStrict( xAddressReg::Empty, xAddressReg(src) ); +} + +template< typename ImmType > +static __forceinline ModSibStrict _mhlp2( x86IntRegType src1, x86IntRegType src2 ) +{ + return ModSibStrict( xAddressReg(src2), xAddressReg(src1) ); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +#define DEFINE_LEGACY_HELPER( cod, bits ) \ + emitterT void cod##bits##RtoR( x86IntRegType to, x86IntRegType from ) { x##cod( _reghlp(to), _reghlp(from) ); } \ + emitterT void cod##bits##ItoR( x86IntRegType to, u##bits imm ) { x##cod( _reghlp(to), imm ); } \ + emitterT void cod##bits##MtoR( x86IntRegType to, uptr from ) { x##cod( _reghlp(to), (void*)from ); } \ + emitterT void cod##bits##RtoM( uptr to, x86IntRegType from ) { x##cod( (void*)to, _reghlp(from) ); } \ + emitterT void cod##bits##ItoM( uptr to, u##bits imm ) { x##cod( ptr##bits[to], imm ); } \ + emitterT void cod##bits##ItoRm( x86IntRegType to, u##bits imm, int offset ) { x##cod( _mhlp(to) + offset, imm ); } \ + emitterT void cod##bits##RmtoR( x86IntRegType to, x86IntRegType from, int offset ) { x##cod( _reghlp(to), _mhlp(from) + offset ); } \ + emitterT void cod##bits##RtoRm( x86IntRegType to, x86IntRegType from, int offset ) { x##cod( _mhlp(to) + offset, _reghlp(from) ); } \ + emitterT void cod##bits##RtoRmS( x86IntRegType to1, x86IntRegType to2, x86IntRegType from, int offset ) \ + { x##cod( _mhlp2(to1,to2) + offset, _reghlp(from) ); } \ + emitterT void cod##bits##RmStoR( x86IntRegType to, x86IntRegType from1, x86IntRegType from2, int offset ) \ + { x##cod( _reghlp(to), _mhlp2(from1,from2) + offset ); } + +#define DEFINE_LEGACY_SHIFT_HELPER( cod, bits ) \ + emitterT void cod##bits##CLtoR( x86IntRegType to ) { x##cod( _reghlp(to), cl ); } \ + emitterT void cod##bits##ItoR( x86IntRegType to, u8 imm ) { x##cod( _reghlp(to), imm ); } \ + emitterT void cod##bits##CLtoM( uptr to ) { x##cod( ptr##bits[to], cl ); } \ + emitterT void cod##bits##ItoM( uptr to, u8 imm ) { x##cod( ptr##bits[to], imm ); } \ + emitterT void cod##bits##ItoRm( x86IntRegType to, u8 imm, int offset ) { x##cod( _mhlp(to) + offset, imm ); } \ + emitterT void cod##bits##CLtoRm( x86IntRegType to, int offset ) { x##cod( _mhlp(to) + offset, cl ); } + +#define DEFINE_LEGACY_ONEREG_HELPER( cod, bits ) \ + emitterT void cod##bits##R( x86IntRegType to ) { x##cod( _reghlp(to) ); } \ + emitterT void cod##bits##M( uptr to ) { x##cod( ptr##bits[to] ); } \ + emitterT void cod##bits##Rm( x86IntRegType to, uptr offset ) { x##cod( _mhlp(to) + offset ); } + +//emitterT void cod##bits##RtoRmS( x86IntRegType to1, x86IntRegType to2, x86IntRegType from, int offset ) \ +// { cod( _mhlp2(to1,to2) + offset, _reghlp(from) ); } \ + +#define DEFINE_OPCODE_LEGACY( cod ) \ + DEFINE_LEGACY_HELPER( cod, 32 ) \ + DEFINE_LEGACY_HELPER( cod, 16 ) \ + DEFINE_LEGACY_HELPER( cod, 8 ) + +#define DEFINE_OPCODE_SHIFT_LEGACY( cod ) \ + DEFINE_LEGACY_SHIFT_HELPER( cod, 32 ) \ + DEFINE_LEGACY_SHIFT_HELPER( cod, 16 ) \ + DEFINE_LEGACY_SHIFT_HELPER( cod, 8 ) + +#define DEFINE_OPCODE_ONEREG_LEGACY( cod ) \ + DEFINE_LEGACY_ONEREG_HELPER( cod, 32 ) \ + DEFINE_LEGACY_ONEREG_HELPER( cod, 16 ) \ + DEFINE_LEGACY_ONEREG_HELPER( cod, 8 ) + +////////////////////////////////////////////////////////////////////////////////////////// +// +DEFINE_OPCODE_LEGACY( ADD ) +DEFINE_OPCODE_LEGACY( CMP ) +DEFINE_OPCODE_LEGACY( OR ) +DEFINE_OPCODE_LEGACY( ADC ) +DEFINE_OPCODE_LEGACY( SBB ) +DEFINE_OPCODE_LEGACY( AND ) +DEFINE_OPCODE_LEGACY( SUB ) +DEFINE_OPCODE_LEGACY( XOR ) + +DEFINE_OPCODE_SHIFT_LEGACY( ROL ) +DEFINE_OPCODE_SHIFT_LEGACY( ROR ) +DEFINE_OPCODE_SHIFT_LEGACY( RCL ) +DEFINE_OPCODE_SHIFT_LEGACY( RCR ) +DEFINE_OPCODE_SHIFT_LEGACY( SHL ) +DEFINE_OPCODE_SHIFT_LEGACY( SHR ) +DEFINE_OPCODE_SHIFT_LEGACY( SAR ) + +DEFINE_OPCODE_LEGACY( MOV ) + +DEFINE_OPCODE_ONEREG_LEGACY( INC ) +DEFINE_OPCODE_ONEREG_LEGACY( DEC ) +DEFINE_OPCODE_ONEREG_LEGACY( NOT ) +DEFINE_OPCODE_ONEREG_LEGACY( NEG ) + + +// ------------------------------------------------------------------------ +#define DEFINE_LEGACY_MOVEXTEND( form, destbits, srcbits ) \ + emitterT void MOV##form##destbits##R##srcbits##toR( x86IntRegType to, x86IntRegType from ) { xMOV##form( xRegister##destbits( to ), xRegister##srcbits( from ) ); } \ + emitterT void MOV##form##destbits##Rm##srcbits##toR( x86IntRegType to, x86IntRegType from, int offset ) { xMOV##form( xRegister##destbits( to ), ptr##srcbits[xAddressReg( from ) + offset] ); } \ + emitterT void MOV##form##destbits##M##srcbits##toR( x86IntRegType to, u32 from ) { xMOV##form( xRegister##destbits( to ), ptr##srcbits[from] ); } + +DEFINE_LEGACY_MOVEXTEND( SX, 32, 16 ) +DEFINE_LEGACY_MOVEXTEND( ZX, 32, 16 ) +DEFINE_LEGACY_MOVEXTEND( SX, 32, 8 ) +DEFINE_LEGACY_MOVEXTEND( ZX, 32, 8 ) + +DEFINE_LEGACY_MOVEXTEND( SX, 16, 8 ) +DEFINE_LEGACY_MOVEXTEND( ZX, 16, 8 ) + +emitterT void TEST32ItoR( x86IntRegType to, u32 from ) { xTEST( xRegister32(to), from ); } +emitterT void TEST32ItoM( uptr to, u32 from ) { xTEST( ptr32[to], from ); } +emitterT void TEST32RtoR( x86IntRegType to, x86IntRegType from ) { xTEST( xRegister32(to), xRegister32(from) ); } +emitterT void TEST32ItoRm( x86IntRegType to, u32 from ) { xTEST( ptr32[xAddressReg(to)], from ); } + +emitterT void TEST16ItoR( x86IntRegType to, u16 from ) { xTEST( xRegister16(to), from ); } +emitterT void TEST16ItoM( uptr to, u16 from ) { xTEST( ptr16[to], from ); } +emitterT void TEST16RtoR( x86IntRegType to, x86IntRegType from ) { xTEST( xRegister16(to), xRegister16(from) ); } +emitterT void TEST16ItoRm( x86IntRegType to, u16 from ) { xTEST( ptr16[xAddressReg(to)], from ); } + +emitterT void TEST8ItoR( x86IntRegType to, u8 from ) { xTEST( xRegister8(to), from ); } +emitterT void TEST8ItoM( uptr to, u8 from ) { xTEST( ptr8[to], from ); } +emitterT void TEST8RtoR( x86IntRegType to, x86IntRegType from ) { xTEST( xRegister8(to), xRegister8(from) ); } +emitterT void TEST8ItoRm( x86IntRegType to, u8 from ) { xTEST( ptr8[xAddressReg(to)], from ); } + +// mov r32 to [r32<(to), from ); +} + +emitterT void AND32I8toM( uptr to, s8 from ) +{ + xAND( ptr8[to], from ); +} + +/* cmove r32 to r32*/ +emitterT void CMOVE32RtoR( x86IntRegType to, x86IntRegType from ) +{ + xCMOVE( xRegister32(to), xRegister32(from) ); +} + +// shld imm8 to r32 +emitterT void SHLD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift ) +{ + xSHLD( xRegister32(to), xRegister32(from), shift ); +} + +// shrd imm8 to r32 +emitterT void SHRD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift ) +{ + xSHRD( xRegister32(to), xRegister32(from), shift ); +} + +/* mul eax by r32 to edx:eax */ +emitterT void MUL32R( x86IntRegType from ) { xUMUL( xRegister32(from) ); } +/* imul eax by r32 to edx:eax */ +emitterT void IMUL32R( x86IntRegType from ) { xMUL( xRegister32(from) ); } +/* mul eax by m32 to edx:eax */ +emitterT void MUL32M( u32 from ) { xUMUL( ptr32[from] ); } +/* imul eax by m32 to edx:eax */ +emitterT void IMUL32M( u32 from ) { xMUL( ptr32[from] ); } + +/* imul r32 by r32 to r32 */ +emitterT void IMUL32RtoR( x86IntRegType to, x86IntRegType from ) +{ + xMUL( xRegister32(to), xRegister32(from) ); +} + +/* div eax by r32 to edx:eax */ +emitterT void DIV32R( x86IntRegType from ) { xUDIV( xRegister32(from) ); } +/* idiv eax by r32 to edx:eax */ +emitterT void IDIV32R( x86IntRegType from ) { xDIV( xRegister32(from) ); } +/* div eax by m32 to edx:eax */ +emitterT void DIV32M( u32 from ) { xUDIV( ptr32[from] ); } +/* idiv eax by m32 to edx:eax */ +emitterT void IDIV32M( u32 from ) { xDIV( ptr32[from] ); } + + +emitterT void LEA32RtoR(x86IntRegType to, x86IntRegType from, s32 offset) +{ + xLEA( xRegister32( to ), ptr[xAddressReg(from)+offset] ); +} + +emitterT void LEA32RRtoR(x86IntRegType to, x86IntRegType from0, x86IntRegType from1) +{ + xLEA( xRegister32( to ), ptr[xAddressReg(from0)+xAddressReg(from1)] ); +} + +// Don't inline recursive functions +emitterT void LEA32RStoR(x86IntRegType to, x86IntRegType from, u32 scale) +{ + xLEA( xRegister32( to ), ptr[xAddressReg(from)*(1< 0x7f ) { + Console::Error( "j8 greater than 0x7f!!" ); + assert(0); + } + *j8 = (u8)jump; +} + +void x86SetJ8A( u8* j8 ) +{ + u32 jump = ( x86Ptr - j8 ) - 1; + + if ( jump > 0x7f ) { + Console::Error( "j8 greater than 0x7f!!" ); + assert(0); + } + + if( ((uptr)x86Ptr&0xf) > 4 ) { + + uptr newjump = jump + 16-((uptr)x86Ptr&0xf); + + if( newjump <= 0x7f ) { + jump = newjump; + while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90; + } + } + *j8 = (u8)jump; +} + +//////////////////////////////////////////////////// +emitterT void x86SetJ32( u32* j32 ) +{ + *j32 = ( x86Ptr - (u8*)j32 ) - 4; +} + +emitterT void x86SetJ32A( u32* j32 ) +{ + while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90; + x86SetJ32(j32); +} + +//////////////////////////////////////////////////// +emitterT void x86Align( int bytes ) +{ + // forward align + x86Ptr = (u8*)( ( (uptr)x86Ptr + bytes - 1) & ~( bytes - 1 ) ); +} + +/********************/ +/* IX86 instructions */ +/********************/ + +emitterT void STC( void ) { xSTC(); } +emitterT void CLC( void ) { xCLC(); } +emitterT void NOP( void ) { xNOP(); } + +//////////////////////////////////// +// jump instructions / +//////////////////////////////////// + +/* jmp rel8 */ +emitterT u8* JMP8( u8 to ) +{ + xWrite8( 0xEB ); + xWrite8( to ); + return x86Ptr - 1; +} + +/* jmp rel32 */ +emitterT u32* JMP32( uptr to ) +{ + assert( (sptr)to <= 0x7fffffff && (sptr)to >= -0x7fffffff ); + xWrite8( 0xE9 ); + xWrite32( to ); + return (u32*)(x86Ptr - 4 ); +} + +/* jmp r32/r64 */ +emitterT void JMPR( x86IntRegType to ) +{ + xJMP( xRegister32(to) ); +} + +// jmp m32 +emitterT void JMP32M( uptr to ) +{ + xJMP( ptr32[to] ); +} + +/* jp rel8 */ +emitterT u8* JP8( u8 to ) { + return J8Rel( 0x7A, to ); +} + +/* jnp rel8 */ +emitterT u8* JNP8( u8 to ) { + return J8Rel( 0x7B, to ); +} + +/* je rel8 */ +emitterT u8* JE8( u8 to ) { + return J8Rel( 0x74, to ); +} + +/* jz rel8 */ +emitterT u8* JZ8( u8 to ) +{ + return J8Rel( 0x74, to ); +} + +/* js rel8 */ +emitterT u8* JS8( u8 to ) +{ + return J8Rel( 0x78, to ); +} + +/* jns rel8 */ +emitterT u8* JNS8( u8 to ) +{ + return J8Rel( 0x79, to ); +} + +/* jg rel8 */ +emitterT u8* JG8( u8 to ) +{ + return J8Rel( 0x7F, to ); +} + +/* jge rel8 */ +emitterT u8* JGE8( u8 to ) +{ + return J8Rel( 0x7D, to ); +} + +/* jl rel8 */ +emitterT u8* JL8( u8 to ) +{ + return J8Rel( 0x7C, to ); +} + +/* ja rel8 */ +emitterT u8* JA8( u8 to ) +{ + return J8Rel( 0x77, to ); +} + +emitterT u8* JAE8( u8 to ) +{ + return J8Rel( 0x73, to ); +} + +/* jb rel8 */ +emitterT u8* JB8( u8 to ) +{ + return J8Rel( 0x72, to ); +} + +/* jbe rel8 */ +emitterT u8* JBE8( u8 to ) +{ + return J8Rel( 0x76, to ); +} + +/* jle rel8 */ +emitterT u8* JLE8( u8 to ) +{ + return J8Rel( 0x7E, to ); +} + +/* jne rel8 */ +emitterT u8* JNE8( u8 to ) +{ + return J8Rel( 0x75, to ); +} + +/* jnz rel8 */ +emitterT u8* JNZ8( u8 to ) +{ + return J8Rel( 0x75, to ); +} + +/* jng rel8 */ +emitterT u8* JNG8( u8 to ) +{ + return J8Rel( 0x7E, to ); +} + +/* jnge rel8 */ +emitterT u8* JNGE8( u8 to ) +{ + return J8Rel( 0x7C, to ); +} + +/* jnl rel8 */ +emitterT u8* JNL8( u8 to ) +{ + return J8Rel( 0x7D, to ); +} + +/* jnle rel8 */ +emitterT u8* JNLE8( u8 to ) +{ + return J8Rel( 0x7F, to ); +} + +/* jo rel8 */ +emitterT u8* JO8( u8 to ) +{ + return J8Rel( 0x70, to ); +} + +/* jno rel8 */ +emitterT u8* JNO8( u8 to ) +{ + return J8Rel( 0x71, to ); +} +// jb rel32 +emitterT u32* JB32( u32 to ) +{ + return J32Rel( 0x82, to ); +} + +/* je rel32 */ +emitterT u32* JE32( u32 to ) +{ + return J32Rel( 0x84, to ); +} + +/* jz rel32 */ +emitterT u32* JZ32( u32 to ) +{ + return J32Rel( 0x84, to ); +} + +/* js rel32 */ +emitterT u32* JS32( u32 to ) +{ + return J32Rel( 0x88, to ); +} + +/* jns rel32 */ +emitterT u32* JNS32( u32 to ) +{ + return J32Rel( 0x89, to ); +} + +/* jg rel32 */ +emitterT u32* JG32( u32 to ) +{ + return J32Rel( 0x8F, to ); +} + +/* jge rel32 */ +emitterT u32* JGE32( u32 to ) +{ + return J32Rel( 0x8D, to ); +} + +/* jl rel32 */ +emitterT u32* JL32( u32 to ) +{ + return J32Rel( 0x8C, to ); +} + +/* jle rel32 */ +emitterT u32* JLE32( u32 to ) +{ + return J32Rel( 0x8E, to ); +} + +/* ja rel32 */ +emitterT u32* JA32( u32 to ) +{ + return J32Rel( 0x87, to ); +} + +/* jae rel32 */ +emitterT u32* JAE32( u32 to ) +{ + return J32Rel( 0x83, to ); +} + +/* jne rel32 */ +emitterT u32* JNE32( u32 to ) +{ + return J32Rel( 0x85, to ); +} + +/* jnz rel32 */ +emitterT u32* JNZ32( u32 to ) +{ + return J32Rel( 0x85, to ); +} + +/* jng rel32 */ +emitterT u32* JNG32( u32 to ) +{ + return J32Rel( 0x8E, to ); +} + +/* jnge rel32 */ +emitterT u32* JNGE32( u32 to ) +{ + return J32Rel( 0x8C, to ); +} + +/* jnl rel32 */ +emitterT u32* JNL32( u32 to ) +{ + return J32Rel( 0x8D, to ); +} + +/* jnle rel32 */ +emitterT u32* JNLE32( u32 to ) +{ + return J32Rel( 0x8F, to ); +} + +/* jo rel32 */ +emitterT u32* JO32( u32 to ) +{ + return J32Rel( 0x80, to ); +} + +/* jno rel32 */ +emitterT u32* JNO32( u32 to ) +{ + return J32Rel( 0x81, to ); +} + + + +/* call func */ +emitterT void CALLFunc( uptr func ) +{ + xCALL( (void*)func ); +} + +/* call r32 */ +emitterT void CALL32R( x86IntRegType to ) +{ + xCALL( xRegister32( to ) ); +} + +/* call m32 */ +emitterT void CALL32M( u32 to ) +{ + xCALL( ptr32[to] ); +} + +emitterT void BSRRtoR(x86IntRegType to, x86IntRegType from) +{ + xBSR( xRegister32(to), xRegister32(from) ); +} + +emitterT void BSWAP32R( x86IntRegType to ) +{ + xBSWAP( xRegister32(to) ); +} diff --git a/pcsx2/x86/ix86/ix86_legacy_sse.cpp b/common/src/x86emitter/legacy_sse.cpp similarity index 98% rename from pcsx2/x86/ix86/ix86_legacy_sse.cpp rename to common/src/x86emitter/legacy_sse.cpp index 169f6ac100..716da65fed 100644 --- a/pcsx2/x86/ix86/ix86_legacy_sse.cpp +++ b/common/src/x86emitter/legacy_sse.cpp @@ -1,533 +1,534 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "PrecompiledHeader.h" -#include "ix86_legacy_internal.h" -#include "ix86_sse_helpers.h" - -using namespace x86Emitter; - -// ------------------------------------------------------------------------ -// MMX / SSE Mixed Bag -// ------------------------------------------------------------------------ - -emitterT void MOVQMtoR( x86MMXRegType to, uptr from ) { xMOVQ( xRegisterMMX(to), (void*)from ); } -emitterT void MOVQRtoM( uptr to, x86MMXRegType from ) { xMOVQ( (void*)to, xRegisterMMX(from) ); } -emitterT void MOVQRtoR( x86MMXRegType to, x86MMXRegType from ) { xMOVQ( xRegisterMMX(to), xRegisterMMX(from) ); } -emitterT void MOVQRmtoR( x86MMXRegType to, x86IntRegType from, int offset ) { xMOVQ( xRegisterMMX(to), ptr[xAddressReg(from)+offset] ); } -emitterT void MOVQRtoRm( x86IntRegType to, x86MMXRegType from, int offset ) { xMOVQ( ptr[xAddressReg(to)+offset], xRegisterMMX(from) ); } - -emitterT void MOVDMtoMMX( x86MMXRegType to, uptr from ) { xMOVDZX( xRegisterMMX(to), (void*)from ); } -emitterT void MOVDMMXtoM( uptr to, x86MMXRegType from ) { xMOVD( (void*)to, xRegisterMMX(from) ); } -emitterT void MOVD32RtoMMX( x86MMXRegType to, x86IntRegType from ) { xMOVDZX( xRegisterMMX(to), xRegister32(from) ); } -emitterT void MOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from, int offset ) { xMOVDZX( xRegisterMMX(to), ptr[xAddressReg(from)+offset] ); } -emitterT void MOVD32MMXtoR( x86IntRegType to, x86MMXRegType from ) { xMOVD( xRegister32(to), xRegisterMMX(from) ); } -emitterT void MOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from, int offset ) { xMOVD( ptr[xAddressReg(to)+offset], xRegisterMMX(from) ); } - -emitterT void PMOVMSKBMMXtoR(x86IntRegType to, x86MMXRegType from) { xPMOVMSKB( xRegister32(to), xRegisterMMX(from) ); } -emitterT void MASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from) { xMASKMOV( xRegisterMMX(to), xRegisterMMX(from) ); } - -#define DEFINE_LEGACY_LOGIC_OPCODE( mod ) \ - emitterT void P##mod##RtoR( x86MMXRegType to, x86MMXRegType from ) { xP##mod( xRegisterMMX(to), xRegisterMMX(from) ); } \ - emitterT void P##mod##MtoR( x86MMXRegType to, uptr from ) { xP##mod( xRegisterMMX(to), (void*)from ); } \ - emitterT void SSE2_P##mod##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xP##mod( xRegisterSSE(to), xRegisterSSE(from) ); } \ - emitterT void SSE2_P##mod##_M128_to_XMM( x86SSERegType to, uptr from ) { xP##mod( xRegisterSSE(to), (void*)from ); } - -#define DEFINE_LEGACY_ARITHMETIC( mod, sub ) \ - emitterT void P##mod##sub##RtoR( x86MMXRegType to, x86MMXRegType from ) { xP##mod.sub( xRegisterMMX(to), xRegisterMMX(from) ); } \ - emitterT void P##mod##sub##MtoR( x86MMXRegType to, uptr from ) { xP##mod.sub( xRegisterMMX(to), (void*)from ); } \ - emitterT void SSE2_P##mod##sub##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xP##mod.sub( xRegisterSSE(to), xRegisterSSE(from) ); } \ - emitterT void SSE2_P##mod##sub##_M128_to_XMM( x86SSERegType to, uptr from ) { xP##mod.sub( xRegisterSSE(to), (void*)from ); } - -#define DEFINE_LEGACY_SHIFT_STUFF( mod, sub ) \ - emitterT void P##mod##sub##RtoR( x86MMXRegType to, x86MMXRegType from ) { xP##mod.sub( xRegisterMMX(to), xRegisterMMX(from) ); } \ - emitterT void P##mod##sub##MtoR( x86MMXRegType to, uptr from ) { xP##mod.sub( xRegisterMMX(to), (void*)from ); } \ - emitterT void P##mod##sub##ItoR( x86MMXRegType to, u8 imm ) { xP##mod.sub( xRegisterMMX(to), imm ); } \ - emitterT void SSE2_P##mod##sub##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xP##mod.sub( xRegisterSSE(to), xRegisterSSE(from) ); } \ - emitterT void SSE2_P##mod##sub##_M128_to_XMM( x86SSERegType to, uptr from ) { xP##mod.sub( xRegisterSSE(to), (void*)from ); } \ - emitterT void SSE2_P##mod##sub##_I8_to_XMM( x86SSERegType to, u8 imm ) { xP##mod.sub( xRegisterSSE(to), imm ); } - -#define DEFINE_LEGACY_SHIFT_OPCODE( mod ) \ - DEFINE_LEGACY_SHIFT_STUFF( mod, Q ) \ - DEFINE_LEGACY_SHIFT_STUFF( mod, D ) \ - DEFINE_LEGACY_SHIFT_STUFF( mod, W ) \ - emitterT void SSE2_P##mod##DQ_I8_to_XMM( x86MMXRegType to, u8 imm ) { xP##mod.DQ( xRegisterSSE(to), imm ); } - -DEFINE_LEGACY_LOGIC_OPCODE( AND ) -DEFINE_LEGACY_LOGIC_OPCODE( ANDN ) -DEFINE_LEGACY_LOGIC_OPCODE( OR ) -DEFINE_LEGACY_LOGIC_OPCODE( XOR ) - -DEFINE_LEGACY_SHIFT_OPCODE( SLL ) -DEFINE_LEGACY_SHIFT_OPCODE( SRL ) -DEFINE_LEGACY_SHIFT_STUFF( SRA, D ) -DEFINE_LEGACY_SHIFT_STUFF( SRA, W ) - -DEFINE_LEGACY_ARITHMETIC( ADD, B ) -DEFINE_LEGACY_ARITHMETIC( ADD, W ) -DEFINE_LEGACY_ARITHMETIC( ADD, D ) -DEFINE_LEGACY_ARITHMETIC( ADD, Q ) -DEFINE_LEGACY_ARITHMETIC( ADD, SB ) -DEFINE_LEGACY_ARITHMETIC( ADD, SW ) -DEFINE_LEGACY_ARITHMETIC( ADD, USB ) -DEFINE_LEGACY_ARITHMETIC( ADD, USW ) - -DEFINE_LEGACY_ARITHMETIC( SUB, B ) -DEFINE_LEGACY_ARITHMETIC( SUB, W ) -DEFINE_LEGACY_ARITHMETIC( SUB, D ) -DEFINE_LEGACY_ARITHMETIC( SUB, Q ) -DEFINE_LEGACY_ARITHMETIC( SUB, SB ) -DEFINE_LEGACY_ARITHMETIC( SUB, SW ) -DEFINE_LEGACY_ARITHMETIC( SUB, USB ) -DEFINE_LEGACY_ARITHMETIC( SUB, USW ) - -DEFINE_LEGACY_ARITHMETIC( CMP, EQB ); -DEFINE_LEGACY_ARITHMETIC( CMP, EQW ); -DEFINE_LEGACY_ARITHMETIC( CMP, EQD ); -DEFINE_LEGACY_ARITHMETIC( CMP, GTB ); -DEFINE_LEGACY_ARITHMETIC( CMP, GTW ); -DEFINE_LEGACY_ARITHMETIC( CMP, GTD ); - -DEFINE_LEGACY_ARITHMETIC( UNPCK, HDQ ); -DEFINE_LEGACY_ARITHMETIC( UNPCK, LDQ ); -DEFINE_LEGACY_ARITHMETIC( UNPCK, HBW ); -DEFINE_LEGACY_ARITHMETIC( UNPCK, LBW ); - -DEFINE_LEGACY_ARITHMETIC( UNPCK, LWD ); -DEFINE_LEGACY_ARITHMETIC( UNPCK, HWD ); - - -emitterT void PMULUDQMtoR( x86MMXRegType to, uptr from ) { xPMUL.UDQ( xRegisterMMX( to ), (void*)from ); } -emitterT void PMULUDQRtoR( x86MMXRegType to, x86MMXRegType from ) { xPMUL.UDQ( xRegisterMMX( to ), xRegisterMMX( from ) ); } - -emitterT void PSHUFWRtoR(x86MMXRegType to, x86MMXRegType from, u8 imm8) { xPSHUF.W( xRegisterMMX(to), xRegisterMMX(from), imm8 ); } -emitterT void PSHUFWMtoR(x86MMXRegType to, uptr from, u8 imm8) { xPSHUF.W( xRegisterMMX(to), (void*)from, imm8 ); } - -emitterT void PINSRWRtoMMX( x86MMXRegType to, x86SSERegType from, u8 imm8 ) { xPINSR.W( xRegisterMMX(to), xRegister32(from), imm8 ); } - -emitterT void EMMS() { xEMMS(); } - -// ------------------------------------------------------------------------ -// Begin SSE-Only Part! -// ------------------------------------------------------------------------ - -#define DEFINE_LEGACY_MOV_OPCODE( mod, sse ) \ - emitterT void sse##_MOV##mod##_M128_to_XMM( x86SSERegType to, uptr from ) { xMOV##mod( xRegisterSSE(to), (void*)from ); } \ - emitterT void sse##_MOV##mod##_XMM_to_M128( uptr to, x86SSERegType from ) { xMOV##mod( (void*)to, xRegisterSSE(from) ); } \ - emitterT void sse##_MOV##mod##RmtoR( x86SSERegType to, x86IntRegType from, int offset ) { xMOV##mod( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); } \ - emitterT void sse##_MOV##mod##RtoRm( x86IntRegType to, x86SSERegType from, int offset ) { xMOV##mod( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); } \ - emitterT void sse##_MOV##mod##RmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ) \ - { xMOV##mod( xRegisterSSE(to), ptr[xAddressReg(from)+xAddressReg(from2)] ); } \ - emitterT void sse##_MOV##mod##RtoRmS( x86IntRegType to, x86SSERegType from, x86IntRegType from2, int scale ) \ - { xMOV##mod( ptr[xAddressReg(to)+xAddressReg(from2)], xRegisterSSE(from) ); } - -#define DEFINE_LEGACY_PSD_OPCODE( mod ) \ - emitterT void SSE_##mod##PS_M128_to_XMM( x86SSERegType to, uptr from ) { x##mod.PS( xRegisterSSE(to), (void*)from ); } \ - emitterT void SSE_##mod##PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.PS( xRegisterSSE(to), xRegisterSSE(from) ); } \ - emitterT void SSE2_##mod##PD_M128_to_XMM( x86SSERegType to, uptr from ) { x##mod.PD( xRegisterSSE(to), (void*)from ); } \ - emitterT void SSE2_##mod##PD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.PD( xRegisterSSE(to), xRegisterSSE(from) ); } - -#define DEFINE_LEGACY_SSSD_OPCODE( mod ) \ - emitterT void SSE_##mod##SS_M32_to_XMM( x86SSERegType to, uptr from ) { x##mod.SS( xRegisterSSE(to), (void*)from ); } \ - emitterT void SSE_##mod##SS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.SS( xRegisterSSE(to), xRegisterSSE(from) ); } \ - emitterT void SSE2_##mod##SD_M64_to_XMM( x86SSERegType to, uptr from ) { x##mod.SD( xRegisterSSE(to), (void*)from ); } \ - emitterT void SSE2_##mod##SD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.SD( xRegisterSSE(to), xRegisterSSE(from) ); } - -#define DEFINE_LEGACY_CMP_OPCODE( comp ) \ - emitterT void SSE_CMP##comp##PS_M128_to_XMM( x86SSERegType to, uptr from ) { xCMP##comp.PS( xRegisterSSE(to), (void*)from ); } \ - emitterT void SSE_CMP##comp##PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCMP##comp.PS( xRegisterSSE(to), xRegisterSSE(from) ); } \ - emitterT void SSE2_CMP##comp##PD_M128_to_XMM( x86SSERegType to, uptr from ) { xCMP##comp.PD( xRegisterSSE(to), (void*)from ); } \ - emitterT void SSE2_CMP##comp##PD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCMP##comp.PD( xRegisterSSE(to), xRegisterSSE(from) ); } \ - emitterT void SSE_CMP##comp##SS_M32_to_XMM( x86SSERegType to, uptr from ) { xCMP##comp.SS( xRegisterSSE(to), (void*)from ); } \ - emitterT void SSE_CMP##comp##SS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCMP##comp.SS( xRegisterSSE(to), xRegisterSSE(from) ); } \ - emitterT void SSE2_CMP##comp##SD_M64_to_XMM( x86SSERegType to, uptr from ) { xCMP##comp.SD( xRegisterSSE(to), (void*)from ); } \ - emitterT void SSE2_CMP##comp##SD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCMP##comp.SD( xRegisterSSE(to), xRegisterSSE(from) ); } - -#define DEFINE_LEGACY_RSQRT_OPCODE(mod) \ - emitterT void SSE_##mod##PS_M128_to_XMM( x86SSERegType to, uptr from ) { x##mod.PS( xRegisterSSE(to), (void*)from ); } \ - emitterT void SSE_##mod##PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.PS( xRegisterSSE(to), xRegisterSSE(from) ); } \ - emitterT void SSE_##mod##SS_M32_to_XMM( x86SSERegType to, uptr from ) { x##mod.SS( xRegisterSSE(to), (void*)from ); } \ - emitterT void SSE_##mod##SS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.SS( xRegisterSSE(to), xRegisterSSE(from) ); } - -#define DEFINE_LEGACY_SQRT_OPCODE(mod) \ - DEFINE_LEGACY_RSQRT_OPCODE(mod) \ - emitterT void SSE2_##mod##SD_M64_to_XMM( x86SSERegType to, uptr from ) { x##mod.SD( xRegisterSSE(to), (void*)from ); } \ - emitterT void SSE2_##mod##SD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.SD( xRegisterSSE(to), xRegisterSSE(from) ); } - -#define DEFINE_LEGACY_OP128( ssenum, mod, sub ) \ - emitterT void SSE##ssenum##_##mod##sub##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.sub( xRegisterSSE(to), xRegisterSSE(from) ); } \ - emitterT void SSE##ssenum##_##mod##sub##_M128_to_XMM( x86SSERegType to, uptr from ) { x##mod.sub( xRegisterSSE(to), (void*)from ); } - -#define DEFINE_LEGACY_MOV128( ssenum, mod, sub ) \ - emitterT void SSE##ssenum##_##mod##sub##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod##sub( xRegisterSSE(to), xRegisterSSE(from) ); } \ - emitterT void SSE##ssenum##_##mod##sub##_M128_to_XMM( x86SSERegType to, uptr from ) { x##mod##sub( xRegisterSSE(to), (void*)from ); } - - -#define DEFINE_LEGACY_PSSD_OPCODE( mod ) \ - DEFINE_LEGACY_PSD_OPCODE( mod ) \ - DEFINE_LEGACY_SSSD_OPCODE( mod ) - -DEFINE_LEGACY_MOV_OPCODE( UPS, SSE ) -DEFINE_LEGACY_MOV_OPCODE( APS, SSE ) -DEFINE_LEGACY_MOV_OPCODE( DQA, SSE2 ) -DEFINE_LEGACY_MOV_OPCODE( DQU, SSE2 ) - -DEFINE_LEGACY_PSD_OPCODE( AND ) -DEFINE_LEGACY_PSD_OPCODE( ANDN ) -DEFINE_LEGACY_PSD_OPCODE( OR ) -DEFINE_LEGACY_PSD_OPCODE( XOR ) - -DEFINE_LEGACY_PSSD_OPCODE( SUB ) -DEFINE_LEGACY_PSSD_OPCODE( ADD ) -DEFINE_LEGACY_PSSD_OPCODE( MUL ) -DEFINE_LEGACY_PSSD_OPCODE( DIV ) - -DEFINE_LEGACY_PSSD_OPCODE( MIN ) -DEFINE_LEGACY_PSSD_OPCODE( MAX ) - -DEFINE_LEGACY_CMP_OPCODE( EQ ) -DEFINE_LEGACY_CMP_OPCODE( LT ) -DEFINE_LEGACY_CMP_OPCODE( LE ) -DEFINE_LEGACY_CMP_OPCODE( UNORD ) -DEFINE_LEGACY_CMP_OPCODE( NE ) -DEFINE_LEGACY_CMP_OPCODE( NLT ) -DEFINE_LEGACY_CMP_OPCODE( NLE ) -DEFINE_LEGACY_CMP_OPCODE( ORD ) - -DEFINE_LEGACY_SSSD_OPCODE( UCOMI ) -DEFINE_LEGACY_RSQRT_OPCODE( RCP ) -DEFINE_LEGACY_RSQRT_OPCODE( RSQRT ) -DEFINE_LEGACY_SQRT_OPCODE( SQRT ) - -DEFINE_LEGACY_OP128( 2, PMUL, LW ) -DEFINE_LEGACY_OP128( 2, PMUL, HW ) -DEFINE_LEGACY_OP128( 2, PMUL, UDQ ) - -DEFINE_LEGACY_OP128( 2, PMAX, SW ) -DEFINE_LEGACY_OP128( 2, PMAX, UB ) -DEFINE_LEGACY_OP128( 2, PMIN, SW ) -DEFINE_LEGACY_OP128( 2, PMIN, UB ) - -DEFINE_LEGACY_OP128( 2, UNPCK, LPS ) -DEFINE_LEGACY_OP128( 2, UNPCK, HPS ) -DEFINE_LEGACY_OP128( 2, PUNPCK, LQDQ ) -DEFINE_LEGACY_OP128( 2, PUNPCK, HQDQ ) - -DEFINE_LEGACY_OP128( 2, PACK, SSWB ) -DEFINE_LEGACY_OP128( 2, PACK, SSDW ) -DEFINE_LEGACY_OP128( 2, PACK, USWB ) - -DEFINE_LEGACY_MOV128( 3, MOV, SLDUP ) -DEFINE_LEGACY_MOV128( 3, MOV, SHDUP ) - -DEFINE_LEGACY_OP128( 4, PMAX, SD ) -DEFINE_LEGACY_OP128( 4, PMIN, SD ) -DEFINE_LEGACY_OP128( 4, PMAX, UD ) -DEFINE_LEGACY_OP128( 4, PMIN, UD ) - - -emitterT void SSE_MOVAPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVAPS( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSE2_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { xMOVDQA( xRegisterSSE(to), xRegisterSSE(from) ); } - -emitterT void SSE2_MOVD_M32_to_XMM( x86SSERegType to, uptr from ) { xMOVDZX( xRegisterSSE(to), (void*)from ); } -emitterT void SSE2_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from ) { xMOVDZX( xRegisterSSE(to), xRegister32(from) ); } -emitterT void SSE2_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) -{ - xMOVDZX( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); -} - -emitterT void SSE2_MOVD_XMM_to_M32( u32 to, x86SSERegType from ) { xMOVD( (void*)to, xRegisterSSE(from) ); } -emitterT void SSE2_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from ) { xMOVD( xRegister32(to), xRegisterSSE(from) ); } -emitterT void SSE2_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) -{ - xMOVD( ptr[xAddressReg(from)+offset], xRegisterSSE(from) ); -} - -emitterT void SSE2_MOVQ_M64_to_XMM( x86SSERegType to, uptr from ) { xMOVQZX( xRegisterSSE(to), (void*)from ); } -emitterT void SSE2_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVQZX( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSE2_MOVQ_XMM_to_M64( u32 to, x86SSERegType from ) { xMOVQ( (void*)to, xRegisterSSE(from) ); } -emitterT void SSE2_MOVDQ2Q_XMM_to_MM( x86MMXRegType to, x86SSERegType from) { xMOVQ( xRegisterMMX(to), xRegisterSSE(from) ); } -emitterT void SSE2_MOVQ2DQ_MM_to_XMM( x86SSERegType to, x86MMXRegType from) { xMOVQ( xRegisterSSE(to), xRegisterMMX(from) ); } - - -emitterT void SSE_MOVSS_M32_to_XMM( x86SSERegType to, uptr from ) { xMOVSSZX( xRegisterSSE(to), (void*)from ); } -emitterT void SSE_MOVSS_XMM_to_M32( u32 to, x86SSERegType from ) { xMOVSS( (void*)to, xRegisterSSE(from) ); } -emitterT void SSE_MOVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVSS( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSE_MOVSS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVSSZX( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); } -emitterT void SSE_MOVSS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVSS( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); } - -emitterT void SSE2_MOVSD_M32_to_XMM( x86SSERegType to, uptr from ) { xMOVSDZX( xRegisterSSE(to), (void*)from ); } -emitterT void SSE2_MOVSD_XMM_to_M32( u32 to, x86SSERegType from ) { xMOVSD( (void*)to, xRegisterSSE(from) ); } -emitterT void SSE2_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVSD( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSE2_MOVSD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVSDZX( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); } -emitterT void SSE2_MOVSD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVSD( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); } - -emitterT void SSE_MOVLPS_M64_to_XMM( x86SSERegType to, uptr from ) { xMOVL.PS( xRegisterSSE(to), (void*)from ); } -emitterT void SSE_MOVLPS_XMM_to_M64( u32 to, x86SSERegType from ) { xMOVL.PS( (void*)to, xRegisterSSE(from) ); } -emitterT void SSE_MOVLPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVL.PS( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); } -emitterT void SSE_MOVLPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVL.PS( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); } - -emitterT void SSE_MOVHPS_M64_to_XMM( x86SSERegType to, uptr from ) { xMOVH.PS( xRegisterSSE(to), (void*)from ); } -emitterT void SSE_MOVHPS_XMM_to_M64( u32 to, x86SSERegType from ) { xMOVH.PS( (void*)to, xRegisterSSE(from) ); } -emitterT void SSE_MOVHPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVH.PS( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); } -emitterT void SSE_MOVHPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVH.PS( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); } - -emitterT void SSE_MOVLHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVLH.PS( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSE_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVHL.PS( xRegisterSSE(to), xRegisterSSE(from) ); } - -emitterT void SSE_MASKMOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMASKMOV( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSE2_PMOVMSKB_XMM_to_R32(x86IntRegType to, x86SSERegType from) { xPMOVMSKB( xRegister32(to), xRegisterSSE(from) ); } - -emitterT void SSE_SHUFPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { xSHUF.PS( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } -emitterT void SSE_SHUFPS_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { xSHUF.PS( xRegisterSSE(to), (void*)from, imm8 ); } -emitterT void SSE_SHUFPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset, u8 imm8 ) -{ - xSHUF.PS( xRegisterSSE(to), ptr[xAddressReg(from)+offset], imm8 ); -} - -emitterT void SSE_SHUFPD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { xSHUF.PD( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } -emitterT void SSE_SHUFPD_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { xSHUF.PD( xRegisterSSE(to), (void*)from, imm8 ); } - -emitterT void SSE_CVTPI2PS_M64_to_XMM( x86SSERegType to, uptr from ) { xCVTPI2PS( xRegisterSSE(to), (u64*)from ); } -emitterT void SSE_CVTPI2PS_MM_to_XMM( x86SSERegType to, x86MMXRegType from ) { xCVTPI2PS( xRegisterSSE(to), xRegisterMMX(from) ); } -emitterT void SSE_CVTPS2PI_M64_to_MM( x86MMXRegType to, uptr from ) { xCVTPS2PI( xRegisterMMX(to), (u64*)from ); } -emitterT void SSE_CVTPS2PI_XMM_to_MM( x86MMXRegType to, x86SSERegType from ) { xCVTPS2PI( xRegisterMMX(to), xRegisterSSE(from) ); } -emitterT void SSE_CVTTSS2SI_M32_to_R32(x86IntRegType to, uptr from) { xCVTTSS2SI( xRegister32(to), (u32*)from ); } -emitterT void SSE_CVTTSS2SI_XMM_to_R32(x86IntRegType to, x86SSERegType from) { xCVTTSS2SI( xRegister32(to), xRegisterSSE(from) ); } -emitterT void SSE_CVTSI2SS_M32_to_XMM(x86SSERegType to, uptr from) { xCVTSI2SS( xRegisterSSE(to), (u32*)from ); } -emitterT void SSE_CVTSI2SS_R_to_XMM(x86SSERegType to, x86IntRegType from) { xCVTSI2SS( xRegisterSSE(to), xRegister32(from) ); } - -emitterT void SSE2_CVTSS2SD_M32_to_XMM( x86SSERegType to, uptr from) { xCVTSS2SD( xRegisterSSE(to), (u32*)from ); } -emitterT void SSE2_CVTSS2SD_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { xCVTSS2SD( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSE2_CVTSD2SS_M64_to_XMM( x86SSERegType to, uptr from) { xCVTSD2SS( xRegisterSSE(to), (u64*)from ); } -emitterT void SSE2_CVTSD2SS_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { xCVTSD2SS( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSE2_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from ) { xCVTDQ2PS( xRegisterSSE(to), (u128*)from ); } -emitterT void SSE2_CVTDQ2PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCVTDQ2PS( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSE2_CVTPS2DQ_M128_to_XMM( x86SSERegType to, uptr from ) { xCVTPS2DQ( xRegisterSSE(to), (u128*)from ); } -emitterT void SSE2_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCVTPS2DQ( xRegisterSSE(to), xRegisterSSE(from) ); } - -emitterT void SSE2_CVTTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCVTTPS2DQ( xRegisterSSE(to), xRegisterSSE(from) ); } - -emitterT void SSE_PMAXSW_MM_to_MM( x86MMXRegType to, x86MMXRegType from ) { xPMAX.SW( xRegisterMMX(to), xRegisterMMX(from) ); } -emitterT void SSE_PMINSW_MM_to_MM( x86MMXRegType to, x86MMXRegType from ) { xPMAX.SW( xRegisterMMX(to), xRegisterMMX(from) ); } - -emitterT void SSE2_PSHUFD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { xPSHUF.D( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } -emitterT void SSE2_PSHUFD_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { xPSHUF.D( xRegisterSSE(to), (void*)from, imm8 ); } -emitterT void SSE2_PSHUFLW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { xPSHUF.LW( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } -emitterT void SSE2_PSHUFLW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { xPSHUF.LW( xRegisterSSE(to), (void*)from, imm8 ); } -emitterT void SSE2_PSHUFHW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { xPSHUF.HW( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } -emitterT void SSE2_PSHUFHW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { xPSHUF.HW( xRegisterSSE(to), (void*)from, imm8 ); } - -emitterT void SSE4_PMULDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPMUL.DQ( xRegisterSSE(to), xRegisterSSE(from) ); } - -emitterT void SSE_UNPCKLPS_M128_to_XMM( x86SSERegType to, uptr from ) { xUNPCK.LPS( xRegisterSSE(to), (void*)from ); } -emitterT void SSE_UNPCKLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xUNPCK.LPS( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSE_UNPCKHPS_M128_to_XMM( x86SSERegType to, uptr from ) { xUNPCK.HPS( xRegisterSSE(to), (void*)from ); } -emitterT void SSE_UNPCKHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xUNPCK.HPS( xRegisterSSE(to), xRegisterSSE(from) ); } - -emitterT void SSE_MOVMSKPS_XMM_to_R32(x86IntRegType to, x86SSERegType from) { xMOVMSKPS( xRegister32(to), xRegisterSSE(from) ); } -emitterT void SSE2_MOVMSKPD_XMM_to_R32(x86IntRegType to, x86SSERegType from) { xMOVMSKPD( xRegister32(to), xRegisterSSE(from) ); } - -emitterT void SSSE3_PABSB_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPABS.B( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSSE3_PABSW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPABS.W( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSSE3_PABSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPABS.D( xRegisterSSE(to), xRegisterSSE(from) ); } - -emitterT void SSSE3_PSIGNB_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPSIGN.B( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSSE3_PSIGNW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPSIGN.W( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSSE3_PSIGND_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPSIGN.D( xRegisterSSE(to), xRegisterSSE(from) ); } - -emitterT void SSE_PEXTRW_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8 ) { xPEXTR.W( xRegister32(to), xRegisterSSE(from), imm8 ); } -emitterT void SSE_PINSRW_R32_to_XMM(x86SSERegType to, x86IntRegType from, u8 imm8 ) { xPINSR.W( xRegisterSSE(to), xRegister32(from), imm8 ); } - -emitterT void SSE2_PMADDWD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPMADD.WD( xRegisterSSE(to), xRegisterSSE(from) ); } - -emitterT void SSE3_HADDPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xHADD.PS( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSE3_HADDPS_M128_to_XMM(x86SSERegType to, uptr from) { xHADD.PS( xRegisterSSE(to), (void*)from ); } - -emitterT void SSE4_PINSRD_R32_to_XMM(x86SSERegType to, x86IntRegType from, u8 imm8) { xPINSR.D( xRegisterSSE(to), xRegister32(from), imm8 ); } - -emitterT void SSE4_INSERTPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8) { xINSERTPS( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } -emitterT void SSE4_EXTRACTPS_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8) { xEXTRACTPS( xRegister32(to), xRegisterSSE(from), imm8 ); } - -emitterT void SSE4_DPPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8) { xDP.PS( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } -emitterT void SSE4_DPPS_M128_to_XMM(x86SSERegType to, uptr from, u8 imm8) { xDP.PS( xRegisterSSE(to), (void*)from, imm8 ); } - -emitterT void SSE4_BLENDPS_XMM_to_XMM(x86IntRegType to, x86SSERegType from, u8 imm8) { xBLEND.PS( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } -emitterT void SSE4_BLENDVPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xBLEND.VPS( xRegisterSSE(to), xRegisterSSE(from) ); } -emitterT void SSE4_BLENDVPS_M128_to_XMM(x86SSERegType to, uptr from) { xBLEND.VPS( xRegisterSSE(to), (void*)from ); } - -emitterT void SSE4_PMOVSXDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPMOVSX.DQ( xRegisterSSE(to), xRegisterSSE(from) ); } - -emitterT void SSE_LDMXCSR( uptr from ) { xLDMXCSR( (u32*)from ); } - - -////////////////////////////////////////////////////////////////////////////////////////// -// SSE-X Helpers (generates either INT or FLOAT versions of certain SSE instructions) -// -// Added AlwaysUseMovaps check to the relevant functions here, which helps reduce the -// overhead of dynarec instructions that use these, even thought the same check would -// have been done redundantly by the emitter function. - -emitterT void SSEX_MOVDQA_M128_to_XMM( x86SSERegType to, uptr from ) -{ - if( !AlwaysUseMovaps && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQA_M128_to_XMM(to, from); - else SSE_MOVAPS_M128_to_XMM(to, from); -} - -emitterT void SSEX_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from ) -{ - if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQA_XMM_to_M128(to, from); - else SSE_MOVAPS_XMM_to_M128(to, from); -} - -emitterT void SSEX_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) -{ - if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQA_XMM_to_XMM(to, from); - else SSE_MOVAPS_XMM_to_XMM(to, from); -} - -emitterT void SSEX_MOVDQARmtoR( x86SSERegType to, x86IntRegType from, int offset ) -{ - if( !AlwaysUseMovaps && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQARmtoR(to, from, offset); - else SSE_MOVAPSRmtoR(to, from, offset); -} - -emitterT void SSEX_MOVDQARtoRm( x86IntRegType to, x86SSERegType from, int offset ) -{ - if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQARtoRm(to, from, offset); - else SSE_MOVAPSRtoRm(to, from, offset); -} - -emitterT void SSEX_MOVDQU_M128_to_XMM( x86SSERegType to, uptr from ) -{ - if( !AlwaysUseMovaps && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQU_M128_to_XMM(to, from); - else SSE_MOVUPS_M128_to_XMM(to, from); -} - -emitterT void SSEX_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from ) -{ - if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQU_XMM_to_M128(to, from); - else SSE_MOVUPS_XMM_to_M128(to, from); -} - -emitterT void SSEX_MOVD_M32_to_XMM( x86SSERegType to, uptr from ) -{ - if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVD_M32_to_XMM(to, from); - else SSE_MOVSS_M32_to_XMM(to, from); -} - -emitterT void SSEX_MOVD_XMM_to_M32( u32 to, x86SSERegType from ) -{ - if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_M32(to, from); - else SSE_MOVSS_XMM_to_M32(to, from); -} - -emitterT void SSEX_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) -{ - if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVD_Rm_to_XMM(to, from, offset); - else SSE_MOVSS_Rm_to_XMM(to, from, offset); -} - -emitterT void SSEX_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) -{ - if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_Rm(to, from, offset); - else SSE_MOVSS_XMM_to_Rm(to, from, offset); -} - -emitterT void SSEX_POR_M128_to_XMM( x86SSERegType to, uptr from ) -{ - if( g_xmmtypes[to] == XMMT_INT ) SSE2_POR_M128_to_XMM(to, from); - else SSE_ORPS_M128_to_XMM(to, from); -} - -emitterT void SSEX_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) -{ - if( g_xmmtypes[from] == XMMT_INT ) SSE2_POR_XMM_to_XMM(to, from); - else SSE_ORPS_XMM_to_XMM(to, from); -} - -emitterT void SSEX_PXOR_M128_to_XMM( x86SSERegType to, uptr from ) -{ - if( g_xmmtypes[to] == XMMT_INT ) SSE2_PXOR_M128_to_XMM(to, from); - else SSE_XORPS_M128_to_XMM(to, from); -} - -emitterT void SSEX_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) -{ - if( g_xmmtypes[from] == XMMT_INT ) SSE2_PXOR_XMM_to_XMM(to, from); - else SSE_XORPS_XMM_to_XMM(to, from); -} - -emitterT void SSEX_PAND_M128_to_XMM( x86SSERegType to, uptr from ) -{ - if( g_xmmtypes[to] == XMMT_INT ) SSE2_PAND_M128_to_XMM(to, from); - else SSE_ANDPS_M128_to_XMM(to, from); -} - -emitterT void SSEX_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) -{ - if( g_xmmtypes[from] == XMMT_INT ) SSE2_PAND_XMM_to_XMM(to, from); - else SSE_ANDPS_XMM_to_XMM(to, from); -} - -emitterT void SSEX_PANDN_M128_to_XMM( x86SSERegType to, uptr from ) -{ - if( g_xmmtypes[to] == XMMT_INT ) SSE2_PANDN_M128_to_XMM(to, from); - else SSE_ANDNPS_M128_to_XMM(to, from); -} - -emitterT void SSEX_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) -{ - if( g_xmmtypes[from] == XMMT_INT ) SSE2_PANDN_XMM_to_XMM(to, from); - else SSE_ANDNPS_XMM_to_XMM(to, from); -} - -emitterT void SSEX_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from) -{ - if( g_xmmtypes[to] == XMMT_INT ) SSE2_PUNPCKLDQ_M128_to_XMM(to, from); - else SSE_UNPCKLPS_M128_to_XMM(to, from); -} - -emitterT void SSEX_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) -{ - if( g_xmmtypes[from] == XMMT_INT ) SSE2_PUNPCKLDQ_XMM_to_XMM(to, from); - else SSE_UNPCKLPS_XMM_to_XMM(to, from); -} - -emitterT void SSEX_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from) -{ - if( g_xmmtypes[to] == XMMT_INT ) SSE2_PUNPCKHDQ_M128_to_XMM(to, from); - else SSE_UNPCKHPS_M128_to_XMM(to, from); -} - -emitterT void SSEX_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) -{ - if( g_xmmtypes[from] == XMMT_INT ) SSE2_PUNPCKHDQ_XMM_to_XMM(to, from); - else SSE_UNPCKHPS_XMM_to_XMM(to, from); -} - -emitterT void SSEX_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) -{ - if( g_xmmtypes[from] == XMMT_INT ) { - SSE2_PUNPCKHQDQ_XMM_to_XMM(to, from); - if( to != from ) SSE2_PSHUFD_XMM_to_XMM(to, to, 0x4e); - } - else { - SSE_MOVHLPS_XMM_to_XMM(to, from); - } -} +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" +#include "legacy_internal.h" +#include "sse_helpers.h" + +using namespace x86Emitter; + +// ------------------------------------------------------------------------ +// MMX / SSE Mixed Bag +// ------------------------------------------------------------------------ + +emitterT void MOVQMtoR( x86MMXRegType to, uptr from ) { xMOVQ( xRegisterMMX(to), (void*)from ); } +emitterT void MOVQRtoM( uptr to, x86MMXRegType from ) { xMOVQ( (void*)to, xRegisterMMX(from) ); } +emitterT void MOVQRtoR( x86MMXRegType to, x86MMXRegType from ) { xMOVQ( xRegisterMMX(to), xRegisterMMX(from) ); } +emitterT void MOVQRmtoR( x86MMXRegType to, x86IntRegType from, int offset ) { xMOVQ( xRegisterMMX(to), ptr[xAddressReg(from)+offset] ); } +emitterT void MOVQRtoRm( x86IntRegType to, x86MMXRegType from, int offset ) { xMOVQ( ptr[xAddressReg(to)+offset], xRegisterMMX(from) ); } + +emitterT void MOVDMtoMMX( x86MMXRegType to, uptr from ) { xMOVDZX( xRegisterMMX(to), (void*)from ); } +emitterT void MOVDMMXtoM( uptr to, x86MMXRegType from ) { xMOVD( (void*)to, xRegisterMMX(from) ); } +emitterT void MOVD32RtoMMX( x86MMXRegType to, x86IntRegType from ) { xMOVDZX( xRegisterMMX(to), xRegister32(from) ); } +emitterT void MOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from, int offset ) { xMOVDZX( xRegisterMMX(to), ptr[xAddressReg(from)+offset] ); } +emitterT void MOVD32MMXtoR( x86IntRegType to, x86MMXRegType from ) { xMOVD( xRegister32(to), xRegisterMMX(from) ); } +emitterT void MOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from, int offset ) { xMOVD( ptr[xAddressReg(to)+offset], xRegisterMMX(from) ); } + +emitterT void PMOVMSKBMMXtoR(x86IntRegType to, x86MMXRegType from) { xPMOVMSKB( xRegister32(to), xRegisterMMX(from) ); } +emitterT void MASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from) { xMASKMOV( xRegisterMMX(to), xRegisterMMX(from) ); } + +#define DEFINE_LEGACY_LOGIC_OPCODE( mod ) \ + emitterT void P##mod##RtoR( x86MMXRegType to, x86MMXRegType from ) { xP##mod( xRegisterMMX(to), xRegisterMMX(from) ); } \ + emitterT void P##mod##MtoR( x86MMXRegType to, uptr from ) { xP##mod( xRegisterMMX(to), (void*)from ); } \ + emitterT void SSE2_P##mod##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xP##mod( xRegisterSSE(to), xRegisterSSE(from) ); } \ + emitterT void SSE2_P##mod##_M128_to_XMM( x86SSERegType to, uptr from ) { xP##mod( xRegisterSSE(to), (void*)from ); } + +#define DEFINE_LEGACY_ARITHMETIC( mod, sub ) \ + emitterT void P##mod##sub##RtoR( x86MMXRegType to, x86MMXRegType from ) { xP##mod.sub( xRegisterMMX(to), xRegisterMMX(from) ); } \ + emitterT void P##mod##sub##MtoR( x86MMXRegType to, uptr from ) { xP##mod.sub( xRegisterMMX(to), (void*)from ); } \ + emitterT void SSE2_P##mod##sub##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xP##mod.sub( xRegisterSSE(to), xRegisterSSE(from) ); } \ + emitterT void SSE2_P##mod##sub##_M128_to_XMM( x86SSERegType to, uptr from ) { xP##mod.sub( xRegisterSSE(to), (void*)from ); } + +#define DEFINE_LEGACY_SHIFT_STUFF( mod, sub ) \ + emitterT void P##mod##sub##RtoR( x86MMXRegType to, x86MMXRegType from ) { xP##mod.sub( xRegisterMMX(to), xRegisterMMX(from) ); } \ + emitterT void P##mod##sub##MtoR( x86MMXRegType to, uptr from ) { xP##mod.sub( xRegisterMMX(to), (void*)from ); } \ + emitterT void P##mod##sub##ItoR( x86MMXRegType to, u8 imm ) { xP##mod.sub( xRegisterMMX(to), imm ); } \ + emitterT void SSE2_P##mod##sub##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xP##mod.sub( xRegisterSSE(to), xRegisterSSE(from) ); } \ + emitterT void SSE2_P##mod##sub##_M128_to_XMM( x86SSERegType to, uptr from ) { xP##mod.sub( xRegisterSSE(to), (void*)from ); } \ + emitterT void SSE2_P##mod##sub##_I8_to_XMM( x86SSERegType to, u8 imm ) { xP##mod.sub( xRegisterSSE(to), imm ); } + +#define DEFINE_LEGACY_SHIFT_OPCODE( mod ) \ + DEFINE_LEGACY_SHIFT_STUFF( mod, Q ) \ + DEFINE_LEGACY_SHIFT_STUFF( mod, D ) \ + DEFINE_LEGACY_SHIFT_STUFF( mod, W ) \ + emitterT void SSE2_P##mod##DQ_I8_to_XMM( x86MMXRegType to, u8 imm ) { xP##mod.DQ( xRegisterSSE(to), imm ); } + +DEFINE_LEGACY_LOGIC_OPCODE( AND ) +DEFINE_LEGACY_LOGIC_OPCODE( ANDN ) +DEFINE_LEGACY_LOGIC_OPCODE( OR ) +DEFINE_LEGACY_LOGIC_OPCODE( XOR ) + +DEFINE_LEGACY_SHIFT_OPCODE( SLL ) +DEFINE_LEGACY_SHIFT_OPCODE( SRL ) +DEFINE_LEGACY_SHIFT_STUFF( SRA, D ) +DEFINE_LEGACY_SHIFT_STUFF( SRA, W ) + +DEFINE_LEGACY_ARITHMETIC( ADD, B ) +DEFINE_LEGACY_ARITHMETIC( ADD, W ) +DEFINE_LEGACY_ARITHMETIC( ADD, D ) +DEFINE_LEGACY_ARITHMETIC( ADD, Q ) +DEFINE_LEGACY_ARITHMETIC( ADD, SB ) +DEFINE_LEGACY_ARITHMETIC( ADD, SW ) +DEFINE_LEGACY_ARITHMETIC( ADD, USB ) +DEFINE_LEGACY_ARITHMETIC( ADD, USW ) + +DEFINE_LEGACY_ARITHMETIC( SUB, B ) +DEFINE_LEGACY_ARITHMETIC( SUB, W ) +DEFINE_LEGACY_ARITHMETIC( SUB, D ) +DEFINE_LEGACY_ARITHMETIC( SUB, Q ) +DEFINE_LEGACY_ARITHMETIC( SUB, SB ) +DEFINE_LEGACY_ARITHMETIC( SUB, SW ) +DEFINE_LEGACY_ARITHMETIC( SUB, USB ) +DEFINE_LEGACY_ARITHMETIC( SUB, USW ) + +DEFINE_LEGACY_ARITHMETIC( CMP, EQB ); +DEFINE_LEGACY_ARITHMETIC( CMP, EQW ); +DEFINE_LEGACY_ARITHMETIC( CMP, EQD ); +DEFINE_LEGACY_ARITHMETIC( CMP, GTB ); +DEFINE_LEGACY_ARITHMETIC( CMP, GTW ); +DEFINE_LEGACY_ARITHMETIC( CMP, GTD ); + +DEFINE_LEGACY_ARITHMETIC( UNPCK, HDQ ); +DEFINE_LEGACY_ARITHMETIC( UNPCK, LDQ ); +DEFINE_LEGACY_ARITHMETIC( UNPCK, HBW ); +DEFINE_LEGACY_ARITHMETIC( UNPCK, LBW ); + +DEFINE_LEGACY_ARITHMETIC( UNPCK, LWD ); +DEFINE_LEGACY_ARITHMETIC( UNPCK, HWD ); + + +emitterT void PMULUDQMtoR( x86MMXRegType to, uptr from ) { xPMUL.UDQ( xRegisterMMX( to ), (void*)from ); } +emitterT void PMULUDQRtoR( x86MMXRegType to, x86MMXRegType from ) { xPMUL.UDQ( xRegisterMMX( to ), xRegisterMMX( from ) ); } + +emitterT void PSHUFWRtoR(x86MMXRegType to, x86MMXRegType from, u8 imm8) { xPSHUF.W( xRegisterMMX(to), xRegisterMMX(from), imm8 ); } +emitterT void PSHUFWMtoR(x86MMXRegType to, uptr from, u8 imm8) { xPSHUF.W( xRegisterMMX(to), (void*)from, imm8 ); } + +emitterT void PINSRWRtoMMX( x86MMXRegType to, x86SSERegType from, u8 imm8 ) { xPINSR.W( xRegisterMMX(to), xRegister32(from), imm8 ); } + +emitterT void EMMS() { xEMMS(); } + +// ------------------------------------------------------------------------ +// Begin SSE-Only Part! +// ------------------------------------------------------------------------ + +#define DEFINE_LEGACY_MOV_OPCODE( mod, sse ) \ + emitterT void sse##_MOV##mod##_M128_to_XMM( x86SSERegType to, uptr from ) { xMOV##mod( xRegisterSSE(to), (void*)from ); } \ + emitterT void sse##_MOV##mod##_XMM_to_M128( uptr to, x86SSERegType from ) { xMOV##mod( (void*)to, xRegisterSSE(from) ); } \ + emitterT void sse##_MOV##mod##RmtoR( x86SSERegType to, x86IntRegType from, int offset ) { xMOV##mod( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); } \ + emitterT void sse##_MOV##mod##RtoRm( x86IntRegType to, x86SSERegType from, int offset ) { xMOV##mod( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); } \ + emitterT void sse##_MOV##mod##RmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ) \ + { xMOV##mod( xRegisterSSE(to), ptr[xAddressReg(from)+xAddressReg(from2)] ); } \ + emitterT void sse##_MOV##mod##RtoRmS( x86IntRegType to, x86SSERegType from, x86IntRegType from2, int scale ) \ + { xMOV##mod( ptr[xAddressReg(to)+xAddressReg(from2)], xRegisterSSE(from) ); } + +#define DEFINE_LEGACY_PSD_OPCODE( mod ) \ + emitterT void SSE_##mod##PS_M128_to_XMM( x86SSERegType to, uptr from ) { x##mod.PS( xRegisterSSE(to), (void*)from ); } \ + emitterT void SSE_##mod##PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.PS( xRegisterSSE(to), xRegisterSSE(from) ); } \ + emitterT void SSE2_##mod##PD_M128_to_XMM( x86SSERegType to, uptr from ) { x##mod.PD( xRegisterSSE(to), (void*)from ); } \ + emitterT void SSE2_##mod##PD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.PD( xRegisterSSE(to), xRegisterSSE(from) ); } + +#define DEFINE_LEGACY_SSSD_OPCODE( mod ) \ + emitterT void SSE_##mod##SS_M32_to_XMM( x86SSERegType to, uptr from ) { x##mod.SS( xRegisterSSE(to), (void*)from ); } \ + emitterT void SSE_##mod##SS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.SS( xRegisterSSE(to), xRegisterSSE(from) ); } \ + emitterT void SSE2_##mod##SD_M64_to_XMM( x86SSERegType to, uptr from ) { x##mod.SD( xRegisterSSE(to), (void*)from ); } \ + emitterT void SSE2_##mod##SD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.SD( xRegisterSSE(to), xRegisterSSE(from) ); } + +#define DEFINE_LEGACY_CMP_OPCODE( comp ) \ + emitterT void SSE_CMP##comp##PS_M128_to_XMM( x86SSERegType to, uptr from ) { xCMP##comp.PS( xRegisterSSE(to), (void*)from ); } \ + emitterT void SSE_CMP##comp##PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCMP##comp.PS( xRegisterSSE(to), xRegisterSSE(from) ); } \ + emitterT void SSE2_CMP##comp##PD_M128_to_XMM( x86SSERegType to, uptr from ) { xCMP##comp.PD( xRegisterSSE(to), (void*)from ); } \ + emitterT void SSE2_CMP##comp##PD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCMP##comp.PD( xRegisterSSE(to), xRegisterSSE(from) ); } \ + emitterT void SSE_CMP##comp##SS_M32_to_XMM( x86SSERegType to, uptr from ) { xCMP##comp.SS( xRegisterSSE(to), (void*)from ); } \ + emitterT void SSE_CMP##comp##SS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCMP##comp.SS( xRegisterSSE(to), xRegisterSSE(from) ); } \ + emitterT void SSE2_CMP##comp##SD_M64_to_XMM( x86SSERegType to, uptr from ) { xCMP##comp.SD( xRegisterSSE(to), (void*)from ); } \ + emitterT void SSE2_CMP##comp##SD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCMP##comp.SD( xRegisterSSE(to), xRegisterSSE(from) ); } + +#define DEFINE_LEGACY_RSQRT_OPCODE(mod) \ + emitterT void SSE_##mod##PS_M128_to_XMM( x86SSERegType to, uptr from ) { x##mod.PS( xRegisterSSE(to), (void*)from ); } \ + emitterT void SSE_##mod##PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.PS( xRegisterSSE(to), xRegisterSSE(from) ); } \ + emitterT void SSE_##mod##SS_M32_to_XMM( x86SSERegType to, uptr from ) { x##mod.SS( xRegisterSSE(to), (void*)from ); } \ + emitterT void SSE_##mod##SS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.SS( xRegisterSSE(to), xRegisterSSE(from) ); } + +#define DEFINE_LEGACY_SQRT_OPCODE(mod) \ + DEFINE_LEGACY_RSQRT_OPCODE(mod) \ + emitterT void SSE2_##mod##SD_M64_to_XMM( x86SSERegType to, uptr from ) { x##mod.SD( xRegisterSSE(to), (void*)from ); } \ + emitterT void SSE2_##mod##SD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.SD( xRegisterSSE(to), xRegisterSSE(from) ); } + +#define DEFINE_LEGACY_OP128( ssenum, mod, sub ) \ + emitterT void SSE##ssenum##_##mod##sub##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod.sub( xRegisterSSE(to), xRegisterSSE(from) ); } \ + emitterT void SSE##ssenum##_##mod##sub##_M128_to_XMM( x86SSERegType to, uptr from ) { x##mod.sub( xRegisterSSE(to), (void*)from ); } + +#define DEFINE_LEGACY_MOV128( ssenum, mod, sub ) \ + emitterT void SSE##ssenum##_##mod##sub##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { x##mod##sub( xRegisterSSE(to), xRegisterSSE(from) ); } \ + emitterT void SSE##ssenum##_##mod##sub##_M128_to_XMM( x86SSERegType to, uptr from ) { x##mod##sub( xRegisterSSE(to), (void*)from ); } + + +#define DEFINE_LEGACY_PSSD_OPCODE( mod ) \ + DEFINE_LEGACY_PSD_OPCODE( mod ) \ + DEFINE_LEGACY_SSSD_OPCODE( mod ) + +DEFINE_LEGACY_MOV_OPCODE( UPS, SSE ) +DEFINE_LEGACY_MOV_OPCODE( APS, SSE ) +DEFINE_LEGACY_MOV_OPCODE( DQA, SSE2 ) +DEFINE_LEGACY_MOV_OPCODE( DQU, SSE2 ) + +DEFINE_LEGACY_PSD_OPCODE( AND ) +DEFINE_LEGACY_PSD_OPCODE( ANDN ) +DEFINE_LEGACY_PSD_OPCODE( OR ) +DEFINE_LEGACY_PSD_OPCODE( XOR ) + +DEFINE_LEGACY_PSSD_OPCODE( SUB ) +DEFINE_LEGACY_PSSD_OPCODE( ADD ) +DEFINE_LEGACY_PSSD_OPCODE( MUL ) +DEFINE_LEGACY_PSSD_OPCODE( DIV ) + +DEFINE_LEGACY_PSSD_OPCODE( MIN ) +DEFINE_LEGACY_PSSD_OPCODE( MAX ) + +DEFINE_LEGACY_CMP_OPCODE( EQ ) +DEFINE_LEGACY_CMP_OPCODE( LT ) +DEFINE_LEGACY_CMP_OPCODE( LE ) +DEFINE_LEGACY_CMP_OPCODE( UNORD ) +DEFINE_LEGACY_CMP_OPCODE( NE ) +DEFINE_LEGACY_CMP_OPCODE( NLT ) +DEFINE_LEGACY_CMP_OPCODE( NLE ) +DEFINE_LEGACY_CMP_OPCODE( ORD ) + +DEFINE_LEGACY_SSSD_OPCODE( COMI ) +DEFINE_LEGACY_SSSD_OPCODE( UCOMI ) +DEFINE_LEGACY_RSQRT_OPCODE( RCP ) +DEFINE_LEGACY_RSQRT_OPCODE( RSQRT ) +DEFINE_LEGACY_SQRT_OPCODE( SQRT ) + +DEFINE_LEGACY_OP128( 2, PMUL, LW ) +DEFINE_LEGACY_OP128( 2, PMUL, HW ) +DEFINE_LEGACY_OP128( 2, PMUL, UDQ ) + +DEFINE_LEGACY_OP128( 2, PMAX, SW ) +DEFINE_LEGACY_OP128( 2, PMAX, UB ) +DEFINE_LEGACY_OP128( 2, PMIN, SW ) +DEFINE_LEGACY_OP128( 2, PMIN, UB ) + +DEFINE_LEGACY_OP128( 2, UNPCK, LPS ) +DEFINE_LEGACY_OP128( 2, UNPCK, HPS ) +DEFINE_LEGACY_OP128( 2, PUNPCK, LQDQ ) +DEFINE_LEGACY_OP128( 2, PUNPCK, HQDQ ) + +DEFINE_LEGACY_OP128( 2, PACK, SSWB ) +DEFINE_LEGACY_OP128( 2, PACK, SSDW ) +DEFINE_LEGACY_OP128( 2, PACK, USWB ) + +DEFINE_LEGACY_MOV128( 3, MOV, SLDUP ) +DEFINE_LEGACY_MOV128( 3, MOV, SHDUP ) + +DEFINE_LEGACY_OP128( 4, PMAX, SD ) +DEFINE_LEGACY_OP128( 4, PMIN, SD ) +DEFINE_LEGACY_OP128( 4, PMAX, UD ) +DEFINE_LEGACY_OP128( 4, PMIN, UD ) + + +emitterT void SSE_MOVAPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVAPS( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSE2_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { xMOVDQA( xRegisterSSE(to), xRegisterSSE(from) ); } + +emitterT void SSE2_MOVD_M32_to_XMM( x86SSERegType to, uptr from ) { xMOVDZX( xRegisterSSE(to), (void*)from ); } +emitterT void SSE2_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from ) { xMOVDZX( xRegisterSSE(to), xRegister32(from) ); } +emitterT void SSE2_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) +{ + xMOVDZX( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); +} + +emitterT void SSE2_MOVD_XMM_to_M32( u32 to, x86SSERegType from ) { xMOVD( (void*)to, xRegisterSSE(from) ); } +emitterT void SSE2_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from ) { xMOVD( xRegister32(to), xRegisterSSE(from) ); } +emitterT void SSE2_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) +{ + xMOVD( ptr[xAddressReg(from)+offset], xRegisterSSE(from) ); +} + +emitterT void SSE2_MOVQ_M64_to_XMM( x86SSERegType to, uptr from ) { xMOVQZX( xRegisterSSE(to), (void*)from ); } +emitterT void SSE2_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVQZX( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSE2_MOVQ_XMM_to_M64( u32 to, x86SSERegType from ) { xMOVQ( (void*)to, xRegisterSSE(from) ); } +emitterT void SSE2_MOVDQ2Q_XMM_to_MM( x86MMXRegType to, x86SSERegType from) { xMOVQ( xRegisterMMX(to), xRegisterSSE(from) ); } +emitterT void SSE2_MOVQ2DQ_MM_to_XMM( x86SSERegType to, x86MMXRegType from) { xMOVQ( xRegisterSSE(to), xRegisterMMX(from) ); } + + +emitterT void SSE_MOVSS_M32_to_XMM( x86SSERegType to, uptr from ) { xMOVSSZX( xRegisterSSE(to), (void*)from ); } +emitterT void SSE_MOVSS_XMM_to_M32( u32 to, x86SSERegType from ) { xMOVSS( (void*)to, xRegisterSSE(from) ); } +emitterT void SSE_MOVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVSS( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSE_MOVSS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVSSZX( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); } +emitterT void SSE_MOVSS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVSS( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); } + +emitterT void SSE2_MOVSD_M32_to_XMM( x86SSERegType to, uptr from ) { xMOVSDZX( xRegisterSSE(to), (void*)from ); } +emitterT void SSE2_MOVSD_XMM_to_M32( u32 to, x86SSERegType from ) { xMOVSD( (void*)to, xRegisterSSE(from) ); } +emitterT void SSE2_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVSD( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSE2_MOVSD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVSDZX( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); } +emitterT void SSE2_MOVSD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVSD( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); } + +emitterT void SSE_MOVLPS_M64_to_XMM( x86SSERegType to, uptr from ) { xMOVL.PS( xRegisterSSE(to), (void*)from ); } +emitterT void SSE_MOVLPS_XMM_to_M64( u32 to, x86SSERegType from ) { xMOVL.PS( (void*)to, xRegisterSSE(from) ); } +emitterT void SSE_MOVLPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVL.PS( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); } +emitterT void SSE_MOVLPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVL.PS( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); } + +emitterT void SSE_MOVHPS_M64_to_XMM( x86SSERegType to, uptr from ) { xMOVH.PS( xRegisterSSE(to), (void*)from ); } +emitterT void SSE_MOVHPS_XMM_to_M64( u32 to, x86SSERegType from ) { xMOVH.PS( (void*)to, xRegisterSSE(from) ); } +emitterT void SSE_MOVHPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVH.PS( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); } +emitterT void SSE_MOVHPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVH.PS( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); } + +emitterT void SSE_MOVLHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVLH.PS( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSE_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVHL.PS( xRegisterSSE(to), xRegisterSSE(from) ); } + +emitterT void SSE_MASKMOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMASKMOV( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSE2_PMOVMSKB_XMM_to_R32(x86IntRegType to, x86SSERegType from) { xPMOVMSKB( xRegister32(to), xRegisterSSE(from) ); } + +emitterT void SSE_SHUFPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { xSHUF.PS( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } +emitterT void SSE_SHUFPS_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { xSHUF.PS( xRegisterSSE(to), (void*)from, imm8 ); } +emitterT void SSE_SHUFPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset, u8 imm8 ) +{ + xSHUF.PS( xRegisterSSE(to), ptr[xAddressReg(from)+offset], imm8 ); +} + +emitterT void SSE_SHUFPD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { xSHUF.PD( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } +emitterT void SSE_SHUFPD_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { xSHUF.PD( xRegisterSSE(to), (void*)from, imm8 ); } + +emitterT void SSE_CVTPI2PS_M64_to_XMM( x86SSERegType to, uptr from ) { xCVTPI2PS( xRegisterSSE(to), (u64*)from ); } +emitterT void SSE_CVTPI2PS_MM_to_XMM( x86SSERegType to, x86MMXRegType from ) { xCVTPI2PS( xRegisterSSE(to), xRegisterMMX(from) ); } +emitterT void SSE_CVTPS2PI_M64_to_MM( x86MMXRegType to, uptr from ) { xCVTPS2PI( xRegisterMMX(to), (u64*)from ); } +emitterT void SSE_CVTPS2PI_XMM_to_MM( x86MMXRegType to, x86SSERegType from ) { xCVTPS2PI( xRegisterMMX(to), xRegisterSSE(from) ); } +emitterT void SSE_CVTTSS2SI_M32_to_R32(x86IntRegType to, uptr from) { xCVTTSS2SI( xRegister32(to), (u32*)from ); } +emitterT void SSE_CVTTSS2SI_XMM_to_R32(x86IntRegType to, x86SSERegType from) { xCVTTSS2SI( xRegister32(to), xRegisterSSE(from) ); } +emitterT void SSE_CVTSI2SS_M32_to_XMM(x86SSERegType to, uptr from) { xCVTSI2SS( xRegisterSSE(to), (u32*)from ); } +emitterT void SSE_CVTSI2SS_R_to_XMM(x86SSERegType to, x86IntRegType from) { xCVTSI2SS( xRegisterSSE(to), xRegister32(from) ); } + +emitterT void SSE2_CVTSS2SD_M32_to_XMM( x86SSERegType to, uptr from) { xCVTSS2SD( xRegisterSSE(to), (u32*)from ); } +emitterT void SSE2_CVTSS2SD_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { xCVTSS2SD( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSE2_CVTSD2SS_M64_to_XMM( x86SSERegType to, uptr from) { xCVTSD2SS( xRegisterSSE(to), (u64*)from ); } +emitterT void SSE2_CVTSD2SS_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { xCVTSD2SS( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSE2_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from ) { xCVTDQ2PS( xRegisterSSE(to), (u128*)from ); } +emitterT void SSE2_CVTDQ2PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCVTDQ2PS( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSE2_CVTPS2DQ_M128_to_XMM( x86SSERegType to, uptr from ) { xCVTPS2DQ( xRegisterSSE(to), (u128*)from ); } +emitterT void SSE2_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCVTPS2DQ( xRegisterSSE(to), xRegisterSSE(from) ); } + +emitterT void SSE2_CVTTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xCVTTPS2DQ( xRegisterSSE(to), xRegisterSSE(from) ); } + +emitterT void SSE_PMAXSW_MM_to_MM( x86MMXRegType to, x86MMXRegType from ) { xPMAX.SW( xRegisterMMX(to), xRegisterMMX(from) ); } +emitterT void SSE_PMINSW_MM_to_MM( x86MMXRegType to, x86MMXRegType from ) { xPMAX.SW( xRegisterMMX(to), xRegisterMMX(from) ); } + +emitterT void SSE2_PSHUFD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { xPSHUF.D( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } +emitterT void SSE2_PSHUFD_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { xPSHUF.D( xRegisterSSE(to), (void*)from, imm8 ); } +emitterT void SSE2_PSHUFLW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { xPSHUF.LW( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } +emitterT void SSE2_PSHUFLW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { xPSHUF.LW( xRegisterSSE(to), (void*)from, imm8 ); } +emitterT void SSE2_PSHUFHW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { xPSHUF.HW( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } +emitterT void SSE2_PSHUFHW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { xPSHUF.HW( xRegisterSSE(to), (void*)from, imm8 ); } + +emitterT void SSE4_PMULDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPMUL.DQ( xRegisterSSE(to), xRegisterSSE(from) ); } + +emitterT void SSE_UNPCKLPS_M128_to_XMM( x86SSERegType to, uptr from ) { xUNPCK.LPS( xRegisterSSE(to), (void*)from ); } +emitterT void SSE_UNPCKLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xUNPCK.LPS( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSE_UNPCKHPS_M128_to_XMM( x86SSERegType to, uptr from ) { xUNPCK.HPS( xRegisterSSE(to), (void*)from ); } +emitterT void SSE_UNPCKHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xUNPCK.HPS( xRegisterSSE(to), xRegisterSSE(from) ); } + +emitterT void SSE_MOVMSKPS_XMM_to_R32(x86IntRegType to, x86SSERegType from) { xMOVMSKPS( xRegister32(to), xRegisterSSE(from) ); } +emitterT void SSE2_MOVMSKPD_XMM_to_R32(x86IntRegType to, x86SSERegType from) { xMOVMSKPD( xRegister32(to), xRegisterSSE(from) ); } + +emitterT void SSSE3_PABSB_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPABS.B( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSSE3_PABSW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPABS.W( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSSE3_PABSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPABS.D( xRegisterSSE(to), xRegisterSSE(from) ); } + +emitterT void SSSE3_PSIGNB_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPSIGN.B( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSSE3_PSIGNW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPSIGN.W( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSSE3_PSIGND_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPSIGN.D( xRegisterSSE(to), xRegisterSSE(from) ); } + +emitterT void SSE_PEXTRW_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8 ) { xPEXTR.W( xRegister32(to), xRegisterSSE(from), imm8 ); } +emitterT void SSE_PINSRW_R32_to_XMM(x86SSERegType to, x86IntRegType from, u8 imm8 ) { xPINSR.W( xRegisterSSE(to), xRegister32(from), imm8 ); } + +emitterT void SSE2_PMADDWD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPMADD.WD( xRegisterSSE(to), xRegisterSSE(from) ); } + +emitterT void SSE3_HADDPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xHADD.PS( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSE3_HADDPS_M128_to_XMM(x86SSERegType to, uptr from) { xHADD.PS( xRegisterSSE(to), (void*)from ); } + +emitterT void SSE4_PINSRD_R32_to_XMM(x86SSERegType to, x86IntRegType from, u8 imm8) { xPINSR.D( xRegisterSSE(to), xRegister32(from), imm8 ); } + +emitterT void SSE4_INSERTPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8) { xINSERTPS( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } +emitterT void SSE4_EXTRACTPS_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8) { xEXTRACTPS( xRegister32(to), xRegisterSSE(from), imm8 ); } + +emitterT void SSE4_DPPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8) { xDP.PS( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } +emitterT void SSE4_DPPS_M128_to_XMM(x86SSERegType to, uptr from, u8 imm8) { xDP.PS( xRegisterSSE(to), (void*)from, imm8 ); } + +emitterT void SSE4_BLENDPS_XMM_to_XMM(x86IntRegType to, x86SSERegType from, u8 imm8) { xBLEND.PS( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } +emitterT void SSE4_BLENDVPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xBLEND.VPS( xRegisterSSE(to), xRegisterSSE(from) ); } +emitterT void SSE4_BLENDVPS_M128_to_XMM(x86SSERegType to, uptr from) { xBLEND.VPS( xRegisterSSE(to), (void*)from ); } + +emitterT void SSE4_PMOVSXDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { xPMOVSX.DQ( xRegisterSSE(to), xRegisterSSE(from) ); } + +emitterT void SSE_LDMXCSR( uptr from ) { xLDMXCSR( (u32*)from ); } + + +////////////////////////////////////////////////////////////////////////////////////////// +// SSE-X Helpers (generates either INT or FLOAT versions of certain SSE instructions) +// +// Added AlwaysUseMovaps check to the relevant functions here, which helps reduce the +// overhead of dynarec instructions that use these, even thought the same check would +// have been done redundantly by the emitter function. + +emitterT void SSEX_MOVDQA_M128_to_XMM( x86SSERegType to, uptr from ) +{ + if( !AlwaysUseMovaps && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQA_M128_to_XMM(to, from); + else SSE_MOVAPS_M128_to_XMM(to, from); +} + +emitterT void SSEX_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from ) +{ + if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQA_XMM_to_M128(to, from); + else SSE_MOVAPS_XMM_to_M128(to, from); +} + +emitterT void SSEX_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQA_XMM_to_XMM(to, from); + else SSE_MOVAPS_XMM_to_XMM(to, from); +} + +emitterT void SSEX_MOVDQARmtoR( x86SSERegType to, x86IntRegType from, int offset ) +{ + if( !AlwaysUseMovaps && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQARmtoR(to, from, offset); + else SSE_MOVAPSRmtoR(to, from, offset); +} + +emitterT void SSEX_MOVDQARtoRm( x86IntRegType to, x86SSERegType from, int offset ) +{ + if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQARtoRm(to, from, offset); + else SSE_MOVAPSRtoRm(to, from, offset); +} + +emitterT void SSEX_MOVDQU_M128_to_XMM( x86SSERegType to, uptr from ) +{ + if( !AlwaysUseMovaps && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQU_M128_to_XMM(to, from); + else SSE_MOVUPS_M128_to_XMM(to, from); +} + +emitterT void SSEX_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from ) +{ + if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQU_XMM_to_M128(to, from); + else SSE_MOVUPS_XMM_to_M128(to, from); +} + +emitterT void SSEX_MOVD_M32_to_XMM( x86SSERegType to, uptr from ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVD_M32_to_XMM(to, from); + else SSE_MOVSS_M32_to_XMM(to, from); +} + +emitterT void SSEX_MOVD_XMM_to_M32( u32 to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_M32(to, from); + else SSE_MOVSS_XMM_to_M32(to, from); +} + +emitterT void SSEX_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVD_Rm_to_XMM(to, from, offset); + else SSE_MOVSS_Rm_to_XMM(to, from, offset); +} + +emitterT void SSEX_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_Rm(to, from, offset); + else SSE_MOVSS_XMM_to_Rm(to, from, offset); +} + +emitterT void SSEX_POR_M128_to_XMM( x86SSERegType to, uptr from ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_POR_M128_to_XMM(to, from); + else SSE_ORPS_M128_to_XMM(to, from); +} + +emitterT void SSEX_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_POR_XMM_to_XMM(to, from); + else SSE_ORPS_XMM_to_XMM(to, from); +} + +emitterT void SSEX_PXOR_M128_to_XMM( x86SSERegType to, uptr from ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_PXOR_M128_to_XMM(to, from); + else SSE_XORPS_M128_to_XMM(to, from); +} + +emitterT void SSEX_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_PXOR_XMM_to_XMM(to, from); + else SSE_XORPS_XMM_to_XMM(to, from); +} + +emitterT void SSEX_PAND_M128_to_XMM( x86SSERegType to, uptr from ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_PAND_M128_to_XMM(to, from); + else SSE_ANDPS_M128_to_XMM(to, from); +} + +emitterT void SSEX_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_PAND_XMM_to_XMM(to, from); + else SSE_ANDPS_XMM_to_XMM(to, from); +} + +emitterT void SSEX_PANDN_M128_to_XMM( x86SSERegType to, uptr from ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_PANDN_M128_to_XMM(to, from); + else SSE_ANDNPS_M128_to_XMM(to, from); +} + +emitterT void SSEX_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_PANDN_XMM_to_XMM(to, from); + else SSE_ANDNPS_XMM_to_XMM(to, from); +} + +emitterT void SSEX_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_PUNPCKLDQ_M128_to_XMM(to, from); + else SSE_UNPCKLPS_M128_to_XMM(to, from); +} + +emitterT void SSEX_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_PUNPCKLDQ_XMM_to_XMM(to, from); + else SSE_UNPCKLPS_XMM_to_XMM(to, from); +} + +emitterT void SSEX_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_PUNPCKHDQ_M128_to_XMM(to, from); + else SSE_UNPCKHPS_M128_to_XMM(to, from); +} + +emitterT void SSEX_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_PUNPCKHDQ_XMM_to_XMM(to, from); + else SSE_UNPCKHPS_XMM_to_XMM(to, from); +} + +emitterT void SSEX_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) { + SSE2_PUNPCKHQDQ_XMM_to_XMM(to, from); + if( to != from ) SSE2_PSHUFD_XMM_to_XMM(to, to, 0x4e); + } + else { + SSE_MOVHLPS_XMM_to_XMM(to, from); + } +} diff --git a/pcsx2/x86/ix86/ix86_simd.cpp b/common/src/x86emitter/simd.cpp similarity index 87% rename from pcsx2/x86/ix86/ix86_simd.cpp rename to common/src/x86emitter/simd.cpp index 860e8ffc0a..7a4b02f24e 100644 --- a/pcsx2/x86/ix86/ix86_simd.cpp +++ b/common/src/x86emitter/simd.cpp @@ -17,9 +17,7 @@ */ #include "PrecompiledHeader.h" - -#include "System.h" -#include "ix86_internal.h" +#include "internal.h" namespace x86Emitter { @@ -90,27 +88,27 @@ const SimdImpl_MoveSSE<0x66,true> xMOVAPD; const SimdImpl_MoveSSE<0x66,false> xMOVUPD; #endif -const MovhlImplAll<0x16> xMOVH; -const MovhlImplAll<0x12> xMOVL; -const MovhlImpl_RtoR<0x16> xMOVLH; -const MovhlImpl_RtoR<0x12> xMOVHL; +const MovhlImplAll<0x16> xMOVH; +const MovhlImplAll<0x12> xMOVL; +const MovhlImpl_RtoR<0x16> xMOVLH; +const MovhlImpl_RtoR<0x12> xMOVHL; + +const SimdImpl_AndNot xANDN; +const SimdImpl_COMI xCOMI; +const SimdImpl_COMI xUCOMI; +const SimdImpl_rSqrt<0x53> xRCP; +const SimdImpl_rSqrt<0x52> xRSQRT; +const SimdImpl_Sqrt<0x51> xSQRT; + +const SimdImpl_MinMax<0x5f> xMAX; +const SimdImpl_MinMax<0x5d> xMIN; +const SimdImpl_Shuffle<0xc6> xSHUF; const SimdImpl_DestRegEither<0x66,0xdb> xPAND; const SimdImpl_DestRegEither<0x66,0xdf> xPANDN; const SimdImpl_DestRegEither<0x66,0xeb> xPOR; const SimdImpl_DestRegEither<0x66,0xef> xPXOR; -const SimdImpl_AndNot xANDN; - -const SimdImpl_UcomI<0x66,0x2e> xUCOMI; -const SimdImpl_rSqrt<0x53> xRCP; -const SimdImpl_rSqrt<0x52> xRSQRT; -const SimdImpl_Sqrt<0x51> xSQRT; - -const SimdImpl_MinMax<0x5f> xMAX; -const SimdImpl_MinMax<0x5d> xMIN; -const SimdImpl_Shuffle<0xc6> xSHUF; - // ------------------------------------------------------------------------ // [SSE-4.1] Performs a bitwise AND of dest against src, and sets the ZF flag @@ -238,19 +236,15 @@ __emitinline void xLDMXCSR( const u32* src ) // __forceinline void xMOVDZX( const xRegisterSSE& to, const xRegister32& from ) { xOpWrite0F( 0x66, 0x6e, to, from ); } -__forceinline void xMOVDZX( const xRegisterSSE& to, const void* src ) { xOpWrite0F( 0x66, 0x6e, to, src ); } __forceinline void xMOVDZX( const xRegisterSSE& to, const ModSibBase& src ) { xOpWrite0F( 0x66, 0x6e, to, src ); } __forceinline void xMOVDZX( const xRegisterMMX& to, const xRegister32& from ) { xOpWrite0F( 0x6e, to, from ); } -__forceinline void xMOVDZX( const xRegisterMMX& to, const void* src ) { xOpWrite0F( 0x6e, to, src ); } __forceinline void xMOVDZX( const xRegisterMMX& to, const ModSibBase& src ) { xOpWrite0F( 0x6e, to, src ); } __forceinline void xMOVD( const xRegister32& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, to ); } -__forceinline void xMOVD( void* dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, dest ); } __forceinline void xMOVD( const ModSibBase& dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, dest ); } __forceinline void xMOVD( const xRegister32& to, const xRegisterMMX& from ) { xOpWrite0F( 0x7e, from, to ); } -__forceinline void xMOVD( void* dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7e, from, dest ); } __forceinline void xMOVD( const ModSibBase& dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7e, from, dest ); } @@ -268,14 +262,10 @@ __forceinline void xMOVQZX( const xRegisterSSE& to, const void* src ) { xOpWri // Moves lower quad of XMM to ptr64 (no bits are cleared) __forceinline void xMOVQ( const ModSibBase& dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xd6, from, dest ); } -// Moves lower quad of XMM to ptr64 (no bits are cleared) -__forceinline void xMOVQ( void* dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xd6, from, dest ); } __forceinline void xMOVQ( const xRegisterMMX& to, const xRegisterMMX& from ) { if( to != from ) xOpWrite0F( 0x6f, to, from ); } __forceinline void xMOVQ( const xRegisterMMX& to, const ModSibBase& src ) { xOpWrite0F( 0x6f, to, src ); } -__forceinline void xMOVQ( const xRegisterMMX& to, const void* src ) { xOpWrite0F( 0x6f, to, src ); } __forceinline void xMOVQ( const ModSibBase& dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7f, from, dest ); } -__forceinline void xMOVQ( void* dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7f, from, dest ); } // This form of xMOVQ is Intel's adeptly named 'MOVQ2DQ' __forceinline void xMOVQ( const xRegisterSSE& to, const xRegisterMMX& from ) { xOpWrite0F( 0xf3, 0xd6, to, from ); } @@ -295,9 +285,7 @@ __forceinline void xMOVQ( const xRegisterMMX& to, const xRegisterSSE& from ) #define IMPLEMENT_xMOVS( ssd, prefix ) \ __forceinline void xMOV##ssd( const xRegisterSSE& to, const xRegisterSSE& from ) { if( to != from ) xOpWrite0F( prefix, 0x10, to, from ); } \ - __forceinline void xMOV##ssd##ZX( const xRegisterSSE& to, const void* from ) { xOpWrite0F( prefix, 0x10, to, from ); } \ __forceinline void xMOV##ssd##ZX( const xRegisterSSE& to, const ModSibBase& from ) { xOpWrite0F( prefix, 0x10, to, from ); } \ - __forceinline void xMOV##ssd( const void* to, const xRegisterSSE& from ) { xOpWrite0F( prefix, 0x11, from, to ); } \ __forceinline void xMOV##ssd( const ModSibBase& to, const xRegisterSSE& from ) { xOpWrite0F( prefix, 0x11, from, to ); } IMPLEMENT_xMOVS( SS, 0xf3 ) @@ -307,27 +295,17 @@ IMPLEMENT_xMOVS( SD, 0xf2 ) // Non-temporal movs only support a register as a target (ie, load form only, no stores) // -__forceinline void xMOVNTDQA( const xRegisterSSE& to, const void* from ) -{ - xWrite32( 0x2A380f66 ); - EmitSibMagic( to.Id, from ); -} - __forceinline void xMOVNTDQA( const xRegisterSSE& to, const ModSibBase& from ) { xWrite32( 0x2A380f66 ); EmitSibMagic( to.Id, from ); } -__forceinline void xMOVNTDQ( void* to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xe7, from, to ); } __forceinline void xMOVNTDQA( const ModSibBase& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xe7, from, to ); } -__forceinline void xMOVNTPD( void* to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x2b, from, to ); } __forceinline void xMOVNTPD( const ModSibBase& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x2b, from, to ); } -__forceinline void xMOVNTPS( void* to, const xRegisterSSE& from ) { xOpWrite0F( 0x2b, from, to ); } __forceinline void xMOVNTPS( const ModSibBase& to, const xRegisterSSE& from ) { xOpWrite0F( 0x2b, from, to ); } -__forceinline void xMOVNTQ( void* to, const xRegisterMMX& from ) { xOpWrite0F( 0xe7, from, to ); } __forceinline void xMOVNTQ( const ModSibBase& to, const xRegisterMMX& from ) { xOpWrite0F( 0xe7, from, to ); } // ------------------------------------------------------------------------ @@ -382,7 +360,6 @@ __forceinline void xPALIGNR( const xRegisterMMX& to, const xRegisterMMX& from, u // with 0.0 if set to 1. // __emitinline void xINSERTPS( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x213a, to, from, imm8 ); } -__emitinline void xINSERTPS( const xRegisterSSE& to, const u32* from, u8 imm8 ) { xOpWrite0F( 0x66, 0x213a, to, from, imm8 ); } __emitinline void xINSERTPS( const xRegisterSSE& to, const ModSibStrict& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x213a, to, from, imm8 ); } // [SSE-4.1] Extract a single-precision floating-point value from src at an offset @@ -390,7 +367,6 @@ __emitinline void xINSERTPS( const xRegisterSSE& to, const ModSibStrict& fr // is stored into the low 32-bits of dest (or at a 32-bit memory pointer). // __emitinline void xEXTRACTPS( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x173a, to, from, imm8 ); } -__emitinline void xEXTRACTPS( u32* dest, const xRegisterSSE& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x173a, from, dest, imm8 ); } __emitinline void xEXTRACTPS( const ModSibStrict& dest, const xRegisterSSE& from, u8 imm8 ){ xOpWrite0F( 0x66, 0x173a, from, dest, imm8 ); } } \ No newline at end of file diff --git a/pcsx2/x86/ix86/ix86_tools.cpp b/common/src/x86emitter/tools.cpp similarity index 76% rename from pcsx2/x86/ix86/ix86_tools.cpp rename to common/src/x86emitter/tools.cpp index bdc4208ac9..37dbadf8bc 100644 --- a/pcsx2/x86/ix86/ix86_tools.cpp +++ b/common/src/x86emitter/tools.cpp @@ -17,9 +17,8 @@ */ #include "PrecompiledHeader.h" - -#include "System.h" -#include "ix86.h" +#include "internal.h" +#include "tools.h" // used to make sure regs don't get changed while in recompiler // use FreezeMMXRegs, FreezeXMMRegs @@ -27,64 +26,12 @@ u8 g_globalMMXSaved = 0; u8 g_globalXMMSaved = 0; -PCSX2_ALIGNED16( static u64 g_globalMMXData[8] ); -PCSX2_ALIGNED16( static u64 g_globalXMMData[2*iREGCNT_XMM] ); - -namespace x86Emitter -{ - void xStoreReg( const xRegisterSSE& src ) - { - xMOVDQA( &g_globalXMMData[src.Id*2], src ); - } - - void xRestoreReg( const xRegisterSSE& dest ) - { - xMOVDQA( dest, &g_globalXMMData[dest.Id*2] ); - } -} - - -///////////////////////////////////////////////////////////////////// -// SetCPUState -- for assignment of SSE roundmodes and clampmodes. - -u32 g_sseMXCSR = DEFAULT_sseMXCSR; -u32 g_sseVUMXCSR = DEFAULT_sseVUMXCSR; - -void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR) -{ - //Msgbox::Alert("SetCPUState: Config.sseMXCSR = %x; Config.sseVUMXCSR = %x \n", Config.sseMXCSR, Config.sseVUMXCSR); - // SSE STATE // - // WARNING: do not touch unless you know what you are doing - - sseMXCSR &= 0xffff; // clear the upper 16 bits since they shouldn't be set - sseVUMXCSR &= 0xffff; - - if( !cpucaps.hasStreamingSIMD2Extensions ) - { - // SSE1 cpus do not support Denormals Are Zero flag (throws an exception - // if we don't mask them off) - - sseMXCSR &= ~0x0040; - sseVUMXCSR &= ~0x0040; - } - - g_sseMXCSR = sseMXCSR; - g_sseVUMXCSR = sseVUMXCSR; - -#ifdef _MSC_VER - __asm ldmxcsr g_sseMXCSR; // set the new sse control -#else - __asm__("ldmxcsr %[g_sseMXCSR]" : : [g_sseMXCSR]"m"(g_sseMXCSR) ); -#endif - //g_sseVUMXCSR = g_sseMXCSR|0x6000; -} +PCSX2_ALIGNED16( u64 g_globalMMXData[8] ); +PCSX2_ALIGNED16( u64 g_globalXMMData[2*iREGCNT_XMM] ); ///////////////////////////////////////////////////////////////////// // MMX Register Freezing -#ifndef __INTEL_COMPILER -extern "C" -{ -#endif +// __forceinline void FreezeRegs(int save) { @@ -92,14 +39,16 @@ __forceinline void FreezeRegs(int save) FreezeMMXRegs(save); } -__forceinline void FreezeMMXRegs_(int save) +__forceinline void FreezeMMXRegs(int save) { - //DevCon::Notice("FreezeMMXRegs_(%d); [%d]\n", save, g_globalMMXSaved); - assert( g_EEFreezeRegs ); + if( !g_EEFreezeRegs ) return; - if( save ) { + //DevCon::Notice("FreezeMMXRegs_(%d); [%d]\n", save, g_globalMMXSaved); + + if( save ) + { g_globalMMXSaved++; - if( g_globalMMXSaved>1 ) + if( g_globalMMXSaved > 1 ) { //DevCon::Notice("MMX Already Saved!\n"); return; @@ -178,10 +127,12 @@ __forceinline void FreezeMMXRegs_(int save) ////////////////////////////////////////////////////////////////////// // XMM Register Freezing -__forceinline void FreezeXMMRegs_(int save) +// +__forceinline void FreezeXMMRegs(int save) { + if( !g_EEFreezeRegs ) return; + //DevCon::Notice("FreezeXMMRegs_(%d); [%d]\n", save, g_globalXMMSaved); - assert( g_EEFreezeRegs ); if( save ) { @@ -264,7 +215,4 @@ __forceinline void FreezeXMMRegs_(int save) #endif // _MSC_VER } } -#ifndef __INTEL_COMPILER -} -#endif diff --git a/pcsx2/x86/ix86/ix86.cpp b/common/src/x86emitter/x86emitter.cpp similarity index 94% rename from pcsx2/x86/ix86/ix86.cpp rename to common/src/x86emitter/x86emitter.cpp index e04a66ddd3..c1b16ab982 100644 --- a/pcsx2/x86/ix86/ix86.cpp +++ b/common/src/x86emitter/x86emitter.cpp @@ -32,9 +32,11 @@ */ #include "PrecompiledHeader.h" +#include "internal.h" + +// defined in tools.cpp +PCSX2_ALIGNED16_EXTERN( u64 g_globalXMMData[2*iREGCNT_XMM] ); -#include "System.h" -#include "ix86_internal.h" // ------------------------------------------------------------------------ // Notes on Thread Local Storage: @@ -96,6 +98,7 @@ const xAddressIndexer ptr8; // ------------------------------------------------------------------------ template< typename OperandType > const xRegisterBase xRegisterBase::Empty; + const xAddressReg xAddressReg::Empty; const xRegisterSSE @@ -113,14 +116,14 @@ const xRegisterMMX const xAddressReg eax( 0 ), ebx( 3 ), ecx( 1 ), edx( 2 ), - esi( 6 ), edi( 7 ), - ebp( 5 ), esp( 4 ); + esp( 4 ), ebp( 5 ), + esi( 6 ), edi( 7 ); const xRegister16 ax( 0 ), bx( 3 ), cx( 1 ), dx( 2 ), - si( 6 ), di( 7 ), - bp( 5 ), sp( 4 ); + sp( 4 ), bp( 5 ), + si( 6 ), di( 7 ); const xRegister8 al( 0 ), @@ -130,10 +133,53 @@ const xRegister8 const xRegisterCL cl; +const char *const x86_regnames_gpr8[8] = +{ + "al", "cl", "dl", "bl", + "ah", "ch", "dh", "bh" +}; + +const char *const x86_regnames_gpr16[8] = +{ + "ax", "cx", "dx", "bx", + "sp", "bp", "si", "di" +}; + +const char *const x86_regnames_gpr32[8] = +{ + "eax", "ecx", "edx", "ebx", + "esp", "ebp", "esi", "edi" +}; + +const char *const x86_regnames_sse[8] = +{ + "xmm0", "xmm1", "xmm2", "xmm3", + "xmm4", "xmm5", "xmm6", "xmm7" +}; + +const char *const x86_regnames_mmx[8] = +{ + "mm0", "mm1", "mm2", "mm3", + "mm4", "mm5", "mm6", "mm7" +}; + ////////////////////////////////////////////////////////////////////////////////////////// namespace Internal { + + template< typename T > + const char* xGetRegName( const xRegister& src ) + { + if( src.IsEmpty() ) return "empty"; + switch( sizeof(T) ) + { + case 1: return tbl_regnames_gpr8[ src.Id ]; + case 2: return tbl_regnames_gpr16[ src.Id ]; + case 4: return tbl_regnames_gpr32[ src.Id ]; + } + } + ////////////////////////////////////////////////////////////////////////////////////////// // Performance note: VC++ wants to use byte/word register form for the following // ModRM/SibSB constructors when we use xWrite, and furthermore unrolls the @@ -201,11 +247,6 @@ namespace Internal xOpWrite0F( 0, opcode, instId, sib ); } - __emitinline void xOpWrite0F( u16 opcode, int instId, const void* data ) - { - xOpWrite0F( 0, opcode, instId, data ); - } - ////////////////////////////////////////////////////////////////////////////////////////// // returns TRUE if this instruction requires SIB to be encoded, or FALSE if the @@ -674,11 +715,9 @@ __emitinline void xPUSH( const ModSibBase& from ) } __forceinline void xPOP( xRegister32 from ) { xWrite8( 0x58 | from.Id ); } -__forceinline void xPOP( void* from ) { xPOP( ptr[from] ); } __forceinline void xPUSH( u32 imm ) { xWrite8( 0x68 ); xWrite32( imm ); } __forceinline void xPUSH( xRegister32 from ) { xWrite8( 0x50 | from.Id ); } -__forceinline void xPUSH( void* from ) { xPUSH( ptr[from] ); } // pushes the EFLAGS register onto the stack __forceinline void xPUSHFD() { xWrite8( 0x9C ); } @@ -710,4 +749,14 @@ __emitinline void xBSWAP( const xRegister32& to ) xWrite8( 0xC8 | to.Id ); } +__emitinline void xStoreReg( const xRegisterSSE& src ) +{ + xMOVDQA( &g_globalXMMData[src.Id*2], src ); +} + +__emitinline void xRestoreReg( const xRegisterSSE& dest ) +{ + xMOVDQA( dest, &g_globalXMMData[dest.Id*2] ); +} + } diff --git a/pcsx2/windows/VCprojects/vsprops/debug.vsprops b/common/vsprops/CodeGen_Debug.vsprops similarity index 57% rename from pcsx2/windows/VCprojects/vsprops/debug.vsprops rename to common/vsprops/CodeGen_Debug.vsprops index af6f81ca44..b4fe7b5204 100644 --- a/pcsx2/windows/VCprojects/vsprops/debug.vsprops +++ b/common/vsprops/CodeGen_Debug.vsprops @@ -2,17 +2,13 @@ - diff --git a/common/vsprops/CodeGen_Devel.vsprops b/common/vsprops/CodeGen_Devel.vsprops new file mode 100644 index 0000000000..6c1089c840 --- /dev/null +++ b/common/vsprops/CodeGen_Devel.vsprops @@ -0,0 +1,18 @@ + + + + diff --git a/common/vsprops/GlobalLinking.vsprops b/common/vsprops/CodeGen_Release.vsprops similarity index 79% rename from common/vsprops/GlobalLinking.vsprops rename to common/vsprops/CodeGen_Release.vsprops index 5bf8cd3a63..ed4e199190 100644 --- a/common/vsprops/GlobalLinking.vsprops +++ b/common/vsprops/CodeGen_Release.vsprops @@ -2,7 +2,7 @@ + + + + + + diff --git a/common/vsprops/pthreads.vsprops b/common/vsprops/pthreads.vsprops index a29230421c..82903d8584 100644 --- a/common/vsprops/pthreads.vsprops +++ b/common/vsprops/pthreads.vsprops @@ -5,16 +5,12 @@ Name="w32pthreads" > - diff --git a/pcsx2/3rdparty b/pcsx2/3rdparty new file mode 120000 index 0000000000..2781723b7c --- /dev/null +++ b/pcsx2/3rdparty @@ -0,0 +1 @@ +../3rdparty/ \ No newline at end of file diff --git a/pcsx2/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp similarity index 95% rename from pcsx2/CDVD.cpp rename to pcsx2/CDVD/CDVD.cpp index e7ba99844c..a287ef6736 100644 --- a/pcsx2/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -1,1983 +1,1988 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "PrecompiledHeader.h" - -#include -#include - -#include "IopCommon.h" -#include "CDVDiso.h" - -static cdvdStruct cdvd; - -static __forceinline void SetResultSize(u8 size) -{ - cdvd.ResultC = size; - cdvd.ResultP = 0; - cdvd.sDataIn&=~0x40; -} - -static void CDVDREAD_INT(int eCycle) -{ - PSX_INT(IopEvt_CdvdRead, eCycle); -} - -static void CDVD_INT(int eCycle) -{ - if( eCycle == 0 ) - cdvdActionInterrupt(); - else - PSX_INT(IopEvt_Cdvd, eCycle); -} - -// Sets the cdvd IRQ and the reason for the IRQ, and signals the IOP for a branch -// test (which will cause the exception to be handled). -static void cdvdSetIrq( uint id = (1< 0) { if (ptr[i] == '.') break; i--; } - ptr[i+1] = '\0'; - strcat(file, "MEC"); - - // if file doesnt exist, create empty one - fd = fopen(file, "r+b"); - if (fd == NULL) { - Console::Notice( "MEC File Not Found, Creating Blank File..." ); - fd = fopen(file, "wb"); - if (fd == NULL) - { - Console::Error( "\tMEC File Creation failed!" ); - throw Exception::CreateStream( file ); - //Msgbox::Alert( "_cdvdOpenMechaVer: Error creating %s", params file); - //exit(1); - } - - fputc(0x03, fd); - fputc(0x06, fd); - fputc(0x02, fd); - fputc(0x00, fd); - } - return fd; -} - -s32 cdvdGetMechaVer(u8* ver) -{ - FILE* fd = _cdvdOpenMechaVer(); - if (fd == NULL) return 1; - fseek(fd, 0, SEEK_SET); - fread(ver, 1, 4, fd); - fclose(fd); - return 0; -} - -FILE *_cdvdOpenNVM() { - char *ptr; - int i; - char file[g_MaxPath]; - FILE* fd; - - // get the name of the bios file - - // use the bios filename to get the name of the nvm file - // [TODO] : Upgrade this to use std::string! - - strcpy( file, g_Conf.Files.Bios().ToAscii().data() ); - ptr = file; - i = (int)strlen(file); - - while (i > 0) { if (ptr[i] == '.') break; i--; } - ptr[i+1] = '\0'; - - strcat(file, "NVM"); - - // if file doesnt exist, create empty one - fd = fopen(file, "r+b"); - if (fd == NULL) { - Console::Notice("NVM File Not Found , Creating Blank File"); - fd = fopen(file, "wb"); - if (fd == NULL) - { - throw Exception::CreateStream( file ); - //Msgbox::Alert("_cdvdOpenNVM: Error creating %s", params file); - //exit(1); - } - for (i=0; i<1024; i++) fputc(0, fd); - } - return fd; -} - -// -// the following 'cdvd' functions all return 0 if successful -// - -s32 cdvdReadNVM(u8 *dst, int offset, int bytes) { - FILE* fd = _cdvdOpenNVM(); - if (fd == NULL) return 1; - - fseek(fd, offset, SEEK_SET); - fread(dst, 1, bytes, fd); - fclose(fd); - - return 0; -} -s32 cdvdWriteNVM(const u8 *src, int offset, int bytes) { - FILE* fd = _cdvdOpenNVM(); - if (fd == NULL) return 1; - - fseek(fd, offset, SEEK_SET); - fwrite(src, 1, bytes, fd); - fclose(fd); - - return 0; -} - -NVMLayout* getNvmLayout(void) -{ - NVMLayout* nvmLayout = NULL; - s32 nvmIdx; - - for(nvmIdx=0; nvmIdx= cdvd.CNumBlocks) - return 1; - else if( - ((cdvd.COffset == 0) && (cdvd.CBlockIndex >= 4))|| - ((cdvd.COffset == 1) && (cdvd.CBlockIndex >= 2))|| - ((cdvd.COffset == 2) && (cdvd.CBlockIndex >= 7)) - ) - { - memzero_ptr<16>(config); - return 0; - } - - // get config data - switch (cdvd.COffset) - { - case 0: - return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config0)); - break; - case 2: - return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config2)); - break; - default: - return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config1)); - } -} -s32 cdvdWriteConfig(const u8* config) -{ - // make sure its in write mode - if(cdvd.CReadWrite != 1) - return 1; - // check if block index is in bounds - else if(cdvd.CBlockIndex >= cdvd.CNumBlocks) - return 1; - else if( - ((cdvd.COffset == 0) && (cdvd.CBlockIndex >= 4))|| - ((cdvd.COffset == 1) && (cdvd.CBlockIndex >= 2))|| - ((cdvd.COffset == 2) && (cdvd.CBlockIndex >= 7)) - ) - return 0; - - // get config data - switch (cdvd.COffset) - { - case 0: - return setNvmData(config, (cdvd.CBlockIndex++)*16, 16,offsetof(NVMLayout, config0)); - break; - case 2: - return setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config2)); - break; - default: - return setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config1)); - } -} - - -void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) { - wxString fname; - char exeName[12]; - s32 numbers, letters; - u32 key_0_3; - u8 key_4, key_14; - - // get main elf name - GetPS2ElfName(fname); - const wxCharBuffer crap( fname.ToAscii() ); - const char* str = crap.data(); - sprintf(exeName, "%c%c%c%c%c%c%c%c%c%c%c",str[8],str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16],str[17],str[18]); - DevCon::Notice("exeName = %s", params &str[8]); - - // convert the number characters to a real 32bit number - numbers = ((((exeName[5] - '0'))*10000) + - (((exeName[ 6] - '0'))*1000) + - (((exeName[ 7] - '0'))*100) + - (((exeName[ 9] - '0'))*10) + - (((exeName[10] - '0'))*1) ); - - // combine the lower 7 bits of each char - // to make the 4 letters fit into a single u32 - letters = (s32)((exeName[3]&0x7F)<< 0) | - (s32)((exeName[2]&0x7F)<< 7) | - (s32)((exeName[1]&0x7F)<<14) | - (s32)((exeName[0]&0x7F)<<21); - - // calculate magic numbers - key_0_3 = ((numbers & 0x1FC00) >> 10) | ((0x01FFFFFF & letters) << 7); // numbers = 7F letters = FFFFFF80 - key_4 = ((numbers & 0x0001F) << 3) | ((0x0E000000 & letters) >> 25); // numbers = F8 letters = 07 - key_14 = ((numbers & 0x003E0) >> 2) | 0x04; // numbers = F8 extra = 04 unused = 03 - - // clear key values - memzero_ptr<16>(key); - - // store key values - key[ 0] = (key_0_3&0x000000FF)>> 0; - key[ 1] = (key_0_3&0x0000FF00)>> 8; - key[ 2] = (key_0_3&0x00FF0000)>>16; - key[ 3] = (key_0_3&0xFF000000)>>24; - key[ 4] = key_4; - - if(arg2 == 75) - { - key[14] = key_14; - key[15] = 0x05; - } - else if(arg2 == 3075) - { - key[15] = 0x01; - } - else if(arg2 == 4246) - { - // 0x0001F2F707 = sector 0x0001F2F7 dec 0x07 - key[ 0] = 0x07; - key[ 1] = 0xF7; - key[ 2] = 0xF2; - key[ 3] = 0x01; - key[ 4] = 0x00; - key[15] = 0x01; - } - else - { - key[15] = 0x01; - } - - Console::WriteLn( "CDVD.KEY = %02X,%02X,%02X,%02X,%02X,%02X,%02X", params - cdvd.Key[0],cdvd.Key[1],cdvd.Key[2],cdvd.Key[3],cdvd.Key[4],cdvd.Key[14],cdvd.Key[15] ); - - // Now's a good time to reload the ELF info... - if( ElfCRC == 0 ) - { - ElfCRC = loadElfCRC( str ); - ElfApplyPatches(); - LoadGameSpecificSettings(); - GSsetGameCRC( ElfCRC, 0 ); - } -} - -s32 cdvdGetToc(void* toc) -{ - s32 ret = CDVDgetTOC(toc); - if (ret == -1) ret = 0x80; - return ret; -} - -s32 cdvdReadSubQ(s32 lsn, cdvdSubQ* subq) -{ - s32 ret = CDVDreadSubQ(lsn, subq); - if (ret == -1) ret = 0x80; - return ret; -} - -s32 cdvdCtrlTrayOpen() -{ - s32 ret = CDVDctrlTrayOpen(); - if (ret == -1) ret = 0x80; - return ret; -} - -s32 cdvdCtrlTrayClose() -{ - s32 ret = CDVDctrlTrayClose(); - if (ret == -1) ret = 0x80; - return ret; -} - -// Modified by (efp) - 16/01/2006 -// checks if tray was opened since last call to this func -s32 cdvdGetTrayStatus() -{ - s32 ret = CDVDgetTrayStatus(); - - if (ret == -1) - return(CDVD_TRAY_CLOSE); - else - return(ret); -} - -// Note: Is tray status being kept as a var here somewhere? -// cdvdNewDiskCB() can update it's status as well... - -// Modified by (efp) - 16/01/2006 -static __forceinline void cdvdGetDiskType() -{ - // defs 0.9.0 - if (CDVDnewDiskCB || (cdvd.Type != CDVD_TYPE_NODISC)) return; - - // defs.0.8.1 - if (cdvdGetTrayStatus() == CDVD_TRAY_OPEN) - { - cdvd.Type = CDVD_TYPE_NODISC; - return; - } - - cdvd.Type = CDVDgetDiskType(); - - // Is the type listed as a PS2 CD? - if (cdvd.Type == CDVD_TYPE_PS2CD) // && needReset == 1) - { - wxString str; - - if (GetPS2ElfName(str) == 1) - { - // Does the SYSTEM.CNF file only say "BOOT="? PS1 CD then. - cdvd.Type = CDVD_TYPE_PSCD; - } - } -} - -// check whether disc is single or dual layer -// if its dual layer, check what the disctype is and what sector number -// layer1 starts at -// -// args: gets value for dvd type (0=single layer, 1=ptp, 2=otp) -// gets value for start lsn of layer1 -// returns: 1 if on dual layer disc -// 0 if not on dual layer disc -static s32 cdvdReadDvdDualInfo(s32* dualType, u32* layer1Start) -{ - u8 toc[2064]; - *dualType = 0; - *layer1Start = 0; - - // if error getting toc, settle for single layer disc ;) - if(cdvdGetToc(toc)) - return 0; - if(toc[14] & 0x60) - { - if(toc[14] & 0x10) - { - // otp dvd - *dualType = 2; - *layer1Start = (toc[25]<<16) + (toc[26]<<8) + (toc[27]) - 0x30000 + 1; - } - else - { - // ptp dvd - *dualType = 1; - *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1; - } - } - else - { - // single layer dvd - *dualType = 0; - *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1; - } - - return 1; -} - -static uint cdvdBlockReadTime( CDVD_MODE_TYPE mode ) -{ - return (PSXCLK * cdvd.BlockSize) / (((mode==MODE_CDROM) ? PSX_CD_READSPEED : PSX_DVD_READSPEED) * cdvd.Speed); -} - -void cdvdReset() -{ - memzero_obj(cdvd); - - cdvd.Type = CDVD_TYPE_NODISC; - cdvd.Spinning = false; - - cdvd.sDataIn = 0x40; - cdvd.Ready = CDVD_READY2; - cdvd.Speed = 4; - cdvd.BlockSize = 2064; - cdvd.Action = cdvdAction_None; - cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); - - // any random valid date will do - //cdvd.RTC.hour = 1; - //cdvd.RTC.day = 25; - //cdvd.RTC.month = 5; - //cdvd.RTC.year = 7; //2007 - - wxDateTime curtime( wxDateTime::GetTimeNow() ); - cdvd.RTC.second = (u8)curtime.GetSecond(); - cdvd.RTC.minute = (u8)curtime.GetMinute(); - cdvd.RTC.hour = (u8)(curtime.GetHour()+1) % 24; - cdvd.RTC.day = (u8)curtime.GetDay(); - cdvd.RTC.month = (u8)curtime.GetMonth(); - cdvd.RTC.year = (u8)(curtime.GetYear() - 2000); -} - -struct Freeze_v10Compat -{ - u8 Action; - u32 SeekToSector; - u32 ReadTime; - bool Spinning; -}; - -void SaveState::cdvdFreeze() -{ - FreezeTag( "cdvd" ); - Freeze( cdvd ); - - if (IsLoading()) - { - // Make sure the Cdvd plugin has the expected track loaded into the buffer. - // If cdvd.Readed is cleared it means we need to load the SeekToSector (ie, a - // seek is in progress!) - - if( cdvd.Reading ) - cdvd.RErr = CDVDreadTrack( cdvd.Readed ? cdvd.Sector : cdvd.SeekToSector, cdvd.ReadMode); - } -} - -// Modified by (efp) - 16/01/2006 -void cdvdNewDiskCB() -{ - cdvd.Type = CDVDgetDiskType(); - - if (cdvd.Type == CDVD_TYPE_PS2CD) - { - wxString str; - - // Does the SYSTEM.CNF file only say "BOOT="? PS1 CD then. - if(GetPS2ElfName(str) == 1) cdvd.Type = CDVD_TYPE_PSCD; - } -} - -void mechaDecryptBytes( u32 madr, int size ) -{ - int i; - - int shiftAmount = (cdvd.decSet>>4) & 7; - int doXor = (cdvd.decSet) & 1; - int doShift = (cdvd.decSet) & 2; - - u8* curval = iopPhysMem( madr ); - for( i=0; i> shiftAmount) | (*curval << (8-shiftAmount) ); - } -} - -int cdvdReadSector() { - s32 bcr; - - CDR_LOG("SECTOR %d (BCR %x;%x)", cdvd.Sector, HW_DMA3_BCR_H16, HW_DMA3_BCR_L16); - - bcr = (HW_DMA3_BCR_H16 * HW_DMA3_BCR_L16) *4; - if (bcr < cdvd.BlockSize) { - CDR_LOG( "READBLOCK: bcr < cdvd.BlockSize; %x < %x", bcr, cdvd.BlockSize ); - if (HW_DMA3_CHCR & 0x01000000) { - HW_DMA3_CHCR &= ~0x01000000; - psxDmaInterrupt(3); - } - return -1; - } - - // DMAs use physical addresses (air) - u8* mdest = iopPhysMem( HW_DMA3_MADR ); - - // if raw dvd sector 'fill in the blanks' - if (cdvd.BlockSize == 2064) - { - // get info on dvd type and layer1 start - u32 layer1Start; - s32 dualType; - s32 layerNum; - u32 lsn = cdvd.Sector; - - cdvdReadDvdDualInfo(&dualType, &layer1Start); - - if((dualType == 1) && (lsn >= layer1Start)) - { - // dual layer ptp disc - layerNum = 1; - lsn = lsn-layer1Start + 0x30000; - } - else if((dualType == 2) && (lsn >= layer1Start)) - { - // dual layer otp disc - layerNum = 1; - lsn = ~(layer1Start+0x30000 - 1); - } - else - { // Assumed the other dualType is 0. - // single layer disc - // or on first layer of dual layer disc - layerNum = 0; - lsn += 0x30000; - } - - mdest[0] = 0x20 | layerNum; - mdest[1] = (u8)(lsn >> 16); - mdest[2] = (u8)(lsn >> 8); - mdest[3] = (u8)(lsn ); - - // sector IED (not calculated at present) - mdest[4] = 0; - mdest[5] = 0; - - // sector CPR_MAI (not calculated at present) - mdest[6] = 0; - mdest[7] = 0; - mdest[8] = 0; - mdest[9] = 0; - mdest[10] = 0; - mdest[11] = 0; - - // normal 2048 bytes of sector data - memcpy_fast( &mdest[12], cdr.pTransfer, 2048); - - // 4 bytes of edc (not calculated at present) - mdest[2060] = 0; - mdest[2061] = 0; - mdest[2062] = 0; - mdest[2063] = 0; - } - else - { - memcpy_fast( mdest, cdr.pTransfer, cdvd.BlockSize); - } - - // decrypt sector's bytes - if( cdvd.decSet ) mechaDecryptBytes( HW_DMA3_MADR, cdvd.BlockSize ); - - // Added a clear after memory write .. never seemed to be necessary before but *should* - // be more correct. (air) - psxCpu->Clear( HW_DMA3_MADR, cdvd.BlockSize/4 ); - -// Console::WriteLn("sector %x;%x;%x", params PSXMu8(madr+0), PSXMu8(madr+1), PSXMu8(madr+2)); - - HW_DMA3_BCR_H16 -= (cdvd.BlockSize / (HW_DMA3_BCR_L16*4)); - HW_DMA3_MADR += cdvd.BlockSize; - - return 0; -} - -// inlined due to being referenced in only one place. -__forceinline void cdvdActionInterrupt() -{ - switch( cdvd.Action ) - { - case cdvdAction_Seek: - case cdvdAction_Standby: - cdvd.Spinning = true; - cdvd.Ready = CDVD_READY1; - cdvd.Sector = cdvd.SeekToSector; - cdvd.Status = CDVD_STATUS_SEEK_COMPLETE; - break; - - case cdvdAction_Stop: - cdvd.Spinning = false; - cdvd.Ready = CDVD_READY1; - cdvd.Sector = 0; - cdvd.Status = CDVD_STATUS_NONE; - break; - - case cdvdAction_Break: - // Make sure the cdvd action state is pretty well cleared: - cdvd.Reading = 0; - cdvd.Readed = 0; - cdvd.Ready = CDVD_READY2; // should be CDVD_READY1 or something else? - cdvd.Status = CDVD_STATUS_NONE; - cdvd.RErr = 0; - cdvd.nCommand = 0; - break; - } - cdvd.Action = cdvdAction_None; - - cdvd.PwOff |= 1< Scheduling block read interrupt at iopcycle=%8.8x.", - psxRegs.cycle + cdvd.ReadTime ); - - CDVDREAD_INT(cdvd.ReadTime); - return; - } - else - { - if (cdvd.RErr == 0) - cdr.pTransfer = CDVDgetBuffer(); - else - cdr.pTransfer = NULL; - - if (cdr.pTransfer == NULL) - { - cdvd.RetryCntP++; - Console::Error("CDVD READ ERROR, sector=%d", params cdvd.Sector); - - if (cdvd.RetryCntP <= cdvd.RetryCnt) - { - cdvd.RErr = CDVDreadTrack(cdvd.Sector, cdvd.ReadMode); - CDVDREAD_INT(cdvd.ReadTime); - return; - } - } - cdvd.Reading = false; - } - - if (cdvdReadSector() == -1) - { - assert((int)cdvd.ReadTime > 0 ); - CDVDREAD_INT(cdvd.ReadTime); - return; - } - - cdvd.Sector++; - - if (--cdvd.nSectors <= 0) - { - cdvd.PwOff |= 1< Simulating CdRom Spinup Time, and seek to sector %d", cdvd.SeekToSector ); - seektime = PSXCLK / 3; // 333ms delay - cdvd.Spinning = true; - } - else if( (tbl_ContigiousSeekDelta[mode] == 0) || (delta >= tbl_ContigiousSeekDelta[mode]) ) - { - // Select either Full or Fast seek depending on delta: - - if( delta >= tbl_FastSeekDelta[mode] ) - { - // Full Seek - CDR_LOG( "CdSeek Begin > to sector %d, from %d - delta=%d [FULL]", cdvd.SeekToSector, cdvd.Sector, delta ); - seektime = Cdvd_FullSeek_Cycles; - } - else - { - CDR_LOG( "CdSeek Begin > to sector %d, from %d - delta=%d [FAST]", cdvd.SeekToSector, cdvd.Sector, delta ); - seektime = Cdvd_FastSeek_Cycles; - } - } - else - { - CDR_LOG( "CdSeek Begin > Contiguous block without seek - delta=%d sectors", delta ); - - // seektime is the time it takes to read to the destination block: - seektime = delta * cdvd.ReadTime; - - if( delta == 0 ) - { - cdvd.Status = CDVD_STATUS_SEEK_COMPLETE; - cdvd.Readed = 1; // Note: 1, not 0, as implied by the next comment. Need to look into this. --arcum42 - cdvd.RetryCntP = 0; - - // setting Readed to 0 skips the seek logic, which means the next call to - // cdvdReadInterrupt will load a block. So make sure it's properly scheduled - // based on sector read speeds: - - seektime = cdvd.ReadTime; - } - } - - return seektime; -} - -u8 monthmap[13] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -void cdvdVsync() { - cdvd.RTCcount++; - if (cdvd.RTCcount < ((Config.PsxType & 1) ? 50 : 60)) return; - cdvd.RTCcount = 0; - - cdvd.RTC.second++; - if (cdvd.RTC.second < 60) return; - cdvd.RTC.second = 0; - - cdvd.RTC.minute++; - if (cdvd.RTC.minute < 60) return; - cdvd.RTC.minute = 0; - - cdvd.RTC.hour++; - if (cdvd.RTC.hour < 24) return; - cdvd.RTC.hour = 0; - - cdvd.RTC.day++; - if (cdvd.RTC.day <= monthmap[cdvd.RTC.month-1]) return; - cdvd.RTC.day = 1; - - cdvd.RTC.month++; - if (cdvd.RTC.month <= 12) return; - cdvd.RTC.month = 1; - - cdvd.RTC.year++; - if (cdvd.RTC.year < 100) return; - cdvd.RTC.year = 0; -} - -static __forceinline u8 cdvdRead18(void) // SDATAOUT -{ - u8 ret = 0; - - if (((cdvd.sDataIn & 0x40) == 0) && (cdvd.ResultP < cdvd.ResultC)) - { - cdvd.ResultP++; - if (cdvd.ResultP >= cdvd.ResultC) cdvd.sDataIn|= 0x40; - ret = cdvd.Result[cdvd.ResultP-1]; - } - CDR_LOG("cdvdRead18(SDataOut) %x (ResultC=%d, ResultP=%d)", ret, cdvd.ResultC, cdvd.ResultP); - - return ret; -} - -u8 cdvdRead(u8 key) -{ - switch (key) - { - case 0x04: // NCOMMAND - CDR_LOG("cdvdRead04(NCMD) %x", cdvd.nCommand); - return cdvd.nCommand; - break; - - case 0x05: // N-READY - CDR_LOG("cdvdRead05(NReady) %x", cdvd.Ready); - return cdvd.Ready; - break; - - case 0x06: // ERROR - CDR_LOG("cdvdRead06(Error) %x", cdvd.Error); - return cdvd.Error; - break; - - case 0x07: // BREAK - CDR_LOG("cdvdRead07(Break) %x", 0); - return 0; - break; - - case 0x08: // STATUS - CDR_LOG("cdvdRead0A(Status) %x", cdvd.Status); - return cdvd.Status; - break; - - case 0x0A: // STATUS - CDR_LOG("cdvdRead0A(Status) %x", cdvd.Status); - return cdvd.Status; - break; - - case 0x0B: // TRAY-STATE (if tray has been opened) - { - u8 tray = cdvdGetTrayStatus(); - CDR_LOG("cdvdRead0B(Tray) %x", tray); - return tray; - break; - } - case 0x0C: // CRT MINUTE - CDR_LOG("cdvdRead0C(Min) %x", itob((u8)(cdvd.Sector/(60*75)))); - return itob((u8)(cdvd.Sector/(60*75))); - break; - - case 0x0D: // CRT SECOND - CDR_LOG("cdvdRead0D(Sec) %x", itob((u8)((cdvd.Sector/75)%60)+2)); - return itob((u8)((cdvd.Sector/75)%60)+2); - break; - - case 0x0E: // CRT FRAME - CDR_LOG("cdvdRead0E(Frame) %x", itob((u8)(cdvd.Sector%75))); - return itob((u8)(cdvd.Sector%75)); - break; - - case 0x0F: // TYPE - CDR_LOG("cdvdRead0F(Disc Type) %x", cdvd.Type); - cdvdGetDiskType(); - return cdvd.Type; - break; - - case 0x13: // UNKNOWN - CDR_LOG("cdvdRead13(Unknown) %x", 4); - return 4; - break; - - case 0x15: // RSV - CDR_LOG("cdvdRead15(RSV)"); - return 0x01; // | 0x80 for ATAPI mode - break; - - case 0x16: // SCOMMAND - CDR_LOG("cdvdRead16(SCMD) %x", cdvd.sCommand); - return cdvd.sCommand; - break; - - case 0x17: // SREADY - CDR_LOG("cdvdRead17(SReady) %x", cdvd.sDataIn); - return cdvd.sDataIn; - break; - - case 0x18: - return cdvdRead18(); - break; - - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - { - int temp = key - 0x20; - - CDR_LOG("cdvdRead%d(Key%d) %x", key, temp, cdvd.Key[temp]); - return cdvd.Key[temp]; - break; - } - case 0x28: - case 0x29: - case 0x2A: - case 0x2B: - case 0x2C: - { - int temp = key - 0x23; - - CDR_LOG("cdvdRead%d(Key%d) %x", key, temp, cdvd.Key[temp]); - return cdvd.Key[temp]; - break; - } - - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - { - int temp = key - 0x26; - - CDR_LOG("cdvdRead%d(Key%d) %x", key, temp, cdvd.Key[temp]); - return cdvd.Key[temp]; - break; - } - - case 0x38: // valid parts of key data (first and last are valid) - CDR_LOG("cdvdRead38(KeysValid) %x", cdvd.Key[15]); - - return cdvd.Key[15]; - break; - - case 0x39: // KEY-XOR - CDR_LOG("cdvdRead39(KeyXor) %x", cdvd.KeyXor); - - return cdvd.KeyXor; - break; - - case 0x3A: // DEC_SET - CDR_LOG("cdvdRead3A(DecSet) %x", cdvd.decSet); - - Console::WriteLn("DecSet Read: %02X", params cdvd.decSet); - return cdvd.decSet; - break; - - default: - // note: notify the console since this is a potentially serious emulation problem: - PSXHW_LOG("*Unknown 8bit read at address 0x1f4020%x", key); - Console::Error( "IOP Unknown 8bit read from addr 0x1f4020%x", params key ); - return 0; - break; - } -} - -static void cdvdWrite04(u8 rt) { // NCOMMAND - CDR_LOG("cdvdWrite04: NCMD %s (%x) (ParamP = %x)", nCmdName[rt], rt, cdvd.ParamP); - - cdvd.nCommand = rt; - cdvd.Status = CDVD_STATUS_NONE; - cdvd.PwOff = Irq_None; // good or bad? - - switch (rt) { - case N_CD_SYNC: // CdSync - case N_CD_NOP: // CdNop_ - cdvdSetIrq(); - break; - - case N_CD_STANDBY: // CdStandby - - // Seek to sector zero. The cdvdStartSeek function will simulate - // spinup times if needed. - - DevCon::Notice( "CdStandby : %d", params rt ); - cdvd.Action = cdvdAction_Standby; - cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); - CDVD_INT( cdvdStartSeek( 0, MODE_DVDROM ) ); - break; - - case N_CD_STOP: // CdStop - DevCon::Notice( "CdStop : %d", params rt ); - cdvd.Action = cdvdAction_Stop; - CDVD_INT( PSXCLK / 6 ); // 166ms delay? - break; - - // from an emulation point of view there is not much need to do anything for this one - case N_CD_PAUSE: // CdPause - cdvdSetIrq(); - break; - - case N_CD_SEEK: // CdSeek - cdvd.Action = cdvdAction_Seek; - cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); - CDVD_INT( cdvdStartSeek( *(uint*)(cdvd.Param+0), MODE_DVDROM ) ); - break; - - case N_CD_READ: // CdRead - cdvd.SeekToSector = *(uint*)(cdvd.Param+0); - cdvd.nSectors = *(int*)(cdvd.Param+4); - cdvd.RetryCnt = (cdvd.Param[8] == 0) ? 0x100 : cdvd.Param[8]; - cdvd.SpindlCtrl = cdvd.Param[9]; - cdvd.Speed = 24; - switch (cdvd.Param[10]) { - case 2: cdvd.ReadMode = CDVD_MODE_2340; cdvd.BlockSize = 2340; break; - case 1: cdvd.ReadMode = CDVD_MODE_2328; cdvd.BlockSize = 2328; break; - case 0: - default: cdvd.ReadMode = CDVD_MODE_2048; cdvd.BlockSize = 2048; break; - } - - CDR_LOG( "CdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)", - cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); - - if( Config.cdvdPrint ) - Console::WriteLn("CdRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx", - params cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed); - - cdvd.ReadTime = cdvdBlockReadTime( MODE_CDROM ); - CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector,MODE_CDROM ) ); - - // Read-ahead by telling the plugin about the track now. - // This helps improve performance on actual from-cd emulation - // (ie, not using the hard drive) - cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); - - // Set the reading block flag. If a seek is pending then Readed will - // take priority in the handler anyway. If the read is contiguous then - // this'll skip the seek delay. - cdvd.Reading = 1; - break; - - case N_CD_READ_CDDA: // CdReadCDDA - case N_CD_READ_XCDDA: // CdReadXCDDA - cdvd.SeekToSector = *(int*)(cdvd.Param+0); - cdvd.nSectors = *(int*)(cdvd.Param+4); - - if (cdvd.Param[8] == 0) - cdvd.RetryCnt = 0x100; - else - cdvd.RetryCnt = cdvd.Param[8]; - - cdvd.SpindlCtrl = cdvd.Param[9]; - - switch (cdvd.Param[9]) { - case 0x01: cdvd.Speed = 1; break; - case 0x02: cdvd.Speed = 2; break; - case 0x03: cdvd.Speed = 4; break; - case 0x04: cdvd.Speed = 12; break; - default: cdvd.Speed = 24; break; - } - - switch (cdvd.Param[10]) { - case 1: cdvd.ReadMode = CDVD_MODE_2368; cdvd.BlockSize = 2368; break; - case 2: - case 0: cdvd.ReadMode = CDVD_MODE_2352; cdvd.BlockSize = 2352; break; - } - - CDR_LOG( "CdReadCDDA > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%xx(%x), ReadMode=%x(%x) (1074=%x)", - cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); - - if( Config.cdvdPrint ) - Console::WriteLn("CdAudioRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx", - params cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed); - - cdvd.ReadTime = cdvdBlockReadTime( MODE_CDROM ); - CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector, MODE_CDROM ) ); - - // Read-ahead by telling the plugin about the track now. - // This helps improve performance on actual from-cd emulation - // (ie, not using the hard drive) - cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); - - // Set the reading block flag. If a seek is pending then Readed will - // take priority in the handler anyway. If the read is contiguous then - // this'll skip the seek delay. - cdvd.Reading = 1; - break; - - case N_DVD_READ: // DvdRead - cdvd.SeekToSector = *(int*)(cdvd.Param+0); - cdvd.nSectors = *(int*)(cdvd.Param+4); - - if (cdvd.Param[8] == 0) - cdvd.RetryCnt = 0x100; - else - cdvd.RetryCnt = cdvd.Param[8]; - - cdvd.SpindlCtrl = cdvd.Param[9]; - cdvd.Speed = 4; - cdvd.ReadMode = CDVD_MODE_2048; - cdvd.BlockSize = 2064; // Why oh why was it 2064 - - CDR_LOG( "DvdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)", - cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); - - if( Config.cdvdPrint ) - Console::WriteLn("DvdRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx", - params cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed); - - cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); - CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector, MODE_DVDROM ) ); - - // Read-ahead by telling the plugin about the track now. - // This helps improve performance on actual from-cd emulation - // (ie, not using the hard drive) - cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); - - // Set the reading block flag. If a seek is pending then Readed will - // take priority in the handler anyway. If the read is contiguous then - // this'll skip the seek delay. - cdvd.Reading = 1; - break; - - case N_CD_GET_TOC: // CdGetToc & cdvdman_call19 - //Param[0] is 0 for CdGetToc and any value for cdvdman_call19 - //the code below handles only CdGetToc! - //if(cdvd.Param[0]==0x01) - //{ - DevCon::WriteLn("CDGetToc Param[0]=%d, Param[1]=%d", params cdvd.Param[0],cdvd.Param[1]); - //} - cdvdGetToc( iopPhysMem( HW_DMA3_MADR ) ); - cdvdSetIrq( (1< remote key code - SetResultSize(5); - cdvd.Result[0] = 0x00; - cdvd.Result[1] = 0x14; - cdvd.Result[2] = 0x00; - cdvd.Result[3] = 0x00; - cdvd.Result[4] = 0x00; - break; - -// case 0x1F: // sceRemote2_7 (2:1) - cdvdman_call117 -// break; - - case 0x20: // sceRemote2_6 (0:3) // 00 01 00 - SetResultSize(3); - cdvd.Result[0] = 0x00; - cdvd.Result[1] = 0x01; - cdvd.Result[2] = 0x00; - break; - -// case 0x21: // sceCdWriteWakeUpTime (8:1) -// break; - - case 0x22: // sceCdReadWakeUpTime (0:10) - SetResultSize(10); - cdvd.Result[0] = 0; - cdvd.Result[1] = 0; - cdvd.Result[2] = 0; - cdvd.Result[3] = 0; - cdvd.Result[4] = 0; - cdvd.Result[5] = 0; - cdvd.Result[6] = 0; - cdvd.Result[7] = 0; - cdvd.Result[8] = 0; - cdvd.Result[9] = 0; - break; - - case 0x24: // sceCdRCBypassCtrl (1:1) - In V10 Bios - // FIXME: because PRId<0x23, the bit 0 of sio2 don't get updated 0xBF808284 - SetResultSize(1); - cdvd.Result[0] = 0; - break; - -// case 0x25: // cdvdman_call120 (1:1) - In V10 Bios -// break; - -// case 0x26: // cdvdman_call128 (0,3) - In V10 Bios -// break; - -// case 0x27: // cdvdman_call148 (0:13) - In V10 Bios -// break; - -// case 0x28: // cdvdman_call150 (1:1) - In V10 Bios -// break; - - case 0x29: //sceCdNoticeGameStart (1:1) - SetResultSize(1); - cdvd.Result[0] = 0; - break; - -// case 0x2C: //sceCdXBSPowerCtl (2:2) -// break; - -// case 0x2D: //sceCdXLEDCtl (2:2) -// break; - -// case 0x2E: //sceCdBuzzerCtl (0:1) -// break; - -// case 0x2F: //cdvdman_call167 (16:1) -// break; - -// case 0x30: //cdvdman_call169 (1:9) -// break; - - case 0x31: //sceCdSetMediumRemoval (1:1) - SetResultSize(1); - cdvd.Result[0] = 0; - break; - - case 0x32: //sceCdGetMediumRemoval (0:2) - SetResultSize(2); - cdvd.Result[0] = 0; - //cdvd.Result[0] = 0; // fixme: I'm pretty sure that the same variable shouldn't be set twice here. Perhaps cdvd.Result[1]? - break; - -// case 0x33: //sceCdXDVRPReset (1:1) -// break; - - case 0x36: //cdvdman_call189 [__sceCdReadRegionParams - made up name] (0:15) i think it is 16, not 15 - SetResultSize(15); - - cdvdGetMechaVer(&cdvd.Result[1]); - cdvd.Result[0] = cdvdReadRegionParams(&cdvd.Result[3]);//size==8 - Console::WriteLn("REGION PARAMS = %s %s", params mg_zones[cdvd.Result[1]], &cdvd.Result[3]); - cdvd.Result[1] = 1 << cdvd.Result[1]; //encryption zone; see offset 0x1C in encrypted headers - ////////////////////////////////////////// - cdvd.Result[2] = 0; //?? -// cdvd.Result[3] == ROMVER[4] == *0xBFC7FF04 -// cdvd.Result[4] == OSDVER[4] == CAP Jjpn, Aeng, Eeng, Heng, Reng, Csch, Kkor? -// cdvd.Result[5] == OSDVER[5] == small -// cdvd.Result[6] == OSDVER[6] == small -// cdvd.Result[7] == OSDVER[7] == small -// cdvd.Result[8] == VERSTR[0x22] == *0xBFC7FF52 -// cdvd.Result[9] == DVDID J U O E A R C M -// cdvd.Result[10]== 0; //?? - cdvd.Result[11] = 0; //?? - cdvd.Result[12] = 0; //?? - ////////////////////////////////////////// - cdvd.Result[13] = 0; //0xFF - 77001 - cdvd.Result[14] = 0; //?? - break; - - case 0x37: //called from EECONF [sceCdReadMAC - made up name] (0:9) - SetResultSize(9); - cdvd.Result[0] = cdvdReadMAC(&cdvd.Result[1]); - break; - - case 0x38: //used to fix the MAC back after accidentally trashed it :D [sceCdWriteMAC - made up name] (8:1) - SetResultSize(1); - cdvd.Result[0] = cdvdWriteMAC(&cdvd.Param[0]); - break; - - case 0x3E: //[__sceCdWriteRegionParams - made up name] (15:1) [Florin: hum, i was expecting 14:1] - SetResultSize(1); - cdvd.Result[0] = cdvdWriteRegionParams(&cdvd.Param[2]); - break; - - case 0x40: // CdOpenConfig (3:1) - SetResultSize(1); - cdvd.CReadWrite = cdvd.Param[0]; - cdvd.COffset = cdvd.Param[1]; - cdvd.CNumBlocks = cdvd.Param[2]; - cdvd.CBlockIndex= 0; - cdvd.Result[0] = 0; - break; - - case 0x41: // CdReadConfig (0:16) - SetResultSize(16); - cdvdReadConfig(&cdvd.Result[0]); - break; - - case 0x42: // CdWriteConfig (16:1) - SetResultSize(1); - cdvd.Result[0] = cdvdWriteConfig(&cdvd.Param[0]); - break; - - case 0x43: // CdCloseConfig (0:1) - SetResultSize(1); - cdvd.CReadWrite = 0; - cdvd.COffset = 0; - cdvd.CNumBlocks = 0; - cdvd.CBlockIndex= 0; - cdvd.Result[0] = 0; - break; - - case 0x80: // secrman: __mechacon_auth_0x80 - SetResultSize(1);//in:1 - cdvd.mg_datatype = 0;//data - cdvd.Result[0] = 0; - break; - - case 0x81: // secrman: __mechacon_auth_0x81 - SetResultSize(1);//in:1 - cdvd.mg_datatype = 0;//data - cdvd.Result[0] = 0; - break; - - case 0x82: // secrman: __mechacon_auth_0x82 - SetResultSize(1);//in:16 - cdvd.Result[0] = 0; - break; - - case 0x83: // secrman: __mechacon_auth_0x83 - SetResultSize(1);//in:8 - cdvd.Result[0] = 0; - break; - - case 0x84: // secrman: __mechacon_auth_0x84 - SetResultSize(1+8+4);//in:0 - cdvd.Result[0] = 0; - - cdvd.Result[1] = 0x21; - cdvd.Result[2] = 0xdc; - cdvd.Result[3] = 0x31; - cdvd.Result[4] = 0x96; - cdvd.Result[5] = 0xce; - cdvd.Result[6] = 0x72; - cdvd.Result[7] = 0xe0; - cdvd.Result[8] = 0xc8; - - cdvd.Result[9] = 0x69; - cdvd.Result[10] = 0xda; - cdvd.Result[11] = 0x34; - cdvd.Result[12] = 0x9b; - break; - - case 0x85: // secrman: __mechacon_auth_0x85 - SetResultSize(1+4+8);//in:0 - cdvd.Result[0] = 0; - - cdvd.Result[1] = 0xeb; - cdvd.Result[2] = 0x01; - cdvd.Result[3] = 0xc7; - cdvd.Result[4] = 0xa9; - - cdvd.Result[ 5] = 0x3f; - cdvd.Result[ 6] = 0x9c; - cdvd.Result[ 7] = 0x5b; - cdvd.Result[ 8] = 0x19; - cdvd.Result[ 9] = 0x31; - cdvd.Result[10] = 0xa0; - cdvd.Result[11] = 0xb3; - cdvd.Result[12] = 0xa3; - break; - - case 0x86: // secrman: __mechacon_auth_0x86 - SetResultSize(1);//in:16 - cdvd.Result[0] = 0; - break; - - case 0x87: // secrman: __mechacon_auth_0x87 - SetResultSize(1);//in:8 - cdvd.Result[0] = 0; - break; - - case 0x8D: // sceMgWriteData - SetResultSize(1);//in:length<=16 - if (cdvd.mg_size + cdvd.ParamC > cdvd.mg_maxsize) - { - cdvd.Result[0] = 0x80; - } - else - { - memcpy_fast(cdvd.mg_buffer + cdvd.mg_size, cdvd.Param, cdvd.ParamC); - cdvd.mg_size += cdvd.ParamC; - cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error - } - break; - - case 0x8E: // sceMgReadData - SetResultSize( std::min(16, cdvd.mg_size) ); - memcpy_fast(cdvd.Result, cdvd.mg_buffer, cdvd.ResultC); - cdvd.mg_size -= cdvd.ResultC; - memcpy_fast(cdvd.mg_buffer, cdvd.mg_buffer+cdvd.ResultC, cdvd.mg_size); - break; - - case 0x88: // secrman: __mechacon_auth_0x88 //for now it is the same; so, fall;) - case 0x8F: // secrman: __mechacon_auth_0x8F - SetResultSize(1);//in:0 - if (cdvd.mg_datatype == 1) // header data - { - u64* psrc, *pdst; - int bit_ofs, i; - - if ((cdvd.mg_maxsize != cdvd.mg_size)||(cdvd.mg_size < 0x20) || (cdvd.mg_size != *(u16*)&cdvd.mg_buffer[0x14])) - { - fail_pol_cal(); - break; - } - - Console::Write("[MG] ELF_size=0x%X Hdr_size=0x%X unk=0x%X flags=0x%X count=%d zones=", - params *(u32*)&cdvd.mg_buffer[0x10], *(u16*)&cdvd.mg_buffer[0x14], *(u16*)&cdvd.mg_buffer[0x16], - *(u16*)&cdvd.mg_buffer[0x18], *(u16*)&cdvd.mg_buffer[0x1A]); - for (i=0; i<8; i++) - { - if (cdvd.mg_buffer[0x1C] & (1<> 0) & 0xFF; - cdvd.Result[2] = (cdvd.mg_size >> 8) & 0xFF; - break; - } - case 0x92: // sceMgWriteDatainLength - SetResultSize(1);//in:2 - cdvd.mg_size = 0; - cdvd.mg_datatype = 0;//data (encrypted) - cdvd.mg_maxsize = cdvd.Param[0] | (((int)cdvd.Param[1])<<8); - cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error - break; - - case 0x93: // sceMgWriteDataoutLength - SetResultSize(1);//in:2 - if (((cdvd.Param[0] | (((int)cdvd.Param[1])<<8)) == cdvd.mg_size) && (cdvd.mg_datatype == 0)) - { - cdvd.mg_maxsize = 0; // don't allow any write - cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error - } - else - { - cdvd.Result[0] = 0x80; - } - break; - - case 0x94: // sceMgReadKbit - read first half of BIT key - SetResultSize(1+8);//in:0 - cdvd.Result[0] = 0; - - ((int*)(cdvd.Result+1))[0] = ((int*)cdvd.mg_kbit)[0]; - ((int*)(cdvd.Result+1))[1] = ((int*)cdvd.mg_kbit)[1]; - //memcpy(cdvd.Result+1, cdvd.mg_kbit, 8); - break; - - case 0x95: // sceMgReadKbit2 - read second half of BIT key - SetResultSize(1+8);//in:0 - cdvd.Result[0] = 0; - ((int*)(cdvd.Result+1))[0] = ((int*)(cdvd.mg_kbit+8))[0]; - ((int*)(cdvd.Result+1))[1] = ((int*)(cdvd.mg_kbit+8))[1]; - //memcpy(cdvd.Result+1, cdvd.mg_kbit+8, 8); - break; - - case 0x96: // sceMgReadKcon - read first half of content key - SetResultSize(1+8);//in:0 - cdvd.Result[0] = 0; - ((int*)(cdvd.Result+1))[0] = ((int*)cdvd.mg_kcon)[0]; - ((int*)(cdvd.Result+1))[1] = ((int*)cdvd.mg_kcon)[1]; - //memcpy(cdvd.Result+1, cdvd.mg_kcon, 8); - break; - - case 0x97: // sceMgReadKcon2 - read second half of content key - SetResultSize(1+8);//in:0 - cdvd.Result[0] = 0; - ((int*)(cdvd.Result+1))[0] = ((int*)(cdvd.mg_kcon+8))[0]; - ((int*)(cdvd.Result+1))[1] = ((int*)(cdvd.mg_kcon+8))[1]; - //memcpy(cdvd.Result+1, cdvd.mg_kcon+8, 8); - break; - - default: - // fake a 'correct' command - SetResultSize(1); //in:0 - cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error - Console::WriteLn("SCMD Unknown %x", params rt); - break; - } // end switch - - //Console::WriteLn("SCMD - 0x%x\n", params rt); - cdvd.ParamP = 0; - cdvd.ParamC = 0; -} - -static __forceinline void cdvdWrite17(u8 rt) { // SDATAIN - CDR_LOG("cdvdWrite17(SDataIn) %x", rt); - - if (cdvd.ParamP < 32) { - cdvd.Param[cdvd.ParamP++] = rt; - cdvd.ParamC++; - } -} - -static __forceinline void cdvdWrite18(u8 rt) { // SDATAOUT - CDR_LOG("cdvdWrite18(SDataOut) %x", rt); - Console::WriteLn("*PCSX2* SDATAOUT"); -} - -static __forceinline void cdvdWrite3A(u8 rt) { // DEC-SET - CDR_LOG("cdvdWrite3A(DecSet) %x", rt); - cdvd.decSet = rt; - Console::WriteLn("DecSet Write: %02X", params cdvd.decSet); -} - -void cdvdWrite(u8 key, u8 rt) -{ - switch (key) - { - case 0x04: cdvdWrite04(rt); break; - case 0x05: cdvdWrite05(rt); break; - case 0x06: cdvdWrite06(rt); break; - case 0x07: cdvdWrite07(rt); break; - case 0x08: cdvdWrite08(rt); break; - case 0x0A: cdvdWrite0A(rt); break; - case 0x0F: cdvdWrite0F(rt); break; - case 0x14: cdvdWrite14(rt); break; - case 0x16: cdvdWrite16(rt); break; - case 0x17: cdvdWrite17(rt); break; - case 0x18: cdvdWrite18(rt); break; - case 0x3A: cdvdWrite3A(rt); break; - default: - Console::Notice("IOP Unknown 8bit write to addr 0x1f4020%x = 0x%x", params key, rt); - break; - } -} \ No newline at end of file +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" + +#include +#include + +#include "IopCommon.h" +#include "CDVDiso.h" +#include "CDVD_internal.h" + +static cdvdStruct cdvd; + +static __forceinline void SetResultSize(u8 size) +{ + cdvd.ResultC = size; + cdvd.ResultP = 0; + cdvd.sDataIn&=~0x40; +} + +static void CDVDREAD_INT(int eCycle) +{ + PSX_INT(IopEvt_CdvdRead, eCycle); +} + +static void CDVD_INT(int eCycle) +{ + if( eCycle == 0 ) + cdvdActionInterrupt(); + else + PSX_INT(IopEvt_Cdvd, eCycle); +} + +// Sets the cdvd IRQ and the reason for the IRQ, and signals the IOP for a branch +// test (which will cause the exception to be handled). +static void cdvdSetIrq( uint id = (1< 0) { if (ptr[i] == '.') break; i--; } + ptr[i+1] = '\0'; + strcat(file, "MEC"); + + // if file doesnt exist, create empty one + fd = fopen(file, "r+b"); + if (fd == NULL) { + Console::Notice("MEC File Not Found , Creating Blank File"); + fd = fopen(file, "wb"); + if (fd == NULL) + { + Console::Error( "\tMEC File Creation failed!" ); + throw Exception::CreateStream( file ); + //Msgbox::Alert( "_cdvdOpenMechaVer: Error creating %s", params file); + //exit(1); + } + + fputc(0x03, fd); + fputc(0x06, fd); + fputc(0x02, fd); + fputc(0x00, fd); + } + return fd; +} + +s32 cdvdGetMechaVer(u8* ver) +{ + FILE* fd = _cdvdOpenMechaVer(); + if (fd == NULL) return 1; + fseek(fd, 0, SEEK_SET); + fread(ver, 1, 4, fd); + fclose(fd); + return 0; +} + +FILE *_cdvdOpenNVM() { + char *ptr; + int i; + char file[g_MaxPath]; + FILE* fd; + + // get the name of the bios file + + // use the bios filename to get the name of the nvm file + // [TODO] : Upgrade this to use std::string! + + strcpy( file, g_Conf.Files.Bios().ToAscii().data() ); + ptr = file; + i = (int)strlen(file); + + while (i > 0) { if (ptr[i] == '.') break; i--; } + ptr[i+1] = '\0'; + + strcat(file, "NVM"); + + // if file doesnt exist, create empty one + fd = fopen(file, "r+b"); + if (fd == NULL) { + Console::Notice("NVM File Not Found , Creating Blank File"); + fd = fopen(file, "wb"); + if (fd == NULL) + { + throw Exception::CreateStream( file ); + //Msgbox::Alert("_cdvdOpenNVM: Error creating %s", params file); + //exit(1); + } + for (i=0; i<1024; i++) fputc(0, fd); + } + return fd; +} + +// +// the following 'cdvd' functions all return 0 if successful +// + +s32 cdvdReadNVM(u8 *dst, int offset, int bytes) { + FILE* fd = _cdvdOpenNVM(); + if (fd == NULL) return 1; + + fseek(fd, offset, SEEK_SET); + fread(dst, 1, bytes, fd); + fclose(fd); + + return 0; +} +s32 cdvdWriteNVM(const u8 *src, int offset, int bytes) { + FILE* fd = _cdvdOpenNVM(); + if (fd == NULL) return 1; + + fseek(fd, offset, SEEK_SET); + fwrite(src, 1, bytes, fd); + fclose(fd); + + return 0; +} + +NVMLayout* getNvmLayout(void) +{ + NVMLayout* nvmLayout = NULL; + s32 nvmIdx; + + for(nvmIdx=0; nvmIdx= cdvd.CNumBlocks) + return 1; + else if( + ((cdvd.COffset == 0) && (cdvd.CBlockIndex >= 4))|| + ((cdvd.COffset == 1) && (cdvd.CBlockIndex >= 2))|| + ((cdvd.COffset == 2) && (cdvd.CBlockIndex >= 7)) + ) + { + memzero_ptr<16>(config); + return 0; + } + + // get config data + switch (cdvd.COffset) + { + case 0: + return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config0)); + break; + case 2: + return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config2)); + break; + default: + return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config1)); + } +} +s32 cdvdWriteConfig(const u8* config) +{ + // make sure its in write mode + if(cdvd.CReadWrite != 1) + return 1; + // check if block index is in bounds + else if(cdvd.CBlockIndex >= cdvd.CNumBlocks) + return 1; + else if( + ((cdvd.COffset == 0) && (cdvd.CBlockIndex >= 4))|| + ((cdvd.COffset == 1) && (cdvd.CBlockIndex >= 2))|| + ((cdvd.COffset == 2) && (cdvd.CBlockIndex >= 7)) + ) + return 0; + + // get config data + switch (cdvd.COffset) + { + case 0: + return setNvmData(config, (cdvd.CBlockIndex++)*16, 16,offsetof(NVMLayout, config0)); + break; + case 2: + return setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config2)); + break; + default: + return setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config1)); + } +} + + +void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) { + wxString fname; + char exeName[12]; + s32 numbers, letters; + u32 key_0_3; + u8 key_4, key_14; + + // get main elf name + GetPS2ElfName(fname); + const wxCharBuffer crap( fname.ToAscii() ); + const char* str = crap.data(); + sprintf(exeName, "%c%c%c%c%c%c%c%c%c%c%c",str[8],str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16],str[17],str[18]); + DevCon::Notice("exeName = %s", params &str[8]); + + // convert the number characters to a real 32bit number + numbers = ((((exeName[5] - '0'))*10000) + + (((exeName[ 6] - '0'))*1000) + + (((exeName[ 7] - '0'))*100) + + (((exeName[ 9] - '0'))*10) + + (((exeName[10] - '0'))*1) ); + + // combine the lower 7 bits of each char + // to make the 4 letters fit into a single u32 + letters = (s32)((exeName[3]&0x7F)<< 0) | + (s32)((exeName[2]&0x7F)<< 7) | + (s32)((exeName[1]&0x7F)<<14) | + (s32)((exeName[0]&0x7F)<<21); + + // calculate magic numbers + key_0_3 = ((numbers & 0x1FC00) >> 10) | ((0x01FFFFFF & letters) << 7); // numbers = 7F letters = FFFFFF80 + key_4 = ((numbers & 0x0001F) << 3) | ((0x0E000000 & letters) >> 25); // numbers = F8 letters = 07 + key_14 = ((numbers & 0x003E0) >> 2) | 0x04; // numbers = F8 extra = 04 unused = 03 + + // clear key values + memzero_ptr<16>(key); + + // store key values + key[ 0] = (key_0_3&0x000000FF)>> 0; + key[ 1] = (key_0_3&0x0000FF00)>> 8; + key[ 2] = (key_0_3&0x00FF0000)>>16; + key[ 3] = (key_0_3&0xFF000000)>>24; + key[ 4] = key_4; + + if(arg2 == 75) + { + key[14] = key_14; + key[15] = 0x05; + } + else if(arg2 == 3075) + { + key[15] = 0x01; + } + else if(arg2 == 4246) + { + // 0x0001F2F707 = sector 0x0001F2F7 dec 0x07 + key[ 0] = 0x07; + key[ 1] = 0xF7; + key[ 2] = 0xF2; + key[ 3] = 0x01; + key[ 4] = 0x00; + key[15] = 0x01; + } + else + { + key[15] = 0x01; + } + + Console::WriteLn( "CDVD.KEY = %02X,%02X,%02X,%02X,%02X,%02X,%02X", params + cdvd.Key[0],cdvd.Key[1],cdvd.Key[2],cdvd.Key[3],cdvd.Key[4],cdvd.Key[14],cdvd.Key[15] ); + + // Now's a good time to reload the ELF info... + if( ElfCRC == 0 ) + { + ElfCRC = loadElfCRC( str ); + ElfApplyPatches(); + GSsetGameCRC( ElfCRC, 0 ); + } +} + +s32 cdvdGetToc(void* toc) +{ + s32 ret = CDVDgetTOC(toc); + if (ret == -1) ret = 0x80; + return ret; +} + +s32 cdvdReadSubQ(s32 lsn, cdvdSubQ* subq) +{ + s32 ret = CDVDreadSubQ(lsn, subq); + if (ret == -1) ret = 0x80; + return ret; +} + +s32 cdvdCtrlTrayOpen() +{ + s32 ret = CDVDctrlTrayOpen(); + if (ret == -1) ret = 0x80; + return ret; +} + +s32 cdvdCtrlTrayClose() +{ + s32 ret = CDVDctrlTrayClose(); + if (ret == -1) ret = 0x80; + return ret; +} + +// Modified by (efp) - 16/01/2006 +// checks if tray was opened since last call to this func +s32 cdvdGetTrayStatus() +{ + s32 ret = CDVDgetTrayStatus(); + + if (ret == -1) + return(CDVD_TRAY_CLOSE); + else + return(ret); +} + +// Note: Is tray status being kept as a var here somewhere? +// cdvdNewDiskCB() can update it's status as well... + +// Modified by (efp) - 16/01/2006 +static __forceinline void cdvdGetDiskType() +{ + // defs 0.9.0 + if (CDVDnewDiskCB || (cdvd.Type != CDVD_TYPE_NODISC)) return; + + // defs.0.8.1 + if (cdvdGetTrayStatus() == CDVD_TRAY_OPEN) + { + cdvd.Type = CDVD_TYPE_NODISC; + return; + } + + cdvd.Type = CDVDgetDiskType(); + + // Is the type listed as a PS2 CD? + if (cdvd.Type == CDVD_TYPE_PS2CD) // && needReset == 1) + { + wxString str; + + if (GetPS2ElfName(str) == 1) + { + // Does the SYSTEM.CNF file only say "BOOT="? PS1 CD then. + cdvd.Type = CDVD_TYPE_PSCD; + } + } +} + +// check whether disc is single or dual layer +// if its dual layer, check what the disctype is and what sector number +// layer1 starts at +// +// args: gets value for dvd type (0=single layer, 1=ptp, 2=otp) +// gets value for start lsn of layer1 +// returns: 1 if on dual layer disc +// 0 if not on dual layer disc +static s32 cdvdReadDvdDualInfo(s32* dualType, u32* layer1Start) +{ + u8 toc[2064]; + *dualType = 0; + *layer1Start = 0; + + // if error getting toc, settle for single layer disc ;) + if(cdvdGetToc(toc)) + return 0; + if(toc[14] & 0x60) + { + if(toc[14] & 0x10) + { + // otp dvd + *dualType = 2; + *layer1Start = (toc[25]<<16) + (toc[26]<<8) + (toc[27]) - 0x30000 + 1; + } + else + { + // ptp dvd + *dualType = 1; + *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1; + } + } + else + { + // single layer dvd + *dualType = 0; + *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1; + } + + return 1; +} + +static uint cdvdBlockReadTime( CDVD_MODE_TYPE mode ) +{ + return (PSXCLK * cdvd.BlockSize) / (((mode==MODE_CDROM) ? PSX_CD_READSPEED : PSX_DVD_READSPEED) * cdvd.Speed); +} + +void cdvdReset() +{ + memzero_obj(cdvd); + + cdvd.Type = CDVD_TYPE_NODISC; + cdvd.Spinning = false; + + cdvd.sDataIn = 0x40; + cdvd.Ready = CDVD_READY2; + cdvd.Speed = 4; + cdvd.BlockSize = 2064; + cdvd.Action = cdvdAction_None; + cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); + + wxDateTime curtime( wxDateTime::GetTimeNow() ); + cdvd.RTC.second = (u8)curtime.GetSecond(); + cdvd.RTC.minute = (u8)curtime.GetMinute(); + cdvd.RTC.hour = (u8)(curtime.GetHour()+1) % 24; + cdvd.RTC.day = (u8)curtime.GetDay(); + cdvd.RTC.month = (u8)curtime.GetMonth(); + cdvd.RTC.year = (u8)(curtime.GetYear() - 2000); +} + +struct Freeze_v10Compat +{ + u8 Action; + u32 SeekToSector; + u32 ReadTime; + bool Spinning; +}; + +void SaveState::cdvdFreeze() +{ + FreezeTag( "cdvd" ); + Freeze( cdvd ); + + if (IsLoading()) + { + // Make sure the Cdvd plugin has the expected track loaded into the buffer. + // If cdvd.Readed is cleared it means we need to load the SeekToSector (ie, a + // seek is in progress!) + + if( cdvd.Reading ) + cdvd.RErr = CDVDreadTrack( cdvd.Readed ? cdvd.Sector : cdvd.SeekToSector, cdvd.ReadMode); + } +} + +// Modified by (efp) - 16/01/2006 +void cdvdNewDiskCB() +{ + cdvd.Type = CDVDgetDiskType(); + + wxString str; + int result = GetPS2ElfName(str); + + if (cdvd.Type == CDVD_TYPE_PS2CD) + { + + // Does the SYSTEM.CNF file only say "BOOT="? PS1 CD then. + if(result == 1) cdvd.Type = CDVD_TYPE_PSCD; + } + + // Now's a good time to reload the ELF info... + if( ElfCRC == 0 ) + { + ElfCRC = loadElfCRC( str.ToAscii().data() ); + ElfApplyPatches(); + GSsetGameCRC( ElfCRC, 0 ); + } + +} + +void mechaDecryptBytes( u32 madr, int size ) +{ + int i; + + int shiftAmount = (cdvd.decSet>>4) & 7; + int doXor = (cdvd.decSet) & 1; + int doShift = (cdvd.decSet) & 2; + + u8* curval = iopPhysMem( madr ); + for( i=0; i> shiftAmount) | (*curval << (8-shiftAmount) ); + } +} + +int cdvdReadSector() { + s32 bcr; + + CDR_LOG("SECTOR %d (BCR %x;%x)", cdvd.Sector, HW_DMA3_BCR_H16, HW_DMA3_BCR_L16); + + bcr = (HW_DMA3_BCR_H16 * HW_DMA3_BCR_L16) *4; + if (bcr < cdvd.BlockSize) { + CDR_LOG( "READBLOCK: bcr < cdvd.BlockSize; %x < %x", bcr, cdvd.BlockSize ); + if (HW_DMA3_CHCR & 0x01000000) { + HW_DMA3_CHCR &= ~0x01000000; + psxDmaInterrupt(3); + } + return -1; + } + + // DMAs use physical addresses (air) + u8* mdest = iopPhysMem( HW_DMA3_MADR ); + + // if raw dvd sector 'fill in the blanks' + if (cdvd.BlockSize == 2064) + { + // get info on dvd type and layer1 start + u32 layer1Start; + s32 dualType; + s32 layerNum; + u32 lsn = cdvd.Sector; + + cdvdReadDvdDualInfo(&dualType, &layer1Start); + + if((dualType == 1) && (lsn >= layer1Start)) + { + // dual layer ptp disc + layerNum = 1; + lsn = lsn-layer1Start + 0x30000; + } + else if((dualType == 2) && (lsn >= layer1Start)) + { + // dual layer otp disc + layerNum = 1; + lsn = ~(layer1Start+0x30000 - 1); + } + else + { // Assumed the other dualType is 0. + // single layer disc + // or on first layer of dual layer disc + layerNum = 0; + lsn += 0x30000; + } + + mdest[0] = 0x20 | layerNum; + mdest[1] = (u8)(lsn >> 16); + mdest[2] = (u8)(lsn >> 8); + mdest[3] = (u8)(lsn ); + + // sector IED (not calculated at present) + mdest[4] = 0; + mdest[5] = 0; + + // sector CPR_MAI (not calculated at present) + mdest[6] = 0; + mdest[7] = 0; + mdest[8] = 0; + mdest[9] = 0; + mdest[10] = 0; + mdest[11] = 0; + + // normal 2048 bytes of sector data + memcpy_fast( &mdest[12], cdr.pTransfer, 2048); + + // 4 bytes of edc (not calculated at present) + mdest[2060] = 0; + mdest[2061] = 0; + mdest[2062] = 0; + mdest[2063] = 0; + } + else + { + memcpy_fast( mdest, cdr.pTransfer, cdvd.BlockSize); + } + + // decrypt sector's bytes + if( cdvd.decSet ) mechaDecryptBytes( HW_DMA3_MADR, cdvd.BlockSize ); + + // Added a clear after memory write .. never seemed to be necessary before but *should* + // be more correct. (air) + psxCpu->Clear( HW_DMA3_MADR, cdvd.BlockSize/4 ); + +// Console::WriteLn("sector %x;%x;%x", params PSXMu8(madr+0), PSXMu8(madr+1), PSXMu8(madr+2)); + + HW_DMA3_BCR_H16 -= (cdvd.BlockSize / (HW_DMA3_BCR_L16*4)); + HW_DMA3_MADR += cdvd.BlockSize; + + return 0; +} + +// inlined due to being referenced in only one place. +__forceinline void cdvdActionInterrupt() +{ + switch( cdvd.Action ) + { + case cdvdAction_Seek: + case cdvdAction_Standby: + cdvd.Spinning = true; + cdvd.Ready = CDVD_READY1; + cdvd.Sector = cdvd.SeekToSector; + cdvd.Status = CDVD_STATUS_SEEK_COMPLETE; + break; + + case cdvdAction_Stop: + cdvd.Spinning = false; + cdvd.Ready = CDVD_READY1; + cdvd.Sector = 0; + cdvd.Status = CDVD_STATUS_NONE; + break; + + case cdvdAction_Break: + // Make sure the cdvd action state is pretty well cleared: + cdvd.Reading = 0; + cdvd.Readed = 0; + cdvd.Ready = CDVD_READY2; // should be CDVD_READY1 or something else? + cdvd.Status = CDVD_STATUS_NONE; + cdvd.RErr = 0; + cdvd.nCommand = 0; + break; + } + cdvd.Action = cdvdAction_None; + + cdvd.PwOff |= 1< Scheduling block read interrupt at iopcycle=%8.8x.", + psxRegs.cycle + cdvd.ReadTime ); + + CDVDREAD_INT(cdvd.ReadTime); + return; + } + else + { + if (cdvd.RErr == 0) + cdr.pTransfer = CDVDgetBuffer(); + else + cdr.pTransfer = NULL; + + if (cdr.pTransfer == NULL) + { + cdvd.RetryCntP++; + Console::Error("CDVD READ ERROR, sector=%d", params cdvd.Sector); + + if (cdvd.RetryCntP <= cdvd.RetryCnt) + { + cdvd.RErr = CDVDreadTrack(cdvd.Sector, cdvd.ReadMode); + CDVDREAD_INT(cdvd.ReadTime); + return; + } + } + cdvd.Reading = false; + } + + if (cdvdReadSector() == -1) + { + assert((int)cdvd.ReadTime > 0 ); + CDVDREAD_INT(cdvd.ReadTime); + return; + } + + cdvd.Sector++; + + if (--cdvd.nSectors <= 0) + { + cdvd.PwOff |= 1< Simulating CdRom Spinup Time, and seek to sector %d", cdvd.SeekToSector ); + seektime = PSXCLK / 3; // 333ms delay + cdvd.Spinning = true; + } + else if( (tbl_ContigiousSeekDelta[mode] == 0) || (delta >= tbl_ContigiousSeekDelta[mode]) ) + { + // Select either Full or Fast seek depending on delta: + + if( delta >= tbl_FastSeekDelta[mode] ) + { + // Full Seek + CDR_LOG( "CdSeek Begin > to sector %d, from %d - delta=%d [FULL]", cdvd.SeekToSector, cdvd.Sector, delta ); + seektime = Cdvd_FullSeek_Cycles; + } + else + { + CDR_LOG( "CdSeek Begin > to sector %d, from %d - delta=%d [FAST]", cdvd.SeekToSector, cdvd.Sector, delta ); + seektime = Cdvd_FastSeek_Cycles; + } + } + else + { + CDR_LOG( "CdSeek Begin > Contiguous block without seek - delta=%d sectors", delta ); + + // seektime is the time it takes to read to the destination block: + seektime = delta * cdvd.ReadTime; + + if( delta == 0 ) + { + cdvd.Status = CDVD_STATUS_SEEK_COMPLETE; + cdvd.Readed = 1; // Note: 1, not 0, as implied by the next comment. Need to look into this. --arcum42 + cdvd.RetryCntP = 0; + + // setting Readed to 0 skips the seek logic, which means the next call to + // cdvdReadInterrupt will load a block. So make sure it's properly scheduled + // based on sector read speeds: + + seektime = cdvd.ReadTime; + } + } + + return seektime; +} + +u8 monthmap[13] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +void cdvdVsync() { + cdvd.RTCcount++; + if (cdvd.RTCcount < ((Config.PsxType & 1) ? 50 : 60)) return; + cdvd.RTCcount = 0; + + cdvd.RTC.second++; + if (cdvd.RTC.second < 60) return; + cdvd.RTC.second = 0; + + cdvd.RTC.minute++; + if (cdvd.RTC.minute < 60) return; + cdvd.RTC.minute = 0; + + cdvd.RTC.hour++; + if (cdvd.RTC.hour < 24) return; + cdvd.RTC.hour = 0; + + cdvd.RTC.day++; + if (cdvd.RTC.day <= monthmap[cdvd.RTC.month-1]) return; + cdvd.RTC.day = 1; + + cdvd.RTC.month++; + if (cdvd.RTC.month <= 12) return; + cdvd.RTC.month = 1; + + cdvd.RTC.year++; + if (cdvd.RTC.year < 100) return; + cdvd.RTC.year = 0; +} + +static __forceinline u8 cdvdRead18(void) // SDATAOUT +{ + u8 ret = 0; + + if (((cdvd.sDataIn & 0x40) == 0) && (cdvd.ResultP < cdvd.ResultC)) + { + cdvd.ResultP++; + if (cdvd.ResultP >= cdvd.ResultC) cdvd.sDataIn|= 0x40; + ret = cdvd.Result[cdvd.ResultP-1]; + } + CDR_LOG("cdvdRead18(SDataOut) %x (ResultC=%d, ResultP=%d)", ret, cdvd.ResultC, cdvd.ResultP); + + return ret; +} + +u8 cdvdRead(u8 key) +{ + switch (key) + { + case 0x04: // NCOMMAND + CDR_LOG("cdvdRead04(NCMD) %x", cdvd.nCommand); + return cdvd.nCommand; + break; + + case 0x05: // N-READY + CDR_LOG("cdvdRead05(NReady) %x", cdvd.Ready); + return cdvd.Ready; + break; + + case 0x06: // ERROR + CDR_LOG("cdvdRead06(Error) %x", cdvd.Error); + return cdvd.Error; + break; + + case 0x07: // BREAK + CDR_LOG("cdvdRead07(Break) %x", 0); + return 0; + break; + + case 0x08: // STATUS + CDR_LOG("cdvdRead0A(Status) %x", cdvd.Status); + return cdvd.Status; + break; + + case 0x0A: // STATUS + CDR_LOG("cdvdRead0A(Status) %x", cdvd.Status); + return cdvd.Status; + break; + + case 0x0B: // TRAY-STATE (if tray has been opened) + { + u8 tray = cdvdGetTrayStatus(); + CDR_LOG("cdvdRead0B(Tray) %x", tray); + return tray; + break; + } + case 0x0C: // CRT MINUTE + CDR_LOG("cdvdRead0C(Min) %x", itob((u8)(cdvd.Sector/(60*75)))); + return itob((u8)(cdvd.Sector/(60*75))); + break; + + case 0x0D: // CRT SECOND + CDR_LOG("cdvdRead0D(Sec) %x", itob((u8)((cdvd.Sector/75)%60)+2)); + return itob((u8)((cdvd.Sector/75)%60)+2); + break; + + case 0x0E: // CRT FRAME + CDR_LOG("cdvdRead0E(Frame) %x", itob((u8)(cdvd.Sector%75))); + return itob((u8)(cdvd.Sector%75)); + break; + + case 0x0F: // TYPE + CDR_LOG("cdvdRead0F(Disc Type) %x", cdvd.Type); + cdvdGetDiskType(); + return cdvd.Type; + break; + + case 0x13: // UNKNOWN + CDR_LOG("cdvdRead13(Unknown) %x", 4); + return 4; + break; + + case 0x15: // RSV + CDR_LOG("cdvdRead15(RSV)"); + return 0x01; // | 0x80 for ATAPI mode + break; + + case 0x16: // SCOMMAND + CDR_LOG("cdvdRead16(SCMD) %x", cdvd.sCommand); + return cdvd.sCommand; + break; + + case 0x17: // SREADY + CDR_LOG("cdvdRead17(SReady) %x", cdvd.sDataIn); + return cdvd.sDataIn; + break; + + case 0x18: + return cdvdRead18(); + break; + + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + { + int temp = key - 0x20; + + CDR_LOG("cdvdRead%d(Key%d) %x", key, temp, cdvd.Key[temp]); + return cdvd.Key[temp]; + break; + } + case 0x28: + case 0x29: + case 0x2A: + case 0x2B: + case 0x2C: + { + int temp = key - 0x23; + + CDR_LOG("cdvdRead%d(Key%d) %x", key, temp, cdvd.Key[temp]); + return cdvd.Key[temp]; + break; + } + + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + { + int temp = key - 0x26; + + CDR_LOG("cdvdRead%d(Key%d) %x", key, temp, cdvd.Key[temp]); + return cdvd.Key[temp]; + break; + } + + case 0x38: // valid parts of key data (first and last are valid) + CDR_LOG("cdvdRead38(KeysValid) %x", cdvd.Key[15]); + + return cdvd.Key[15]; + break; + + case 0x39: // KEY-XOR + CDR_LOG("cdvdRead39(KeyXor) %x", cdvd.KeyXor); + + return cdvd.KeyXor; + break; + + case 0x3A: // DEC_SET + CDR_LOG("cdvdRead3A(DecSet) %x", cdvd.decSet); + + Console::WriteLn("DecSet Read: %02X", params cdvd.decSet); + return cdvd.decSet; + break; + + default: + // note: notify the console since this is a potentially serious emulation problem: + PSXHW_LOG("*Unknown 8bit read at address 0x1f4020%x", key); + Console::Error( "IOP Unknown 8bit read from addr 0x1f4020%x", params key ); + return 0; + break; + } +} + +static void cdvdWrite04(u8 rt) { // NCOMMAND + CDR_LOG("cdvdWrite04: NCMD %s (%x) (ParamP = %x)", nCmdName[rt], rt, cdvd.ParamP); + + cdvd.nCommand = rt; + cdvd.Status = CDVD_STATUS_NONE; + cdvd.PwOff = Irq_None; // good or bad? + + switch (rt) { + case N_CD_SYNC: // CdSync + case N_CD_NOP: // CdNop_ + cdvdSetIrq(); + break; + + case N_CD_STANDBY: // CdStandby + + // Seek to sector zero. The cdvdStartSeek function will simulate + // spinup times if needed. + + DevCon::Notice( "CdStandby : %d", params rt ); + cdvd.Action = cdvdAction_Standby; + cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); + CDVD_INT( cdvdStartSeek( 0, MODE_DVDROM ) ); + break; + + case N_CD_STOP: // CdStop + DevCon::Notice( "CdStop : %d", params rt ); + cdvd.Action = cdvdAction_Stop; + CDVD_INT( PSXCLK / 6 ); // 166ms delay? + break; + + // from an emulation point of view there is not much need to do anything for this one + case N_CD_PAUSE: // CdPause + cdvdSetIrq(); + break; + + case N_CD_SEEK: // CdSeek + cdvd.Action = cdvdAction_Seek; + cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); + CDVD_INT( cdvdStartSeek( *(uint*)(cdvd.Param+0), MODE_DVDROM ) ); + break; + + case N_CD_READ: // CdRead + cdvd.SeekToSector = *(uint*)(cdvd.Param+0); + cdvd.nSectors = *(int*)(cdvd.Param+4); + cdvd.RetryCnt = (cdvd.Param[8] == 0) ? 0x100 : cdvd.Param[8]; + cdvd.SpindlCtrl = cdvd.Param[9]; + cdvd.Speed = 24; + switch (cdvd.Param[10]) { + case 2: cdvd.ReadMode = CDVD_MODE_2340; cdvd.BlockSize = 2340; break; + case 1: cdvd.ReadMode = CDVD_MODE_2328; cdvd.BlockSize = 2328; break; + case 0: + default: cdvd.ReadMode = CDVD_MODE_2048; cdvd.BlockSize = 2048; break; + } + + CDR_LOG( "CdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)", + cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); + + if( Config.cdvdPrint ) + Console::WriteLn("CdRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx", + params cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed); + + cdvd.ReadTime = cdvdBlockReadTime( MODE_CDROM ); + CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector,MODE_CDROM ) ); + + // Read-ahead by telling the plugin about the track now. + // This helps improve performance on actual from-cd emulation + // (ie, not using the hard drive) + cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); + + // Set the reading block flag. If a seek is pending then Readed will + // take priority in the handler anyway. If the read is contiguous then + // this'll skip the seek delay. + cdvd.Reading = 1; + break; + + case N_CD_READ_CDDA: // CdReadCDDA + case N_CD_READ_XCDDA: // CdReadXCDDA + cdvd.SeekToSector = *(int*)(cdvd.Param+0); + cdvd.nSectors = *(int*)(cdvd.Param+4); + + if (cdvd.Param[8] == 0) + cdvd.RetryCnt = 0x100; + else + cdvd.RetryCnt = cdvd.Param[8]; + + cdvd.SpindlCtrl = cdvd.Param[9]; + + switch (cdvd.Param[9]) { + case 0x01: cdvd.Speed = 1; break; + case 0x02: cdvd.Speed = 2; break; + case 0x03: cdvd.Speed = 4; break; + case 0x04: cdvd.Speed = 12; break; + default: cdvd.Speed = 24; break; + } + + switch (cdvd.Param[10]) { + case 1: cdvd.ReadMode = CDVD_MODE_2368; cdvd.BlockSize = 2368; break; + case 2: + case 0: cdvd.ReadMode = CDVD_MODE_2352; cdvd.BlockSize = 2352; break; + } + + CDR_LOG( "CdReadCDDA > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%xx(%x), ReadMode=%x(%x) (1074=%x)", + cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); + + if( Config.cdvdPrint ) + Console::WriteLn("CdAudioRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx", + params cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed); + + cdvd.ReadTime = cdvdBlockReadTime( MODE_CDROM ); + CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector, MODE_CDROM ) ); + + // Read-ahead by telling the plugin about the track now. + // This helps improve performance on actual from-cd emulation + // (ie, not using the hard drive) + cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); + + // Set the reading block flag. If a seek is pending then Readed will + // take priority in the handler anyway. If the read is contiguous then + // this'll skip the seek delay. + cdvd.Reading = 1; + break; + + case N_DVD_READ: // DvdRead + cdvd.SeekToSector = *(int*)(cdvd.Param+0); + cdvd.nSectors = *(int*)(cdvd.Param+4); + + if (cdvd.Param[8] == 0) + cdvd.RetryCnt = 0x100; + else + cdvd.RetryCnt = cdvd.Param[8]; + + cdvd.SpindlCtrl = cdvd.Param[9]; + cdvd.Speed = 4; + cdvd.ReadMode = CDVD_MODE_2048; + cdvd.BlockSize = 2064; // Why oh why was it 2064 + + CDR_LOG( "DvdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)", + cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); + + if( Config.cdvdPrint ) + Console::WriteLn("DvdRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx", + params cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed); + + cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); + CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector, MODE_DVDROM ) ); + + // Read-ahead by telling the plugin about the track now. + // This helps improve performance on actual from-cd emulation + // (ie, not using the hard drive) + cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); + + // Set the reading block flag. If a seek is pending then Readed will + // take priority in the handler anyway. If the read is contiguous then + // this'll skip the seek delay. + cdvd.Reading = 1; + break; + + case N_CD_GET_TOC: // CdGetToc & cdvdman_call19 + //Param[0] is 0 for CdGetToc and any value for cdvdman_call19 + //the code below handles only CdGetToc! + //if(cdvd.Param[0]==0x01) + //{ + DevCon::WriteLn("CDGetToc Param[0]=%d, Param[1]=%d", params cdvd.Param[0],cdvd.Param[1]); + //} + cdvdGetToc( iopPhysMem( HW_DMA3_MADR ) ); + cdvdSetIrq( (1< remote key code + SetResultSize(5); + cdvd.Result[0] = 0x00; + cdvd.Result[1] = 0x14; + cdvd.Result[2] = 0x00; + cdvd.Result[3] = 0x00; + cdvd.Result[4] = 0x00; + break; + +// case 0x1F: // sceRemote2_7 (2:1) - cdvdman_call117 +// break; + + case 0x20: // sceRemote2_6 (0:3) // 00 01 00 + SetResultSize(3); + cdvd.Result[0] = 0x00; + cdvd.Result[1] = 0x01; + cdvd.Result[2] = 0x00; + break; + +// case 0x21: // sceCdWriteWakeUpTime (8:1) +// break; + + case 0x22: // sceCdReadWakeUpTime (0:10) + SetResultSize(10); + cdvd.Result[0] = 0; + cdvd.Result[1] = 0; + cdvd.Result[2] = 0; + cdvd.Result[3] = 0; + cdvd.Result[4] = 0; + cdvd.Result[5] = 0; + cdvd.Result[6] = 0; + cdvd.Result[7] = 0; + cdvd.Result[8] = 0; + cdvd.Result[9] = 0; + break; + + case 0x24: // sceCdRCBypassCtrl (1:1) - In V10 Bios + // FIXME: because PRId<0x23, the bit 0 of sio2 don't get updated 0xBF808284 + SetResultSize(1); + cdvd.Result[0] = 0; + break; + +// case 0x25: // cdvdman_call120 (1:1) - In V10 Bios +// break; + +// case 0x26: // cdvdman_call128 (0,3) - In V10 Bios +// break; + +// case 0x27: // cdvdman_call148 (0:13) - In V10 Bios +// break; + +// case 0x28: // cdvdman_call150 (1:1) - In V10 Bios +// break; + + case 0x29: //sceCdNoticeGameStart (1:1) + SetResultSize(1); + cdvd.Result[0] = 0; + break; + +// case 0x2C: //sceCdXBSPowerCtl (2:2) +// break; + +// case 0x2D: //sceCdXLEDCtl (2:2) +// break; + +// case 0x2E: //sceCdBuzzerCtl (0:1) +// break; + +// case 0x2F: //cdvdman_call167 (16:1) +// break; + +// case 0x30: //cdvdman_call169 (1:9) +// break; + + case 0x31: //sceCdSetMediumRemoval (1:1) + SetResultSize(1); + cdvd.Result[0] = 0; + break; + + case 0x32: //sceCdGetMediumRemoval (0:2) + SetResultSize(2); + cdvd.Result[0] = 0; + //cdvd.Result[0] = 0; // fixme: I'm pretty sure that the same variable shouldn't be set twice here. Perhaps cdvd.Result[1]? + break; + +// case 0x33: //sceCdXDVRPReset (1:1) +// break; + + case 0x36: //cdvdman_call189 [__sceCdReadRegionParams - made up name] (0:15) i think it is 16, not 15 + SetResultSize(15); + + cdvdGetMechaVer(&cdvd.Result[1]); + cdvd.Result[0] = cdvdReadRegionParams(&cdvd.Result[3]);//size==8 + Console::WriteLn("REGION PARAMS = %s %s", params mg_zones[cdvd.Result[1]], &cdvd.Result[3]); + cdvd.Result[1] = 1 << cdvd.Result[1]; //encryption zone; see offset 0x1C in encrypted headers + ////////////////////////////////////////// + cdvd.Result[2] = 0; //?? +// cdvd.Result[3] == ROMVER[4] == *0xBFC7FF04 +// cdvd.Result[4] == OSDVER[4] == CAP Jjpn, Aeng, Eeng, Heng, Reng, Csch, Kkor? +// cdvd.Result[5] == OSDVER[5] == small +// cdvd.Result[6] == OSDVER[6] == small +// cdvd.Result[7] == OSDVER[7] == small +// cdvd.Result[8] == VERSTR[0x22] == *0xBFC7FF52 +// cdvd.Result[9] == DVDID J U O E A R C M +// cdvd.Result[10]== 0; //?? + cdvd.Result[11] = 0; //?? + cdvd.Result[12] = 0; //?? + ////////////////////////////////////////// + cdvd.Result[13] = 0; //0xFF - 77001 + cdvd.Result[14] = 0; //?? + break; + + case 0x37: //called from EECONF [sceCdReadMAC - made up name] (0:9) + SetResultSize(9); + cdvd.Result[0] = cdvdReadMAC(&cdvd.Result[1]); + break; + + case 0x38: //used to fix the MAC back after accidentally trashed it :D [sceCdWriteMAC - made up name] (8:1) + SetResultSize(1); + cdvd.Result[0] = cdvdWriteMAC(&cdvd.Param[0]); + break; + + case 0x3E: //[__sceCdWriteRegionParams - made up name] (15:1) [Florin: hum, i was expecting 14:1] + SetResultSize(1); + cdvd.Result[0] = cdvdWriteRegionParams(&cdvd.Param[2]); + break; + + case 0x40: // CdOpenConfig (3:1) + SetResultSize(1); + cdvd.CReadWrite = cdvd.Param[0]; + cdvd.COffset = cdvd.Param[1]; + cdvd.CNumBlocks = cdvd.Param[2]; + cdvd.CBlockIndex= 0; + cdvd.Result[0] = 0; + break; + + case 0x41: // CdReadConfig (0:16) + SetResultSize(16); + cdvdReadConfig(&cdvd.Result[0]); + break; + + case 0x42: // CdWriteConfig (16:1) + SetResultSize(1); + cdvd.Result[0] = cdvdWriteConfig(&cdvd.Param[0]); + break; + + case 0x43: // CdCloseConfig (0:1) + SetResultSize(1); + cdvd.CReadWrite = 0; + cdvd.COffset = 0; + cdvd.CNumBlocks = 0; + cdvd.CBlockIndex= 0; + cdvd.Result[0] = 0; + break; + + case 0x80: // secrman: __mechacon_auth_0x80 + SetResultSize(1);//in:1 + cdvd.mg_datatype = 0;//data + cdvd.Result[0] = 0; + break; + + case 0x81: // secrman: __mechacon_auth_0x81 + SetResultSize(1);//in:1 + cdvd.mg_datatype = 0;//data + cdvd.Result[0] = 0; + break; + + case 0x82: // secrman: __mechacon_auth_0x82 + SetResultSize(1);//in:16 + cdvd.Result[0] = 0; + break; + + case 0x83: // secrman: __mechacon_auth_0x83 + SetResultSize(1);//in:8 + cdvd.Result[0] = 0; + break; + + case 0x84: // secrman: __mechacon_auth_0x84 + SetResultSize(1+8+4);//in:0 + cdvd.Result[0] = 0; + + cdvd.Result[1] = 0x21; + cdvd.Result[2] = 0xdc; + cdvd.Result[3] = 0x31; + cdvd.Result[4] = 0x96; + cdvd.Result[5] = 0xce; + cdvd.Result[6] = 0x72; + cdvd.Result[7] = 0xe0; + cdvd.Result[8] = 0xc8; + + cdvd.Result[9] = 0x69; + cdvd.Result[10] = 0xda; + cdvd.Result[11] = 0x34; + cdvd.Result[12] = 0x9b; + break; + + case 0x85: // secrman: __mechacon_auth_0x85 + SetResultSize(1+4+8);//in:0 + cdvd.Result[0] = 0; + + cdvd.Result[1] = 0xeb; + cdvd.Result[2] = 0x01; + cdvd.Result[3] = 0xc7; + cdvd.Result[4] = 0xa9; + + cdvd.Result[ 5] = 0x3f; + cdvd.Result[ 6] = 0x9c; + cdvd.Result[ 7] = 0x5b; + cdvd.Result[ 8] = 0x19; + cdvd.Result[ 9] = 0x31; + cdvd.Result[10] = 0xa0; + cdvd.Result[11] = 0xb3; + cdvd.Result[12] = 0xa3; + break; + + case 0x86: // secrman: __mechacon_auth_0x86 + SetResultSize(1);//in:16 + cdvd.Result[0] = 0; + break; + + case 0x87: // secrman: __mechacon_auth_0x87 + SetResultSize(1);//in:8 + cdvd.Result[0] = 0; + break; + + case 0x8D: // sceMgWriteData + SetResultSize(1);//in:length<=16 + if (cdvd.mg_size + cdvd.ParamC > cdvd.mg_maxsize) + { + cdvd.Result[0] = 0x80; + } + else + { + memcpy_fast(cdvd.mg_buffer + cdvd.mg_size, cdvd.Param, cdvd.ParamC); + cdvd.mg_size += cdvd.ParamC; + cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error + } + break; + + case 0x8E: // sceMgReadData + SetResultSize( std::min(16, cdvd.mg_size) ); + memcpy_fast(cdvd.Result, cdvd.mg_buffer, cdvd.ResultC); + cdvd.mg_size -= cdvd.ResultC; + memcpy_fast(cdvd.mg_buffer, cdvd.mg_buffer+cdvd.ResultC, cdvd.mg_size); + break; + + case 0x88: // secrman: __mechacon_auth_0x88 //for now it is the same; so, fall;) + case 0x8F: // secrman: __mechacon_auth_0x8F + SetResultSize(1);//in:0 + if (cdvd.mg_datatype == 1) // header data + { + u64* psrc, *pdst; + int bit_ofs, i; + + if ((cdvd.mg_maxsize != cdvd.mg_size)||(cdvd.mg_size < 0x20) || (cdvd.mg_size != *(u16*)&cdvd.mg_buffer[0x14])) + { + fail_pol_cal(); + break; + } + + Console::Write("[MG] ELF_size=0x%X Hdr_size=0x%X unk=0x%X flags=0x%X count=%d zones=", + params *(u32*)&cdvd.mg_buffer[0x10], *(u16*)&cdvd.mg_buffer[0x14], *(u16*)&cdvd.mg_buffer[0x16], + *(u16*)&cdvd.mg_buffer[0x18], *(u16*)&cdvd.mg_buffer[0x1A]); + for (i=0; i<8; i++) + { + if (cdvd.mg_buffer[0x1C] & (1<> 0) & 0xFF; + cdvd.Result[2] = (cdvd.mg_size >> 8) & 0xFF; + break; + } + case 0x92: // sceMgWriteDatainLength + SetResultSize(1);//in:2 + cdvd.mg_size = 0; + cdvd.mg_datatype = 0;//data (encrypted) + cdvd.mg_maxsize = cdvd.Param[0] | (((int)cdvd.Param[1])<<8); + cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error + break; + + case 0x93: // sceMgWriteDataoutLength + SetResultSize(1);//in:2 + if (((cdvd.Param[0] | (((int)cdvd.Param[1])<<8)) == cdvd.mg_size) && (cdvd.mg_datatype == 0)) + { + cdvd.mg_maxsize = 0; // don't allow any write + cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error + } + else + { + cdvd.Result[0] = 0x80; + } + break; + + case 0x94: // sceMgReadKbit - read first half of BIT key + SetResultSize(1+8);//in:0 + cdvd.Result[0] = 0; + + ((int*)(cdvd.Result+1))[0] = ((int*)cdvd.mg_kbit)[0]; + ((int*)(cdvd.Result+1))[1] = ((int*)cdvd.mg_kbit)[1]; + //memcpy(cdvd.Result+1, cdvd.mg_kbit, 8); + break; + + case 0x95: // sceMgReadKbit2 - read second half of BIT key + SetResultSize(1+8);//in:0 + cdvd.Result[0] = 0; + ((int*)(cdvd.Result+1))[0] = ((int*)(cdvd.mg_kbit+8))[0]; + ((int*)(cdvd.Result+1))[1] = ((int*)(cdvd.mg_kbit+8))[1]; + //memcpy(cdvd.Result+1, cdvd.mg_kbit+8, 8); + break; + + case 0x96: // sceMgReadKcon - read first half of content key + SetResultSize(1+8);//in:0 + cdvd.Result[0] = 0; + ((int*)(cdvd.Result+1))[0] = ((int*)cdvd.mg_kcon)[0]; + ((int*)(cdvd.Result+1))[1] = ((int*)cdvd.mg_kcon)[1]; + //memcpy(cdvd.Result+1, cdvd.mg_kcon, 8); + break; + + case 0x97: // sceMgReadKcon2 - read second half of content key + SetResultSize(1+8);//in:0 + cdvd.Result[0] = 0; + ((int*)(cdvd.Result+1))[0] = ((int*)(cdvd.mg_kcon+8))[0]; + ((int*)(cdvd.Result+1))[1] = ((int*)(cdvd.mg_kcon+8))[1]; + //memcpy(cdvd.Result+1, cdvd.mg_kcon+8, 8); + break; + + default: + // fake a 'correct' command + SetResultSize(1); //in:0 + cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error + Console::WriteLn("SCMD Unknown %x", params rt); + break; + } // end switch + + //Console::WriteLn("SCMD - 0x%x\n", params rt); + cdvd.ParamP = 0; + cdvd.ParamC = 0; +} + +static __forceinline void cdvdWrite17(u8 rt) { // SDATAIN + CDR_LOG("cdvdWrite17(SDataIn) %x", rt); + + if (cdvd.ParamP < 32) { + cdvd.Param[cdvd.ParamP++] = rt; + cdvd.ParamC++; + } +} + +static __forceinline void cdvdWrite18(u8 rt) { // SDATAOUT + CDR_LOG("cdvdWrite18(SDataOut) %x", rt); + Console::WriteLn("*PCSX2* SDATAOUT"); +} + +static __forceinline void cdvdWrite3A(u8 rt) { // DEC-SET + CDR_LOG("cdvdWrite3A(DecSet) %x", rt); + cdvd.decSet = rt; + Console::WriteLn("DecSet Write: %02X", params cdvd.decSet); +} + +void cdvdWrite(u8 key, u8 rt) +{ + switch (key) + { + case 0x04: cdvdWrite04(rt); break; + case 0x05: cdvdWrite05(rt); break; + case 0x06: cdvdWrite06(rt); break; + case 0x07: cdvdWrite07(rt); break; + case 0x08: cdvdWrite08(rt); break; + case 0x0A: cdvdWrite0A(rt); break; + case 0x0F: cdvdWrite0F(rt); break; + case 0x14: cdvdWrite14(rt); break; + case 0x16: cdvdWrite16(rt); break; + case 0x17: cdvdWrite17(rt); break; + case 0x18: cdvdWrite18(rt); break; + case 0x3A: cdvdWrite3A(rt); break; + default: + Console::Notice("IOP Unknown 8bit write to addr 0x1f4020%x = 0x%x", params key, rt); + break; + } +} diff --git a/pcsx2/CDVD/CDVD.h b/pcsx2/CDVD/CDVD.h new file mode 100644 index 0000000000..0fd7822a38 --- /dev/null +++ b/pcsx2/CDVD/CDVD.h @@ -0,0 +1,103 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +#include "IopCommon.h" + +#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ +#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ + +struct cdvdRTC { + u8 status; + u8 second; + u8 minute; + u8 hour; + u8 pad; + u8 day; + u8 month; + u8 year; +}; + +struct cdvdStruct { + u8 nCommand; + u8 Ready; + u8 Error; + u8 PwOff; + u8 Status; + u8 Type; + u8 sCommand; + u8 sDataIn; + u8 sDataOut; + u8 HowTo; + + u8 Param[32]; + u8 Result[32]; + + u8 ParamC; + u8 ParamP; + u8 ResultC; + u8 ResultP; + + u8 CBlockIndex; + u8 COffset; + u8 CReadWrite; + u8 CNumBlocks; + + int RTCcount; + cdvdRTC RTC; + + u32 Sector; + int nSectors; + int Readed; // change to bool. --arcum42 + int Reading; // same here. + int ReadMode; + int BlockSize; // Total bytes transfered at 1x speed + int Speed; + int RetryCnt; + int RetryCntP; + int RErr; + int SpindlCtrl; + + u8 Key[16]; + u8 KeyXor; + u8 decSet; + + u8 mg_buffer[65536]; + int mg_size; + int mg_maxsize; + int mg_datatype;//0-data(encrypted); 1-header + u8 mg_kbit[16];//last BIT key 'seen' + u8 mg_kcon[16];//last content key 'seen' + + u8 Action; // the currently scheduled emulated action + u32 SeekToSector; // Holds the destination sector during seek operations. + u32 ReadTime; // Avg. time to read one block of data (in Iop cycles) + bool Spinning; // indicates if the Cdvd is spinning or needs a spinup delay +}; + +extern void cdvdReset(); +extern void cdvdVsync(); +extern void cdvdActionInterrupt(); +extern void cdvdReadInterrupt(); + +// We really should not have a function with the exact same name as a callback except for case! +extern void cdvdNewDiskCB(); +extern u8 cdvdRead(u8 key); +extern void cdvdWrite(u8 key, u8 rt); + diff --git a/pcsx2/CDVD.h b/pcsx2/CDVD/CDVD_internal.h similarity index 83% rename from pcsx2/CDVD.h rename to pcsx2/CDVD/CDVD_internal.h index 3cdff54af2..c51c46e309 100644 --- a/pcsx2/CDVD.h +++ b/pcsx2/CDVD/CDVD_internal.h @@ -15,79 +15,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#ifndef __CDVD_H__ -#define __CDVD_H__ - -#include "IopCommon.h" - -struct cdvdRTC { - u8 status; - u8 second; - u8 minute; - u8 hour; - u8 pad; - u8 day; - u8 month; - u8 year; -}; - -struct cdvdStruct { - u8 nCommand; - u8 Ready; - u8 Error; - u8 PwOff; - u8 Status; - u8 Type; - u8 sCommand; - u8 sDataIn; - u8 sDataOut; - u8 HowTo; - - u8 Param[32]; - u8 Result[32]; - - u8 ParamC; - u8 ParamP; - u8 ResultC; - u8 ResultP; - - u8 CBlockIndex; - u8 COffset; - u8 CReadWrite; - u8 CNumBlocks; - - int RTCcount; - cdvdRTC RTC; - - u32 Sector; - int nSectors; - int Readed; // change to bool. --arcum42 - int Reading; // same here. - int ReadMode; - int BlockSize; // Total bytes transfered at 1x speed - int Speed; - int RetryCnt; - int RetryCntP; - int RErr; - int SpindlCtrl; - - u8 Key[16]; - u8 KeyXor; - u8 decSet; - - u8 mg_buffer[65536]; - int mg_size; - int mg_maxsize; - int mg_datatype;//0-data(encrypted); 1-header - u8 mg_kbit[16];//last BIT key 'seen' - u8 mg_kcon[16];//last content key 'seen' - - u8 Action; // the currently scheduled emulated action - u32 SeekToSector; // Holds the destination sector during seek operations. - u32 ReadTime; // Avg. time to read one block of data (in Iop cycles) - bool Spinning; // indicates if the Cdvd is spinning or needs a spinup delay -}; + +#ifndef __CDVD_INTERNAL_H__ +#define __CDVD_INTERNAL_H__ /* Interrupts - values are flag bits. @@ -191,7 +121,6 @@ static const uint tbl_ContigiousSeekDelta[3] = static const uint PSX_CD_READSPEED = 153600; // 1 Byte Time @ x1 (150KB = cd x 1) static const uint PSX_DVD_READSPEED = 1382400 + 256000; // normal is 1 Byte Time @ x1 (1350KB = dvd x 1). - // Legacy Note: FullSeek timing causes many games to load very slow, but it likely not the real problem. // Games breaking with it set to PSXCLK*40 : "wrath unleashed" and "Shijou Saikyou no Deshi Kenichi". @@ -301,15 +230,4 @@ static NVMLayout nvmlayouts[NVM_FORMAT_MAX] = {0x146, 0x270, 0x2B0, 0x200, 0x1C8, 0x1E0, 0x1B0, 0x180, 0x198}, // eeproms from bios v1.70 and up }; -#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ -#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ - -void cdvdReset(); -void cdvdVsync(); -extern void cdvdActionInterrupt(); -extern void cdvdReadInterrupt(); -void cdvdNewDiskCB(); -u8 cdvdRead(u8 key); -void cdvdWrite(u8 key, u8 rt); - -#endif /* __CDVD_H__ */ +#endif \ No newline at end of file diff --git a/pcsx2/CDVDiso.cpp b/pcsx2/CDVD/CDVDiso.cpp similarity index 100% rename from pcsx2/CDVDiso.cpp rename to pcsx2/CDVD/CDVDiso.cpp diff --git a/pcsx2/CDVDiso.h b/pcsx2/CDVD/CDVDiso.h similarity index 100% rename from pcsx2/CDVDiso.h rename to pcsx2/CDVD/CDVDiso.h diff --git a/pcsx2/CDVDisodrv.cpp b/pcsx2/CDVD/CDVDisodrv.cpp similarity index 100% rename from pcsx2/CDVDisodrv.cpp rename to pcsx2/CDVD/CDVDisodrv.cpp diff --git a/pcsx2/CDVDisodrv.h b/pcsx2/CDVD/CDVDisodrv.h similarity index 100% rename from pcsx2/CDVDisodrv.h rename to pcsx2/CDVD/CDVDisodrv.h diff --git a/pcsx2/CDVDlib.h b/pcsx2/CDVD/CDVDlib.h similarity index 100% rename from pcsx2/CDVDlib.h rename to pcsx2/CDVD/CDVDlib.h diff --git a/pcsx2/CdRom.cpp b/pcsx2/CDVD/CdRom.cpp similarity index 97% rename from pcsx2/CdRom.cpp rename to pcsx2/CDVD/CdRom.cpp index 6d8e3ab8bd..7f5c940d9a 100644 --- a/pcsx2/CdRom.cpp +++ b/pcsx2/CDVD/CdRom.cpp @@ -71,7 +71,7 @@ const char *CmdName[0x100]= { }; cdrStruct cdr; -long LoadCdBios; +s32 LoadCdBios; u8 Test04[] = { 0 }; u8 Test05[] = { 0 }; @@ -83,12 +83,15 @@ u8 Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; // PSXCLK = 1 sec in the ps // so (PSXCLK / 75) / BIAS = cdr read time (linuzappz) //#define cdReadTime ((PSXCLK / 75) / BIAS) -unsigned long cdReadTime;// = ((PSXCLK / 75) / BIAS); +u32 cdReadTime;// = ((PSXCLK / 75) / BIAS); #define CDR_INT(eCycle) PSX_INT(IopEvt_Cdrom, eCycle) #define CDREAD_INT(eCycle) PSX_INT(IopEvt_CdromRead, eCycle) -static __forceinline void StartReading(unsigned long type) { + +static void AddIrqQueue(u8 irq, u32 ecycle); + +static __forceinline void StartReading(u32 type) { cdr.Reading = type; cdr.FirstSector = 1; cdr.Readed = 0xff; @@ -149,7 +152,7 @@ static void ReadTrack() { #define DataEnd 4 #define DiskError 5 -static void AddIrqQueue(u8 irq, unsigned long ecycle) { +static void AddIrqQueue(u8 irq, u32 ecycle) { cdr.Irq = irq; if (cdr.Stat) { cdr.eCycle = ecycle; @@ -510,7 +513,7 @@ void cdrReadInterrupt() { cdr.StatP|= 0x22; cdr.Result[0] = cdr.StatP; - Console::Status( "Reading From CDR" ); + Console::Status("Reading From CDR"); buf = CDVDgetBuffer(); if (buf == NULL) cdr.RErr = -1; @@ -649,7 +652,7 @@ void cdrWrite1(u8 rt) { for (i=0; i<3; i++) cdr.SetSector[i] = btoi(cdr.Param[i]); cdr.SetSector[3] = 0; if ((cdr.SetSector[0] | cdr.SetSector[1] | cdr.SetSector[2]) == 0) { - *(unsigned long *)cdr.SetSector = *(unsigned long *)cdr.SetSectorSeek; + *(u32 *)cdr.SetSector = *(u32 *)cdr.SetSectorSeek; } cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; @@ -780,14 +783,14 @@ void cdrWrite1(u8 rt) { break; case CdlSeekL: - ((unsigned long *)cdr.SetSectorSeek)[0] = ((unsigned long *)cdr.SetSector)[0]; + ((u32 *)cdr.SetSectorSeek)[0] = ((u32 *)cdr.SetSector)[0]; cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlSeekP: - ((unsigned long *)cdr.SetSectorSeek)[0] = ((unsigned long *)cdr.SetSector)[0]; + ((u32 *)cdr.SetSectorSeek)[0] = ((u32 *)cdr.SetSector)[0]; cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); diff --git a/pcsx2/CdRom.h b/pcsx2/CDVD/CdRom.h similarity index 87% rename from pcsx2/CdRom.h rename to pcsx2/CDVD/CdRom.h index 36ceba98a2..cb46373957 100644 --- a/pcsx2/CdRom.h +++ b/pcsx2/CDVD/CdRom.h @@ -20,9 +20,23 @@ #define __CDROM_H__ #include "IopCommon.h" -#include "Decode_XA.h" #include "PS2Edefs.h" +// Not used. +typedef struct { + s32 y0, y1; +} ADPCM_Decode_t; + +// Not used. +typedef struct { + s32 freq; + s32 nbits; + s32 stereo; + s32 nsamples; + ADPCM_Decode_t left, right; + s16 pcm[16384]; +} xa_decode_t; + struct cdrStruct { u8 OCUP; @@ -48,7 +62,7 @@ struct cdrStruct u8 ResultReady; u8 Cmd; u8 Readed; - unsigned long Reading; + u32 Reading; cdvdTN ResultTN; u8 ResultTD[4]; @@ -67,13 +81,11 @@ struct cdrStruct int Init; u8 Irq; - unsigned long eCycle; + u32 eCycle; char Unused[4087]; }; -void AddIrqQueue(u8 irq, unsigned long ecycle); - extern cdrStruct cdr; void cdrReset(); diff --git a/pcsx2/CDVD/Makefile.am b/pcsx2/CDVD/Makefile.am new file mode 100644 index 0000000000..be2de4296b --- /dev/null +++ b/pcsx2/CDVD/Makefile.am @@ -0,0 +1,18 @@ +pcsx2_dir = $(top_srcdir)/.. +common_dir = $(pcsx2_dir)/common/include +third_dir = $(pcsx2_dir)/3rdparty +cdvd_dir = $(top_srcdir)/CDVD +x86_dir = $(top_srcdir)/x86 +rdebug_dir = $(top_srcdir)/RDebug +debugtools_dir = $(top_srcdir)/DebugTools +ipu_dir = $(top_srcdir)/IPU +linux_dir = $(top_srcdir)/Linux + +INCLUDES = -I$(top_srcdir) -I$(x86_dir) -I$(common_dir) -I$(third_dir) +noinst_LIBRARIES = libps2_cdvd.a + +libps2_cdvd_a_SOURCES = \ +CDVD.cpp CDVDiso.cpp CDVDisodrv.cpp CdRom.cpp \ +CDVD.h CDVD_internal.h CDVDiso.h CDVDisodrv.h CDVDlib.h CdRom.h + +#SUBDIRS = \ No newline at end of file diff --git a/pcsx2/COP0.cpp b/pcsx2/COP0.cpp index 181636f78b..1e50e509db 100644 --- a/pcsx2/COP0.cpp +++ b/pcsx2/COP0.cpp @@ -56,7 +56,7 @@ void MapTLB(int i) if (tlb[i].S) { DevCon::WriteLn("OMG SPRAM MAPPING %08X %08X\n",params tlb[i].VPN2,tlb[i].Mask); - vtlb_VMapBuffer(tlb[i].VPN2,psS,0x4000); + vtlb_VMapBuffer(tlb[i].VPN2, psS, 0x4000); } if (tlb[i].VPN2 == 0x70000000) return; //uh uhh right ... @@ -69,7 +69,7 @@ void MapTLB(int i) for (addr=saddr; addr> 12) & mask)) { //match memSetPageAddr(addr << 12, tlb[i].PFN0 + ((addr - saddr) << 12)); - Cpu->Clear(addr << 12, 1); + Cpu->Clear(addr << 12, 0x400); } } } @@ -82,7 +82,7 @@ void MapTLB(int i) for (addr=saddr; addr> 12) & mask)) { //match memSetPageAddr(addr << 12, tlb[i].PFN1 + ((addr - saddr) << 12)); - Cpu->Clear(addr << 12, 1); + Cpu->Clear(addr << 12, 0x400); } } } @@ -109,7 +109,7 @@ void UnmapTLB(int i) for (addr=saddr; addr> 12) & mask)) { //match memClearPageAddr(addr << 12); - Cpu->Clear(addr << 12, 1); + Cpu->Clear(addr << 12, 0x400); } } } @@ -122,7 +122,7 @@ void UnmapTLB(int i) for (addr=saddr; addr> 12) & mask)) { //match memClearPageAddr(addr << 12); - Cpu->Clear(addr << 12, 1); + Cpu->Clear(addr << 12, 0x400); } } } @@ -217,15 +217,15 @@ void COP0_DiagnosticPCCR() if( cpuRegs.PERF.n.pccr.b.Event1 >= 7 && cpuRegs.PERF.n.pccr.b.Event1 <= 10 ) Console::Notice( "PERF/PCR1 Unsupported Update Event Mode = 0x%x", params cpuRegs.PERF.n.pccr.b.Event1 ); } - +extern int branch; __forceinline void COP0_UpdatePCCR() { - if( cpuRegs.CP0.n.Status.b.ERL || !cpuRegs.PERF.n.pccr.b.CTE ) return; + //if( cpuRegs.CP0.n.Status.b.ERL || !cpuRegs.PERF.n.pccr.b.CTE ) return; // TODO : Implement memory mode checks here (kernel/super/user) // For now we just assume user mode. - if( cpuRegs.PERF.n.pccr.b.U0 ) + if( cpuRegs.PERF.n.pccr.val & 0xf ) { // ---------------------------------- // Update Performance Counter 0 @@ -243,24 +243,25 @@ __forceinline void COP0_UpdatePCCR() //prev ^= (1UL<<31); // XOR is fun! //if( (prev & cpuRegs.PERF.n.pcr0) & (1UL<<31) ) - if( cpuRegs.PERF.n.pcr0 & 0x80000000 ) + if( (cpuRegs.PERF.n.pcr0 & 0x80000000) && (cpuRegs.CP0.n.Status.b.ERL == 1) && cpuRegs.PERF.n.pccr.b.CTE) { // TODO: Vector to the appropriate exception here. // This code *should* be correct, but is untested (and other parts of the emu are // not prepared to handle proper Level 2 exception vectors yet) - /*if( delay_slot ) + //branch == 1 is probably not the best way to check for the delay slot, but it beats nothing! (Refraction) + /* if( branch == 1 ) { - cpuRegs.CP0.ErrorEPC = cpuRegs.pc - 4; - cpuRegs.CP0.Cause.BD2 = 1; + cpuRegs.CP0.n.ErrorEPC = cpuRegs.pc - 4; + cpuRegs.CP0.n.Cause |= 0x40000000; } else { - cpuRegs.CP0.ErrorEPC = cpuRegs.pc; - cpuRegs.CP0.Cause.BD2 = 0; + cpuRegs.CP0.n.ErrorEPC = cpuRegs.pc; + cpuRegs.CP0.n.Cause &= ~0x40000000; } - if( cpuRegs.CP0.Status.DEV ) + if( cpuRegs.CP0.n.Status.b.DEV ) { // Bootstrap vector cpuRegs.pc = 0xbfc00280; @@ -269,8 +270,8 @@ __forceinline void COP0_UpdatePCCR() { cpuRegs.pc = 0x80000080; } - cpuRegs.CP0.Status.ERL = 1; - cpuRegs.CP0.Cause.EXC2 = 2;*/ + cpuRegs.CP0.n.Status.b.ERL = 1; + cpuRegs.CP0.n.Cause |= 0x20000;*/ } } } @@ -289,9 +290,36 @@ __forceinline void COP0_UpdatePCCR() cpuRegs.PERF.n.pcr1 += incr; s_iLastPERFCycle[1] = cpuRegs.cycle; - if( cpuRegs.PERF.n.pcr1 & 0x80000000 ) + if( (cpuRegs.PERF.n.pcr1 & 0x80000000) && (cpuRegs.CP0.n.Status.b.ERL == 1) && cpuRegs.PERF.n.pccr.b.CTE) { - // See PCR0 comments for notes on exceptions + // TODO: Vector to the appropriate exception here. + // This code *should* be correct, but is untested (and other parts of the emu are + // not prepared to handle proper Level 2 exception vectors yet) + + //branch == 1 is probably not the best way to check for the delay slot, but it beats nothing! (Refraction) + + /*if( branch == 1 ) + { + cpuRegs.CP0.n.ErrorEPC = cpuRegs.pc - 4; + cpuRegs.CP0.n.Cause |= 0x40000000; + } + else + { + cpuRegs.CP0.n.ErrorEPC = cpuRegs.pc; + cpuRegs.CP0.n.Cause &= ~0x40000000; + } + + if( cpuRegs.CP0.n.Status.b.DEV ) + { + // Bootstrap vector + cpuRegs.pc = 0xbfc00280; + } + else + { + cpuRegs.pc = 0x80000080; + } + cpuRegs.CP0.n.Status.b.ERL = 1; + cpuRegs.CP0.n.Cause |= 0x20000;*/ } } } @@ -412,11 +440,6 @@ int CPCOND0() { //#define CPCOND0 1 -/*#define BC0(cond) \ - if (CPCOND0() cond) { \ - intDoBranch(_BranchTarget_); \ - }*/ - void BC0F() { if (CPCOND0() == 0) intDoBranch(_BranchTarget_); } @@ -424,11 +447,6 @@ void BC0F() { void BC0T() { if (CPCOND0() == 1) intDoBranch(_BranchTarget_); } - -/*#define BC0L(cond) \ - if (CPCOND0() cond) { \ - intDoBranch(_BranchTarget_); \ - } else cpuRegs.pc+= 4;*/ void BC0FL() { if (CPCOND0() == 0) diff --git a/pcsx2/Console.cpp b/pcsx2/Console.cpp deleted file mode 100644 index 481f3009c6..0000000000 --- a/pcsx2/Console.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "PrecompiledHeader.h" -#include "System.h" -#include "DebugTools/Debug.h" -#include "NewGUI/App.h" - - -using namespace Threading; -using namespace std; - -const _VARG_PARAM va_arg_dummy = { 0 }; - -// Methods of the Console namespace not defined here are to be found in the platform -// dependent implementations in WinConsole.cpp and LnxConsole.cpp. - -namespace Console -{ - ConsoleLogFrame* FrameHandle = NULL; - MutexLock m_writelock; - std::string m_format_buffer; - - // ------------------------------------------------------------------------ - void __fastcall SetTitle( const wxString& title ) - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - if( FrameHandle != NULL ) - FrameHandle->SetTitle( title ); - } - - // ------------------------------------------------------------------------ - void __fastcall SetColor( Colors color ) - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - if( FrameHandle != NULL ) - FrameHandle->SetColor( color ); - } - - void ClearColor() - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - if( FrameHandle != NULL ) - FrameHandle->ClearColor(); - } - - // ------------------------------------------------------------------------ - bool Newline() - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - if( FrameHandle != NULL ) - FrameHandle->Newline(); - - fputs( "", emuLog ); - return false; - } - - // ------------------------------------------------------------------------ - bool __fastcall Write( const char* fmt ) - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - if( FrameHandle != NULL ) - FrameHandle->Write( fmt ); - - fputs( fmt, emuLog ); - return false; - } - - bool __fastcall Write( Colors color, const char* fmt ) - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - if( FrameHandle != NULL ) - { - FrameHandle->SetColor( color ); - FrameHandle->Write( fmt ); - FrameHandle->ClearColor(); - } - - fwrite( fmt, 1, strlen( fmt ), emuLog ); - return false; - } - - // ------------------------------------------------------------------------ - bool __fastcall Write( const wxString& fmt ) - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - if( FrameHandle != NULL ) - FrameHandle->Write( fmt ); - - wxCharBuffer jones( fmt.ToAscii() ); - fwrite( fmt, 1, strlen( jones.data() ), emuLog ); - return false; - } - - bool __fastcall Write( Colors color, const wxString& fmt ) - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - if( FrameHandle != NULL ) - { - FrameHandle->SetColor( color ); - FrameHandle->Write( fmt ); - FrameHandle->ClearColor(); - } - - wxCharBuffer jones( fmt.ToAscii() ); - fwrite( fmt, 1, strlen( jones.data() ), emuLog ); - return false; - } - - // ------------------------------------------------------------------------ - bool __fastcall WriteLn( const char* fmt ) - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - if( FrameHandle != NULL ) - { - FrameHandle->Write( fmt ); - FrameHandle->Newline(); - } - - fputs( fmt, emuLog ); - return false; - } - - bool __fastcall WriteLn( Colors color, const char* fmt ) - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - if( FrameHandle != NULL ) - { - FrameHandle->SetColor( color ); - FrameHandle->Write( fmt ); - FrameHandle->Newline(); - FrameHandle->ClearColor(); - } - - fputs( fmt, emuLog ); - return false; - } - - // ------------------------------------------------------------------------ - bool __fastcall WriteLn( const wxString& fmt ) - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - if( FrameHandle != NULL ) - { - FrameHandle->Write( fmt.c_str() ); - FrameHandle->Newline(); - } - - wxCharBuffer jones( fmt.ToAscii() ); - fputs( jones.data(), emuLog ); - return false; - } - - bool __fastcall WriteLn( Colors color, const wxString& fmt ) - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - if( FrameHandle != NULL ) - { - FrameHandle->SetColor( color ); - FrameHandle->Write( fmt ); - FrameHandle->Newline(); - FrameHandle->ClearColor(); - } - - wxCharBuffer jones( fmt.ToAscii() ); - fputs( jones.data(), emuLog ); - return false; - } - - // ------------------------------------------------------------------------ - __forceinline void __fastcall _WriteLn( Colors color, const char* fmt, va_list args ) - { - ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); - - ScopedLock locker( m_writelock ); - vssprintf( m_format_buffer, fmt, args ); - const char* cstr = m_format_buffer.c_str(); - if( FrameHandle != NULL ) - { - FrameHandle->SetColor( color ); - FrameHandle->Write( cstr ); - FrameHandle->Newline(); - FrameHandle->ClearColor(); - } - else - { - // The logging system hasn't been initialized, so log to stderr which at least - // has a chance of being visible, and then assert (really there shouldn't be logs - // being attempted prior to log/console initialization anyway, and the programmer - // should replace these with MessageBoxes or something). - - if( color == Color_Red || color == Color_Yellow ) - fputs( cstr, stderr ); // log notices and errors to stderr - - wxASSERT_MSG_A( 0, cstr ); - } - - fputs( cstr, emuLog ); - } - - // ------------------------------------------------------------------------ - bool Write( const char* fmt, VARG_PARAM dummy, ... ) - { - varg_assert(); - - va_list list; - va_start(list,dummy); - - ScopedLock locker( m_writelock ); - vssprintf( m_format_buffer, fmt, list ); - Write( m_format_buffer.c_str() ); - - va_end(list); - - return false; - } - - bool Write( Colors color, const char* fmt, VARG_PARAM dummy, ... ) - { - varg_assert(); - - va_list list; - va_start(list,dummy); - - ScopedLock locker( m_writelock ); - vssprintf( m_format_buffer, fmt, list ); - Write( color, m_format_buffer.c_str() ); - - va_end(list); - return false; - } - - // ------------------------------------------------------------------------ - bool WriteLn( const char* fmt, VARG_PARAM dummy, ... ) - { - varg_assert(); - va_list list; - va_start(list,dummy); - - ScopedLock locker( m_writelock ); - vssprintf( m_format_buffer, fmt, list ); - WriteLn( m_format_buffer.c_str() ); - - va_end(list); - return false; - } - - // ------------------------------------------------------------------------ - bool WriteLn( Colors color, const char* fmt, VARG_PARAM dummy, ... ) - { - varg_assert(); - - va_list list; - va_start(list,dummy); - _WriteLn( Color_White, fmt, list ); - va_end(list); - return false; - } - - // ------------------------------------------------------------------------ - bool Error( const char* fmt, VARG_PARAM dummy, ... ) - { - varg_assert(); - - va_list list; - va_start(list,dummy); - _WriteLn( Color_Red, fmt, list ); - va_end(list); - return false; - } - - // ------------------------------------------------------------------------ - bool Notice( const char* fmt, VARG_PARAM dummy, ... ) - { - varg_assert(); - - va_list list; - va_start(list,dummy); - _WriteLn( Color_Yellow, fmt, list ); - va_end(list); - return false; - } - - // ------------------------------------------------------------------------ - bool Status( const char* fmt, VARG_PARAM dummy, ... ) - { - varg_assert(); - - va_list list; - va_start(list,dummy); - _WriteLn( Color_Green, fmt, list ); - va_end(list); - return false; - } - - // ------------------------------------------------------------------------ - bool __fastcall Error( const char* fmt ) - { - WriteLn( Color_Red, fmt ); - return false; - } - - bool __fastcall Notice( const char* fmt ) - { - WriteLn( Color_Yellow, fmt ); - return false; - } - - bool __fastcall Status( const char* fmt ) - { - WriteLn( Color_Green, fmt ); - return false; - } - - // ------------------------------------------------------------------------ - bool __fastcall Error( const wxString& src ) - { - WriteLn( Color_Red, src ); - return false; - } - - bool __fastcall Notice( const wxString& src ) - { - WriteLn( Color_Yellow, src ); - return false; - } - - bool __fastcall Status( const wxString& src ) - { - WriteLn( Color_Green, src ); - return false; - } - -} - -namespace Msgbox -{ - bool Alert( const wxString& text ) - { - wxMessageBox( text, L"Pcsx2 Message", wxOK, wxGetApp().GetTopWindow() ); - return false; - } - - bool OkCancel( const wxString& text ) - { - int result = wxMessageBox( text, L"Pcsx2 Message", wxOK | wxCANCEL, wxGetApp().GetTopWindow() ); - return result == wxOK; - } -} \ No newline at end of file diff --git a/pcsx2/Counters.cpp b/pcsx2/Counters.cpp index 89a5cf8bd6..b43cf890f7 100644 --- a/pcsx2/Counters.cpp +++ b/pcsx2/Counters.cpp @@ -82,16 +82,30 @@ static __forceinline void _rcntSet( int cntidx ) c = ((0x10000 - counter.count) * counter.rate) - (cpuRegs.cycle - counter.sCycleT); c += cpuRegs.cycle - nextsCounter; // adjust for time passed since last rcntUpdate(); - if (c < nextCounter) nextCounter = c; - + if (c < nextCounter) + { + nextCounter = c; + cpuSetNextBranch( nextsCounter, nextCounter ); //Need to update on counter resets/target changes + } + // Ignore target diff if target is currently disabled. // (the overflow is all we care about since it goes first, and then the - // target will be turned on afterward). + // target will be turned on afterward, and handled in the next event test). - if( counter.target & EECNT_FUTURE_TARGET ) return; - c = ((counter.target - counter.count) * counter.rate) - (cpuRegs.cycle - counter.sCycleT); - c += cpuRegs.cycle - nextsCounter; // adjust for time passed since last rcntUpdate(); - if (c < nextCounter) nextCounter = c; + if( counter.target & EECNT_FUTURE_TARGET ) + { + return; + } + else + { + c = ((counter.target - counter.count) * counter.rate) - (cpuRegs.cycle - counter.sCycleT); + c += cpuRegs.cycle - nextsCounter; // adjust for time passed since last rcntUpdate(); + if (c < nextCounter) + { + nextCounter = c; + cpuSetNextBranch( nextsCounter, nextCounter ); //Need to update on counter resets/target changes + } + } } @@ -100,7 +114,7 @@ static __forceinline void cpuRcntSet() int i; nextsCounter = cpuRegs.cycle; - nextCounter = (vsyncCounter.sCycle + vsyncCounter.CycleT) - cpuRegs.cycle; + nextCounter = vsyncCounter.CycleT - (cpuRegs.cycle - vsyncCounter.sCycle); for (i = 0; i < 4; i++) _rcntSet( i ); @@ -322,8 +336,16 @@ static __forceinline void VSyncStart(u32 sCycle) EECNT_LOG( "///////// EE COUNTER VSYNC START \\\\\\\\\\\\\\\\\\\\ (frame: %d)", iFrame ); vSyncDebugStuff( iFrame ); // EE Profiling and Debug code - if ((CSRw & 0x8)) GSCSRr|= 0x8; - if (!(GSIMR&0x800)) gsIrq(); + if ((CSRw & 0x8)) + { + + + if (!(GSIMR&0x800)) + { + gsIrq(); + } + GSCSRr|= 0x8; + } hwIntcIrq(INTC_VBLANK_S); psxVBlankStart(); @@ -390,8 +412,16 @@ __forceinline void rcntUpdate_hScanline() hsyncCounter.Mode = MODE_HRENDER; } else { //HBLANK END / HRENDER Begin - if (CSRw & 0x4) GSCSRr |= 4; // signal - if (!(GSIMR&0x400)) gsIrq(); + if (CSRw & 0x4) + { + + + if (!(GSIMR&0x400)) + { + gsIrq(); + } + GSCSRr |= 4; // signal + } if (gates) rcntEndGate(false, hsyncCounter.sCycle); if (psxhblankgate) psxCheckEndGate16(0); @@ -432,6 +462,9 @@ __forceinline bool rcntUpdate_vSync() // Accumulate hsync rounding errors: hsyncCounter.sCycle += vSyncInfo.hSyncError; + + if (CHECK_MICROVU0) vsyncVUrec(0); + if (CHECK_MICROVU1) vsyncVUrec(1); # ifdef VSYNC_DEBUG vblankinc++; @@ -714,6 +747,19 @@ __forceinline void rcntWtarget(int index, u32 value) // If the target is behind the current count, set it up so that the counter must // overflow first before the target fires: + if(counters[index].mode.IsCounting) { + if(counters[index].mode.ClockSource != 0x3) { + + u32 change = cpuRegs.cycle - counters[index].sCycleT; + if( change > 0 ) + { + counters[index].count += change / counters[index].rate; + change -= (change / counters[index].rate) * counters[index].rate; + counters[index].sCycleT = cpuRegs.cycle - change; + } + } + } + if( counters[index].target <= rcntCycle(index) ) counters[index].target |= EECNT_FUTURE_TARGET; diff --git a/pcsx2/DebugTools/Debug.h b/pcsx2/DebugTools/Debug.h index 3f965fe000..89e54e6593 100644 --- a/pcsx2/DebugTools/Debug.h +++ b/pcsx2/DebugTools/Debug.h @@ -16,9 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#ifndef __DEBUG_H__ -#define __DEBUG_H__ +#pragma once #include "Pcsx2Config.h" @@ -223,5 +221,3 @@ extern bool SrcLog_GPU( const char* fmt, ... ); #else #define VIFUNPACK_LOG 0&& #endif - -#endif /* __DEBUG_H__ */ diff --git a/pcsx2/DebugTools/DisR3000asm.cpp b/pcsx2/DebugTools/DisR3000asm.cpp deleted file mode 100644 index 840adaaa03..0000000000 --- a/pcsx2/DebugTools/DisR3000asm.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "PrecompiledHeader.h" - -#include "Debug.h" -#include "R3000A.h" -#include "DisASM.h" - -namespace R3000A { - -unsigned long IOP_opcode_addr; - -const char *GPR_IOP_REG[32] = { - "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" -}; -const char *COP0_IOP_REG[32] ={ - "Index","Random","EntryLo0","EntryLo1","Context","PageMask", - "Wired","C0r7","BadVaddr","Count","EntryHi","Compare","Status", - "Cause","EPC","PRId","Config","C0r17","C0r18","C0r19","C0r20", - "C0r21","C0r22","C0r23","Debug","Perf","C0r26","C0r27","TagLo", - "TagHi","ErrorPC","C0r31" -}; -void IOPD_SPECIAL(char *buf); -void IOPD_REGIMM(char *buf); -void IOPD_J(char *buf); -void IOPD_JAL(char *buf); -void IOPD_BEQ(char *buf); -void IOPD_BNE(char *buf); -void IOPD_BLEZ(char *buf); -void IOPD_BGTZ(char *buf); -void IOPD_ADDI(char *buf); -void IOPD_ADDIU(char *buf); -void IOPD_SLTI(char *buf); -void IOPD_SLTIU(char *buf); -void IOPD_ANDI(char *buf); -void IOPD_ORI(char *buf); -void IOPD_XORI(char *buf); -void IOPD_LUI(char *buf); -void IOPD_COP0(char *buf); -void IOPD_COP2(char *buf); -void IOPD_LB(char *buf); -void IOPD_LH(char *buf); -void IOPD_LWL(char *buf); -void IOPD_LW(char *buf); -void IOPD_LBU(char *buf); -void IOPD_LHU(char *buf); -void IOPD_LWR(char *buf); -void IOPD_SB(char *buf); -void IOPD_SH(char *buf); -void IOPD_SWL(char *buf); -void IOPD_SW(char *buf); -void IOPD_SWR(char *buf); -void IOPD_LWC2(char *buf); -void IOPD_SWC2(char *buf); - -void IOPD_SLL(char *buf); -void IOPD_SRL(char *buf); -void IOPD_SRA(char *buf); -void IOPD_SLLV(char *buf); -void IOPD_SRLV(char *buf); -void IOPD_SRAV(char *buf); -void IOPD_JR(char *buf); -void IOPD_JALR(char *buf); -void IOPD_SYSCALL(char *buf); -void IOPD_BREAK(char *buf); -void IOPD_MFHI(char *buf); -void IOPD_MTHI(char *buf); -void IOPD_MFLO(char *buf); -void IOPD_MTLO(char *buf); -void IOPD_MULT(char *buf); -void IOPD_MULTU(char *buf); -void IOPD_DIV(char *buf); -void IOPD_DIVU(char *buf); -void IOPD_ADD(char *buf); -void IOPD_ADDU(char *buf); -void IOPD_SUB(char *buf); -void IOPD_SUBU(char *buf); -void IOPD_AND(char *buf); -void IOPD_OR(char *buf); -void IOPD_XOR(char *buf); -void IOPD_NOR(char *buf); -void IOPD_SLT(char *buf); -void IOPD_SLTU(char *buf); - - -void IOPD_BLTZ(char *buf); -void IOPD_BGEZ(char *buf); -void IOPD_BLTZAL(char *buf); -void IOPD_BGEZAL(char *buf); - - - -void IOPD_MFC0(char *buf); -void IOPD_CFC0(char *buf); -void IOPD_MTC0(char *buf); -void IOPD_CTC0(char *buf); -void IOPD_RFE(char *buf); - - - -void IOPD_BASIC(char *buf); -void IOPD_RTPS(char *buf); -void IOPD_NCLIP(char *buf); -void IOPD_OP(char *buf); -void IOPD_DPCS(char *buf); -void IOPD_INTPL(char *buf); -void IOPD_MVMVA(char *buf); -void IOPD_NCDS(char *buf); -void IOPD_CDP(char *buf); -void IOPD_NCDT(char *buf); -void IOPD_NCCS(char *buf); -void IOPD_CC(char *buf); -void IOPD_NCS(char *buf); -void IOPD_NCT(char *buf); -void IOPD_SQR(char *buf); -void IOPD_DCPL(char *buf); -void IOPD_DPCT(char *buf); -void IOPD_AVSZ3(char *buf); -void IOPD_AVSZ4(char *buf); -void IOPD_RTPT(char *buf); -void IOPD_GPF(char *buf); -void IOPD_GPL(char *buf); -void IOPD_NCCT(char *buf); - - - -void IOPD_MFC2(char *buf); -void IOPD_CFC2(char *buf); -void IOPD_MTC2(char *buf); -void IOPD_CTC2(char *buf); -void IOPD_NULL(char *buf); - - - - void (*IOP_DEBUG_BSC[64])(char *buf) = { - IOPD_SPECIAL, IOPD_REGIMM, IOPD_J , IOPD_JAL , IOPD_BEQ , IOPD_BNE , IOPD_BLEZ, IOPD_BGTZ, - IOPD_ADDI , IOPD_ADDIU , IOPD_SLTI, IOPD_SLTIU, IOPD_ANDI, IOPD_ORI , IOPD_XORI, IOPD_LUI , - IOPD_COP0 , IOPD_NULL , IOPD_COP2, IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, - IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, - IOPD_LB , IOPD_LH , IOPD_LWL , IOPD_LW , IOPD_LBU , IOPD_LHU , IOPD_LWR , IOPD_NULL, - IOPD_SB , IOPD_SH , IOPD_SWL , IOPD_SW , IOPD_NULL, IOPD_NULL, IOPD_SWR , IOPD_NULL, - IOPD_NULL , IOPD_NULL , IOPD_LWC2, IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, - IOPD_NULL , IOPD_NULL , IOPD_SWC2, IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL -}; - - -void (*IOP_DEBUG_SPC[64])(char *buf) = { - IOPD_SLL , IOPD_NULL , IOPD_SRL , IOPD_SRA , IOPD_SLLV , IOPD_NULL , IOPD_SRLV, IOPD_SRAV, - IOPD_JR , IOPD_JALR , IOPD_NULL, IOPD_NULL, IOPD_SYSCALL, IOPD_BREAK, IOPD_NULL, IOPD_NULL, - IOPD_MFHI, IOPD_MTHI , IOPD_MFLO, IOPD_MTLO, IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, - IOPD_MULT, IOPD_MULTU, IOPD_DIV , IOPD_DIVU, IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, - IOPD_ADD , IOPD_ADDU , IOPD_SUB , IOPD_SUBU, IOPD_AND , IOPD_OR , IOPD_XOR , IOPD_NOR , - IOPD_NULL, IOPD_NULL , IOPD_SLT , IOPD_SLTU, IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, - IOPD_NULL, IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, - IOPD_NULL, IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL -}; - -void (*IOP_DEBUG_REG[32])(char *buf) = { - IOPD_BLTZ , IOPD_BGEZ , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, - IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, - IOPD_BLTZAL, IOPD_BGEZAL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, - IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL -}; - -void (*IOP_DEBUG_CP0[32])(char *buf) = { - IOPD_MFC0, IOPD_NULL, IOPD_CFC0, IOPD_NULL, IOPD_MTC0, IOPD_NULL, IOPD_CTC0, IOPD_NULL, - IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, - IOPD_RFE , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, - IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL -}; - -void (*IOP_DEBUG_CP2[64])(char *buf) = { - IOPD_BASIC, IOPD_RTPS , IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL , IOPD_NCLIP, IOPD_NULL, - IOPD_NULL , IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_OP , IOPD_NULL , IOPD_NULL , IOPD_NULL, - IOPD_DPCS , IOPD_INTPL, IOPD_MVMVA, IOPD_NCDS, IOPD_CDP , IOPD_NULL , IOPD_NCDT , IOPD_NULL, - IOPD_NULL , IOPD_NULL , IOPD_NULL , IOPD_NCCS, IOPD_CC , IOPD_NULL , IOPD_NCS , IOPD_NULL, - IOPD_NCT , IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL , IOPD_NULL , IOPD_NULL, - IOPD_SQR , IOPD_DCPL , IOPD_DPCT , IOPD_NULL, IOPD_NULL, IOPD_AVSZ3, IOPD_AVSZ4, IOPD_NULL, - IOPD_RTPT , IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL , IOPD_NULL , IOPD_NULL, - IOPD_NULL , IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_GPF , IOPD_GPL , IOPD_NCCT -}; - -void (*IOP_DEBUG_CP2BSC[32])(char *buf) = { - IOPD_MFC2, IOPD_NULL, IOPD_CFC2, IOPD_NULL, IOPD_MTC2, IOPD_NULL, IOPD_CTC2, IOPD_NULL, - IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, - IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, - IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL -}; - -static char dbuf2[1024]; -static char obuf2[1024]; - -char *disR3000Fasm(u32 code, u32 pc) { - u32 scode = psxRegs.code; - IOP_opcode_addr = pc; - psxRegs.code = code; - IOP_DEBUG_BSC[(code) >> 26](dbuf2); - - sprintf(obuf2, "%08lX:\t%s", pc, dbuf2); - - psxRegs.code = scode; - return obuf2; -} -char *IOP_jump_decode(void) -{ - static char buf[256]; - unsigned long addr; - addr = (IOP_opcode_addr & 0xf0000000)|((psxRegs.code&0x3ffffff)<<2); - sprintf(buf, "0x%08lX", addr); - return buf; -} -char *IOP_offset_decode(void) -{ - static char buf[256]; - unsigned long addr; - addr = ((((short)( psxRegs.code & 0xFFFF) * 4) + IOP_opcode_addr + 4)); - sprintf(buf, "0x%08lX", addr); - return buf; -} -//basic table -void IOPD_SPECIAL(char *buf){IOP_DEBUG_SPC[((psxRegs.code) & 0x3F)](buf);} -void IOPD_REGIMM(char *buf){IOP_DEBUG_REG[DECODE_RT_IOP](buf);} -void IOPD_J(char *buf) { sprintf(buf, "j\t%s", IOP_jump_decode());} -void IOPD_JAL(char *buf){sprintf(buf, "jal\t%s", IOP_jump_decode());} -void IOPD_BEQ(char *buf){sprintf(buf, "beq\t%s, %s, %s", GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP], IOP_offset_decode()); } -void IOPD_BNE(char *buf){sprintf(buf, "bne\t%s, %s, %s", GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP], IOP_offset_decode()); } -void IOPD_BLEZ(char *buf){sprintf(buf, "blez\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], IOP_offset_decode()); } -void IOPD_BGTZ(char *buf){sprintf(buf, "bgtz\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], IOP_offset_decode()); } -void IOPD_ADDI(char *buf){sprintf(buf, "addi\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP);} -void IOPD_ADDIU(char *buf){sprintf(buf, "addiu\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP);} -void IOPD_SLTI(char *buf){sprintf(buf, "slti\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP);} -void IOPD_SLTIU(char *buf){sprintf(buf, "sltiu\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP);} -void IOPD_ANDI(char *buf){sprintf(buf, "andi\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP);} -void IOPD_ORI(char *buf){sprintf(buf, "ori\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP); } -void IOPD_XORI(char *buf){sprintf(buf, "xori\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP); } -void IOPD_LUI(char *buf){sprintf(buf, "lui\t%s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP); } -void IOPD_COP0(char *buf){IOP_DEBUG_CP0[DECODE_RS_IOP](buf);} -void IOPD_COP2(char *buf){IOP_DEBUG_CP2[((psxRegs.code) & 0x3F)](buf);} -void IOPD_LB(char *buf){sprintf(buf, "lb\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_LH(char *buf){sprintf(buf, "lh\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_LWL(char *buf){sprintf(buf, "lwl\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_LW(char *buf){sprintf(buf, "lw\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_LBU(char *buf){sprintf(buf, "lbu\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_LHU(char *buf){sprintf(buf, "lhu\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_LWR(char *buf){sprintf(buf, "lwr\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]);} -void IOPD_SB(char *buf){sprintf(buf, "sb\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]);} -void IOPD_SH(char *buf){sprintf(buf, "sh\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_SWL(char *buf){sprintf(buf, "swl\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_SW(char *buf){sprintf(buf, "sw\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_SWR(char *buf){sprintf(buf, "swr\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]);} -void IOPD_LWC2(char *buf){strcpy(buf, "lwc2");} -void IOPD_SWC2(char *buf){strcpy(buf, "swc2");} -//special table -void IOPD_SLL(char *buf) -{ - if (psxRegs.code == 0x00000000) - strcpy(buf, "nop"); - else - sprintf(buf, "sll\t%s, %s, 0x%02lX", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RT_IOP], DECODE_SA_IOP); -} -void IOPD_SRL(char *buf){sprintf(buf, "srl\t%s, %s, 0x%02lX", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RT_IOP], DECODE_SA_IOP); } -void IOPD_SRA(char *buf){sprintf(buf, "sra\t%s, %s, 0x%02lX", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RT_IOP], DECODE_SA_IOP);} -void IOPD_SLLV(char *buf){sprintf(buf, "sllv\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_SRLV(char *buf){sprintf(buf, "srlv\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP]);} -void IOPD_SRAV(char *buf){sprintf(buf, "srav\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_JR(char *buf){sprintf(buf, "jr\t%s", GPR_IOP_REG[DECODE_RS_IOP]);} -void IOPD_JALR(char *buf) -{ - int rd = DECODE_RD_IOP; - - if (rd == 31) - sprintf(buf, "jalr\t%s", GPR_IOP_REG[DECODE_RS_IOP]); - else - sprintf(buf, "jalr\t%s, %s", GPR_IOP_REG[rd], GPR_IOP_REG[DECODE_RS_IOP]); -} - -void IOPD_SYSCALL(char *buf){strcpy(buf, "syscall");} -void IOPD_BREAK(char *buf){strcpy(buf, "break");} -void IOPD_MFHI(char *buf){sprintf(buf, "mfhi\t%s", GPR_IOP_REG[DECODE_RD_IOP]); } -void IOPD_MTHI(char *buf){sprintf(buf, "mthi\t%s", GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_MFLO(char *buf){sprintf(buf, "mflo\t%s", GPR_IOP_REG[DECODE_RD_IOP]); } -void IOPD_MTLO(char *buf){sprintf(buf, "mtlo\t%s", GPR_IOP_REG[DECODE_RS_IOP]); } -void IOPD_MULT(char *buf){sprintf(buf, "mult\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]);} -void IOPD_MULTU(char *buf){sprintf(buf, "multu\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]);} -void IOPD_DIV(char *buf){sprintf(buf, "div\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]);} -void IOPD_DIVU(char *buf){sprintf(buf, "divu\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); } - -void IOPD_ADD(char *buf) { sprintf(buf, "add\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); } -void IOPD_ADDU(char *buf) { sprintf(buf, "addu\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); } -void IOPD_SUB(char *buf) { sprintf(buf, "sub\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); } -void IOPD_SUBU(char *buf) { sprintf(buf, "subu\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); } -void IOPD_AND(char *buf) { sprintf(buf, "and\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); } -void IOPD_OR(char *buf) { sprintf(buf, "or\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); } -void IOPD_XOR(char *buf) { sprintf(buf, "xor\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); } -void IOPD_NOR(char *buf) { sprintf(buf, "nor\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); } -void IOPD_SLT(char *buf) { sprintf(buf, "slt\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); } -void IOPD_SLTU(char *buf) { sprintf(buf, "sltu\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); } -//regimm - -void IOPD_BLTZ(char *buf) { sprintf(buf, "bltz\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], IOP_offset_decode()); } -void IOPD_BGEZ(char *buf) { sprintf(buf, "bgez\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], IOP_offset_decode()); } -void IOPD_BLTZAL(char *buf) { sprintf(buf, "bltzal\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], IOP_offset_decode()); } -void IOPD_BGEZAL(char *buf) { sprintf(buf, "bgezal\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], IOP_offset_decode()); } - -//cop0 - -void IOPD_MFC0(char *buf){ sprintf(buf, "mfc0\t%s, %s", GPR_IOP_REG[DECODE_RT_IOP], COP0_IOP_REG[DECODE_FS_IOP]); } -void IOPD_MTC0(char *buf){ sprintf(buf, "mtc0\t%s, %s", GPR_IOP_REG[DECODE_RT_IOP], COP0_IOP_REG[DECODE_FS_IOP]); } -void IOPD_CFC0(char *buf){ sprintf(buf, "cfc0\t%s, %s", GPR_IOP_REG[DECODE_RT_IOP], COP0_IOP_REG[DECODE_FS_IOP]); } -void IOPD_CTC0(char *buf){ sprintf(buf, "ctc0\t%s, %s", GPR_IOP_REG[DECODE_RT_IOP], COP0_IOP_REG[DECODE_FS_IOP]); } -void IOPD_RFE(char *buf){strcpy(buf, "rfe");} -//cop2 -void IOPD_BASIC(char *buf){IOP_DEBUG_CP2BSC[DECODE_RS_IOP](buf);} -void IOPD_RTPS(char *buf){strcpy(buf, "rtps");} -void IOPD_NCLIP(char *buf){strcpy(buf, "nclip");} -void IOPD_OP(char *buf){strcpy(buf, "op");} -void IOPD_DPCS(char *buf){strcpy(buf, "dpcs");} -void IOPD_INTPL(char *buf){strcpy(buf, "intpl");} -void IOPD_MVMVA(char *buf){strcpy(buf, "mvmva");} -void IOPD_NCDS(char *buf){strcpy(buf, "ncds");} -void IOPD_CDP(char *buf){strcpy(buf, "cdp");} -void IOPD_NCDT(char *buf){strcpy(buf, "ncdt");} -void IOPD_NCCS(char *buf){strcpy(buf, "nccs");} -void IOPD_CC(char *buf){strcpy(buf, "cc");} -void IOPD_NCS(char *buf){strcpy(buf, "ncs");} -void IOPD_NCT(char *buf){strcpy(buf, "nct");} -void IOPD_SQR(char *buf){strcpy(buf, "sqr");} -void IOPD_DCPL(char *buf){strcpy(buf, "dcpl");} -void IOPD_DPCT(char *buf){strcpy(buf, "dpct");} -void IOPD_AVSZ3(char *buf){strcpy(buf, "avsz3");} -void IOPD_AVSZ4(char *buf){strcpy(buf, "avsz4");} -void IOPD_RTPT(char *buf){strcpy(buf, "rtpt");} -void IOPD_GPF(char *buf){strcpy(buf, "gpf");} -void IOPD_GPL(char *buf){strcpy(buf, "gpl");} -void IOPD_NCCT(char *buf){strcpy(buf, "ncct");} -//cop2 basic -void IOPD_MFC2(char *buf){strcpy(buf, "mfc2");} -void IOPD_CFC2(char *buf){strcpy(buf, "cfc2");} -void IOPD_MTC2(char *buf){strcpy(buf, "mtc2");} -void IOPD_CTC2(char *buf){strcpy(buf, "ctc2");} -//null -void IOPD_NULL(char *buf){strcpy(buf, "????");} - -} // end Namespace R3000A \ No newline at end of file diff --git a/pcsx2/DebugTools/DisR5900.cpp b/pcsx2/DebugTools/DisR5900.cpp index 5607247451..7c17ff7c8a 100644 --- a/pcsx2/DebugTools/DisR5900.cpp +++ b/pcsx2/DebugTools/DisR5900.cpp @@ -470,8 +470,8 @@ MakeDisF(disCVTSw, dName("CVTSw"); dCP132(_Fd_); dCP132(_Fs_);) * Format: OP rt, offset(base) * *********************************************************/ -MakeDisF(disLWC1, dName("LWC1"); dCP132(_Rt_); dOffset();) -MakeDisF(disSWC1, dName("SWC1"); dCP132(_Rt_); dOffset();) +MakeDisF(disLWC1, dName("LWC1"); dCP132(_Ft_); dOffset();) +MakeDisF(disSWC1, dName("SWC1"); dCP132(_Ft_); dOffset();) /********************************************************* * Conditional Move * diff --git a/pcsx2/DebugTools/DisVU0Micro.cpp b/pcsx2/DebugTools/DisVU0Micro.cpp index b1c994e2ac..62c42b97e1 100644 --- a/pcsx2/DebugTools/DisVU0Micro.cpp +++ b/pcsx2/DebugTools/DisVU0Micro.cpp @@ -40,6 +40,9 @@ typedef char* (*TdisR5900F)DisFInterface; #define _Ft_ ((code >> 16) & 0x1F) // The rt part of the instruction register #define _Fs_ ((code >> 11) & 0x1F) // The rd part of the instruction register #define _Fd_ ((code >> 6) & 0x1F) // The sa part of the instruction register +#define _It_ (_Ft_ & 15) +#define _Is_ (_Fs_ & 15) +#define _Id_ (_Fd_ & 15) #define dName(i) sprintf(ostr, "%s %-7s,", ostr, i) #define dNameU(i) { char op[256]; sprintf(op, "%s.%s%s%s%s", i, _X ? "x" : "", _Y ? "y" : "", _Z ? "z" : "", _W ? "w" : ""); sprintf(ostr, "%s %-7s,", ostr, op); } diff --git a/pcsx2/DebugTools/DisVU1Micro.cpp b/pcsx2/DebugTools/DisVU1Micro.cpp index de50040b8c..02eb0fa9ee 100644 --- a/pcsx2/DebugTools/DisVU1Micro.cpp +++ b/pcsx2/DebugTools/DisVU1Micro.cpp @@ -42,6 +42,9 @@ typedef char* (*TdisR5900F)DisFInterface; #define _Ft_ ((code >> 16) & 0x1F) // The rt part of the instruction register #define _Fs_ ((code >> 11) & 0x1F) // The rd part of the instruction register #define _Fd_ ((code >> 6) & 0x1F) // The sa part of the instruction register +#define _It_ (_Ft_ & 15) +#define _Is_ (_Fs_ & 15) +#define _Id_ (_Fd_ & 15) #define dName(i) sprintf(ostr, "%s %-12s", ostr, i); \ diff --git a/pcsx2/DebugTools/DisVUops.h b/pcsx2/DebugTools/DisVUops.h index 6ca88bcfb5..7316168242 100644 --- a/pcsx2/DebugTools/DisVUops.h +++ b/pcsx2/DebugTools/DisVUops.h @@ -26,55 +26,55 @@ MakeDisF(dis##VU##MI_DIV, dName("DIV"); dCP232f(_Fs_, _Fsf_); dCP232f(_Ft_, _Ftf_);) \ MakeDisF(dis##VU##MI_SQRT, dName("SQRT"); dCP232f(_Ft_, _Ftf_);) \ MakeDisF(dis##VU##MI_RSQRT, dName("RSQRT"); dCP232f(_Fs_, _Fsf_); dCP232f(_Ft_, _Ftf_);) \ -MakeDisF(dis##VU##MI_IADDI, dName("IADDI"); dCP232i(_Ft_); dCP232i(_Fs_); dImm5();) \ -MakeDisF(dis##VU##MI_IADDIU, dName("IADDIU"); dCP232i(_Ft_); dCP232i(_Fs_); dImm15();) \ -MakeDisF(dis##VU##MI_IADD, dName("IADD"); dCP232i(_Fd_); dCP232i(_Fs_); dCP232i(_Ft_);) \ -MakeDisF(dis##VU##MI_IAND, dName("IAND"); dCP232i(_Fd_); dCP232i(_Fs_); dCP232i(_Ft_);) \ -MakeDisF(dis##VU##MI_IOR, dName("IOR"); dCP232i(_Fd_); dCP232i(_Fs_); dCP232i(_Ft_);) \ -MakeDisF(dis##VU##MI_ISUB, dName("ISUB"); dCP232i(_Fd_); dCP232i(_Fs_); dCP232i(_Ft_);) \ -MakeDisF(dis##VU##MI_ISUBIU, dName("ISUBIU"); dCP232i(_Ft_); dCP232i(_Fs_); dImm15();) \ +MakeDisF(dis##VU##MI_IADDI, dName("IADDI"); dCP232i(_It_); dCP232i(_Is_); dImm5();) \ +MakeDisF(dis##VU##MI_IADDIU, dName("IADDIU"); dCP232i(_It_); dCP232i(_Is_); dImm15();) \ +MakeDisF(dis##VU##MI_IADD, dName("IADD"); dCP232i(_Id_); dCP232i(_Is_); dCP232i(_It_);) \ +MakeDisF(dis##VU##MI_IAND, dName("IAND"); dCP232i(_Id_); dCP232i(_Is_); dCP232i(_It_);) \ +MakeDisF(dis##VU##MI_IOR, dName("IOR"); dCP232i(_Id_); dCP232i(_Is_); dCP232i(_It_);) \ +MakeDisF(dis##VU##MI_ISUB, dName("ISUB"); dCP232i(_Id_); dCP232i(_Is_); dCP232i(_It_);) \ +MakeDisF(dis##VU##MI_ISUBIU, dName("ISUBIU"); dCP232i(_It_); dCP232i(_Is_); dImm15();) \ MakeDisF(dis##VU##MI_MOVE, if (_Fs_ == 0 && _Ft_ == 0) { dNameU("NOP"); } else { dNameU("MOVE"); dCP2128f(_Ft_); dCP2128f(_Fs_); }) \ -MakeDisF(dis##VU##MI_MFIR, dNameU("MFIR"); dCP2128f(_Ft_); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_MTIR, dNameU("MTIR"); dCP232i(_Ft_); dCP232f(_Fs_, _Fsf_);) \ +MakeDisF(dis##VU##MI_MFIR, dNameU("MFIR"); dCP2128f(_Ft_); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_MTIR, dNameU("MTIR"); dCP232i(_It_); dCP232f(_Fs_, _Fsf_);) \ MakeDisF(dis##VU##MI_MR32, dNameU("MR32"); dCP2128f(_Ft_); dCP2128f(_Fs_);) \ -MakeDisF(dis##VU##MI_LQ, dNameU("LQ"); dCP2128f(_Ft_); dCP232i(_Fs_); dImm11();) \ -MakeDisF(dis##VU##MI_LQD, dNameU("LQD"); dCP2128f(_Ft_); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_LQI, dNameU("LQI"); dCP2128f(_Ft_); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_SQ, dNameU("SQ"); dCP2128f(_Fs_); dCP232i(_Ft_); dImm11(); ) \ -MakeDisF(dis##VU##MI_SQD, dNameU("SQD"); dCP2128f(_Fs_); dCP232i(_Ft_);) \ -MakeDisF(dis##VU##MI_SQI, dNameU("SQI"); dCP2128f(_Fs_); dCP232i(_Ft_);) \ -MakeDisF(dis##VU##MI_ILW, dNameU("ILW"); dCP232i(_Ft_); dImm11(); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_ISW, dNameU("ISW"); dCP232i(_Ft_); dImm11(); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_ILWR, dNameU("ILWR"); dCP232i(_Ft_); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_ISWR, dNameU("ISWR"); dCP232i(_Ft_); dCP232i(_Fs_);) \ +MakeDisF(dis##VU##MI_LQ, dNameU("LQ"); dCP2128f(_Ft_); dCP232i(_Is_); dImm11();) \ +MakeDisF(dis##VU##MI_LQD, dNameU("LQD"); dCP2128f(_Ft_); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_LQI, dNameU("LQI"); dCP2128f(_Ft_); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_SQ, dNameU("SQ"); dCP2128f(_Fs_); dCP232i(_It_); dImm11(); ) \ +MakeDisF(dis##VU##MI_SQD, dNameU("SQD"); dCP2128f(_Fs_); dCP232i(_It_);) \ +MakeDisF(dis##VU##MI_SQI, dNameU("SQI"); dCP2128f(_Fs_); dCP232i(_It_);) \ +MakeDisF(dis##VU##MI_ILW, dNameU("ILW"); dCP232i(_It_); dImm11(); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_ISW, dNameU("ISW"); dCP232i(_It_); dImm11(); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_ILWR, dNameU("ILWR"); dCP232i(_It_); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_ISWR, dNameU("ISWR"); dCP232i(_It_); dCP232i(_Is_);) \ MakeDisF(dis##VU##MI_LOI, dName("LOI"); ) \ MakeDisF(dis##VU##MI_RINIT, dNameU("RINIT"); dCP232i(REG_R); dCP232f(_Fs_, _Fsf_);) \ MakeDisF(dis##VU##MI_RGET, dNameU("RGET"); dCP232i(REG_R); dCP2128f(_Ft_);) \ MakeDisF(dis##VU##MI_RNEXT, dNameU("RNEXT"); dCP232i(REG_R); dCP2128f(_Ft_);) \ MakeDisF(dis##VU##MI_RXOR, dNameU("RXOR"); dCP232i(REG_R); dCP232f(_Fs_, _Fsf_);) \ MakeDisF(dis##VU##MI_WAITQ, dName("WAITQ"); ) \ -MakeDisF(dis##VU##MI_FSAND, dName("FSAND"); dCP232i(_Ft_); dCP232i(REG_STATUS_FLAG); sprintf(ostr, "%s %.3x,", ostr, code&0xfff); ) \ -MakeDisF(dis##VU##MI_FSEQ, dName("FSEQ"); dCP232i(_Ft_); dCP232i(REG_STATUS_FLAG); sprintf(ostr, "%s %.3x,", ostr, code&0xfff);) \ -MakeDisF(dis##VU##MI_FSOR, dName("FSOR"); dCP232i(_Ft_); dCP232i(REG_STATUS_FLAG); sprintf(ostr, "%s %.3x,", ostr, code&0xfff);) \ +MakeDisF(dis##VU##MI_FSAND, dName("FSAND"); dCP232i(_It_); dCP232i(REG_STATUS_FLAG); sprintf(ostr, "%s %.3x,", ostr, code&0xfff); ) \ +MakeDisF(dis##VU##MI_FSEQ, dName("FSEQ"); dCP232i(_It_); dCP232i(REG_STATUS_FLAG); sprintf(ostr, "%s %.3x,", ostr, code&0xfff);) \ +MakeDisF(dis##VU##MI_FSOR, dName("FSOR"); dCP232i(_It_); dCP232i(REG_STATUS_FLAG); sprintf(ostr, "%s %.3x,", ostr, code&0xfff);) \ MakeDisF(dis##VU##MI_FSSET, dName("FSSET"); dCP232i(REG_STATUS_FLAG);) \ -MakeDisF(dis##VU##MI_FMAND, dName("FMAND"); dCP232i(_Ft_); dCP232i(REG_MAC_FLAG); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_FMEQ, dName("FMEQ"); dCP232i(_Ft_); dCP232i(REG_MAC_FLAG); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_FMOR, dName("FMOR"); dCP232i(_Ft_); dCP232i(REG_MAC_FLAG); dCP232i(_Fs_);) \ +MakeDisF(dis##VU##MI_FMAND, dName("FMAND"); dCP232i(_It_); dCP232i(REG_MAC_FLAG); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_FMEQ, dName("FMEQ"); dCP232i(_It_); dCP232i(REG_MAC_FLAG); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_FMOR, dName("FMOR"); dCP232i(_It_); dCP232i(REG_MAC_FLAG); dCP232i(_Is_);) \ MakeDisF(dis##VU##MI_FCAND, dName("FCAND"); dCP232i(1); sprintf(ostr, "%s %8.8x,", ostr, code&0xffffff); ) \ MakeDisF(dis##VU##MI_FCEQ, dName("FCEQ"); dCP232i(1); dCP232i(REG_CLIP_FLAG);) \ MakeDisF(dis##VU##MI_FCOR, dName("FCOR"); dCP232i(1); dCP232i(REG_CLIP_FLAG);) \ MakeDisF(dis##VU##MI_FCSET, dName("FCSET"); dCP232i(REG_CLIP_FLAG); sprintf(ostr, "%s %.6x,", ostr, code&0xffffff); ) \ -MakeDisF(dis##VU##MI_FCGET, dName("FCGET"); dCP232i(_Ft_); dCP232i(REG_CLIP_FLAG);) \ -MakeDisF(dis##VU##MI_IBEQ, dName("IBEQ"); dImm11(); dCP232i(_Ft_); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_IBGEZ, dName("IBEZ"); dImm11(); dCP232i(_Ft_); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_IBGTZ, dName("IBGTZ"); dImm11(); dCP232i(_Ft_); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_IBLEZ, dName("IBLEZ"); dImm11(); dCP232i(_Ft_); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_IBLTZ, dName("IBLTZ"); dImm11(); dCP232i(_Ft_); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_IBNE, dName("IBNE"); dImm11(); dCP232i(_Ft_); dCP232i(_Fs_);) \ +MakeDisF(dis##VU##MI_FCGET, dName("FCGET"); dCP232i(_It_); dCP232i(REG_CLIP_FLAG);) \ +MakeDisF(dis##VU##MI_IBEQ, dName("IBEQ"); dImm11(); dCP232i(_It_); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_IBGEZ, dName("IBEZ"); dImm11(); dCP232i(_It_); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_IBGTZ, dName("IBGTZ"); dImm11(); dCP232i(_It_); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_IBLEZ, dName("IBLEZ"); dImm11(); dCP232i(_It_); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_IBLTZ, dName("IBLTZ"); dImm11(); dCP232i(_It_); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_IBNE, dName("IBNE"); dImm11(); dCP232i(_It_); dCP232i(_Is_);) \ MakeDisF(dis##VU##MI_B, dName("B"); dImm11();) \ -MakeDisF(dis##VU##MI_BAL, dName("BAL"); dImm11(); dCP232i(_Ft_);) \ -MakeDisF(dis##VU##MI_JR, dName("JR"); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_JALR, dName("JALR"); dCP232i(_Ft_); dCP232i(_Fs_); ) \ +MakeDisF(dis##VU##MI_BAL, dName("BAL"); dImm11(); dCP232i(_It_);) \ +MakeDisF(dis##VU##MI_JR, dName("JR"); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_JALR, dName("JALR"); dCP232i(_It_); dCP232i(_Is_); ) \ MakeDisF(dis##VU##MI_MFP, dNameU("MFP"); dCP2128f(_Ft_); dCP232i(REG_P);) \ MakeDisF(dis##VU##MI_WAITP, dName("WAITP"); ) \ MakeDisF(dis##VU##MI_ESADD, dName("ESADD"); dCP2128f(_Fs_);) \ @@ -83,16 +83,16 @@ MakeDisF(dis##VU##MI_ELENG, dName("ELENG"); dCP2128f(_Fs_); ) \ MakeDisF(dis##VU##MI_ERLENG, dName("ERLENG"); dCP2128f(_Fs_); ) \ MakeDisF(dis##VU##MI_EATANxy, dName("EATANxy"); dCP2128f(_Fs_);) \ MakeDisF(dis##VU##MI_EATANxz, dName("EATANxz"); dCP2128f(_Fs_);) \ -MakeDisF(dis##VU##MI_ESUM, dName("ESUM"); dCP232i(_Fs_); ) \ +MakeDisF(dis##VU##MI_ESUM, dName("ESUM"); dCP2128f(_Fs_); ) \ MakeDisF(dis##VU##MI_ERCPR, dName("ERCPR"); dCP232f(_Fs_, _Fsf_); ) \ MakeDisF(dis##VU##MI_ESQRT, dName("ESQRT"); dCP232f(_Fs_, _Fsf_); ) \ MakeDisF(dis##VU##MI_ERSQRT, dName("ERSQRT"); dCP232f(_Fs_, _Fsf_); ) \ MakeDisF(dis##VU##MI_ESIN, dName("ESIN"); dCP232f(_Fs_, _Fsf_); ) \ MakeDisF(dis##VU##MI_EATAN, dName("EATAN"); dCP232f(_Fs_, _Fsf_); ) \ MakeDisF(dis##VU##MI_EEXP, dName("EEXP"); dCP232f(_Fs_, _Fsf_); ) \ -MakeDisF(dis##VU##MI_XITOP, dName("XITOP"); dCP232i(_Ft_);) \ -MakeDisF(dis##VU##MI_XGKICK, dName("XGKICK"); dCP232i(_Fs_);) \ -MakeDisF(dis##VU##MI_XTOP, dName("XTOP"); dCP232i(_Ft_);) \ +MakeDisF(dis##VU##MI_XITOP, dName("XITOP"); dCP232i(_It_);) \ +MakeDisF(dis##VU##MI_XGKICK, dName("XGKICK"); dCP232i(_Is_);) \ +MakeDisF(dis##VU##MI_XTOP, dName("XTOP"); dCP232i(_It_);) \ \ \ /*****************/ \ diff --git a/pcsx2/DebugTools/Makefile.am b/pcsx2/DebugTools/Makefile.am deleted file mode 100644 index 5edd2a6e1c..0000000000 --- a/pcsx2/DebugTools/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -INCLUDES = -I@srcdir@/../ -I@srcdir@/../../common/include -I@srcdir@/../../3rdparty $(shell wx-config --cppflags) -noinst_LIBRARIES = libDebugTools.a - -libDebugTools_a_SOURCES = \ -DisR3000A.cpp DisR5900.cpp DisVU0Micro.cpp \ -DisR3000asm.cpp DisR5900asm.cpp DisVU1Micro.cpp \ -Debug.h DisVUmicro.h DisASM.h DisVUops.h diff --git a/pcsx2/Decode_XA.cpp b/pcsx2/Decode_XA.cpp deleted file mode 100644 index 51de78a58e..0000000000 --- a/pcsx2/Decode_XA.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2008 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ -//============================================ -//=== Audio XA decoding -//=== Kazzuya -//============================================ -//=== Modified by linuzappz -//============================================ - -#include - -#include "Decode_XA.h" - -#ifdef __WIN32__ -#pragma warning(disable:4244) -#endif - -typedef unsigned char U8; -typedef unsigned short U16; -typedef unsigned long U32; - -#define NOT(_X_) (!(_X_)) -#define CLAMP(_X_,_MI_,_MA_) {if(_X_<_MI_)_X_=_MI_;if(_X_>_MA_)_X_=_MA_;} - -//============================================ -//=== ADPCM DECODING ROUTINES -//============================================ - -static double K0[4] = { - 0.0, - 0.9375, - 1.796875, - 1.53125 -}; - -static double K1[4] = { - 0.0, - 0.0, - -0.8125, - -0.859375 -}; - -#define BLKSIZ 28 /* block size (32 - 4 nibbles) */ - -//=========================================== -void ADPCM_InitDecode( ADPCM_Decode_t *decp ) -{ - decp->y0 = 0; - decp->y1 = 0; -} - -//=========================================== -#define SH 4 -#define SHC 10 - -#define IK0(fid) ((int)((-K0[fid]) * (1<> 4) & 0x0f; - range = (filter_range >> 0) & 0x0f; - - fy0 = decp->y0; - fy1 = decp->y1; - - for (i = BLKSIZ/4; i; --i) { - long y; - long x0, x1, x2, x3; - - y = *blockp++; - x3 = (short)( y & 0xf000) >> range; x3 <<= SH; - x2 = (short)((y << 4) & 0xf000) >> range; x2 <<= SH; - x1 = (short)((y << 8) & 0xf000) >> range; x1 <<= SH; - x0 = (short)((y << 12) & 0xf000) >> range; x0 <<= SH; - - x0 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x0; - x1 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x1; - x2 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x2; - x3 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x3; - - CLAMP( x0, -32768<> SH; destp += inc; - CLAMP( x1, -32768<> SH; destp += inc; - CLAMP( x2, -32768<> SH; destp += inc; - CLAMP( x3, -32768<> SH; destp += inc; - } - decp->y0 = fy0; - decp->y1 = fy1; -} - -static int headtable[4] = {0,2,8,10}; - -//=========================================== -static void xa_decode_data( xa_decode_t *xdp, unsigned char *srcp ) { - const U8 *sound_groupsp; - const U8 *sound_datap, *sound_datap2; - int i, j, k, nbits; - U16 data[4096], *datap; - short *destp; - - destp = xdp->pcm; - nbits = xdp->nbits == 4 ? 4 : 2; - - if (xdp->stereo) { // stereo - for (j=0; j < 18; j++) { - sound_groupsp = srcp + j * 128; // sound groups header - sound_datap = sound_groupsp + 16; // sound data just after the header - - for (i=0; i < nbits; i++) { - datap = data; - sound_datap2 = sound_datap + i; - if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A - for (k=0; k < 14; k++, sound_datap2 += 8) { - *(datap++) = (U16)sound_datap2[0] | - (U16)(sound_datap2[4] << 8); - } - } else { // level B/C - for (k=0; k < 7; k++, sound_datap2 += 16) { - *(datap++) = (U16)(sound_datap2[ 0] & 0x0f) | - ((U16)(sound_datap2[ 4] & 0x0f) << 4) | - ((U16)(sound_datap2[ 8] & 0x0f) << 8) | - ((U16)(sound_datap2[12] & 0x0f) << 12); - } - } - ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data, - destp+0, 2 ); - - datap = data; - sound_datap2 = sound_datap + i; - if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A - for (k=0; k < 14; k++, sound_datap2 += 8) { - *(datap++) = (U16)sound_datap2[0] | - (U16)(sound_datap2[4] << 8); - } - } else { // level B/C - for (k=0; k < 7; k++, sound_datap2 += 16) { - *(datap++) = (U16)(sound_datap2[ 0] >> 4) | - ((U16)(sound_datap2[ 4] >> 4) << 4) | - ((U16)(sound_datap2[ 8] >> 4) << 8) | - ((U16)(sound_datap2[12] >> 4) << 12); - } - } - ADPCM_DecodeBlock16( &xdp->right, sound_groupsp[headtable[i]+1], data, - destp+1, 2 ); - - destp += 28*2; - } - } - } - else { // mono - for (j=0; j < 18; j++) { - sound_groupsp = srcp + j * 128; // sound groups header - sound_datap = sound_groupsp + 16; // sound data just after the header - - for (i=0; i < nbits; i++) { - datap = data; - sound_datap2 = sound_datap + i; - if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A - for (k=0; k < 14; k++, sound_datap2 += 8) { - *(datap++) = (U16)sound_datap2[0] | - (U16)(sound_datap2[4] << 8); - } - } else { // level B/C - for (k=0; k < 7; k++, sound_datap2 += 16) { - *(datap++) = (U16)(sound_datap2[ 0] & 0x0f) | - ((U16)(sound_datap2[ 4] & 0x0f) << 4) | - ((U16)(sound_datap2[ 8] & 0x0f) << 8) | - ((U16)(sound_datap2[12] & 0x0f) << 12); - } - } - ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data, - destp, 1 ); - - destp += 28; - - datap = data; - sound_datap2 = sound_datap + i; - if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A - for (k=0; k < 14; k++, sound_datap2 += 8) { - *(datap++) = (U16)sound_datap2[0] | - (U16)(sound_datap2[4] << 8); - } - } else { // level B/C - for (k=0; k < 7; k++, sound_datap2 += 16) { - *(datap++) = (U16)(sound_datap2[ 0] >> 4) | - ((U16)(sound_datap2[ 4] >> 4) << 4) | - ((U16)(sound_datap2[ 8] >> 4) << 8) | - ((U16)(sound_datap2[12] >> 4) << 12); - } - } - ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+1], data, - destp, 1 ); - - destp += 28; - } - } - } -} - -//============================================ -//=== XA SPECIFIC ROUTINES -//============================================ -typedef struct { -U8 filenum; -U8 channum; -U8 submode; -U8 coding; - -U8 filenum2; -U8 channum2; -U8 submode2; -U8 coding2; -} xa_subheader_t; - -#define SUB_SUB_EOF (1<<7) // end of file -#define SUB_SUB_RT (1<<6) // real-time sector -#define SUB_SUB_FORM (1<<5) // 0 form1 1 form2 -#define SUB_SUB_TRIGGER (1<<4) // used for interrupt -#define SUB_SUB_DATA (1<<3) // contains data -#define SUB_SUB_AUDIO (1<<2) // contains audio -#define SUB_SUB_VIDEO (1<<1) // contains video -#define SUB_SUB_EOR (1<<0) // end of record - -#define AUDIO_CODING_GET_STEREO(_X_) ( (_X_) & 3) -#define AUDIO_CODING_GET_FREQ(_X_) (((_X_) >> 2) & 3) -#define AUDIO_CODING_GET_BPS(_X_) (((_X_) >> 4) & 3) -#define AUDIO_CODING_GET_EMPHASIS(_X_) (((_X_) >> 6) & 1) - -#define SUB_UNKNOWN 0 -#define SUB_VIDEO 1 -#define SUB_AUDIO 2 - -//============================================ -static int parse_xa_audio_sector( xa_decode_t *xdp, - xa_subheader_t *subheadp, - unsigned char *sectorp, - int is_first_sector ) { - if ( is_first_sector ) { - switch ( AUDIO_CODING_GET_FREQ(subheadp->coding) ) { - case 0: xdp->freq = 37800; break; - case 1: xdp->freq = 18900; break; - default: xdp->freq = 0; break; - } - switch ( AUDIO_CODING_GET_BPS(subheadp->coding) ) { - case 0: xdp->nbits = 4; break; - case 1: xdp->nbits = 8; break; - default: xdp->nbits = 0; break; - } - switch ( AUDIO_CODING_GET_STEREO(subheadp->coding) ) { - case 0: xdp->stereo = 0; break; - case 1: xdp->stereo = 1; break; - default: xdp->stereo = 0; break; - } - - if ( xdp->freq == 0 ) - return -1; - - ADPCM_InitDecode( &xdp->left ); - ADPCM_InitDecode( &xdp->right ); - - xdp->nsamples = 18 * 28 * 8; - if (xdp->stereo == 1) xdp->nsamples /= 2; - } - xa_decode_data( xdp, sectorp ); - - return 0; -} - -//================================================================ -//=== THIS IS WHAT YOU HAVE TO CALL -//=== xdp - structure were all important data are returned -//=== sectorp - data in input -//=== pcmp - data in output -//=== is_first_sector - 1 if it's the 1st sector of the stream -//=== - 0 for any other successive sector -//=== return -1 if error -//================================================================ -long xa_decode_sector( xa_decode_t *xdp, - unsigned char *sectorp, int is_first_sector ) { - if (parse_xa_audio_sector(xdp, (xa_subheader_t *)sectorp, sectorp + sizeof(xa_subheader_t), is_first_sector)) - return -1; - - return 0; -} - -/* EXAMPLE: -"nsamples" is the number of 16 bit samples -every sample is 2 bytes in mono and 4 bytes in stereo - -xa_decode_t xa; - - sectorp = read_first_sector(); - xa_decode_sector( &xa, sectorp, 1 ); - play_wave( xa.pcm, xa.freq, xa.nsamples ); - - while ( --n_sectors ) - { - sectorp = read_next_sector(); - xa_decode_sector( &xa, sectorp, 0 ); - play_wave( xa.pcm, xa.freq, xa.nsamples ); - } -*/ diff --git a/pcsx2/Docs/ChangeLog.txt b/pcsx2/Docs/ChangeLog.txt index 4c9c3ea7f2..182d60802b 100644 --- a/pcsx2/Docs/ChangeLog.txt +++ b/pcsx2/Docs/ChangeLog.txt @@ -221,7 +221,7 @@ v0.9.1: * 05/08/05:[+] Added faster Cd/DVD reads to the Advanced options (Refraction) [-] The previous DVD/CD change by ref was just a hack, so i commited the old version again - [-] I've commented out RECOMPILE_VUMI_LOADSTORE on iVUmicro.h, instead + [-] I've commented out RECOMPILE_VUMI_LOADSTORE on sVU_Micro.h, instead of commenting it out in iVU1micro.c as ref did on last update, that way is better until i fix the real problem [*] Improved vuDIV for .x to .x cases diff --git a/pcsx2/Elfheader.cpp b/pcsx2/Elfheader.cpp index d1681dd97f..8be8701552 100644 --- a/pcsx2/Elfheader.cpp +++ b/pcsx2/Elfheader.cpp @@ -19,7 +19,7 @@ #include "PrecompiledHeader.h" #include "Common.h" -#include "CDVDisodrv.h" +#include "CDVD/CDVDisodrv.h" using namespace std; @@ -232,7 +232,7 @@ struct ElfObject ElfObject( const wxString& srcfile, uint hdrsize ) : filename( srcfile ) - , data( hdrsize, "ELF headers" ) + , data( hdrsize, L"ELF headers" ) , header( *(ELF_HEADER*)data.GetPtr() ) , proghead( NULL ) , secthead( NULL ) @@ -582,28 +582,7 @@ int loadElfFile(const wxString& filename) Console::Status( wxsFormat( L"loadElfFile: %s; CRC = %8.8X", filename.c_str(), ElfCRC ) ); ElfApplyPatches(); - LoadGameSpecificSettings(); - + return 0; } -#include "VU.h" -extern bool path3hack; -int g_VUGameFixes = 0; - -// fixme - this should be moved to patches or eliminated -void LoadGameSpecificSettings() -{ - // default - g_VUGameFixes = 0; - - switch(ElfCRC) { - case 0xb99379b7: // erementar gerad (discolored chars) - g_VUGameFixes |= VUFIX_XGKICKDELAY2; // Tested - still needed - arcum42 - break; - //case 0xa08c4057: //Sprint Cars (SLUS) - //case 0x8b0725d5: //Flinstones Bedrock Racing (SLES) - //path3hack = TRUE; // We can move this to patch files right now - //break; - } -} diff --git a/pcsx2/Elfheader.h b/pcsx2/Elfheader.h index cc61fa18cd..6a7a3b94b0 100644 --- a/pcsx2/Elfheader.h +++ b/pcsx2/Elfheader.h @@ -26,7 +26,6 @@ extern unsigned int args_ptr; //------------------- int loadElfFile(const wxString& filename); u32 loadElfCRC(const char *filename); -void LoadGameSpecificSettings(); void ElfApplyPatches(); extern u32 ElfCRC; diff --git a/pcsx2/FiFo.cpp b/pcsx2/FiFo.cpp index 92756317d5..2b0a022404 100644 --- a/pcsx2/FiFo.cpp +++ b/pcsx2/FiFo.cpp @@ -53,7 +53,7 @@ extern int FOreadpos; void __fastcall ReadFIFO_page_4(u32 mem, u64 *out) { - jASSUME( (mem >= 0x10004000) && (mem < 0x10005000) ); + jASSUME( (mem >= VIF0_FIFO) && (mem < VIF1_FIFO) ); VIF_LOG("ReadFIFO/VIF0 0x%08X", mem); //out[0] = psHu64(mem ); @@ -65,7 +65,7 @@ void __fastcall ReadFIFO_page_4(u32 mem, u64 *out) void __fastcall ReadFIFO_page_5(u32 mem, u64 *out) { - jASSUME( (mem >= 0x10005000) && (mem < 0x10006000) ); + jASSUME( (mem >= VIF1_FIFO) && (mem < GIF_FIFO) ); VIF_LOG("ReadFIFO/VIF1, addr=0x%08X", mem); @@ -87,7 +87,7 @@ void __fastcall ReadFIFO_page_5(u32 mem, u64 *out) void __fastcall ReadFIFO_page_6(u32 mem, u64 *out) { - jASSUME( (mem >= 0x10006000) && (mem < 0x10007000) ); + jASSUME( (mem >= GIF_FIFO) && (mem < IPUout_FIFO) ); DevCon::Notice( "ReadFIFO/GIF, addr=0x%x", params mem ); @@ -100,7 +100,7 @@ void __fastcall ReadFIFO_page_6(u32 mem, u64 *out) void __fastcall ReadFIFO_page_7(u32 mem, u64 *out) { - jASSUME( (mem >= 0x10007000) && (mem < 0x10008000) ); + jASSUME( (mem >= IPUout_FIFO) && (mem < D0_CHCR) ); // All addresses in this page map to 0x7000 and 0x7010: mem &= 0x10; @@ -125,7 +125,7 @@ void __fastcall ReadFIFO_page_7(u32 mem, u64 *out) void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value) { - jASSUME( (mem >= 0x10004000) && (mem < 0x10005000) ); + jASSUME( (mem >= VIF0_FIFO) && (mem < VIF1_FIFO) ); VIF_LOG("WriteFIFO/VIF0, addr=0x%08X", mem); @@ -142,7 +142,7 @@ void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value) void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value) { - jASSUME( (mem >= 0x10005000) && (mem < 0x10006000) ); + jASSUME( (mem >= VIF1_FIFO) && (mem < GIF_FIFO) ); VIF_LOG("WriteFIFO/VIF1, addr=0x%08X", mem); @@ -164,7 +164,7 @@ void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value) void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value) { - jASSUME( (mem >= 0x10006000) && (mem < 0x10007000) ); + jASSUME( (mem >= GIF_FIFO) && (mem < IPUout_FIFO) ); GIF_LOG("WriteFIFO/GIF, addr=0x%08X", mem); //psHu64(mem ) = value[0]; @@ -192,7 +192,7 @@ void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value) void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value) { - jASSUME( (mem >= 0x10007000) && (mem < 0x10008000) ); + jASSUME( (mem >= IPUout_FIFO) && (mem < D0_CHCR) ); // All addresses in this page map to 0x7000 and 0x7010: mem &= 0x10; diff --git a/pcsx2/GS.cpp b/pcsx2/GS.cpp index caacae525d..c711e9b415 100644 --- a/pcsx2/GS.cpp +++ b/pcsx2/GS.cpp @@ -243,9 +243,7 @@ void gsReset() memzero_obj(g_RealGSMem); - Path3transfer = FALSE; - - GSCSRr = 0x551B400F; // Set the FINISH bit to 1 for now + GSCSRr = 0x551B4000; // Set the FINISH bit to 1 for now GSIMR = 0x7f00; psHu32(GIF_STAT) = 0; psHu32(GIF_CTRL) = 0; @@ -277,12 +275,14 @@ void gsGIFReset() { // fixme - should this be here? (air) //memzero_obj(g_RealGSMem); + // none of this should be here, its a GIF reset, not GS, only the dma side of it is reset. (Refraction) // perform a soft reset (but do not do a full reset if the soft reset API is unavailable) - gsGIFSoftReset( 7 ); + //gsGIFSoftReset( 7 ); - GSCSRr = 0x551B400F; // Set the FINISH bit to 1 for now - GSIMR = 0x7f00; + + //GSCSRr = 0x551B4000; // Set the FINISH bit to 1 for now + //GSIMR = 0x7f00; psHu32(GIF_STAT) = 0; psHu32(GIF_CTRL) = 0; psHu32(GIF_MODE) = 0; @@ -290,14 +290,7 @@ void gsGIFReset() void gsCSRwrite(u32 value) { - CSRw |= value & ~0x60; - - if( mtgsThread != NULL ) - mtgsThread->SendSimplePacket( GS_RINGTYPE_WRITECSR, CSRw, 0, 0 ); - else - GSwriteCSR(CSRw); - - GSCSRr = ((GSCSRr&~value)&0x1f)|(GSCSRr&~0x1f); + // Our emulated GS has no FIFO... /*if( value & 0x100 ) { // FLUSH @@ -317,15 +310,36 @@ void gsCSRwrite(u32 value) GSreset(); } - GSCSRr = 0x551B400F; // Set the FINISH bit to 1 - GS is always at a finish state as we don't have a FIFO(saqib) + CSRw |= 0x1f; + GSCSRr = 0x551B4000; // Set the FINISH bit to 1 - GS is always at a finish state as we don't have a FIFO(saqib) GSIMR = 0x7F00; //This is bits 14-8 thats all that should be 1 + } + else if( value & 0x100 ) // FLUSH + { + //Console::WriteLn("GS_CSR FLUSH GS fifo: %x (CSRr=%x)", params value, GSCSRr); } + else + { + CSRw |= value & 0x1f; + + if( mtgsThread != NULL ) + mtgsThread->SendSimplePacket( GS_RINGTYPE_WRITECSR, CSRw, 0, 0 ); + else + GSwriteCSR(CSRw); + + GSCSRr = ((GSCSRr&~value)&0x1f)|(GSCSRr&~0x1f); + } + } static void IMRwrite(u32 value) { GSIMR = (value & 0x1f00)|0x6000; + if((GSCSRr & 0x1f) & (~(GSIMR >> 8) & 0x1f)) + { + gsIrq(); + } // don't update mtgs mem } @@ -435,6 +449,8 @@ void __fastcall gsWrite64_page_00( u32 mem, const mem64_t* value ) void __fastcall gsWrite64_page_01( u32 mem, const mem64_t* value ) { + GIF_LOG("GS Write64 at %8.8lx with data %8.8x_%8.8x", mem, (u32*)value[1], (u32*)value[0]); + switch( mem ) { case GS_CSR: diff --git a/pcsx2/GS.h b/pcsx2/GS.h index 983d13a9b1..a15a8c1977 100644 --- a/pcsx2/GS.h +++ b/pcsx2/GS.h @@ -25,9 +25,7 @@ #include #include "Common.h" -#include "Threading.h" - -#define GSPATH3FIX +#include "Utilities/Threading.h" PCSX2_ALIGNED16( extern u8 g_RealGSMem[0x2000] ); #define GSCSRr *((u64*)(g_RealGSMem+0x1000)) @@ -99,6 +97,21 @@ struct GIFPath __forceinline void PrepRegs(); void SetTag(const void* mem); u32 GetReg(); + + __forceinline bool StepReg() + { + if((++curreg & 0xf) == tag.nreg) + { + curreg = 0; + + if(--tag.nloop == 0) + { + return false; + } + } + + return true; + } }; @@ -250,7 +263,7 @@ protected: // Processes a GIFtag & packet, and throws out some gsIRQs as needed. // Used to keep interrupts in sync with the EE, while the GS itself // runs potentially several frames behind. - u32 _gifTransferDummy( GIF_PATH pathidx, const u8 *pMem, u32 size ); + int _gifTransferDummy( GIF_PATH pathidx, const u8 *pMem, u32 size ); // Used internally by SendSimplePacket type functions uint _PrepForSimplePacket(); @@ -263,7 +276,7 @@ extern mtgsThreadObject* mtgsThread; void mtgsWaitGS(); bool mtgsOpen(); -void mtgsRingBufSimplePacket( s32 command, u32 data0, u32 data1, u32 data2 ); +//void mtgsRingBufSimplePacket( s32 command, u32 data0, u32 data1, u32 data2 ); ///////////////////////////////////////////////////////////////////////////// // Generalized GS Functions and Stuff diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index edb8ee7069..fb29f830b5 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -28,7 +28,7 @@ using std::min; -#define gifsplit 64 +#define gifsplit 0x10000 enum gifstate_t { GIF_STATE_READY = 0, @@ -38,6 +38,7 @@ enum gifstate_t }; // A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished). +// Should be a gifstate_t rather then int, but I don't feel like possibly interfering with savestates right now. static int gifstate = GIF_STATE_READY; static u64 s_gstag = 0; // used for querying the last tag @@ -48,17 +49,39 @@ static int gspath3done = 0; static u32 gscycles = 0, prevcycles = 0, mfifocycles = 0; static u32 gifqwc = 0; -bool gifmfifoirq = FALSE; +bool gifmfifoirq = false; -__forceinline void gsInterrupt() { +static __forceinline void clearFIFOstuff(bool full) +{ + GSCSRr &= ~0xC000; //Clear FIFO stuff + + if (full) + GSCSRr |= 0x8000; //FIFO full + else + GSCSRr |= 0x4000; //FIFO empty +} + +__forceinline void gsInterrupt() +{ GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle); - if((gif->chcr & 0x100) == 0){ + if ((gif->chcr & 0x100) == 0) + { //Console::WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", params gif->chcr, gif->qwc, done); return; } - if (gif->qwc > 0 || gspath3done == 0) { - if (!(psHu32(DMAC_CTRL) & 0x1)) { + + if ((vif1.cmd & 0x7f) == 0x51) + { + if (Path3progress != IMAGE_MODE) vif1Regs->stat &= ~VIF1_STAT_VGW; + } + + if (Path3progress == STOPPED_MODE) psHu32(GIF_STAT) &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0 + + if ((gif->qwc > 0) || (gspath3done == 0)) + { + if (!(psHu32(DMAC_CTRL) & 0x1)) + { Console::Notice("gs dma masked, re-scheduling..."); // re-raise the int shortly in the future CPU_INT( 2, 64 ); @@ -66,39 +89,31 @@ __forceinline void gsInterrupt() { } GIFdma(); -#ifdef GSPATH3FIX - // re-raise the IRQ as part of the mysterious Path3fix. - // fixme - this hack *should* have the gs_irq raised from the VIF, I think. It would be - // more efficient and more correct. (air) - /*if (!(vif1Regs->mskpath3 && (vif1ch->chcr & 0x100)) || (psHu32(GIF_MODE) & 0x1)) - CPU_INT( 2, 64 );*/ -#endif - if(gspath3done == 0 || gif->qwc > 0) return; + return; } gspath3done = 0; gscycles = 0; - Path3transfer = FALSE; gif->chcr &= ~0x100; - GSCSRr &= ~0xC000; //Clear FIFO stuff - GSCSRr |= 0x4000; //FIFO empty - psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 - psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0 + vif1Regs->stat &= ~VIF1_STAT_VGW; + + psHu32(GIF_STAT)&= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0 + psHu32(GIF_STAT) &= ~GIF_STAT_P3Q; + psHu32(GIF_STAT) &= ~0x1F000000; // QFC=0 + + clearFIFOstuff(false); hwDmacIrq(DMAC_GIF); GIF_LOG("GIF DMA end"); } -static void WRITERING_DMA(u32 *pMem, u32 qwc) +static u32 WRITERING_DMA(u32 *pMem, u32 qwc) { - psHu32(GIF_STAT) |= 0xE00; - - // Path3 transfer will be set to false by the GIFtag handler. - Path3transfer = TRUE; + psHu32(GIF_STAT) |= GIF_STAT_APATH3 | GIF_STAT_OPH; if( mtgsThread != NULL ) { - int sizetoread = (qwc)<<4; + int sizetoread = qwc; sizetoread = mtgsThread->PrepDataPacket( GIF_PATH_3, pMem, qwc ); u8* pgsmem = mtgsThread->GetDataPacketPtr(); @@ -114,28 +129,26 @@ static void WRITERING_DMA(u32 *pMem, u32 qwc) memcpy_aligned(pgsmem, pMem, sizetoread<<4); mtgsThread->SendDataPacket(); + return sizetoread; } else { GSGIFTRANSFER3(pMem, qwc); - if (GSgetLastTag != NULL) - { - GSgetLastTag(&s_gstag); - if (s_gstag == 1) Path3transfer = FALSE; /* fixes SRS and others */ - } + gif->madr+= qwc*16; + gif->qwc -= qwc; + return qwc; } } -int _GIFchain() { -#ifdef GSPATH3FIX - u32 qwc = ((psHu32(GIF_MODE) & 0x4) && (vif1Regs->mskpath3)) ? min(8, (int)gif->qwc) : min( gifsplit, (int)gif->qwc ); -#else - u32 qwc = gif->qwc; -#endif +int _GIFchain() +{ + //u32 qwc = ((psHu32(GIF_MODE) & 0x4) || vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : min( gifsplit, (int)gif->qwc ); + u32 qwc = min( gifsplit, (int)gif->qwc ); u32 *pMem; pMem = (u32*)dmaGetAddr(gif->madr); - if (pMem == NULL) { + if (pMem == NULL) + { // reset path3, fixes dark cloud 2 gsGIFSoftReset(4); @@ -145,11 +158,8 @@ int _GIFchain() { Console::Notice( "Hackfix - NULL GIFchain" ); return -1; } - WRITERING_DMA(pMem, qwc); - gif->madr+= qwc*16; - gif->qwc -= qwc; - return (qwc)*2; + return (WRITERING_DMA(pMem, qwc)); } static __forceinline void GIFchain() @@ -159,23 +169,47 @@ static __forceinline void GIFchain() FreezeRegs(0); } -static __forceinline void dmaGIFend() +static __forceinline bool checkTieBit(u32* &ptag) { - if ((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0) - CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/); - else - CPU_INT(2, min( gifsplit, (int)gif->qwc ) /** BIAS*/); + if ((gif->chcr & 0x80) && (ptag[0] >> 31)) //Check TIE bit of CHCR and IRQ bit of tag + { + GIF_LOG("dmaIrq Set"); + gspath3done = 1; + return true; + } + + return false; } -// These could probably be consolidated into one function, -// but I wasn't absolutely sure if there was a good reason -// not to do the gif->qwc != 0 check. --arcum42 -static __forceinline void GIFdmaEnd() +static __forceinline bool ReadTag(u32* &ptag, u32 &id) { - if (psHu32(GIF_MODE) & 0x4) - CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/); - else - CPU_INT(2, min( gifsplit, (int)gif->qwc ) /** BIAS*/); + ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + + if (ptag == NULL) //Is ptag empty? + { + //If yes, set BEIS (BUSERR) in DMAC_STAT register + psHu32(DMAC_STAT)|= DMAC_STAT_BEIS; + return false; + } + gscycles+=2; // Add 1 cycles from the QW read for the tag + gif->chcr = ( gif->chcr & 0xFFFF ) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15 + + id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag + gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag + gif->madr = ptag[1]; //MADR = ADDR field + + gspath3done = hwDmacSrcChainWithStack(gif, id); + return true; +} + +static __forceinline void ReadTag2(u32* &ptag) +{ + ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag + gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 + gif->madr = ptag[1]; + + gspath3done = hwDmacSrcChainWithStack(gif, (ptag[0] >> 28) & 0x7); } void GIFdma() @@ -183,224 +217,196 @@ void GIFdma() u32 *ptag; u32 id; - gscycles= prevcycles ? prevcycles: gscycles; + gscycles = prevcycles; - if ((psHu32(GIF_CTRL) & 8)) { // temporarily stop + if ((psHu32(GIF_CTRL) & 8)) // temporarily stop + { Console::WriteLn("Gif dma temp paused?"); return; } - - -#ifndef GSPATH3FIX - if ( !(psHu32(GIF_MODE) & 0x4) ) { - if (vif1Regs->mskpath3 || psHu32(GIF_MODE) & 0x1) { - gif->chcr &= ~0x100; - psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 - hwDmacIrq(2); - return; - } - } -#endif - - if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80 && prevcycles != 0) { // STD == GIF + if (((psHu32(DMAC_CTRL) & 0xC0) == 0x80) && (prevcycles != 0)) // STD == GIF + { Console::WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", params (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3, gif->madr, psHu32(DMAC_STADR)); - if( gif->madr + (gif->qwc * 16) > psHu32(DMAC_STADR) ) { + if ((gif->madr + (gif->qwc * 16)) > psHu32(DMAC_STADR)) + { CPU_INT(2, gscycles); gscycles = 0; return; } + prevcycles = 0; gif->qwc = 0; } - GSCSRr &= ~0xC000; //Clear FIFO stuff - GSCSRr |= 0x8000; //FIFO full - psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [ used to be 0xE00; // OPH=1 | APATH=3] + clearFIFOstuff(true); + psHu32(GIF_STAT) |= 0x10000000; // FQC=31, hack ;) [ used to be 0xE00; // OPH=1 | APATH=3] + + //Path2 gets priority in intermittent mode + if (((psHu32(GIF_STAT) & 0x100) || (vif1.cmd & 0x7f) == 0x50) && (psHu32(GIF_MODE) & 0x4) && (Path3progress == IMAGE_MODE)) + { + GIF_LOG("Waiting VU %x, PATH2 %x, GIFMODE %x Progress %x", psHu32(GIF_STAT) & 0x100, (vif1.cmd & 0x7f), psHu32(GIF_MODE), Path3progress); + CPU_INT(2, 16); + return; + } -#ifdef GSPATH3FIX - if (vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1)) { - if(gif->qwc == 0) { - if((gif->chcr & 0x10e) == 0x104) { - ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR - - if (ptag == NULL) { //Is ptag empty? - psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register - return; - } - gscycles += 2; - gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag - gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag - gif->madr = ptag[1]; //MADR = ADDR field - gspath3done = hwDmacSrcChainWithStack(gif, id); + if (vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1)) + { + if (gif->qwc == 0) + { + if ((gif->chcr & 0x10c) == 0x104) + { + if (!ReadTag(ptag, id)) return; GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr); - if ((gif->chcr & 0x80) && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag - GIF_LOG("PATH3 MSK dmaIrq Set"); - Console::WriteLn("GIF TIE"); - gspath3done |= 1; - } + //Check TIE bit of CHCR and IRQ bit of tag + if (checkTieBit(ptag)) GIF_LOG("PATH3 MSK dmaIrq Set"); } + } + + if (Path3progress == STOPPED_MODE) /*|| (vif1Regs->stat |= VIF1_STAT_VGW) == 0*/ + { + vif1Regs->stat &= ~VIF1_STAT_VGW; + if (gif->qwc == 0) CPU_INT(2, 16); + return; } - - GIFchain(); - if((gif->qwc == 0) && ((gspath3done == 1) || (gif->chcr & 0xc) == 0)){ - gspath3done = 0; - gif->chcr &= ~0x100; - GSCSRr &= ~0xC000; - GSCSRr |= 0x4000; - Path3transfer = FALSE; - psHu32(GIF_STAT)&= ~0x1F000E00; // OPH=0 | APATH=0 | QFC=0 - hwDmacIrq(DMAC_GIF); - } - //Dont unfreeze xmm regs here, Masked PATH3 can only be called by VIF, which is already handling it. + GIFchain(); + CPU_INT(2, gscycles * BIAS); return; } -#endif + // Transfer Dn_QWC from Dn_MADR to GIF - if ((gif->chcr & 0xc) == 0 || gif->qwc > 0) { // Normal Mode - if ((((psHu32(DMAC_CTRL) & 0xC0) == 0x80) && ((gif->chcr & 0xc) == 0))) { + if (((gif->chcr & 0xc) == 0) || (gif->qwc > 0)) // Normal Mode + { + + if (((psHu32(DMAC_CTRL) & 0xC0) == 0x80) && ((gif->chcr & 0xc) == 0)) + { Console::WriteLn("DMA Stall Control on GIF normal"); } + GIFchain(); //Transfers the data set by the switch - - if (((gif->qwc == 0) && (gif->chcr & 0xc) == 0)) - gspath3done = 1; - else if(gif->qwc > 0) - { - GIFdmaEnd(); - return; - + + CPU_INT(2, gscycles * BIAS); + return; } - } - if ((gif->chcr & 0xc) == 0x4 && gspath3done == 0) + if (((gif->chcr & 0xc) == 0x4) && (gspath3done == 0)) // Chain Mode { - // Chain Mode - //while ((gspath3done == 0) && (gif->qwc == 0)) { //Loop if the transfers aren't intermittent - ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR - if (ptag == NULL) { //Is ptag empty? - psHu32(DMAC_STAT)|= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register + if (!ReadTag(ptag, id)) return; + GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr); + + if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80) // STD == GIF + { + // there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall + if (!gspath3done && ((gif->madr + (gif->qwc * 16)) > psHu32(DMAC_STADR)) && (id == 4)) + { + // stalled + Console::WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", params (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR)); + prevcycles = gscycles; + gif->tadr -= 16; + hwDmacIrq(DMAC_13); + CPU_INT(2, gscycles); + gscycles = 0; return; } - gscycles+=2; // Add 1 cycles from the QW read for the tag - - // We used to transfer dma tags if tte is set here - - gif->chcr = ( gif->chcr & 0xFFFF ) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15 - - id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag - gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag - gif->madr = ptag[1]; //MADR = ADDR field + } - gspath3done = hwDmacSrcChainWithStack(gif, id); - GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr); - - if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80) { // STD == GIF - // there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall - if(!gspath3done && ((gif->madr + (gif->qwc * 16)) > psHu32(DMAC_STADR)) && (id == 4)) { - // stalled - Console::WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", params (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR)); - prevcycles = gscycles; - gif->tadr -= 16; - hwDmacIrq(13); - CPU_INT(2, gscycles); - gscycles = 0; - return; - } - } - GIFchain(); //Transfers the data set by the switch - - if ((gif->chcr & 0x80) && (ptag[0] >> 31)) { //Check TIE bit of CHCR and IRQ bit of tag - GIF_LOG("dmaIrq Set"); - gspath3done = 1; - } - //} + checkTieBit(ptag); } prevcycles = 0; - if (!(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))) { - if (gspath3done == 0 || gif->qwc > 0) - { - if (gif->qwc != 0) - { - GIFdmaEnd(); - } - else - { - ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR - gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag - gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - - GIFdmaEnd(); - gif->qwc = 0; - return; - } - } + + if ((gspath3done == 0) && (gif->qwc == 0)) + { + ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag + gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 + gif->madr = ptag[1]; + + gspath3done = hwDmacSrcChainWithStack(gif, (ptag[0] >> 28) & 0x7); + + checkTieBit(ptag); + + GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, (ptag[0] >> 28) & 0x7, gif->madr); + CPU_INT(2, gscycles * BIAS); + } + else + { + CPU_INT(2, gscycles * BIAS); gscycles = 0; } } -void dmaGIF() { - //We used to addd wait time for the buffer to fill here, fixing some timing problems in path 3 masking - //It takes the time of 24 QW for the BUS to become ready - The Punisher, And1 Streetball +void dmaGIF() +{ + //We used to add wait time for the buffer to fill here, fixing some timing problems in path 3 masking + //It takes the time of 24 QW for the BUS to become ready - The Punisher And Streetball GIF_LOG("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1); - if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) { // GIF MFIFO + + Path3progress = STOPPED_MODE; + gspath3done = 0; // For some reason this doesn't clear? So when the system starts the thread, we will clear it :) + psHu32(GIF_STAT) |= GIF_STAT_P3Q; + psHu32(GIF_STAT) |= 0x10000000; // FQC=31, hack ;) [used to be 0xE00; // OPH=1 | APATH=3] + clearFIFOstuff(true); + + if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) // GIF MFIFO + { //Console::WriteLn("GIF MFIFO"); gifMFIFOInterrupt(); return; - } + } - gspath3done = 0; // For some reason this doesnt clear? So when the system starts the thread, we will clear it :) - - GSCSRr &= ~0xC000; //Clear FIFO stuff - GSCSRr |= 0x8000; //FIFO full - psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [used to be 0xE00; // OPH=1 | APATH=3] - - if ((gif->qwc == 0) && ((gif->chcr & 0xc) != 0)){ + if ((gif->qwc == 0) && ((gif->chcr & 0xc) != 0)) + { u32 *ptag; - ptag = (u32*)dmaGetAddr(gif->tadr); - gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag - gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - //gspath3done = hwDmacSrcChainWithStack(gif, (ptag[0] >> 28) & 0x7); - GIFdmaEnd(); - gif->qwc = 0; + ReadTag2(ptag); + GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, (ptag[0] >> 28), gif->madr); + + checkTieBit(ptag); + GIFdma(); return; } //Halflife sets a QWC amount in chain mode, no tadr set. - if((gif->qwc > 0) && ((gif->chcr & 0x4) == 0x4)) gspath3done = 1; + if (gif->qwc > 0) gspath3done = 1; - dmaGIFend(); + GIFdma(); } // called from only one location, so forceinline it: -static __forceinline int mfifoGIFrbTransfer() { - u32 qwc = (psHu32(GIF_MODE) & 0x4 && vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : gif->qwc; - int mfifoqwc = min(gifqwc, qwc); +static __forceinline int mfifoGIFrbTransfer() +{ + u32 mfifoqwc = min(gifqwc, (u32)gif->qwc); u32 *src; /* Check if the transfer should wrap around the ring buffer */ if ((gif->madr+mfifoqwc*16) > (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16)) { int s1 = ((psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16) - gif->madr) >> 4; - + int s2 = (mfifoqwc - s1); // fixme - I don't think these should use WRITERING_DMA, since our source // isn't the DmaGetAddr(gif->madr) address that WRITERING_DMA expects. /* it does, so first copy 's1' bytes from 'addr' to 'data' */ src = (u32*)PSM(gif->madr); if (src == NULL) return -1; - WRITERING_DMA(src, s1); + s1 = WRITERING_DMA(src, s1); - /* and second copy 's2' bytes from 'maddr' to '&data[s1]' */ - src = (u32*)PSM(psHu32(DMAC_RBOR)); - if (src == NULL) return -1; - WRITERING_DMA(src, (mfifoqwc - s1)); + if (s1 == (mfifoqwc - s2)) + { + /* and second copy 's2' bytes from 'maddr' to '&data[s1]' */ + src = (u32*)PSM(psHu32(DMAC_RBOR)); + if (src == NULL) return -1; + s2 = WRITERING_DMA(src, s2); + } + else + { + s2 = 0; + } + mfifoqwc = s1 + s2; } else { @@ -409,67 +415,67 @@ static __forceinline int mfifoGIFrbTransfer() { src = (u32*)PSM(gif->madr); if (src == NULL) return -1; - WRITERING_DMA(src, mfifoqwc); + mfifoqwc = WRITERING_DMA(src, mfifoqwc); gif->madr = psHu32(DMAC_RBOR) + (gif->madr & psHu32(DMAC_RBSR)); } gifqwc -= mfifoqwc; - gif->qwc -= mfifoqwc; - gif->madr += mfifoqwc*16; - //mfifocycles += (mfifoqwc) * 2; /* guessing */ return 0; } // called from only one location, so forceinline it: -static __forceinline int mfifoGIFchain() { +static __forceinline int mfifoGIFchain() +{ /* Is QWC = 0? if so there is nothing to transfer */ - if (gif->qwc == 0) return 0; if (gif->madr >= psHu32(DMAC_RBOR) && - gif->madr <= (psHu32(DMAC_RBOR)+psHu32(DMAC_RBSR))) + gif->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR))) { if (mfifoGIFrbTransfer() == -1) return -1; } else { - int mfifoqwc = (psHu32(GIF_MODE) & 0x4 && vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : gif->qwc; + int mfifoqwc = gif->qwc; u32 *pMem = (u32*)dmaGetAddr(gif->madr); if (pMem == NULL) return -1; - WRITERING_DMA(pMem, mfifoqwc); - gif->madr += mfifoqwc*16; - gif->qwc -= mfifoqwc; + mfifoqwc = WRITERING_DMA(pMem, mfifoqwc); mfifocycles += (mfifoqwc) * 2; /* guessing */ } return 0; } -void mfifoGIFtransfer(int qwc) { +void mfifoGIFtransfer(int qwc) +{ u32 *ptag; int id; u32 temp = 0; mfifocycles = 0; - gifmfifoirq = FALSE; + gifmfifoirq = false; - if(qwc > 0 ) { + if(qwc > 0 ) + { gifqwc += qwc; if (gifstate != GIF_STATE_EMPTY) return; gifstate &= ~GIF_STATE_EMPTY; } - SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr); + GIF_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr); - if (gif->qwc == 0) { - if (gif->tadr == spr0->madr) { + if (gif->qwc == 0) + { + if (gif->tadr == spr0->madr) + { //if( gifqwc > 1 ) DevCon::WriteLn("gif mfifo tadr==madr but qwc = %d", params gifqwc); - //hwDmacIrq(14); - + hwDmacIrq(DMAC_14); + gifstate |= GIF_STATE_EMPTY; return; } + gif->tadr = psHu32(DMAC_RBOR) + (gif->tadr & psHu32(DMAC_RBSR)); ptag = (u32*)dmaGetAddr(gif->tadr); @@ -479,11 +485,12 @@ void mfifoGIFtransfer(int qwc) { mfifocycles += 2; gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); - SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x", + GIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x", ptag[1], ptag[0], gif->qwc, id, gif->madr, gif->tadr, gifqwc, spr0->madr); gifqwc--; - switch (id) { + switch (id) + { case 0: // Refe - Transfer Packet According to ADDR field gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); gifstate = GIF_STATE_DONE; //End Transfer @@ -515,7 +522,8 @@ void mfifoGIFtransfer(int qwc) { break; } - if ((gif->chcr & 0x80) && (ptag[0] >> 31)) { + if ((gif->chcr & 0x80) && (ptag[0] >> 31)) + { SPR_LOG("dmaIrq Set"); gifstate = GIF_STATE_DONE; gifmfifoirq = TRUE; @@ -523,16 +531,15 @@ void mfifoGIFtransfer(int qwc) { } FreezeRegs(1); - - if (mfifoGIFchain() == -1) { - Console::WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", params - gif->qwc, gif->madr, gif->tadr); - gifstate = GIF_STATE_STALL; - } - + if (mfifoGIFchain() == -1) + { + Console::WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", params + gif->qwc, gif->madr, gif->tadr); + gifstate = GIF_STATE_STALL; + } FreezeRegs(0); - if(gif->qwc == 0 && gifstate == GIF_STATE_DONE) gifstate = GIF_STATE_STALL; + if ((gif->qwc == 0) && (gifstate == GIF_STATE_DONE)) gifstate = GIF_STATE_STALL; CPU_INT(11,mfifocycles); SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr); @@ -540,43 +547,65 @@ void mfifoGIFtransfer(int qwc) { void gifMFIFOInterrupt() { - if (!(gif->chcr & 0x100)) { - Console::WriteLn("WTF GIFMFIFO"); - cpuRegs.interrupt &= ~(1 << 11); - return ; - } - if((spr0->chcr & 0x100) && spr0->qwc == 0) + mfifocycles = 0; + if (Path3progress == STOPPED_MODE) psHu32(GIF_STAT)&= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0 + + if ((spr0->chcr & 0x100) && (spr0->qwc == 0)) { spr0->chcr &= ~0x100; - hwDmacIrq(8); + hwDmacIrq(DMAC_FROM_SPR); } + + if (!(gif->chcr & 0x100)) + { + Console::WriteLn("WTF GIFMFIFO"); + cpuRegs.interrupt &= ~(1 << 11); + return; + } + + if (((psHu32(GIF_STAT) & 0x100) || (vif1.cmd & 0x7f) == 0x50) && (psHu32(GIF_MODE) & 0x4) && Path3progress == IMAGE_MODE) //Path2 gets priority in intermittent mode + { + //GIF_LOG("Waiting VU %x, PATH2 %x, GIFMODE %x Progress %x", psHu32(GIF_STAT) & 0x100, (vif1.cmd & 0x7f), psHu32(GIF_MODE), Path3progress); + CPU_INT(11,mfifocycles); + return; + } - if(gifstate != GIF_STATE_STALL) { - if(gifqwc <= 0) { + if (gifstate != GIF_STATE_STALL) + { + if (gifqwc <= 0) + { //Console::WriteLn("Empty"); gifstate |= GIF_STATE_EMPTY; psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 - hwDmacIrq(14); + hwDmacIrq(DMAC_14); return; } mfifoGIFtransfer(0); return; } + #ifdef PCSX2_DEVBUILD - if(gifstate == GIF_STATE_READY || gif->qwc > 0) { + if (gifstate == GIF_STATE_READY || gif->qwc > 0) + { Console::Error("gifMFIFO Panic > Shouldn't go here!"); return; } #endif //if(gifqwc > 0) Console::WriteLn("GIF MFIFO ending with stuff in it %x", params gifqwc); if (!gifmfifoirq) gifqwc = 0; - gifstate = GIF_STATE_READY; - gif->chcr &= ~0x100; - hwDmacIrq(DMAC_GIF); - GSCSRr &= ~0xC000; //Clear FIFO stuff - GSCSRr |= 0x4000; //FIFO empty - psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 + + gspath3done = 0; + gscycles = 0; + + psHu32(GIF_STAT) &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0 + psHu32(GIF_STAT) &= ~GIF_STAT_P3Q; psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0 + + vif1Regs->stat &= ~VIF1_STAT_VGW; + gif->chcr &= ~0x100; + gifstate = GIF_STATE_READY; + hwDmacIrq(DMAC_GIF); + clearFIFOstuff(false); } void SaveState::gifFreeze() diff --git a/pcsx2/HostGui.h b/pcsx2/HostGui.h index 6f44b2a655..684a26dc7c 100644 --- a/pcsx2/HostGui.h +++ b/pcsx2/HostGui.h @@ -25,7 +25,8 @@ enum StartupMode { BootMode_Bios, BootMode_Quick, - BootMode_Elf + BootMode_Elf, + BootMode_Normal }; class StartupParams diff --git a/pcsx2/Hw.cpp b/pcsx2/Hw.cpp index 3ff49efc15..7d3f740e8e 100644 --- a/pcsx2/Hw.cpp +++ b/pcsx2/Hw.cpp @@ -90,7 +90,7 @@ __forceinline void intcInterrupt() cpuException(0x400, cpuRegs.branch); } -__forceinline void dmacInterrupt() +__forceinline void dmacInterrupt() { if ((cpuRegs.CP0.n.Status.val & 0x10807) != 0x10801) return; @@ -116,7 +116,7 @@ void hwDmacIrq(int n) { } /* Write 'size' bytes to memory address 'addr' from 'data'. */ -int hwMFIFOWrite(u32 addr, u8 *data, u32 size) { +bool hwMFIFOWrite(u32 addr, u8 *data, u32 size) { u32 msize = psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16; u8 *dst; @@ -129,22 +129,22 @@ int hwMFIFOWrite(u32 addr, u8 *data, u32 size) { /* it does, so first copy 's1' bytes from 'data' to 'addr' */ dst = (u8*)PSM(addr); - if (dst == NULL) return -1; + if (dst == NULL) return false; memcpy_fast(dst, data, s1); /* and second copy 's2' bytes from '&data[s1]' to 'maddr' */ dst = (u8*)PSM(psHu32(DMAC_RBOR)); - if (dst == NULL) return -1; + if (dst == NULL) return false; memcpy_fast(dst, &data[s1], s2); } else { /* it doesn't, so just copy 'size' bytes from 'data' to 'addr' */ dst = (u8*)PSM(addr); - if (dst == NULL) return -1; + if (dst == NULL) return false; memcpy_fast(dst, data, size); } - return 0; + return true; } @@ -206,7 +206,7 @@ bool hwDmacSrcChainWithStack(DMACh *dma, int id) { dma->asr0 = 0; //Clear ASR0 } else { //Else if ASR1 and ASR0 are empty //dma->tadr += 16; //Clear tag address - Kills Klonoa 2 - return 1; //End Transfer + return true; //End Transfer } } return false; diff --git a/pcsx2/Hw.h b/pcsx2/Hw.h index 2c7774f39f..8151099b1d 100644 --- a/pcsx2/Hw.h +++ b/pcsx2/Hw.h @@ -99,6 +99,55 @@ enum HWaddress GIF_CNT = 0x10003080, GIF_P3CNT = 0x10003090, GIF_P3TAG = 0x100030A0, + + // Vif Memory Locations + VIF0_STAT = 0x10003800, + VIF0_FBRST = 0x10003810, + VIF0_ERR = 0x10003820, + VIF0_MARK = 0x10003830, + VIF0_CYCLE = 0x10003840, + VIF0_MODE = 0x10003850, + VIF0_NUM = 0x10003860, + VIF0_MASK = 0x10003870, + VIF0_CODE = 0x10003880, + VIF0_ITOPS = 0x10003890, + VIF0_ITOP = 0x100038d0, + VIF0_TOP = 0x100038e0, + VIF0_R0 = 0x10003900, + VIF0_R1 = 0x10003910, + VIF0_R2 = 0x10003920, + VIF0_R3 = 0x10003930, + VIF0_C0 = 0x10003940, + VIF0_C1 = 0x10003950, + VIF0_C2 = 0x10003960, + VIF0_C3 = 0x10003970, + + VIF1_STAT = 0x10003c00, + VIF1_FBRST = 0x10003c10, + VIF1_ERR = 0x10003c20, + VIF1_MARK = 0x10003c30, + VIF1_CYCLE = 0x10003c40, + VIF1_MODE = 0x10003c50, + VIF1_NUM = 0x10003c60, + VIF1_MASK = 0x10003c70, + VIF1_CODE = 0x10003c80, + VIF1_ITOPS = 0x10003c90, + VIF1_BASE = 0x10003ca0, + VIF1_OFST = 0x10003cb0, + VIF1_TOPS = 0x10003cc0, + VIF1_ITOP = 0x10003cd0, + VIF1_TOP = 0x10003ce0, + VIF1_R0 = 0x10003d00, + VIF1_R1 = 0x10003d10, + VIF1_R2 = 0x10003d20, + VIF1_R3 = 0x10003d30, + VIF1_C0 = 0x10003d40, + VIF1_C1 = 0x10003d50, + VIF1_C2 = 0x10003d60, + VIF1_C3 = 0x10003d70, + + VIF0_FIFO = 0x10004000, + VIF1_FIFO = 0x10005000, GIF_FIFO = 0x10006000, IPUout_FIFO = 0x10007000, @@ -150,6 +199,7 @@ enum HWaddress D6_CHCR = 0x1000C400, D6_MADR = 0x1000C410, D6_QWC = 0x1000C420, + D6_TADR = 0x1000C430, //SIF2 D7_CHCR = 0x1000C800, @@ -161,6 +211,7 @@ enum HWaddress D8_MADR = 0x1000D010, D8_QWC = 0x1000D020, D8_SADR = 0x1000D080, + SPR1_CHCR = 0x1000D400, DMAC_CTRL = 0x1000E000, DMAC_STAT = 0x1000E010, @@ -173,10 +224,26 @@ enum HWaddress INTC_STAT = 0x1000F000, INTC_MASK = 0x1000F010, - SBUS_F220 = 0x1000F220, - SBUS_SMFLG = 0x1000F230, + SIO_LCR = 0x1000F100, + SIO_LSR = 0x1000F110, + SIO_IER = 0x1000F120, + SIO_ISR = 0x1000F130,// + SIO_FCR = 0x1000F140, + SIO_BGR = 0x1000F150, + SIO_TXFIFO = 0x1000F180, + SIO_RXFIFO = 0x1000F1C0, + + SBUS_F200 = 0x1000F200, //MSCOM + SBUS_F210 = 0x1000F210, //SMCOM + SBUS_F220 = 0x1000F220, //MSFLG + SBUS_F230 = 0x1000F230, //SMFLG SBUS_F240 = 0x1000F240, + SBUS_F250 = 0x1000F250, + SBUS_F260 = 0x1000F260, + MCH_RICM = 0x1000F430, + MCH_DRD = 0x1000F440, + DMAC_ENABLER = 0x1000F520, DMAC_ENABLEW = 0x1000F590, @@ -239,6 +306,8 @@ enum DMACIrqs DMAC_SIF2, DMAC_FROM_SPR, DMAC_TO_SPR, + DMAC_13 = 13, // Stall? + DMAC_14 = 14, // Transfer? DMAC_ERROR = 15, }; @@ -288,6 +357,23 @@ enum DMACIrqs #define VIF_STAT_ER1 (1<<13) #define VIF_STAT_FDR (1<<23) +//GIF_STAT + +#define GIF_STAT_M3R (1) //GIF_MODE Mask +#define GIF_STAT_M3P (1<<1) //VIF PATH3 Mask +#define GIF_STAT_IMT (1<<2) //Intermittent Transfer Mode +#define GIF_STAT_PSE (1<<3) //Temporary Transfer Stop +#define GIF_STAT_IP3 (1<<5) //Interrupted PATH3 +#define GIF_STAT_P3Q (1<<6) //PATH3 request Queued +#define GIF_STAT_P2Q (1<<7) //PATH2 request Queued +#define GIF_STAT_P1Q (1<<8) //PATH1 request Queued +#define GIF_STAT_OPH (1<<9) //Output Path (Outputting Data) +#define GIF_STAT_APATH1 (1<<10) //Data Transfer Path 1 (In progress) +#define GIF_STAT_APATH2 (2<<10) //Data Transfer Path 2 (In progress) +#define GIF_STAT_APATH3 (3<<10) //Data Transfer Path 3 (In progress) (Mask too) +#define GIF_STAT_DIR (1<<12) //Transfer Direction +#define GIF_STAT_FQC (31<<24) //QWC in GIF-FIFO + //DMA interrupts & masks enum DMAInter { @@ -350,8 +436,8 @@ static __forceinline void *dmaGetAddr(u32 addr) { // if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); } - // teh sux why the f00k 0xE0000000 - if (addr & 0x80000000) return (void*)&psS[addr & 0x3ff0]; + // Need to check the physical address as well as just the "SPR" flag, as VTLB doesnt seem to handle it + if ((addr & 0x80000000) || (addr & 0x70000000) == 0x70000000) return (void*)&psS[addr & 0x3ff0]; ptr = (u8*)vtlb_GetPhyPtr(addr&0x1FFFFFF0); if (ptr == NULL) { @@ -384,8 +470,8 @@ void hwReset(); void hwShutdown(); // hw read functions -extern u8 hwRead8 (u32 mem); -extern u16 hwRead16(u32 mem); +extern mem8_t hwRead8 (u32 mem); +extern mem16_t hwRead16(u32 mem); extern mem32_t __fastcall hwRead32_page_00(u32 mem); extern mem32_t __fastcall hwRead32_page_01(u32 mem); @@ -409,14 +495,14 @@ extern void __fastcall hwRead128_generic(u32 mem, mem128_t *out); extern void hwWrite8 (u32 mem, u8 value); extern void hwWrite16(u32 mem, u16 value); -extern void __fastcall hwWrite32_page_00( u32 mem, u32 value ); -extern void __fastcall hwWrite32_page_01( u32 mem, u32 value ); -extern void __fastcall hwWrite32_page_02( u32 mem, u32 value ); -extern void __fastcall hwWrite32_page_03( u32 mem, u32 value ); -extern void __fastcall hwWrite32_page_0B( u32 mem, u32 value ); -extern void __fastcall hwWrite32_page_0E( u32 mem, u32 value ); -extern void __fastcall hwWrite32_page_0F( u32 mem, u32 value ); -extern void __fastcall hwWrite32_generic( u32 mem, u32 value ); +extern void __fastcall hwWrite32_page_00( u32 mem, mem32_t value ); +extern void __fastcall hwWrite32_page_01( u32 mem, mem32_t value ); +extern void __fastcall hwWrite32_page_02( u32 mem, mem32_t value ); +extern void __fastcall hwWrite32_page_03( u32 mem, mem32_t value ); +extern void __fastcall hwWrite32_page_0B( u32 mem, mem32_t value ); +extern void __fastcall hwWrite32_page_0E( u32 mem, mem32_t value ); +extern void __fastcall hwWrite32_page_0F( u32 mem, mem32_t value ); +extern void __fastcall hwWrite32_generic( u32 mem, mem32_t value ); extern void __fastcall hwWrite64_page_02( u32 mem, const mem64_t* srcval ); extern void __fastcall hwWrite64_page_03( u32 mem, const mem64_t* srcval ); @@ -435,8 +521,8 @@ extern void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval); void hwIntcIrq(int n); void hwDmacIrq(int n); -int hwMFIFORead(u32 addr, u8 *data, u32 size); -int hwMFIFOWrite(u32 addr, u8 *data, u32 size); +//bool hwMFIFORead(u32 addr, u8 *data, u32 size); +bool hwMFIFOWrite(u32 addr, u8 *data, u32 size); bool hwDmacSrcChainWithStack(DMACh *dma, int id); bool hwDmacSrcChain(DMACh *dma, int id); diff --git a/pcsx2/HwRead.cpp b/pcsx2/HwRead.cpp index 2104c8acb8..d84b9a7da2 100644 --- a/pcsx2/HwRead.cpp +++ b/pcsx2/HwRead.cpp @@ -52,57 +52,65 @@ static __forceinline void IntCHackCheck() ///////////////////////////////////////////////////////////////////////// // Hardware READ 8 bit -__forceinline u8 hwRead8(u32 mem) +__forceinline mem8_t hwRead8(u32 mem) { u8 ret; - if( mem >= 0x10002000 && mem < 0x10008000 ) + if( mem >= IPU_CMD && mem < D0_CHCR ) DevCon::Notice("Unexpected hwRead8 from 0x%x", params mem); switch (mem) { - // Note: the values without defines = the defines + 1. case RCNT0_COUNT: ret = (u8)rcntRcount(0); break; case RCNT0_MODE: ret = (u8)counters[0].modeval; break; case RCNT0_TARGET: ret = (u8)counters[0].target; break; case RCNT0_HOLD: ret = (u8)counters[0].hold; break; - case 0x10000001: ret = (u8)(rcntRcount(0)>>8); break; - case 0x10000011: ret = (u8)(counters[0].modeval>>8); break; - case 0x10000021: ret = (u8)(counters[0].target>>8); break; - case 0x10000031: ret = (u8)(counters[0].hold>>8); break; + case RCNT0_COUNT + 1: ret = (u8)(rcntRcount(0)>>8); break; + case RCNT0_MODE + 1: ret = (u8)(counters[0].modeval>>8); break; + case RCNT0_TARGET + 1: ret = (u8)(counters[0].target>>8); break; + case RCNT0_HOLD + 1: ret = (u8)(counters[0].hold>>8); break; case RCNT1_COUNT: ret = (u8)rcntRcount(1); break; case RCNT1_MODE: ret = (u8)counters[1].modeval; break; case RCNT1_TARGET: ret = (u8)counters[1].target; break; case RCNT1_HOLD: ret = (u8)counters[1].hold; break; - case 0x10000801: ret = (u8)(rcntRcount(1)>>8); break; - case 0x10000811: ret = (u8)(counters[1].modeval>>8); break; - case 0x10000821: ret = (u8)(counters[1].target>>8); break; - case 0x10000831: ret = (u8)(counters[1].hold>>8); break; + case RCNT1_COUNT + 1: ret = (u8)(rcntRcount(1)>>8); break; + case RCNT1_MODE + 1: ret = (u8)(counters[1].modeval>>8); break; + case RCNT1_TARGET + 1: ret = (u8)(counters[1].target>>8); break; + case RCNT1_HOLD + 1: ret = (u8)(counters[1].hold>>8); break; case RCNT2_COUNT: ret = (u8)rcntRcount(2); break; case RCNT2_MODE: ret = (u8)counters[2].modeval; break; case RCNT2_TARGET: ret = (u8)counters[2].target; break; - case 0x10001001: ret = (u8)(rcntRcount(2)>>8); break; - case 0x10001011: ret = (u8)(counters[2].modeval>>8); break; - case 0x10001021: ret = (u8)(counters[2].target>>8); break; + case RCNT2_COUNT + 1: ret = (u8)(rcntRcount(2)>>8); break; + case RCNT2_MODE + 1: ret = (u8)(counters[2].modeval>>8); break; + case RCNT2_TARGET + 1: ret = (u8)(counters[2].target>>8); break; case RCNT3_COUNT: ret = (u8)rcntRcount(3); break; case RCNT3_MODE: ret = (u8)counters[3].modeval; break; case RCNT3_TARGET: ret = (u8)counters[3].target; break; - case 0x10001801: ret = (u8)(rcntRcount(3)>>8); break; - case 0x10001811: ret = (u8)(counters[3].modeval>>8); break; - case 0x10001821: ret = (u8)(counters[3].target>>8); break; + case RCNT3_COUNT + 1: ret = (u8)(rcntRcount(3)>>8); break; + case RCNT3_MODE + 1: ret = (u8)(counters[3].modeval>>8); break; + case RCNT3_TARGET + 1: ret = (u8)(counters[3].target>>8); break; default: - if ((mem & 0xffffff0f) == 0x1000f200) + if ((mem & 0xffffff0f) == SBUS_F200) { - if(mem == 0x1000f260) ret = 0; - else if(mem == SBUS_F240) { - ret = psHu32(mem); - //psHu32(mem) &= ~0x4000; + switch (mem) + { + case SBUS_F240: + ret = psHu32(mem); + //psHu32(mem) &= ~0x4000; + break; + + case SBUS_F260: + ret = 0; + break; + + default: + ret = psHu32(mem); + break; } - else ret = psHu32(mem); return (u8)ret; } @@ -117,7 +125,7 @@ __forceinline u8 hwRead8(u32 mem) ///////////////////////////////////////////////////////////////////////// // Hardware READ 16 bit -__forceinline u16 hwRead16(u32 mem) +__forceinline mem16_t hwRead16(u32 mem) { u16 ret; @@ -145,15 +153,23 @@ __forceinline u16 hwRead16(u32 mem) case RCNT3_TARGET: ret = (u16)counters[3].target; break; default: - if ((mem & 0xffffff0f) == 0x1000f200) + if ((mem & 0xffffff0f) == SBUS_F200) { - if(mem == 0x1000f260) ret = 0; - else if(mem == SBUS_F240) { - ret = psHu16(mem) | 0x0102; - psHu32(mem) &= ~0x4000; + switch (mem) + { + case SBUS_F240: + ret = psHu16(mem) | 0x0102; + psHu32(mem) &= ~0x4000; // not commented out like in bit mode? + break; + + case SBUS_F260: + ret = 0; + break; + + default: + ret = psHu32(mem); + break; } - else - ret = psHu32(mem); return (u16)ret; } ret = psHu16(mem); @@ -208,7 +224,7 @@ mem32_t __fastcall hwRead32_page_01(u32 mem) // This is used internally to produce two inline versions, one with INTC_HACK, and one without. static __forceinline mem32_t __hwRead32_page_0F( u32 mem, bool intchack ) { - // *Performance Warning* This function is called -A-LOT. Be weary when making changes. It + // *Performance Warning* This function is called -A-LOT. Be wary when making changes. It // could impact FPS significantly. mem &= 0xffff; @@ -231,17 +247,16 @@ static __forceinline mem32_t __hwRead32_page_0F( u32 mem, bool intchack ) HW_LOG("INTC_MASK Read32, value=0x%x", psHu32(INTC_MASK)); break; - case 0xf130: // 0x1000f130 - case 0xf260: // 0x1000f260 SBUS? + case 0xf130: // SIO_ISR + case 0xf260: // SBUS_F260 case 0xf410: // 0x1000f410 case 0xf430: // MCH_RICM return 0; - case 0xf240: // 0x1000f240: SBUS + case 0xf240: // SBUS_F240 return psHu32(0xf240) | 0xF0000102; - case 0xf440: // 0x1000f440: MCH_DRD - + case 0xf440: // MCH_DRD if( !((psHu32(0xf430) >> 6) & 0xF) ) { switch ((psHu32(0xf430)>>16) & 0xFFF) @@ -362,7 +377,7 @@ void __fastcall hwRead64_page_02(u32 mem, mem64_t* result ) void __fastcall hwRead64_generic_INTC_HACK(u32 mem, mem64_t* result ) { - if( mem == INTC_STAT ) IntCHackCheck(); + if (mem == INTC_STAT) IntCHackCheck(); *result = psHu64(mem); HW_LOG("Unknown Hardware Read 64 at %x",mem); diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index fc978a6f67..17924fdada 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -43,7 +43,8 @@ static __forceinline void DmaExec8( void (*func)(), u32 mem, u8 value ) u32 qwcRegister = (mem | 0x20) & ~0x1; //Need to remove the lower bit else we end up clearing TADR //Its invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC - if((value & 0x1) && (psHu8(mem) & 0x1) == 0x1 && (psHu32(DMAC_CTRL) & 0x1) == 1) { + if ((value & 0x1) && ((psHu8(mem) & 0x1) == 0x1) && ((psHu32(DMAC_CTRL) & 0x1) == 1)) + { DMA_LOG( "DMAExec8 Attempt to run DMA while one is already active mem = %x", mem ); } @@ -69,7 +70,8 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value ) u32 qwcRegister = mem | 0x20; //Its invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC - if((value & 0x100) && (psHu32(mem) & 0x100) == 0x100 && (psHu32(DMAC_CTRL) & 0x1) == 1) { + if ((value & 0x100) && ((psHu32(mem) & 0x100) == 0x100) && ((psHu32(DMAC_CTRL) & 0x1) == 1)) + { DMA_LOG( "DMAExec16 Attempt to run DMA while one is already active mem = %x", mem); } @@ -95,8 +97,13 @@ static void DmaExec( void (*func)(), u32 mem, u32 value ) u32 qwcRegister = mem | 0x20; //Its invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC - if((value & 0x100) && (psHu32(mem) & 0x100) == 0x100 && (psHu32(DMAC_CTRL) & 0x1) == 1) { + if ((value & 0x100) && ((psHu32(mem) & 0x100) == 0x100) && ((psHu32(DMAC_CTRL) & 0x1) == 1)) + { DMA_LOG( "DMAExec32 Attempt to run DMA while one is already active mem = %x", mem ); + + // Returning here breaks every single Gust game written. :( + // Not returning here breaks Fatal Frame. Gamefix time. + if (CHECK_DMAEXECHACK) return; } // Upper 16bits of QWC should not be written since QWC is 16bits in size. @@ -109,8 +116,8 @@ static void DmaExec( void (*func)(), u32 mem, u32 value ) } /* Keep the old tag if in chain mode and hw doesnt set it*/ - if( (value & 0xc) == 0x4 && (value & 0xffff0000) == 0) - psHu32(mem) = (psHu32(mem) & 0xFFFF0000) | (u16)value; + if (((value & 0xc) == 0x4) && ((value & 0xffff0000) == 0)) + psHu32(mem) = (psHu32(mem) & 0xffff0000) | (u16)value; else /* Else (including Normal mode etc) write whatever the hardware sends*/ psHu32(mem) = (u32)value; @@ -126,14 +133,15 @@ char sio_buffer[1024]; int sio_count; u16 QueuedDMA = 0; -void hwWrite8(u32 mem, u8 value) { - - if( (mem>=0x10003800) && (mem<0x10004000) ) +void hwWrite8(u32 mem, u8 value) +{ + if ((mem >= VIF0_STAT) && (mem < VIF0_FIFO)) { u32 bytemod = mem & 0x3; u32 bitpos = 8 * bytemod; u32 newval = psHu8(mem) & (255UL << bitpos); - if( mem < 0x10003c00 ) + + if (mem < VIF1_STAT) vif0Write32( mem & ~0x3, newval | (value<= 0x10002000 && mem < 0x10008000 ) + if( mem >= IPU_CMD && mem < D0_CHCR ) DevCon::Notice( "hwWrite8 to 0x%x = 0x%x", params mem, value ); switch (mem) { case RCNT0_COUNT: rcntWcount(0, value); break; case RCNT0_MODE: rcntWmode(0, (counters[0].modeval & 0xff00) | value); break; - case 0x10000011: rcntWmode(0, (counters[0].modeval & 0xff) | value << 8); break; + case RCNT0_MODE + 1: rcntWmode(0, (counters[0].modeval & 0xff) | value << 8); break; case RCNT0_TARGET: rcntWtarget(0, value); break; case RCNT0_HOLD: rcntWhold(0, value); break; case RCNT1_COUNT: rcntWcount(1, value); break; case RCNT1_MODE: rcntWmode(1, (counters[1].modeval & 0xff00) | value); break; - case 0x10000811: rcntWmode(1, (counters[1].modeval & 0xff) | value << 8); break; + case RCNT1_MODE + 1: rcntWmode(1, (counters[1].modeval & 0xff) | value << 8); break; case RCNT1_TARGET: rcntWtarget(1, value); break; case RCNT1_HOLD: rcntWhold(1, value); break; case RCNT2_COUNT: rcntWcount(2, value); break; case RCNT2_MODE: rcntWmode(2, (counters[2].modeval & 0xff00) | value); break; - case 0x10001011: rcntWmode(2, (counters[2].modeval & 0xff) | value << 8); break; + case RCNT2_MODE + 1: rcntWmode(2, (counters[2].modeval & 0xff) | value << 8); break; case RCNT2_TARGET: rcntWtarget(2, value); break; case RCNT3_COUNT: rcntWcount(3, value); break; case RCNT3_MODE: rcntWmode(3, (counters[3].modeval & 0xff00) | value); break; - case 0x10001811: rcntWmode(3, (counters[3].modeval & 0xff) | value << 8); break; + case RCNT3_MODE + 1: rcntWmode(3, (counters[3].modeval & 0xff) | value << 8); break; case RCNT3_TARGET: rcntWtarget(3, value); break; - case 0x1000f180: + case SIO_TXFIFO: { - bool flush = false; - // Terminate lines on CR or full buffers, and ignore \n's if the string contents // are empty (otherwise terminate on \n too!) - if( ( value == '\r' ) || ( sio_count == 1023 ) || - ( value == '\n' && sio_count != 0 ) ) + if (( value == '\r' ) || ( sio_count == 1023 ) || + ( value == '\n' && sio_count != 0 )) { sio_buffer[sio_count] = 0; Console::WriteLn( Color_Cyan, sio_buffer ); @@ -190,7 +196,7 @@ void hwWrite8(u32 mem, u8 value) { //case 0x10003c02: //Tony Hawks Project 8 uses this // vif1Write32(mem & ~0x2, value << 16); // break; - case 0x10008001: // dma0 - vif0 + case D0_CHCR + 1: // dma0 - vif0 DMA_LOG("VIF0dma EXECUTE, value=0x%x", value); if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1)) { @@ -200,7 +206,7 @@ void hwWrite8(u32 mem, u8 value) { DmaExec8(dmaVIF0, mem, value); break; - case 0x10009001: // dma1 - vif1 + case D1_CHCR + 1: // dma1 - vif1 DMA_LOG("VIF1dma EXECUTE, value=0x%x", value); if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1)) { @@ -211,7 +217,7 @@ void hwWrite8(u32 mem, u8 value) { DmaExec8(dmaVIF1, mem, value); break; - case 0x1000a001: // dma2 - gif + case D2_CHCR + 1: // dma2 - gif DMA_LOG("GSdma EXECUTE, value=0x%x", value); if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1)) { @@ -221,7 +227,7 @@ void hwWrite8(u32 mem, u8 value) { DmaExec8(dmaGIF, mem, value); break; - case 0x1000b001: // dma3 - fromIPU + case D3_CHCR + 1: // dma3 - fromIPU DMA_LOG("IPU0dma EXECUTE, value=0x%x", value); if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1)) { @@ -231,7 +237,7 @@ void hwWrite8(u32 mem, u8 value) { DmaExec8(dmaIPU0, mem, value); break; - case 0x1000b401: // dma4 - toIPU + case D4_CHCR + 1: // dma4 - toIPU DMA_LOG("IPU1dma EXECUTE, value=0x%x", value); if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1)) { @@ -241,7 +247,7 @@ void hwWrite8(u32 mem, u8 value) { DmaExec8(dmaIPU1, mem, value); break; - case 0x1000c001: // dma5 - sif0 + case D5_CHCR + 1: // dma5 - sif0 DMA_LOG("SIF0dma EXECUTE, value=0x%x", value); // if (value == 0) psxSu32(0x30) = 0x40000; if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1)) @@ -252,7 +258,7 @@ void hwWrite8(u32 mem, u8 value) { DmaExec8(dmaSIF0, mem, value); break; - case 0x1000c401: // dma6 - sif1 + case D6_CHCR + 1: // dma6 - sif1 DMA_LOG("SIF1dma EXECUTE, value=0x%x", value); if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1)) { @@ -262,7 +268,7 @@ void hwWrite8(u32 mem, u8 value) { DmaExec8(dmaSIF1, mem, value); break; - case 0x1000c801: // dma7 - sif2 + case D7_CHCR + 1: // dma7 - sif2 DMA_LOG("SIF2dma EXECUTE, value=0x%x", value); if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1)) { @@ -272,7 +278,7 @@ void hwWrite8(u32 mem, u8 value) { DmaExec8(dmaSIF2, mem, value); break; - case 0x1000d001: // dma8 - fromSPR + case D8_CHCR + 1: // dma8 - fromSPR DMA_LOG("fromSPRdma8 EXECUTE, value=0x%x", value); if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1)) { @@ -282,7 +288,7 @@ void hwWrite8(u32 mem, u8 value) { DmaExec8(dmaSPR0, mem, value); break; - case 0x1000d401: // dma9 - toSPR + case SPR1_CHCR + 1: // dma9 - toSPR DMA_LOG("toSPRdma8 EXECUTE, value=0x%x", value); if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1)) { @@ -292,28 +298,48 @@ void hwWrite8(u32 mem, u8 value) { DmaExec8(dmaSPR1, mem, value); break; - case 0x1000f592: // DMAC_ENABLEW + case DMAC_ENABLEW + 2: psHu8(0xf592) = value; psHu8(0xf522) = value; break; - case 0x1000f200: // SIF(?) + case SBUS_F200: // SIF(?) psHu8(mem) = value; break; - case 0x1000f240:// SIF(?) - if(!(value & 0x100)) - psHu32(mem) &= ~0x100; + case SBUS_F210: + psHu8(mem) = value; + break; + + case SBUS_F220: + psHu8(mem) = value; + break; + + case SBUS_F230: + psHu8(mem) = value; + break; + + case SBUS_F240: + if (!(value & 0x100)) psHu32(mem) &= ~0x100; + break; + + case SBUS_F250: + psHu8(mem) = value; + break; + + case SBUS_F260: + psHu8(mem) = value; break; default: assert( (mem&0xff0f) != 0xf200 ); switch(mem&~3) { - case 0x1000f130: + case SIO_ISR: case 0x1000f410: - case 0x1000f430: + case MCH_RICM: break; + default: psHu8(mem) = value; } @@ -324,7 +350,7 @@ void hwWrite8(u32 mem, u8 value) { __forceinline void hwWrite16(u32 mem, u16 value) { - if( mem >= 0x10002000 && mem < 0x10008000 ) + if( mem >= IPU_CMD && mem < D0_CHCR ) Console::Notice( "hwWrite16 to %x", params mem ); switch(mem) @@ -373,22 +399,27 @@ __forceinline void hwWrite16(u32 mem, u16 value) HW_LOG("VIF1dma Madr %lx", value); psHu16(mem) = value;//dma1 madr break; + case D1_QWC: // dma1 - vif1 - qwc HW_LOG("VIF1dma QWC %lx", value); psHu16(mem) = value;//dma1 qwc break; + case D1_TADR: // dma1 - vif1 - tadr HW_LOG("VIF1dma TADR %lx", value); psHu16(mem) = value;//dma1 tadr break; + case D1_ASR0: // dma1 - vif1 - asr0 HW_LOG("VIF1dma ASR0 %lx", value); psHu16(mem) = value;//dma1 asr0 break; + case D1_ASR1: // dma1 - vif1 - asr1 HW_LOG("VIF1dma ASR1 %lx", value); psHu16(mem) = value;//dma1 asr1 break; + case D1_SADR: // dma1 - vif1 - sadr HW_LOG("VIF1dma SADR %lx", value); psHu16(mem) = value;//dma1 sadr @@ -411,22 +442,27 @@ __forceinline void hwWrite16(u32 mem, u16 value) psHu16(mem) = value;//dma2 madr HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x",mem,value); break; + case D2_QWC: psHu16(mem) = value;//dma2 qwc HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x",mem,value); break; + case D2_TADR: psHu16(mem) = value;//dma2 taddr HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x",mem,value); break; + case D2_ASR0: psHu16(mem) = value;//dma2 asr0 HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x",mem,value); break; + case D2_ASR1: psHu16(mem) = value;//dma2 asr1 HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x",mem,value); break; + case D2_SADR: psHu16(mem) = value;//dma2 saddr HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x",mem,value); @@ -448,14 +484,17 @@ __forceinline void hwWrite16(u32 mem, u16 value) psHu16(mem) = value;//dma2 madr HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x",mem,value); break; + case D3_QWC: psHu16(mem) = value;//dma2 madr HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x",mem,value); - break; + break; + case D3_TADR: psHu16(mem) = value;//dma2 tadr HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x",mem,value); break; + case D3_SADR: psHu16(mem) = value;//dma2 saddr HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x",mem,value); @@ -477,14 +516,17 @@ __forceinline void hwWrite16(u32 mem, u16 value) psHu16(mem) = value;//dma2 madr HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x",mem,value); break; + case D4_QWC: psHu16(mem) = value;//dma2 madr HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x",mem,value); break; + case D4_TADR: psHu16(mem) = value;//dma2 tadr HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x",mem,value); break; + case D4_SADR: psHu16(mem) = value;//dma2 saddr HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x",mem,value); @@ -501,9 +543,10 @@ __forceinline void hwWrite16(u32 mem, u16 value) DmaExec16(dmaSIF0, mem, value); break; - case 0x1000c002: + case D5_CHCR + 2: //? break; + case D6_CHCR: // dma6 - sif1 DMA_LOG("SIF1dma %lx", value); if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) @@ -513,15 +556,24 @@ __forceinline void hwWrite16(u32 mem, u16 value) } DmaExec16(dmaSIF1, mem, value); break; - + + // Given the other values here, perhaps something like this is in order? + /*case 0x1000C402: // D6_CHCR + 2 + //? + break;*/ + #ifdef PCSX2_DEVBUILD - // No D6_MADR, and a TADR address that's not in the defines? + case D6_MADR: // dma6 - sif1 - madr + HW_LOG("SIF1dma MADR = %lx", value); + psHu16(mem) = value; + break; + case D6_QWC: // dma6 - sif1 - qwc HW_LOG("SIF1dma QWC = %lx", value); psHu16(mem) = value; break; - case 0x1000c430: // dma6 - sif1 - tadr + case D6_TADR: // dma6 - sif1 - tadr HW_LOG("SIF1dma TADR = %lx", value); psHu16(mem) = value; break; @@ -536,9 +588,11 @@ __forceinline void hwWrite16(u32 mem, u16 value) } DmaExec16(dmaSIF2, mem, value); break; - case 0x1000c802: + + case D7_CHCR + 2: //? break; + case D8_CHCR: // dma8 - fromSPR DMA_LOG("fromSPRdma %lx", value); if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) @@ -549,7 +603,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) DmaExec16(dmaSPR0, mem, value); break; - case 0x1000d400: // dma9 - toSPR + case SPR1_CHCR: // dma9 - toSPR DMA_LOG("toSPRdma %lx", value); if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) { @@ -558,35 +612,48 @@ __forceinline void hwWrite16(u32 mem, u16 value) } DmaExec16(dmaSPR1, mem, value); break; - case 0x1000f592: // DMAC_ENABLEW + + case DMAC_ENABLEW + 2: psHu16(0xf592) = value; psHu16(0xf522) = value; break; - case 0x1000f130: - case 0x1000f132: + + case SIO_ISR: + case SIO_ISR + 2: case 0x1000f410: - case 0x1000f412: - case 0x1000f430: - case 0x1000f432: + case 0x1000f410 + 2: + case MCH_RICM: + case MCH_RICM + 2: break; - case 0x1000f200: + case SBUS_F200: + psHu16(mem) = value; + break; + + case SBUS_F210: psHu16(mem) = value; break; case SBUS_F220: psHu16(mem) |= value; break; - case SBUS_SMFLG: + + case SBUS_F230: psHu16(mem) &= ~value; break; + case SBUS_F240: - if(!(value & 0x100)) + if (!(value & 0x100)) psHu16(mem) &= ~0x100; else psHu16(mem) |= 0x100; break; - case 0x1000f260: + + case SBUS_F250: + psHu16(mem) = value; + break; + + case SBUS_F260: psHu16(mem) = 0; break; @@ -643,9 +710,9 @@ void __fastcall hwWrite32_page_02( u32 mem, u32 value ) // Page 3 contains writes to vif0 and vif1 registers, plus some GIF stuff! void __fastcall hwWrite32_page_03( u32 mem, u32 value ) { - if(mem>=0x10003800) + if (mem >= VIF0_STAT) { - if(mem<0x10003c00) + if(mem < VIF1_STAT) vif0Write32(mem, value); else vif1Write32(mem, value); @@ -656,6 +723,7 @@ void __fastcall hwWrite32_page_03( u32 mem, u32 value ) { case GIF_CTRL: psHu32(mem) = value & 0x8; + if (value & 0x1) gsGIFReset(); else if( value & 8 ) @@ -700,7 +768,7 @@ void __fastcall hwWrite32_page_0B( u32 mem, u32 value ) QueuedDMA |= 0x8; } DmaExec(dmaIPU0, mem, value); - return; + return; case D3_MADR: regName = "IPU0DMA_MADR"; break; case D3_QWC: regName = "IPU0DMA_QWC"; break; @@ -717,7 +785,7 @@ void __fastcall hwWrite32_page_0B( u32 mem, u32 value ) QueuedDMA |= 0x10; } DmaExec(dmaIPU1, mem, value); - return; + return; case D4_MADR: regName = "IPU1DMA_MADR"; break; case D4_QWC: regName = "IPU1DMA_QWC"; break; @@ -745,32 +813,39 @@ void __fastcall StartQueuedDMA() void __fastcall hwWrite32_page_0E( u32 mem, u32 value ) { - if( mem == DMAC_CTRL ) + switch (mem) { - HW_LOG("DMAC_CTRL Write 32bit %x", value); - //Check for DMAS that were started while the DMAC was disabled - if((psHu32(mem) & 0x1) == 0 && (value & 0x1) == 1) + case DMAC_CTRL: { + u32 oldvalue = psHu32(mem); + + HW_LOG("DMAC_CTRL Write 32bit %x", value); + psHu32(mem) = value; - if(QueuedDMA != 0) StartQueuedDMA(); - return; + //Check for DMAS that were started while the DMAC was disabled + if (((oldvalue & 0x1) == 0) && ((value & 0x1) == 1)) + { + if (QueuedDMA != 0) StartQueuedDMA(); + } + break; } + + case DMAC_STAT: + HW_LOG("DMAC_STAT Write 32bit %x", value); + + // lower 16 bits: clear on 1 + // upper 16 bits: reverse on 1 + + psHu16(0xe010) &= ~(value & 0xffff); + psHu16(0xe012) ^= (u16)(value >> 16); + + cpuTestDMACInts(); + break; + + default: + psHu32(mem) = value; + break; } - else if( mem == DMAC_STAT ) - { - HW_LOG("DMAC_STAT Write 32bit %x", value); - - // lower 16 bits: clear on 1 - // upper 16 bits: reverse on 1 - - psHu16(0xe010) &= ~(value & 0xffff); - psHu16(0xe012) ^= (u16)(value >> 16); - - cpuTestDMACInts(); - return; - } - - psHu32(mem) = value; } void __fastcall hwWrite32_page_0F( u32 mem, u32 value ) @@ -795,46 +870,50 @@ void __fastcall hwWrite32_page_0F( u32 mem, u32 value ) break; //------------------------------------------------------------------ - case HELPSWITCH(0x1000f430)://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 + case HELPSWITCH(MCH_RICM)://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 if ((((value >> 16) & 0xFFF) == 0x21) && (((value >> 6) & 0xF) == 1) && (((psHu32(0xf440) >> 7) & 1) == 0))//INIT & SRP=0 rdram_sdevid = 0; // if SIO repeater is cleared, reset sdevid psHu32(mem) = value & ~0x80000000; //kill the busy bit break; - case HELPSWITCH(0x1000f200): + case HELPSWITCH(SBUS_F200): psHu32(mem) = value; break; + case HELPSWITCH(SBUS_F220): psHu32(mem) |= value; break; - case HELPSWITCH(SBUS_SMFLG): + + case HELPSWITCH(SBUS_F230): psHu32(mem) &= ~value; break; + case HELPSWITCH(SBUS_F240): if(!(value & 0x100)) psHu32(mem) &= ~0x100; else psHu32(mem) |= 0x100; break; - case HELPSWITCH(0x1000f260): + + case HELPSWITCH(SBUS_F260): psHu32(mem) = 0; break; - case HELPSWITCH(0x1000f440)://MCH_DRD: + case HELPSWITCH(MCH_DRD)://MCH_DRD: psHu32(mem) = value; break; - case HELPSWITCH(DMAC_ENABLEW): // DMAC_ENABLEW + case HELPSWITCH(DMAC_ENABLEW): HW_LOG("DMAC_ENABLEW Write 32bit %lx", value); psHu32(0xf590) = value; psHu32(0xf520) = value; break; //------------------------------------------------------------------ - case HELPSWITCH(0x1000f130): + case HELPSWITCH(SIO_ISR): case HELPSWITCH(0x1000f410): HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)", mem, value, cpuRegs.CP0.n.Status.val); - break; + break; default: psHu32(mem) = value; @@ -850,26 +929,31 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value ) { case D0_CHCR: // dma0 - vif0 DMA_LOG("VIF0dma EXECUTE, value=0x%x", value); + if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) { DevCon::Notice("32 bit VIF0 DMA Start while DMAC Disabled\n"); QueuedDMA |= 0x1; } + DmaExec(dmaVIF0, mem, value); return; //------------------------------------------------------------------ case D1_CHCR: // dma1 - vif1 - chcr DMA_LOG("VIF1dma EXECUTE, value=0x%x", value); + if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) { DevCon::Notice("32 bit VIF1 DMA Start while DMAC Disabled\n"); QueuedDMA |= 0x2; } - if(value & 0x100) + + if (value & 0x100) { vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO - } + } else cpuRegs.interrupt &= ~(1<<10) | ~(1<<1); //Tekken tag seems to stop vif and start it again in normal, so we will cancel the mfifo loop + DmaExec(dmaVIF1, mem, value); return; @@ -920,9 +1004,9 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value ) DmaExec(dmaSIF1, mem, value); return; - // Again, no MADR, and an undefined TADR. + case D6_MADR: regName = "SIF1dma MADR"; break; case D6_QWC: regName = "SIF1dma QWC"; break; - case 0x1000c430: regName = "SIF1dma TADR"; break; + case D6_TADR: regName = "SIF1dma TADR"; break; //------------------------------------------------------------------ case D7_CHCR: // dma7 - sif2 @@ -945,7 +1029,7 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value ) DmaExec(dmaSPR0, mem, value); return; //------------------------------------------------------------------ - case 0x1000d400: // dma9 - toSPR + case SPR1_CHCR: // dma9 - toSPR DMA_LOG("SPR1dma EXECUTE (toSPR), value=0x%x", value); if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) { @@ -973,9 +1057,9 @@ void __fastcall hwWrite64_page_03( u32 mem, const mem64_t* srcval ) //hwWrite64( mem, *srcval ); return; const u64 value = *srcval; - if(mem>=0x10003800) + if (mem >= VIF0_STAT) { - if(mem<0x10003c00) + if (mem < VIF1_STAT) vif0Write32(mem, value); else vif1Write32(mem, value); @@ -996,24 +1080,23 @@ void __fastcall hwWrite64_page_03( u32 mem, const mem64_t* srcval ) else psHu32(GIF_STAT) &= ~8; } - - return; + break; case GIF_MODE: { -#ifdef GSPATH3FIX - Console::Status("GIFMODE64 %x", params value); -#endif - psHu64(GIF_MODE) = value; - // set/clear bits 0 and 2 as per the GIF_MODE value. const u32 bitmask = 0x1 | 0x4; + + Console::Status("GIFMODE64 %x", params value); + + psHu64(GIF_MODE) = value; psHu32(GIF_STAT) &= ~bitmask; psHu32(GIF_STAT) |= (u32)value & bitmask; + break; } case GIF_STAT: // stat is readonly - return; + break; } } @@ -1023,37 +1106,42 @@ void __fastcall hwWrite64_page_0E( u32 mem, const mem64_t* srcval ) const u64 value = *srcval; - if( mem == DMAC_CTRL ) + switch (mem) { - HW_LOG("DMAC_CTRL Write 64bit %x", value); - if((psHu32(mem) & 0x1) == 0 && (value & 0x1) == 1) + case DMAC_CTRL: { + u32 oldvalue = psHu32(mem); psHu64(mem) = value; - if(QueuedDMA != 0) StartQueuedDMA(); - return; + + HW_LOG("DMAC_CTRL Write 64bit %x", value); + + if (((oldvalue & 0x1) == 0) && ((value & 0x1) == 1)) + { + if (QueuedDMA != 0) StartQueuedDMA(); + } + break; } + + case DMAC_STAT: + HW_LOG("DMAC_STAT Write 64bit %x", value); + + // lower 16 bits: clear on 1 + // upper 16 bits: reverse on 1 + + psHu16(0xe010) &= ~(value & 0xffff); + psHu16(0xe012) ^= (u16)(value >> 16); + + cpuTestDMACInts(); + break; + + default: + psHu64(mem) = value; + break; } - else if( mem == DMAC_STAT ) - { - HW_LOG("DMAC_STAT Write 64bit %x", value); - - // lower 16 bits: clear on 1 - // upper 16 bits: reverse on 1 - - psHu16(0xe010) &= ~(value & 0xffff); - psHu16(0xe012) ^= (u16)(value >> 16); - - cpuTestDMACInts(); - return; - } - - psHu64(mem) = value; } void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval ) { - //hwWrite64( mem, *srcval ); return; - const u64 value = *srcval; switch (mem) @@ -1061,23 +1149,23 @@ void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval ) case D2_CHCR: // dma2 - gif DMA_LOG("0x%8.8x hwWrite64: GSdma %x", cpuRegs.cycle, value); DmaExec(dmaGIF, mem, value); - break; + break; case INTC_STAT: HW_LOG("INTC_STAT Write 64bit %x", (u32)value); psHu32(INTC_STAT) &= ~value; //cpuTestINTCInts(); - break; + break; case INTC_MASK: HW_LOG("INTC_MASK Write 64bit %x", (u32)value); psHu32(INTC_MASK) ^= (u16)value; cpuTestINTCInts(); - break; + break; - case 0x1000f130: + case SIO_ISR: case 0x1000f410: - case 0x1000f430: + case MCH_RICM: break; case DMAC_ENABLEW: // DMAC_ENABLEW @@ -1118,9 +1206,9 @@ void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval) psHu32(0xf520) = srcval[0]; break; - case 0x1000f130: + case SIO_ISR: case 0x1000f410: - case 0x1000f430: + case MCH_RICM: break; default: diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index e8f9fa72a6..4b4cd3845c 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -174,6 +174,27 @@ void ipuShutdown() { } +void ReportIPU() +{ + Console::WriteLn("g_nDMATransfer = 0x%x.", params g_nDMATransfer); + Console::WriteLn("FIreadpos = 0x%x, FIwritepos = 0x%x.", params FIreadpos, FIwritepos); + Console::WriteLn("fifo_input = 0x%x.", params fifo_input); + Console::WriteLn("FOreadpos = 0x%x, FOwritepos = 0x%x.", params FOreadpos, FOwritepos); + Console::WriteLn("fifo_output = 0x%x.", params fifo_output); + Console::WriteLn("g_BP = 0x%x.", params g_BP); + Console::WriteLn("niq = 0x%x, iq = 0x%x.", params niq, iq); + Console::WriteLn("vqclut = 0x%x.", params vqclut); + Console::WriteLn("s_thresh = 0x%x.", params s_thresh); + Console::WriteLn("coded_block_pattern = 0x%x.", params coded_block_pattern); + Console::WriteLn("g_decoder = 0x%x.", params g_decoder); + Console::WriteLn("mpeg2_scan_norm = 0x%x, mpeg2_scan_alt = 0x%x.", params mpeg2_scan_norm, mpeg2_scan_alt); + Console::WriteLn("g_nCmdPos = 0x%x.", params g_nCmdPos); + Console::WriteLn("g_nCmdIndex = 0x%x.", params g_nCmdIndex); + Console::WriteLn("ipuCurCmd = 0x%x.", params ipuCurCmd); + Console::WriteLn("_readbits = 0x%x.", params _readbits); + Console::WriteLn("temp will equal 0x%x.", params readbits - _readbits); + Console::WriteLn(""); +} // fixme - ipuFreeze looks fairly broken. Should probably take a closer look at some point. void SaveState::ipuFreeze() @@ -220,7 +241,7 @@ void SaveState::ipuFreeze() bool ipuCanFreeze() { - return ipuCurCmd == 0xffffffff; + return (ipuCurCmd == 0xffffffff); } __forceinline u32 ipuRead32(u32 mem) @@ -235,7 +256,7 @@ __forceinline u32 ipuRead32(u32 mem) switch (mem) { - case 0x10: // IPU_CTRL + ipucase(IPU_CTRL): // IPU_CTRL ipuRegs->ctrl.IFC = g_BP.IFC; ipuRegs->ctrl.CBP = coded_block_pattern; @@ -244,7 +265,7 @@ __forceinline u32 ipuRead32(u32 mem) return ipuRegs->ctrl._u32; - case 0x20: // IPU_BP + ipucase(IPU_BP): // IPU_BP ipuRegs->ipubp = g_BP.BP & 0x7f; ipuRegs->ipubp |= g_BP.IFC << 8; @@ -269,20 +290,20 @@ __forceinline u64 ipuRead64(u32 mem) switch (mem) { - case 0x00: // IPU_CMD - if (ipuRegs->cmd.DATA&0xffffff) + ipucase(IPU_CMD): // IPU_CMD + if (ipuRegs->cmd.DATA & 0xffffff) IPU_LOG("Ipu read64: IPU_CMD=BUSY=%x, DATA=%08X", ipuRegs->cmd.BUSY ? 1 : 0, ipuRegs->cmd.DATA); break; - case 0x10: + ipucase(IPU_CTRL): DevCon::Notice("reading 64bit IPU ctrl"); break; - case 0x20: + ipucase(IPU_BP): DevCon::Notice("reading 64bit IPU top"); break; - case 0x30: // IPU_TOP + ipucase(IPU_TOP): // IPU_TOP IPU_LOG("Ipu read64: IPU_TOP=%x, bp = %d", ipuRegs->top, g_BP.BP); break; @@ -327,12 +348,12 @@ __forceinline void ipuWrite32(u32 mem, u32 value) switch (mem) { - case 0x00: // IPU_CMD + ipucase(IPU_CMD): // IPU_CMD IPU_LOG("Ipu write32: IPU_CMD=0x%08X", value); IPUCMD_WRITE(value); break; - case 0x10: // IPU_CTRL + ipucase(IPU_CTRL): // IPU_CTRL ipuRegs->ctrl._u32 = (value & 0x47f30000) | (ipuRegs->ctrl._u32 & 0x8000ffff); if (ipuRegs->ctrl.IDP == 3) { @@ -364,7 +385,7 @@ __forceinline void ipuWrite64(u32 mem, u64 value) switch (mem) { - case 0x00: + ipucase(IPU_CMD): IPU_LOG("Ipu write64: IPU_CMD=0x%08X", value); IPUCMD_WRITE((u32)value); break; @@ -446,11 +467,7 @@ static __forceinline BOOL ipuIDEC(u32 val) return s_RoutineDone; } -#ifdef _DEBUG static int s_bdec = 0; -#else -#define s_bdec 0 -#endif static __forceinline BOOL ipuBDEC(u32 val) { @@ -476,9 +493,8 @@ static __forceinline BOOL ipuBDEC(u32 val) IPU_LOG(" Quantizer step=0x%X", bdec.QSC); -#ifdef _DEBUG - s_bdec++; -#endif + if( IsDebugBuild ) + s_bdec++; g_BP.BP += bdec.FB;//skip FB bits g_decoder.coding_type = I_TYPE; @@ -767,7 +783,6 @@ __forceinline void IPU_INTERRUPT() //dma void IPUCMD_WRITE(u32 val) { - // don't process anything if currently busy if (ipuRegs->ctrl.BUSY) Console::WriteLn("IPU BUSY!"); // wait for thread @@ -1352,22 +1367,47 @@ int FIFOto_write(u32* pMem, int size) return firsttrans; } -// To do: convert this into a static inlined function. -#define IPU1chain() { \ - if (ipu1dma->qwc > 0) \ - { \ - int qwc = ipu1dma->qwc; \ - pMem = (u32*)dmaGetAddr(ipu1dma->madr); \ - if (pMem == NULL) { Console::Error("ipu1dma NULL!"); return totalqwc; } \ - qwc = FIFOto_write(pMem, qwc); \ - ipu1dma->madr += qwc<< 4; \ - ipu1dma->qwc -= qwc; \ - totalqwc += qwc; \ - if( ipu1dma->qwc > 0 ) { \ - g_nDMATransfer |= IPU_DMA_ACTV1; \ - return totalqwc; \ - } \ - } \ +static __forceinline bool IPU1chain(u32* &pMem, int &totalqwc) +{ + if (ipu1dma->qwc > 0) + { + int qwc = ipu1dma->qwc; + + pMem = (u32*)dmaGetAddr(ipu1dma->madr); + + if (pMem == NULL) + { + Console::Error("ipu1dma NULL!"); + return true; + } + + qwc = FIFOto_write(pMem, qwc); + ipu1dma->madr += qwc<< 4; + ipu1dma->qwc -= qwc; + totalqwc += qwc; + + if (ipu1dma->qwc > 0) + { + g_nDMATransfer |= IPU_DMA_ACTV1; + return true; + } + } + return false; +} + +static __forceinline bool IncreaseTadr(u32 tag) +{ + switch (tag & 0x70000000) + { + case 0x00000000: + ipu1dma->tadr += 16; + return true; + + case 0x70000000: + ipu1dma->tadr = ipu1dma->madr; + return true; + } + return false; } extern void gsInterrupt(); @@ -1386,7 +1426,7 @@ int IPU1dma() assert(!(g_nDMATransfer & IPU_DMA_TIE1)); //We need to make sure GIF has flushed before sending IPU data, it seems to REALLY screw FFX videos - while(gif->chcr & 0x100) + while(gif->chcr & 0x100 && vif1Regs->mskpath3 == 0) { GIF_LOG("Flushing gif chcr %x tadr %x madr %x qwc %x", gif->chcr, gif->tadr, gif->madr, gif->qwc); gsInterrupt(); @@ -1395,91 +1435,76 @@ int IPU1dma() // in kh, qwc == 0 when dma_actv1 is set if ((g_nDMATransfer & IPU_DMA_ACTV1) && ipu1dma->qwc > 0) { - IPU1chain(); + if (IPU1chain(pMem, totalqwc)) return totalqwc; //Check TIE bit of CHCR and IRQ bit of tag - if ((ipu1dma->chcr & 0x80) && (g_nDMATransfer&IPU_DMA_DOTIE1)) + if ((ipu1dma->chcr & 0x80) && (g_nDMATransfer & IPU_DMA_DOTIE1)) { Console::WriteLn("IPU1 TIE"); - IPU_INT_TO(totalqwc*BIAS); + IPU_INT_TO(totalqwc * BIAS); g_nDMATransfer &= ~(IPU_DMA_ACTV1 | IPU_DMA_DOTIE1); g_nDMATransfer |= IPU_DMA_TIE1; return totalqwc; } - if ((ipu1dma->chcr&0xc) == 0) + if (!(ipu1dma->chcr & 0xc)) { - IPU_INT_TO(totalqwc*BIAS); + IPU_INT_TO(totalqwc * BIAS); return totalqwc; } else { u32 tag = ipu1dma->chcr; // upper bits describe current tag - if ((ipu1dma->chcr & 0x80) && (tag&0x80000000)) + if ((ipu1dma->chcr & 0x80) && (tag & 0x80000000)) { ptag = (u32*)dmaGetAddr(ipu1dma->tadr); - switch (tag&0x70000000) - { - case 0x00000000: - ipu1dma->tadr += 16; - break; - case 0x70000000: - ipu1dma->tadr = ipu1dma->madr; - break; - } + IncreaseTadr(tag); ipu1dma->chcr = (ipu1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); IPU_LOG("IPU dmaIrq Set"); - IPU_INT_TO(totalqwc*BIAS); + IPU_INT_TO(totalqwc * BIAS); g_nDMATransfer |= IPU_DMA_TIE1; return totalqwc; } - switch (tag&0x70000000) + if (IncreaseTadr(tag)) { - case 0x00000000: - ipu1dma->tadr += 16; - IPU_INT_TO((1 + totalqwc)*BIAS); - return totalqwc; - - case 0x70000000: - ipu1dma->tadr = ipu1dma->madr; - IPU_INT_TO((1 + totalqwc)*BIAS); - return totalqwc; + IPU_INT_TO((1 + totalqwc)*BIAS); + return totalqwc; } } g_nDMATransfer &= ~(IPU_DMA_ACTV1 | IPU_DMA_DOTIE1); } - - if ((ipu1dma->chcr & 0xc) == 0 && ipu1dma->qwc == 0) // Normal Mode + + if (((ipu1dma->chcr & 0xc) == 0) && (ipu1dma->qwc == 0)) // Normal Mode { //Console::WriteLn("ipu1 normal empty qwc?"); return totalqwc; } // Transfer Dn_QWC from Dn_MADR to GIF - - if ((ipu1dma->chcr & 0xc) == 0 || ipu1dma->qwc > 0) // Normal Mode + if (ipu1dma->qwc > 0) { IPU_LOG("dmaIPU1 Normal size=%d, addr=%lx, fifosize=%x", ipu1dma->qwc, ipu1dma->madr, 8 - g_BP.IFC); - IPU1chain(); - IPU_INT_TO((ipu1cycles + totalqwc)*BIAS); + + if (!IPU1chain(pMem, totalqwc)) IPU_INT_TO((ipu1cycles + totalqwc) * BIAS); + return totalqwc; } else { - // Chain Mode + // Chain Mode & ipu1dma->qwc is 0 ptag = (u32*)dmaGetAddr(ipu1dma->tadr); //Set memory pointer to TADR if (ptag == NULL) //Is ptag empty? { Console::Error("IPU1 BUSERR"); ipu1dma->chcr = (ipu1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15 - psHu32(DMAC_STAT) |= 1 << 15; //If yes, set BEIS (BUSERR) in DMAC_STAT register + psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register return totalqwc; } @@ -1530,54 +1555,45 @@ int IPU1dma() g_nDMATransfer |= IPU_DMA_DOTIE1; else g_nDMATransfer &= ~IPU_DMA_DOTIE1; - - //Britney Dance beat does a blank NEXT tag, for some odd reason the fix doesnt work if after IPU1Chain O_o - if ((ipu1dma->qwc == 0) && (!done) && !(g_nDMATransfer & IPU_DMA_DOTIE1)) IPU1dma(); - - IPU1chain(); - - if ((ipu1dma->chcr & 0x80) && (ptag[0]&0x80000000) && ipu1dma->qwc == 0) //Check TIE bit of CHCR and IRQ bit of tag - { - Console::WriteLn("IPU1 TIE"); - - if (done) - { - ptag = (u32*)dmaGetAddr(ipu1dma->tadr); - - switch (ptag[0]&0x70000000) - { - case 0x00000000: - ipu1dma->tadr += 16; - break; - case 0x70000000: - ipu1dma->tadr = ipu1dma->madr; - break; - } - - ipu1dma->chcr = (ipu1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); - } - - IPU_INT_TO(ipu1cycles + totalqwc*BIAS); - g_nDMATransfer |= IPU_DMA_TIE1; - return totalqwc; - } - + if (ipu1dma->qwc == 0) { - switch (ptag[0]&0x70000000) + //if ((ipu1dma->chcr & 0x80) && (ptag[0] & 0x80000000)) //Check TIE bit of CHCR and IRQ bit of tag + if (g_nDMATransfer & IPU_DMA_DOTIE1) { - case 0x00000000: - ipu1dma->tadr += 16; - break; + Console::WriteLn("IPU1 TIE"); + + if (IPU1chain(pMem, totalqwc)) return totalqwc; + + if (done) + { + ptag = (u32*)dmaGetAddr(ipu1dma->tadr); - case 0x70000000: - ipu1dma->tadr = ipu1dma->madr; - break; + IncreaseTadr(ptag[0]); + + ipu1dma->chcr = (ipu1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); + } + + IPU_INT_TO(ipu1cycles + totalqwc * BIAS); // Should it be (ipu1cycles + totalqwc) * BIAS? + g_nDMATransfer |= IPU_DMA_TIE1; + return totalqwc; } + else + { + //Britney Dance beat does a blank NEXT tag, for some odd reason the fix doesnt work if after IPU1Chain O_o + if (!done) IPU1dma(); + if (IPU1chain(pMem, totalqwc)) return totalqwc; + } + + IncreaseTadr(ptag[0]); + } + else + { + if (IPU1chain(pMem, totalqwc)) return totalqwc; } } - IPU_INT_TO((ipu1cycles + totalqwc)*BIAS); + IPU_INT_TO((ipu1cycles + totalqwc) * BIAS); return totalqwc; } diff --git a/pcsx2/IPU/IPU.h b/pcsx2/IPU/IPU.h index b644887550..c148bac652 100644 --- a/pcsx2/IPU/IPU.h +++ b/pcsx2/IPU/IPU.h @@ -41,6 +41,10 @@ #pragma pack(1) #endif + +#define ipumsk( src ) ( (src) & 0xff ) +#define ipucase( src ) case ipumsk(src) + // // Bitfield Structure // diff --git a/pcsx2/IPU/Makefile.am b/pcsx2/IPU/Makefile.am deleted file mode 100644 index 29f0e46eaa..0000000000 --- a/pcsx2/IPU/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -INCLUDES = -I@srcdir@/../ -I@srcdir@/../x86 -I@srcdir@/../../common/include -I@srcdir@/../../3rdparty $(shell wx-config --cppflags) -noinst_LIBRARIES = libIPU.a - -libIPU_a_SOURCES = IPU.cpp yuv2rgb.cpp coroutine.cpp \ -IPU.h yuv2rgb.h coroutine.h \ -acoroutine.S - -SUBDIRS = mpeg2lib - -#libIPU_a_LIBADD = mpeg2lib/libmpeg2IPU.a \ No newline at end of file diff --git a/pcsx2/IPU/coroutine.cpp b/pcsx2/IPU/coroutine.cpp index ac89043d8d..3ccfc84e1b 100644 --- a/pcsx2/IPU/coroutine.cpp +++ b/pcsx2/IPU/coroutine.cpp @@ -26,8 +26,8 @@ struct coroutine { uptr storeebx, storeesi, storeedi, storeebp; - int restore; // if nonzero, restore the registers - int alloc; + s32 restore; // if nonzero, restore the registers + s32 alloc; //struct s_coroutine *caller; //struct s_coroutine *restarget; @@ -45,7 +45,7 @@ coroutine_t so_create(void (*func)(void *), void *data, void *stack, int size) int alloc = 0; // r = CO_STK_COROSIZE; coroutine *co; - if ((size &= ~(sizeof(long) - 1)) < CO_MIN_SIZE) return NULL; + if ((size &= ~(sizeof(s32) - 1)) < CO_MIN_SIZE) return NULL; if (!stack) { size = (size + sizeof(coroutine) + CO_STK_ALIGN - 1) & ~(CO_STK_ALIGN - 1); stack = malloc(size); diff --git a/pcsx2/IPU/mpeg2lib/Makefile.am b/pcsx2/IPU/mpeg2lib/Makefile.am deleted file mode 100644 index 005b1b84c5..0000000000 --- a/pcsx2/IPU/mpeg2lib/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -INCLUDES = -I@srcdir@/../ -I@srcdir@/../../ -I@srcdir@/../../../common/include -I@srcdir@/../../../3rdparty $(shell wx-config --cppflags) -noinst_LIBRARIES = libmpeg2IPU.a - -libmpeg2IPU_a_SOURCES = Idct.cpp Mpeg.cpp Mpeg.h Vlc.h \ No newline at end of file diff --git a/pcsx2/IPU/mpeg2lib/Mpeg.cpp b/pcsx2/IPU/mpeg2lib/Mpeg.cpp index 68a8c9e666..347aa61c7f 100644 --- a/pcsx2/IPU/mpeg2lib/Mpeg.cpp +++ b/pcsx2/IPU/mpeg2lib/Mpeg.cpp @@ -900,7 +900,7 @@ static void __fastcall slice_non_intra_DCT (decoder_t * const decoder, } #if defined(_MSC_VER) -#pragma pack(push, 1) +#pragma pack(1) #endif struct TGA_HEADER { @@ -922,7 +922,7 @@ struct TGA_HEADER // pixel data follows header #if defined(_MSC_VER) }; -#pragma pack(pop) +#pragma pack() #else } __attribute__((packed)); #endif diff --git a/pcsx2/IopCommon.h b/pcsx2/IopCommon.h index 18b2161e32..c153504a55 100644 --- a/pcsx2/IopCommon.h +++ b/pcsx2/IopCommon.h @@ -23,8 +23,8 @@ #include "R3000A.h" #include "Common.h" -#include "CdRom.h" -#include "CDVD.h" +#include "CDVD/CdRom.h" +#include "CDVD/CDVD.h" #include "Sio.h" #include "Sif.h" diff --git a/pcsx2/IopCounters.cpp b/pcsx2/IopCounters.cpp index 9e169100f7..b92e55a082 100644 --- a/pcsx2/IopCounters.cpp +++ b/pcsx2/IopCounters.cpp @@ -91,14 +91,24 @@ static void _rcntSet( int cntidx ) c = (u64)((overflowCap - counter.count) * counter.rate) - (psxRegs.cycle - counter.sCycleT); c += psxRegs.cycle - psxNextsCounter; // adjust for time passed since last rcntUpdate(); - if(c < (u64)psxNextCounter) psxNextCounter = (u32)c; + + if(c < (u64)psxNextCounter) + { + psxNextCounter = (u32)c; + psxSetNextBranch( psxNextsCounter, psxNextCounter ); //Need to update on counter resets/target changes + } //if((counter.mode & 0x10) == 0 || psxCounters[i].target > 0xffff) continue; if( counter.target & IOPCNT_FUTURE_TARGET ) return; - c = (s64)((counter.target - counter.count) * counter.rate) - (psxRegs.cycle - counter.sCycleT); - c += psxRegs.cycle - psxNextsCounter; // adjust for time passed since last rcntUpdate(); - if(c < (u64)psxNextCounter) psxNextCounter = (u32)c; + c = (s64)((counter.target - counter.count) * counter.rate) - (psxRegs.cycle - counter.sCycleT); + c += psxRegs.cycle - psxNextsCounter; // adjust for time passed since last rcntUpdate(); + + if(c < (u64)psxNextCounter) + { + psxNextCounter = (u32)c; + psxSetNextBranch( psxNextsCounter, psxNextCounter ); //Need to update on counter resets/target changes + } } @@ -383,15 +393,20 @@ void psxRcntUpdate() int i; //u32 change = 0; + g_psxNextBranchCycle = psxRegs.cycle + 32; + + psxNextCounter = 0x7fffffff; + psxNextsCounter = psxRegs.cycle; + for (i=0; i<=5; i++) { s32 change = psxRegs.cycle - psxCounters[i].sCycleT; - // don't count disabled, gated, or hblank counters... + // don't count disabled or hblank counters... // We can't check the ALTSOURCE flag because the PSXCLOCK source *should* // be counted here. - if( psxCounters[i].mode & (IOPCNT_STOPPED | IOPCNT_ENABLE_GATE) ) continue; + if( psxCounters[i].mode & IOPCNT_STOPPED ) continue; if( psxCounters[i].rate == PSXHBLANK ) continue; if( change <= 0 ) continue; @@ -424,9 +439,7 @@ void psxRcntUpdate() //if( psxCounters[i].count >= psxCounters[i].target ) _rcntTestTarget( i ); } - - psxNextCounter = 0xffffff; - psxNextsCounter = psxRegs.cycle; + if(SPU2async) { @@ -563,7 +576,7 @@ __forceinline void psxRcntWmode16( int index, u32 value ) { // gated counters are added up as per the h/vblank timers. // (the PIXEL alt source becomes a vsync gate) - + counter.mode |= IOPCNT_STOPPED; PSXCNT_LOG( "IOP Counter[%d] Gate Check set, value = 0x%04X", index, value ); if( index == 0 ) psxhblankgate |= 1; // fixme: these gate flags should be one var >_< @@ -608,6 +621,7 @@ __forceinline void psxRcntWmode32( int index, u32 value ) if(counter.mode & IOPCNT_ENABLE_GATE) { PSXCNT_LOG("IOP Counter[3] Gate Check set, value = %x", value); + counter.mode |= IOPCNT_STOPPED; psxvblankgate |= 1<<3; } else psxvblankgate &= ~(1<<3); diff --git a/pcsx2/IopDma.cpp b/pcsx2/IopDma.cpp index 1af6cef622..96ed3e3c7e 100644 --- a/pcsx2/IopDma.cpp +++ b/pcsx2/IopDma.cpp @@ -54,6 +54,12 @@ static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _ psxNextsCounter = psxRegs.cycle; if (psxCounters[6].CycleT < psxNextCounter) psxNextCounter = psxCounters[6].CycleT; + + if((g_psxNextBranchCycle - psxNextsCounter) > (u32)psxNextCounter) + { + //DevCon::Notice("SPU2async Setting new counter branch, old %x new %x ((%x - %x = %x) > %x delta)", params g_psxNextBranchCycle, psxNextsCounter + psxNextCounter, g_psxNextBranchCycle, psxNextsCounter, (g_psxNextBranchCycle - psxNextsCounter), psxNextCounter); + g_psxNextBranchCycle = psxNextsCounter + psxNextCounter; + } } switch (chcr) @@ -164,13 +170,13 @@ void psxDma9(u32 madr, u32 bcr, u32 chcr) SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx", chcr, madr, bcr, HW_DMA9_TADR); iopsifbusy[0] = 1; - psHu32(0x1000F240) |= 0x2000; + psHu32(SBUS_F240) |= 0x2000; if (eesifbusy[0] == 1) { SIF0Dma(); - psHu32(0x1000F240) &= ~0x20; - psHu32(0x1000F240) &= ~0x2000; + psHu32(SBUS_F240) &= ~0x20; + psHu32(SBUS_F240) &= ~0x2000; } } @@ -179,15 +185,15 @@ void psxDma10(u32 madr, u32 bcr, u32 chcr) SIF_LOG("IOP: dmaSIF1 chcr = %lx, madr = %lx, bcr = %lx", chcr, madr, bcr); iopsifbusy[1] = 1; - psHu32(0x1000F240) |= 0x4000; + psHu32(SBUS_F240) |= 0x4000; if (eesifbusy[1] == 1) { FreezeXMMRegs(1); SIF1Dma(); - psHu32(0x1000F240) &= ~0x40; - psHu32(0x1000F240) &= ~0x100; - psHu32(0x1000F240) &= ~0x4000; + psHu32(SBUS_F240) &= ~0x40; + psHu32(SBUS_F240) &= ~0x100; + psHu32(SBUS_F240) &= ~0x4000; FreezeXMMRegs(0); } } diff --git a/pcsx2/IopHw.cpp b/pcsx2/IopHw.cpp index b05428e598..69ed0cafc7 100644 --- a/pcsx2/IopHw.cpp +++ b/pcsx2/IopHw.cpp @@ -618,7 +618,7 @@ u32 psxHwRead32(u32 add) { } // A buffer that stores messages until it gets a /n or the number of chars (g_pbufi) is more then 1023. -static s8 g_pbuf[1024]; +static char g_pbuf[1024]; static int g_pbufi; void psxHwWrite8(u32 add, u8 value) { if (add >= HW_USB_START && add < HW_USB_END) { @@ -1313,26 +1313,19 @@ void psxHwWrite32(u32 add, u32 value) { PSXHW_LOG("*Known 32bit write at address %lx value %lx", add, value); } -u8 psxHw4Read8(u32 add) +__forceinline u8 psxHw4Read8(u32 add) { - //u8 hard; u16 mem = add & 0xFF; - - //Console::WriteLn("psxHw4Read8 0x%x, %x", params add, mem); - return cdvdRead(mem); - - //PSXHW_LOG( "Known 8bit read from addr 0x%x = 0x%x", add, hard ); - - //return hard; + u8 ret = cdvdRead(mem); + PSXHW_LOG("HwRead8 from Cdvd [segment 0x1f40], addr 0x%02x = 0x%02x", mem, ret); + return ret; } -void psxHw4Write8(u32 add, u8 value) +__forceinline void psxHw4Write8(u32 add, u8 value) { - - u16 mem = add & 0xFF; - //Console::WriteLn("psxHw4Write8 0x%x, %x", params add, mem); + u8 mem = (u8)add; // only lower 8 bits are relevant (cdvd regs mirror across the page) cdvdWrite(mem, value); - PSXHW_LOG("Known 8bit write to addr 0x%x = 0x%x", add, value); + PSXHW_LOG("HwWrite8 to Cdvd [segment 0x1f40], addr 0x%02x = 0x%02x", mem, value); } void psxDmaInterrupt(int n) diff --git a/pcsx2/IopHw.h b/pcsx2/IopHw.h index 4b31f5f2c0..898b2de489 100644 --- a/pcsx2/IopHw.h +++ b/pcsx2/IopHw.h @@ -220,28 +220,19 @@ extern void psxSetNextBranchDelta( s32 delta ); extern int iopTestCycle( u32 startCycle, s32 delta ); extern void _iopTestInterrupts(); -void psxHwReset(); +// Depreciated : Use iopHwRead* functions defined in IopMem.h instead. u8 psxHwRead8 (u32 add); u16 psxHwRead16(u32 add); u32 psxHwRead32(u32 add); +// Depreciated : Use iopHwWrite* functions defined in IopMem.h instead. void psxHwWrite8 (u32 add, u8 value); void psxHwWrite16(u32 add, u16 value); void psxHwWrite32(u32 add, u32 value); -u8 psxHw4Read8 (u32 add); -void psxHw4Write8(u32 add, u8 value); +extern void psxHwReset(); +extern u8 psxHw4Read8 (u32 add); +extern void psxHw4Write8(u32 add, u8 value); -void psxDmaInterrupt(int n); -void psxDmaInterrupt2(int n); - -int psxHwFreeze(gzFile f, int Mode); - -int psxHwConstRead8(u32 x86reg, u32 add, u32 sign); -int psxHwConstRead16(u32 x86reg, u32 add, u32 sign); -int psxHwConstRead32(u32 x86reg, u32 add); -void psxHwConstWrite8(u32 add, int mmreg); -void psxHwConstWrite16(u32 add, int mmreg); -void psxHwConstWrite32(u32 add, int mmreg); -int psxHw4ConstRead8 (u32 x86reg, u32 add, u32 sign); -void psxHw4ConstWrite8(u32 add, int mmreg); +extern void psxDmaInterrupt(int n); +extern void psxDmaInterrupt2(int n); diff --git a/pcsx2/IopMem.cpp b/pcsx2/IopMem.cpp index a9580a1cdb..55003d58b7 100644 --- a/pcsx2/IopMem.cpp +++ b/pcsx2/IopMem.cpp @@ -195,13 +195,13 @@ u16 iopMemRead16(u32 mem) switch(mem & 0xF0) { case 0x00: - ret= psHu16(0x1000F200); + ret= psHu16(SBUS_F200); break; case 0x10: - ret= psHu16(0x1000F210); + ret= psHu16(SBUS_F210); break; case 0x40: - ret= psHu16(0x1000F240) | 0x0002; + ret= psHu16(SBUS_F240) | 0x0002; break; case 0x60: ret = 0; @@ -261,19 +261,19 @@ u32 iopMemRead32(u32 mem) switch(mem & 0xF0) { case 0x00: - ret= psHu32(0x1000F200); + ret= psHu32(SBUS_F200); break; case 0x10: - ret= psHu32(0x1000F210); + ret= psHu32(SBUS_F210); break; case 0x20: - ret= psHu32(0x1000F220); + ret= psHu32(SBUS_F220); break; case 0x30: // EE Side - ret= psHu32(0x1000F230); + ret= psHu32(SBUS_F230); break; case 0x40: - ret= psHu32(0x1000F240) | 0xF0000002; + ret= psHu32(SBUS_F240) | 0xF0000002; break; case 0x60: ret = 0; @@ -405,7 +405,7 @@ void iopMemWrite16(u32 mem, u16 value) { case 0x10: // write to ps2 mem - psHu16(0x1000F210) = value; + psHu16(SBUS_F210) = value; return; case 0x40: { @@ -413,17 +413,19 @@ void iopMemWrite16(u32 mem, u16 value) // write to ps2 mem if(value & 0x20 || value & 0x80) { - psHu16(0x1000F240) &= ~0xF000; - psHu16(0x1000F240) |= 0x2000; + psHu16(SBUS_F240) &= ~0xF000; + psHu16(SBUS_F240) |= 0x2000; } - if(psHu16(0x1000F240) & temp) psHu16(0x1000F240) &= ~temp; - else psHu16(0x1000F240) |= temp; + if(psHu16(SBUS_F240) & temp) + psHu16(SBUS_F240) &= ~temp; + else + psHu16(SBUS_F240) |= temp; return; } case 0x60: - psHu32(0x1000F260) = 0; + psHu32(SBUS_F260) = 0; return; } @@ -490,36 +492,36 @@ void iopMemWrite32(u32 mem, u32 value) return; // this is the IOP, so read-only (do nothing) case 0x10: // IOP write path (EE/IOP readable) - psHu32(0x1000F210) = value; + psHu32(SBUS_F210) = value; return; case 0x20: // Bits cleared when written from IOP. - psHu32(0x1000F220) &= ~value; + psHu32(SBUS_F220) &= ~value; return; case 0x30: // bits set when written from IOP - psHu32(0x1000F230) |= value; + psHu32(SBUS_F230) |= value; return; case 0x40: // Control Register { u32 temp = value & 0xF0; - if(value & 0x20 || value & 0x80) + if (value & 0x20 || value & 0x80) { - psHu32(0x1000F240) &= ~0xF000; - psHu32(0x1000F240) |= 0x2000; + psHu32(SBUS_F240) &= ~0xF000; + psHu32(SBUS_F240) |= 0x2000; } - if(psHu32(0x1000F240) & temp) - psHu32(0x1000F240) &= ~temp; + if (psHu32(SBUS_F240) & temp) + psHu32(SBUS_F240) &= ~temp; else - psHu32(0x1000F240) |= temp; + psHu32(SBUS_F240) |= temp; return; } case 0x60: - psHu32(0x1000F260) = 0; + psHu32(SBUS_F260) = 0; return; } psxSu32(mem) = value; diff --git a/pcsx2/IopMem.h b/pcsx2/IopMem.h index dc62657c45..ab7d9a4a5c 100644 --- a/pcsx2/IopMem.h +++ b/pcsx2/IopMem.h @@ -18,6 +18,8 @@ #pragma once +#include "MemoryTypes.h" + extern u8 *psxM; extern u8 *psxP; extern u8 *psxH; @@ -98,31 +100,39 @@ void psxRecMemWrite32(); namespace IopMemory { // Sif functions not made yet (will for future Iop improvements): - extern u8 __fastcall SifRead8( u32 iopaddr ); - extern u16 __fastcall SifRead16( u32 iopaddr ); - extern u32 __fastcall SifRead32( u32 iopaddr ); + extern mem8_t __fastcall SifRead8( u32 iopaddr ); + extern mem16_t __fastcall SifRead16( u32 iopaddr ); + extern mem32_t __fastcall SifRead32( u32 iopaddr ); - extern void __fastcall SifWrite8( u32 iopaddr, u8 data ); - extern void __fastcall SifWrite16( u32 iopaddr, u16 data ); - extern void __fastcall SifWrite32( u32 iopaddr, u32 data ); + extern void __fastcall SifWrite8( u32 iopaddr, mem8_t data ); + extern void __fastcall SifWrite16( u32 iopaddr, mem16_t data ); + extern void __fastcall SifWrite32( u32 iopaddr, mem32_t data ); - extern u8 __fastcall iopHwRead8_Page1( u32 iopaddr ); - extern u8 __fastcall iopHwRead8_Page3( u32 iopaddr ); - extern u8 __fastcall iopHwRead8_Page8( u32 iopaddr ); - extern u16 __fastcall iopHwRead16_Page1( u32 iopaddr ); - extern u16 __fastcall iopHwRead16_Page3( u32 iopaddr ); - extern u16 __fastcall iopHwRead16_Page8( u32 iopaddr ); - extern u32 __fastcall iopHwRead32_Page1( u32 iopaddr ); - extern u32 __fastcall iopHwRead32_Page3( u32 iopaddr ); - extern u32 __fastcall iopHwRead32_Page8( u32 iopaddr ); + extern mem8_t __fastcall iopHwRead8_generic( u32 addr ); + extern mem16_t __fastcall iopHwRead16_generic( u32 addr ); + extern mem32_t __fastcall iopHwRead32_generic( u32 addr ); + extern void __fastcall iopHwWrite8_generic( u32 addr, mem8_t val ); + extern void __fastcall iopHwWrite16_generic( u32 addr, mem16_t val ); + extern void __fastcall iopHwWrite32_generic( u32 addr, mem32_t val ); - extern void __fastcall iopHwWrite8_Page1( u32 iopaddr, u8 data ); - extern void __fastcall iopHwWrite8_Page3( u32 iopaddr, u8 data ); - extern void __fastcall iopHwWrite8_Page8( u32 iopaddr, u8 data ); - extern void __fastcall iopHwWrite16_Page1( u32 iopaddr, u16 data ); - extern void __fastcall iopHwWrite16_Page3( u32 iopaddr, u16 data ); - extern void __fastcall iopHwWrite16_Page8( u32 iopaddr, u16 data ); - extern void __fastcall iopHwWrite32_Page1( u32 iopaddr, u32 data ); - extern void __fastcall iopHwWrite32_Page3( u32 iopaddr, u32 data ); - extern void __fastcall iopHwWrite32_Page8( u32 iopaddr, u32 data ); + + extern mem8_t __fastcall iopHwRead8_Page1( u32 iopaddr ); + extern mem8_t __fastcall iopHwRead8_Page3( u32 iopaddr ); + extern mem8_t __fastcall iopHwRead8_Page8( u32 iopaddr ); + extern mem16_t __fastcall iopHwRead16_Page1( u32 iopaddr ); + extern mem16_t __fastcall iopHwRead16_Page3( u32 iopaddr ); + extern mem16_t __fastcall iopHwRead16_Page8( u32 iopaddr ); + extern mem32_t __fastcall iopHwRead32_Page1( u32 iopaddr ); + extern mem32_t __fastcall iopHwRead32_Page3( u32 iopaddr ); + extern mem32_t __fastcall iopHwRead32_Page8( u32 iopaddr ); + + extern void __fastcall iopHwWrite8_Page1( u32 iopaddr, mem8_t data ); + extern void __fastcall iopHwWrite8_Page3( u32 iopaddr, mem8_t data ); + extern void __fastcall iopHwWrite8_Page8( u32 iopaddr, mem8_t data ); + extern void __fastcall iopHwWrite16_Page1( u32 iopaddr, mem16_t data ); + extern void __fastcall iopHwWrite16_Page3( u32 iopaddr, mem16_t data ); + extern void __fastcall iopHwWrite16_Page8( u32 iopaddr, mem16_t data ); + extern void __fastcall iopHwWrite32_Page1( u32 iopaddr, mem32_t data ); + extern void __fastcall iopHwWrite32_Page3( u32 iopaddr, mem32_t data ); + extern void __fastcall iopHwWrite32_Page8( u32 iopaddr, mem32_t data ); } \ No newline at end of file diff --git a/pcsx2/IopSio2.cpp b/pcsx2/IopSio2.cpp index d3ffd8271e..369591f265 100644 --- a/pcsx2/IopSio2.cpp +++ b/pcsx2/IopSio2.cpp @@ -17,8 +17,8 @@ */ #include "PrecompiledHeader.h" - #include "IopCommon.h" +#include "sio_internal.h" sio2Struct sio2; diff --git a/pcsx2/Linux/ConfigDlg.cpp b/pcsx2/Linux/ConfigDlg.cpp index df988d459a..dd0f3f924d 100644 --- a/pcsx2/Linux/ConfigDlg.cpp +++ b/pcsx2/Linux/ConfigDlg.cpp @@ -88,7 +88,7 @@ static void ConfPlugin(plugin_types type, plugin_callback call, bool pullcombo = void OnConf_Menu(GtkMenuItem *menuitem, gpointer user_data) { - char *name = gtk_widget_get_name(GTK_WIDGET(menuitem)); + char *name = (char*)gtk_widget_get_name(GTK_WIDGET(menuitem)); plugin_types type = strToPluginType(name); gtk_widget_set_sensitive(MainWindow, FALSE); @@ -134,11 +134,11 @@ void OnConfConf_Ok(GtkButton *button, gpointer user_data) plugin_types type; applychanges = TRUE; - for (type = GS; type <= BIOS; type = type + 1) + for (type = GS; type <= BIOS; type = (plugin_types)((int)type + 1)) { PluginConf *confs = ConfS(type); - if (!GetComboText(confs->Combo, confs->plist, PluginName(type))) + if (!GetComboText(confs->Combo, confs->plist, (char*)PluginName(type))) applychanges = FALSE; } @@ -153,14 +153,13 @@ void OnConfConf_Ok(GtkButton *button, gpointer user_data) void OnConfButton(GtkButton *button, gpointer user_data) { - char *name = gtk_widget_get_name(GTK_WIDGET(button)); + char *name = (char*)gtk_widget_get_name(GTK_WIDGET(button)); plugin_types type = strToPluginType(name); plugin_callback call = strToPluginCall(name); - // Don't uncomment till fixing CDVDIso's dialog box. - //gtk_widget_set_sensitive(ConfDlg, FALSE); - ConfPlugin(type, call, false); - //gtk_widget_set_sensitive(ConfDlg, TRUE); + gtk_widget_set_sensitive(ConfDlg, FALSE); + ConfPlugin(type, call, true); + gtk_widget_set_sensitive(ConfDlg, TRUE); } void SetComboToGList(GtkComboBox *widget, GList *list) @@ -189,7 +188,7 @@ void UpdateConfDlg() plugin_types type; FindPlugins(); - for (type = GS; type <= BIOS; type = type + 1) + for (type = GS; type <= BIOS; type = (plugin_types)((int)type + 1)) { char tmp[50]; PluginConf *confs = ConfS(type); @@ -197,7 +196,7 @@ void UpdateConfDlg() sprintf(tmp, "GtkCombo_%s", PluginTypeToStr(type)); confs->Combo = lookup_widget(ConfDlg, tmp); SetComboToGList(GTK_COMBO_BOX(confs->Combo), confs->PluginNameList); - FindComboText(confs->Combo, confs->plist, confs->PluginNameList, PluginName(type)); + FindComboText(confs->Combo, confs->plist, confs->PluginNameList, (char*)PluginName(type)); } } @@ -275,7 +274,7 @@ void FindPlugins() char plugin[g_MaxPath], name[g_MaxPath]; plugin_types type; - for (type = GS; type <= BIOS; type = type + 1) + for (type = GS; type <= BIOS; type = (plugin_types)((int)type + 1)) { PluginConf *confs = ConfS(type); diff --git a/pcsx2/Linux/ConfigDlg.h b/pcsx2/Linux/ConfigDlg.h index 5a8f971e11..081e2c0a3f 100644 --- a/pcsx2/Linux/ConfigDlg.h +++ b/pcsx2/Linux/ConfigDlg.h @@ -171,7 +171,7 @@ __forceinline const char *PluginCallbackName(int type, int call) return NULL; } -__forceinline int strToPluginCall(char *s) +__forceinline plugin_callback strToPluginCall(char *s) { char *sub = NULL; @@ -187,7 +187,7 @@ __forceinline int strToPluginCall(char *s) return PLUGIN_NULL; } -__forceinline int strToPluginType(char *s) +__forceinline plugin_types strToPluginType(char *s) { char *sub = NULL; diff --git a/pcsx2/Linux/CpuDlg.cpp b/pcsx2/Linux/CpuDlg.cpp index 4baca1577e..e9be522c1d 100644 --- a/pcsx2/Linux/CpuDlg.cpp +++ b/pcsx2/Linux/CpuDlg.cpp @@ -25,21 +25,20 @@ void OnCpu_Ok(GtkButton *button, gpointer user_data) { u32 newopts = 0; - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkCheckButton_EERec")))) - newopts |= PCSX2_EEREC; - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkCheckButton_VU0rec")))) - newopts |= PCSX2_VU0REC; - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkCheckButton_VU1rec")))) - newopts |= PCSX2_VU1REC; - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkCheckButton_MTGS")))) - newopts |= PCSX2_GSMULTITHREAD; - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkRadioButton_LimitNormal")))) + if is_checked(CpuDlg, "GtkCheckButton_EERec") newopts |= PCSX2_EEREC; + if is_checked(CpuDlg, "GtkCheckButton_VU0rec") newopts |= PCSX2_VU0REC; + if is_checked(CpuDlg, "GtkCheckButton_VU1rec") newopts |= PCSX2_VU1REC; + if is_checked(CpuDlg, "GtkCheckButton_microVU0rec") newopts |= PCSX2_MICROVU0; + if is_checked(CpuDlg, "GtkCheckButton_microVU1rec") newopts |= PCSX2_MICROVU1; + if is_checked(CpuDlg, "GtkCheckButton_MTGS") newopts |= PCSX2_GSMULTITHREAD; + + if is_checked(CpuDlg, "GtkRadioButton_LimitNormal") newopts |= PCSX2_FRAMELIMIT_NORMAL; - else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkRadioButton_LimitLimit")))) + else if is_checked(CpuDlg, "GtkRadioButton_LimitLimit") newopts |= PCSX2_FRAMELIMIT_LIMIT; - else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkRadioButton_LimitFS")))) + else if is_checked(CpuDlg, "GtkRadioButton_LimitFS") newopts |= PCSX2_FRAMELIMIT_SKIP; - + Config.CustomFps = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(CpuDlg, "CustomFPSLimit"))); Config.CustomFrameSkip = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(CpuDlg, "FrameThreshold"))); Config.CustomConsecutiveFrames = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(CpuDlg, "FramesBeforeSkipping"))); @@ -72,6 +71,19 @@ void OnCpu_Ok(GtkButton *button, gpointer user_data) gtk_main_quit(); } +void DisableMicroVU() +{ + if is_checked(CpuDlg, "GtkCheckButton_VU0rec") + gtk_widget_set_sensitive(lookup_widget(CpuDlg, "GtkCheckButton_microVU0rec"), true); + else + gtk_widget_set_sensitive(lookup_widget(CpuDlg, "GtkCheckButton_microVU0rec"), false); + + if is_checked(CpuDlg, "GtkCheckButton_VU1rec") + gtk_widget_set_sensitive(lookup_widget(CpuDlg, "GtkCheckButton_microVU1rec"), true); + else + gtk_widget_set_sensitive(lookup_widget(CpuDlg, "GtkCheckButton_microVU1rec"), false); +} + void OnConf_Cpu(GtkMenuItem *menuitem, gpointer user_data) { char str[512]; @@ -79,14 +91,17 @@ void OnConf_Cpu(GtkMenuItem *menuitem, gpointer user_data) CpuDlg = create_CpuDlg(); gtk_window_set_title(GTK_WINDOW(CpuDlg), _("Configuration")); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkCheckButton_EERec")), !!CHECK_EEREC); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkCheckButton_VU0rec")), !!CHECK_VU0REC); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkCheckButton_VU1rec")), !!CHECK_VU1REC); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkCheckButton_MTGS")), !!CHECK_MULTIGS); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkRadioButton_LimitNormal")), CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_NORMAL); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkRadioButton_LimitLimit")), CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_LIMIT); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkRadioButton_LimitFS")), CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_SKIP); - + set_checked(CpuDlg, "GtkCheckButton_EERec", !!CHECK_EEREC); + set_checked(CpuDlg, "GtkCheckButton_VU0rec", !!CHECK_VU0REC); + set_checked(CpuDlg, "GtkCheckButton_VU1rec", !!CHECK_VU1REC); + set_checked(CpuDlg, "GtkCheckButton_microVU0rec", !!CHECK_MICROVU0); + set_checked(CpuDlg, "GtkCheckButton_microVU1rec", !!CHECK_MICROVU1); + set_checked(CpuDlg, "GtkCheckButton_MTGS", !!CHECK_MULTIGS); + set_checked(CpuDlg, "GtkRadioButton_LimitNormal", CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_NORMAL); + set_checked(CpuDlg, "GtkRadioButton_LimitLimit", CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_LIMIT); + set_checked(CpuDlg, "GtkRadioButton_LimitFS", CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_SKIP); + DisableMicroVU(); + sprintf(str, "Cpu Vendor: %s", cpuinfo.x86ID); gtk_label_set_text(GTK_LABEL(lookup_widget(CpuDlg, "GtkLabel_CpuVendor")), str); sprintf(str, "Familly: %s", cpuinfo.x86Fam); @@ -110,4 +125,9 @@ void OnConf_Cpu(GtkMenuItem *menuitem, gpointer user_data) gtk_widget_show_all(CpuDlg); if (MainWindow) gtk_widget_set_sensitive(MainWindow, FALSE); gtk_main(); -} \ No newline at end of file +} + +void OnCpuCheckToggled(GtkToggleButton *togglebutton, gpointer user_data) +{ + DisableMicroVU(); +} diff --git a/pcsx2/Linux/DebugDlg.cpp b/pcsx2/Linux/DebugDlg.cpp index 7e4b11e50e..4f0b19210b 100644 --- a/pcsx2/Linux/DebugDlg.cpp +++ b/pcsx2/Linux/DebugDlg.cpp @@ -18,7 +18,7 @@ #include "DebugDlg.h" using namespace R5900; -unsigned long DebuggerPC = 0; +u32 DebuggerPC = 0; /*void UpdateDebugger() { @@ -70,7 +70,7 @@ unsigned long DebuggerPC = 0; void UpdateDebugger(void) { - /* unsigned long t; + /* u32 t; int cnt; if (DebuggerPC == 0) DebuggerPC = cpuRegs.pc; //- 0x00000038; diff --git a/pcsx2/Linux/HacksDlg.cpp b/pcsx2/Linux/HacksDlg.cpp index 0177d60930..c4e17fcab1 100644 --- a/pcsx2/Linux/HacksDlg.cpp +++ b/pcsx2/Linux/HacksDlg.cpp @@ -29,6 +29,8 @@ GtkWidget *GameFixDlg, *SpeedHacksDlg; set_checked(GameFixDlg, "check_FPU_Compare", (Config.GameFixes & FLAG_FPU_Compare)); set_checked(GameFixDlg, "check_FPU_Mul", (Config.GameFixes & FLAG_FPU_MUL)); + set_checked(GameFixDlg, "check_DMAExec", (Config.GameFixes & FLAG_DMAExec)); + set_checked(GameFixDlg, "check_XGKick", (Config.GameFixes & FLAG_XGKick)); gtk_widget_show_all(GameFixDlg); gtk_widget_set_sensitive(MainWindow, FALSE); @@ -45,6 +47,8 @@ void on_Game_Fix_OK(GtkButton *button, gpointer user_data) Config.GameFixes |= is_checked(GameFixDlg, "check_FPU_Compare") ? FLAG_FPU_Compare : 0; Config.GameFixes |= is_checked(GameFixDlg, "check_FPU_Mul") ? FLAG_FPU_MUL : 0; + Config.GameFixes |= is_checked(GameFixDlg, "check_DMAExec") ? FLAG_DMAExec : 0; + Config.GameFixes |= is_checked(GameFixDlg, "check_XGKick") ? FLAG_XGKick : 0; SaveConfig(); @@ -75,10 +79,12 @@ void on_Speed_Hacks(GtkMenuItem *menuitem, gpointer user_data) GtkRange *vuScale = GTK_RANGE(lookup_widget(SpeedHacksDlg, "VUCycleHackScale")); GtkRange *eeScale = GTK_RANGE(lookup_widget(SpeedHacksDlg, "EECycleHackScale")); - set_checked(SpeedHacksDlg, "check_iop_cycle_rate", Config.Hacks.IOPCycleDouble); - set_checked(SpeedHacksDlg, "check_wait_cycles_sync_hack", Config.Hacks.WaitCycleExt); - set_checked(SpeedHacksDlg, "check_intc_sync_hack", Config.Hacks.INTCSTATSlow); - set_checked(SpeedHacksDlg, "check_idle_loop_fastforward", Config.Hacks.IdleLoopFF); + set_checked(SpeedHacksDlg, "check_iop_cycle_rate", Config.Hacks.IOPCycleDouble); + set_checked(SpeedHacksDlg, "check_wait_cycles_sync_hack", Config.Hacks.WaitCycleExt); + set_checked(SpeedHacksDlg, "check_intc_sync_hack", Config.Hacks.INTCSTATSlow); + set_checked(SpeedHacksDlg, "check_idle_loop_fastforward", Config.Hacks.IdleLoopFF); + set_checked(SpeedHacksDlg, "check_microvu_flag_hack", Config.Hacks.vuFlagHack); + set_checked(SpeedHacksDlg, "check_microvu_min_max_hack", Config.Hacks.vuMinMax); gtk_range_set_value(vuScale, Config.Hacks.VUCycleSteal); on_vu_slider_changed(vuScale, NULL); @@ -101,6 +107,8 @@ void on_Speed_Hack_OK(GtkButton *button, gpointer user_data) newhacks.WaitCycleExt = is_checked(SpeedHacksDlg, "check_wait_cycles_sync_hack"); newhacks.INTCSTATSlow = is_checked(SpeedHacksDlg, "check_intc_sync_hack"); newhacks.IdleLoopFF = is_checked(SpeedHacksDlg, "check_idle_loop_fastforward"); + newhacks.vuFlagHack = is_checked(SpeedHacksDlg, "check_microvu_flag_hack"); + newhacks.vuMinMax = is_checked(SpeedHacksDlg, "check_microvu_min_max_hack"); newhacks.VUCycleSteal = gtk_range_get_value(GTK_RANGE(lookup_widget(SpeedHacksDlg, "VUCycleHackScale"))); newhacks.EECycleRate = gtk_range_get_value(GTK_RANGE(lookup_widget(SpeedHacksDlg, "EECycleHackScale"))); diff --git a/pcsx2/Linux/HostGui.cpp b/pcsx2/Linux/HostGui.cpp index 609fc67e3e..6e0d8701ef 100644 --- a/pcsx2/Linux/HostGui.cpp +++ b/pcsx2/Linux/HostGui.cpp @@ -21,7 +21,6 @@ #include #include #include "Common.h" -//#include "x86/iR5900.h" extern void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * ); extern void __fastcall InstallLinuxExceptionHandler(); @@ -66,38 +65,3 @@ void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * ) mmap_ClearCpuBlock( offset & ~m_pagemask ); } - -namespace HostSys -{ - void *Mmap(uptr base, u32 size) - { - u8 *Mem; - Mem = (u8*)mmap((uptr*)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); - if (Mem == MAP_FAILED) Console::Notice("Mmap Failed!"); - - return Mem; - } - - void Munmap(uptr base, u32 size) - { - munmap((uptr*)base, size); - } - - void MemProtect( void* baseaddr, size_t size, PageProtectionMode mode, bool allowExecution ) - { - int lnxmode = 0; - - // make sure size is aligned to the system page size: - size = (size + m_pagemask) & ~m_pagemask; - - switch( mode ) - { - case Protect_NoAccess: break; - case Protect_ReadOnly: lnxmode = PROT_READ; break; - case Protect_ReadWrite: lnxmode = PROT_READ | PROT_WRITE; break; - } - - if( allowExecution ) lnxmode |= PROT_EXEC; - mprotect( baseaddr, size, lnxmode ); - } -} diff --git a/pcsx2/Linux/Linux.h b/pcsx2/Linux/Linux.h index e1cf6b6272..49de616d43 100644 --- a/pcsx2/Linux/Linux.h +++ b/pcsx2/Linux/Linux.h @@ -125,6 +125,10 @@ char ee_cycle_labels[3][256] = #define FLAG_FPU_Compare 0x4 //Tales of Destiny - IDC_GAMEFIX5 #define FLAG_FPU_MUL 0x8 +//Fatal Frame +#define FLAG_DMAExec 0x10 +//Erementar Gerad +#define FLAG_XGKick 0x20 #define FLAG_VU_NO_OVERFLOW 0x2 #define FLAG_VU_EXTRA_OVERFLOW 0x40 diff --git a/pcsx2/Linux/LnxMain.cpp b/pcsx2/Linux/LnxMain.cpp index 4f764cfac7..251d9f13d1 100644 --- a/pcsx2/Linux/LnxMain.cpp +++ b/pcsx2/Linux/LnxMain.cpp @@ -216,6 +216,11 @@ void On_Dialog_Cancelled(GtkButton* button, gpointer user_data) gtk_main_quit(); } +void On_Dialog_Close(GtkDialog* dialog, gpointer user_data) +{ + gtk_widget_set_sensitive(MainWindow, TRUE); +} + void RefreshMenuSlots() { GtkWidget *Item; diff --git a/pcsx2/Linux/LnxSysExec.cpp b/pcsx2/Linux/LnxSysExec.cpp index 5ce58e3b1c..e5da6434f0 100644 --- a/pcsx2/Linux/LnxSysExec.cpp +++ b/pcsx2/Linux/LnxSysExec.cpp @@ -22,10 +22,11 @@ static bool sinit = false; GtkWidget *FileSel; - +static uptr current_offset = 0; +static uptr offset_counter = 0; bool Slots[5] = { false, false, false, false, false }; -void InstallLinuxExceptionHandler() +__noinline void InstallLinuxExceptionHandler() { struct sigaction sa; @@ -35,25 +36,51 @@ void InstallLinuxExceptionHandler() sigaction(SIGSEGV, &sa, NULL); } -void ReleaseLinuxExceptionHandler() +__noinline void ReleaseLinuxExceptionHandler() { - // Code this later. + // This may be called too early or something, since implementing it causes all games to segfault. + // I'll look in to it. --arcum42 } +__noinline void KillLinuxExceptionHandler() +{ + struct sigaction sa; + + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESETHAND; + //sa.sa_sigaction = &SysPageFaultExceptionFilter; + sigaction(SIGSEGV, &sa, NULL); +} static const uptr m_pagemask = getpagesize()-1; // Linux implementation of SIGSEGV handler. Bind it using sigaction(). -void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * ) +__noinline void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * ) { // get bad virtual address uptr offset = (u8*)info->si_addr - psM; - - DevCon::Status( "Protected memory cleanup. Offset 0x%x", params offset ); + + if (offset != current_offset) + { + current_offset = offset; + offset_counter = 0; + } + else + { + offset_counter++; + if (offset_counter > 500) + { + DevCon::Status( "Offset 0x%x endlessly repeating. Aborting.", params offset ); + KillLinuxExceptionHandler(); + assert( false ); + } + } if (offset>=Ps2MemSize::Base) { // Bad mojo! Completely invalid address. // Instigate a crash or abort emulation or something. + DevCon::Status( "Offset 0x%x invalid. Legit SIGSEGV. Aborting.", params offset ); + KillLinuxExceptionHandler(); assert( false ); } @@ -190,7 +217,6 @@ void OnStates_Load(GtkMenuItem *menuitem, gpointer user_data) } sscanf(name, "Slot %d", &i); - //if (States_Load(i)) ExecuteCpu(); States_Load(i); RefreshMenuSlots(); } @@ -203,8 +229,6 @@ void OnLoadOther_Ok(GtkButton* button, gpointer user_data) File = (gchar*)gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel)); strcpy(str, File); gtk_widget_destroy(FileSel); - - //if (States_Load(str)) ExecuteCpu(); States_Load(str); RefreshMenuSlots(); } @@ -382,10 +406,21 @@ namespace HostSys void MemProtect( void* baseaddr, size_t size, PageProtectionMode mode, bool allowExecution ) { + // Breakpoint this to trap potentially inappropriate use of page protection, which would + // be caused by failed aligned directives on global vars. + if( ((uptr)baseaddr & m_pagemask) != 0 ) + { + Console::Error( + "*PCSX2/Linux Warning* Inappropriate use of page protection detected.\n" + "\tbaseaddr not page aligned: 0x%08X", params (uptr)baseaddr + ); + } + int lnxmode = 0; - // make sure size is aligned to the system page size: + // make sure base and size are aligned to the system page size: size = (size + m_pagemask) & ~m_pagemask; + baseaddr = (void*)( ((uptr)baseaddr) & ~m_pagemask ); switch( mode ) { diff --git a/pcsx2/Linux/Makefile.am b/pcsx2/Linux/Makefile.am deleted file mode 100644 index b5eac7e818..0000000000 --- a/pcsx2/Linux/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -AUTOMAKE_OPTIONS = foreign -INCLUDES = $(shell pkg-config --cflags gtk+-2.0) -I@srcdir@/../ -I@srcdir@/../../common/include -I@srcdir@/../../3rdparty $(shell wx-config --cppflags) - -bin_PROGRAMS = pcsx2 - -# the application source, library search path, and link libraries -pcsx2_SOURCES = \ -interface.c support.c LnxMain.cpp LnxThreads.cpp LnxConsole.cpp LnxSysExec.cpp LnxMisc.cpp \ -AboutDlg.cpp ConfigDlg.cpp DebugDlg.cpp AdvancedDlg.cpp CpuDlg.cpp HacksDlg.cpp McdDlgs.cpp Pref.cpp \ -GtkGui.h Linux.h LnxMain.h ConfigDlg.h DebugDlg.h McdDlgs.h interface.h callbacks.h memzero.h support.h - -pcsx2_LDFLAGS = - -pcsx2_DEPENDENCIES = ../libpcsx2.a ../IPU/libIPU.a ../IPU/mpeg2lib/libmpeg2IPU.a ../RDebug/libRDebug.a ../tinyxml/libtinyxml.a -pcsx2_DEPENDENCIES += ../x86/libx86recomp.a ../x86/ix86/libix86.a -pcsx2_DEPENDENCIES += ../DebugTools/libDebugTools.a - -pcsx2_LDADD = ../libpcsx2.a ../IPU/libIPU.a ../IPU/mpeg2lib/libmpeg2IPU.a ../RDebug/libRDebug.a ../tinyxml/libtinyxml.a -pcsx2_LDADD += ../x86/libx86recomp.a ../x86/ix86/libix86.a -pcsx2_LDADD += ../DebugTools/libDebugTools.a \ No newline at end of file diff --git a/pcsx2/Linux/Pref.cpp b/pcsx2/Linux/Pref.cpp index 7db9dd2d4f..ff06af2b48 100644 --- a/pcsx2/Linux/Pref.cpp +++ b/pcsx2/Linux/Pref.cpp @@ -104,12 +104,14 @@ int LoadConfig() GetValuel("EECycleRate", Config.Hacks.EECycleRate); if (Config.Hacks.EECycleRate > 2) Config.Hacks.EECycleRate = 2; - GetValuel("IOPCycleDouble", Config.Hacks.IOPCycleDouble); - GetValuel("WaitCycleExt", Config.Hacks.WaitCycleExt); - GetValuel("INTCSTATSlow", Config.Hacks.INTCSTATSlow); - GetValuel("VUCycleSteal", Config.Hacks.VUCycleSteal); - GetValuel("IdleLoopFF", Config.Hacks.IdleLoopFF); - GetValuel("ESCExits", Config.Hacks.ESCExits); + GetValuel("IOPCycleDouble", Config.Hacks.IOPCycleDouble); + GetValuel("WaitCycleExt", Config.Hacks.WaitCycleExt); + GetValuel("INTCSTATSlow", Config.Hacks.INTCSTATSlow); + GetValuel("VUCycleSteal", Config.Hacks.VUCycleSteal); + GetValuel("vuFlagHack", Config.Hacks.vuFlagHack); + GetValuel("vuMinMax", Config.Hacks.vuMinMax); + GetValuel("IdleLoopFF", Config.Hacks.IdleLoopFF); + GetValuel("ESCExits", Config.Hacks.ESCExits); if (Config.Hacks.VUCycleSteal < 0 || Config.Hacks.VUCycleSteal > 4) Config.Hacks.VUCycleSteal = 0; diff --git a/pcsx2/Linux/callbacks.h b/pcsx2/Linux/callbacks.h index 771418a3ca..5b02c1aa37 100644 --- a/pcsx2/Linux/callbacks.h +++ b/pcsx2/Linux/callbacks.h @@ -1,6 +1,10 @@ #include +void +On_Dialog_Close (GtkDialog *dialog, + gpointer user_data); + void on_Advanced_Defaults (GtkButton *button, gpointer user_data); @@ -246,6 +250,10 @@ void OnHelp_About (GtkMenuItem *menuitem, gpointer user_data); +void +OnCpuCheckToggled (GtkToggleButton *togglebutton, + gpointer user_data); + void OnCpu_Ok (GtkButton *button, gpointer user_data); diff --git a/pcsx2/Linux/interface.c b/pcsx2/Linux/interface.c index 87e6a49abf..774b27f02c 100644 --- a/pcsx2/Linux/interface.c +++ b/pcsx2/Linux/interface.c @@ -523,6 +523,9 @@ create_AdvDlg (void) gtk_dialog_add_action_widget (GTK_DIALOG (AdvDlg), button80, GTK_RESPONSE_CANCEL); GTK_WIDGET_SET_FLAGS (button80, GTK_CAN_DEFAULT); + g_signal_connect ((gpointer) AdvDlg, "close", + G_CALLBACK (On_Dialog_Close), + NULL); g_signal_connect ((gpointer) AdvDefaultBtn, "clicked", G_CALLBACK (on_Advanced_Defaults), NULL); @@ -631,19 +634,26 @@ create_SpeedHacksDlg (void) GtkWidget *vu_cycle_stealing_label; GtkWidget *label111; GtkWidget *vbox60; + GtkWidget *frame42; + GtkWidget *alignment37; + GtkWidget *vbox76; GtkWidget *check_iop_cycle_rate; - GtkWidget *label96; GtkWidget *check_wait_cycles_sync_hack; - GtkWidget *label97; GtkWidget *check_intc_sync_hack; - GtkWidget *label101; - GtkWidget *vbox71; GtkWidget *check_idle_loop_fastforward; - GtkWidget *label110; - GtkWidget *hseparator1; + GtkWidget *label114; + GtkWidget *frame41; + GtkWidget *alignment36; + GtkWidget *vbox75; + GtkWidget *check_microvu_flag_hack; + GtkWidget *check_microvu_min_max_hack; + GtkWidget *label113; GtkWidget *dialog_action_area3; GtkWidget *button99; GtkWidget *button98; + GtkTooltips *tooltips; + + tooltips = gtk_tooltips_new (); SpeedHacksDlg = gtk_dialog_new (); gtk_widget_set_name (SpeedHacksDlg, "SpeedHacksDlg"); @@ -714,7 +724,7 @@ create_SpeedHacksDlg (void) gtk_box_pack_start (GTK_BOX (vbox61), label91, FALSE, FALSE, 0); gtk_label_set_line_wrap (GTK_LABEL (label91), TRUE); - label105 = gtk_label_new (_("EmotionEngine (EE) Sync Hacks")); + label105 = gtk_label_new (_("EmotionEngine (EE) Sync Hacks")); gtk_widget_set_name (label105, "label105"); gtk_widget_show (label105); gtk_frame_set_label_widget (GTK_FRAME (frame37), label105); @@ -749,7 +759,7 @@ create_SpeedHacksDlg (void) gtk_box_pack_start (GTK_BOX (vbox73), vu_cycle_stealing_label, FALSE, FALSE, 0); gtk_label_set_line_wrap (GTK_LABEL (vu_cycle_stealing_label), TRUE); - label111 = gtk_label_new (_("VU Cycle Stealing (Speedup for 3d geometry)")); + label111 = gtk_label_new (_("VU Cycle Stealing (Speedup for 3d geometry)")); gtk_widget_set_name (label111, "label111"); gtk_widget_show (label111); gtk_frame_set_label_widget (GTK_FRAME (frame39), label111); @@ -760,59 +770,85 @@ create_SpeedHacksDlg (void) gtk_widget_show (vbox60); gtk_box_pack_start (GTK_BOX (hbox39), vbox60, FALSE, FALSE, 0); + frame42 = gtk_frame_new (NULL); + gtk_widget_set_name (frame42, "frame42"); + gtk_widget_show (frame42); + gtk_box_pack_start (GTK_BOX (vbox60), frame42, FALSE, FALSE, 0); + + alignment37 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_set_name (alignment37, "alignment37"); + gtk_widget_show (alignment37); + gtk_container_add (GTK_CONTAINER (frame42), alignment37); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment37), 0, 0, 12, 0); + + vbox76 = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (vbox76, "vbox76"); + gtk_widget_show (vbox76); + gtk_container_add (GTK_CONTAINER (alignment37), vbox76); + check_iop_cycle_rate = gtk_check_button_new_with_mnemonic (_("Enable IOP x2 Cycle Rate")); gtk_widget_set_name (check_iop_cycle_rate, "check_iop_cycle_rate"); gtk_widget_show (check_iop_cycle_rate); - gtk_box_pack_start (GTK_BOX (vbox60), check_iop_cycle_rate, FALSE, FALSE, 0); - - label96 = gtk_label_new (_("Small speedup, and works well with most games,")); - gtk_widget_set_name (label96, "label96"); - gtk_widget_show (label96); - gtk_box_pack_start (GTK_BOX (vbox60), label96, FALSE, FALSE, 0); - gtk_label_set_line_wrap (GTK_LABEL (label96), TRUE); + gtk_box_pack_start (GTK_BOX (vbox76), check_iop_cycle_rate, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, check_iop_cycle_rate, _("Small speedup, and works well with most games."), NULL); check_wait_cycles_sync_hack = gtk_check_button_new_with_mnemonic (_("WaitCycles Sync Hack")); gtk_widget_set_name (check_wait_cycles_sync_hack, "check_wait_cycles_sync_hack"); gtk_widget_show (check_wait_cycles_sync_hack); - gtk_box_pack_start (GTK_BOX (vbox60), check_wait_cycles_sync_hack, FALSE, FALSE, 0); - - label97 = gtk_label_new (_("Small speedup. Works well with most games, but it may cause certain games to crash, or freeze up during bootup or stage changes.")); - gtk_widget_set_name (label97, "label97"); - gtk_widget_show (label97); - gtk_box_pack_start (GTK_BOX (vbox60), label97, FALSE, FALSE, 0); - gtk_label_set_line_wrap (GTK_LABEL (label97), TRUE); + gtk_box_pack_start (GTK_BOX (vbox76), check_wait_cycles_sync_hack, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, check_wait_cycles_sync_hack, _("Small speedup. Works well with most games, but it may cause certain games to crash, or freeze up during bootup or stage changes."), NULL); check_intc_sync_hack = gtk_check_button_new_with_mnemonic (_("INTC Sync Hack")); gtk_widget_set_name (check_intc_sync_hack, "check_intc_sync_hack"); gtk_widget_show (check_intc_sync_hack); - gtk_box_pack_start (GTK_BOX (vbox60), check_intc_sync_hack, FALSE, FALSE, 0); - - label101 = gtk_label_new (_("Huge speedup in many games, and a pretty high compatibility rate (some games still work better with EE sync hacks).")); - gtk_widget_set_name (label101, "label101"); - gtk_widget_show (label101); - gtk_box_pack_start (GTK_BOX (vbox60), label101, FALSE, FALSE, 0); - gtk_label_set_line_wrap (GTK_LABEL (label101), TRUE); - - vbox71 = gtk_vbox_new (FALSE, 0); - gtk_widget_set_name (vbox71, "vbox71"); - gtk_widget_show (vbox71); - gtk_box_pack_start (GTK_BOX (vbox60), vbox71, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox76), check_intc_sync_hack, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, check_intc_sync_hack, _("Huge speedup in many games, and a pretty high compatibility rate (some games still work better with EE sync hacks)."), NULL); check_idle_loop_fastforward = gtk_check_button_new_with_mnemonic (_("Idle Loop Fast-Forward (experimental)")); gtk_widget_set_name (check_idle_loop_fastforward, "check_idle_loop_fastforward"); gtk_widget_show (check_idle_loop_fastforward); - gtk_box_pack_start (GTK_BOX (vbox71), check_idle_loop_fastforward, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox76), check_idle_loop_fastforward, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, check_idle_loop_fastforward, _("Speedup for a few games, including FFX with no known side effects."), NULL); - label110 = gtk_label_new (_("Speedup for a few games, including FFX with no known side effects. More later.")); - gtk_widget_set_name (label110, "label110"); - gtk_widget_show (label110); - gtk_box_pack_start (GTK_BOX (vbox71), label110, FALSE, FALSE, 0); - gtk_label_set_line_wrap (GTK_LABEL (label110), TRUE); + label114 = gtk_label_new (_("Misc Hacks")); + gtk_widget_set_name (label114, "label114"); + gtk_widget_show (label114); + gtk_frame_set_label_widget (GTK_FRAME (frame42), label114); + gtk_label_set_use_markup (GTK_LABEL (label114), TRUE); - hseparator1 = gtk_hseparator_new (); - gtk_widget_set_name (hseparator1, "hseparator1"); - gtk_widget_show (hseparator1); - gtk_box_pack_start (GTK_BOX (vbox60), hseparator1, FALSE, FALSE, 0); + frame41 = gtk_frame_new (NULL); + gtk_widget_set_name (frame41, "frame41"); + gtk_widget_show (frame41); + gtk_box_pack_start (GTK_BOX (vbox60), frame41, FALSE, FALSE, 0); + + alignment36 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_set_name (alignment36, "alignment36"); + gtk_widget_show (alignment36); + gtk_container_add (GTK_CONTAINER (frame41), alignment36); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment36), 0, 0, 12, 0); + + vbox75 = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (vbox75, "vbox75"); + gtk_widget_show (vbox75); + gtk_container_add (GTK_CONTAINER (alignment36), vbox75); + + check_microvu_flag_hack = gtk_check_button_new_with_mnemonic (_("Status Flag Hack (microVU only)")); + gtk_widget_set_name (check_microvu_flag_hack, "check_microvu_flag_hack"); + gtk_widget_show (check_microvu_flag_hack); + gtk_box_pack_start (GTK_BOX (vbox75), check_microvu_flag_hack, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, check_microvu_flag_hack, _("Big Speedup and high compatiblity. SuperVU does something similar by default."), NULL); + + check_microvu_min_max_hack = gtk_check_button_new_with_mnemonic (_("Min / Max Hack (microVU only)")); + gtk_widget_set_name (check_microvu_min_max_hack, "check_microvu_min_max_hack"); + gtk_widget_show (check_microvu_min_max_hack); + gtk_box_pack_start (GTK_BOX (vbox75), check_microvu_min_max_hack, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, check_microvu_min_max_hack, _("Small Speedup. May cause SPS, hanging, graphical corruption, and missing geometry."), NULL); + + label113 = gtk_label_new (_("Vertex Unit (VU) Hacks")); + gtk_widget_set_name (label113, "label113"); + gtk_widget_show (label113); + gtk_frame_set_label_widget (GTK_FRAME (frame41), label113); + gtk_label_set_use_markup (GTK_LABEL (label113), TRUE); dialog_action_area3 = GTK_DIALOG (SpeedHacksDlg)->action_area; gtk_widget_set_name (dialog_action_area3, "dialog_action_area3"); @@ -831,6 +867,9 @@ create_SpeedHacksDlg (void) gtk_dialog_add_action_widget (GTK_DIALOG (SpeedHacksDlg), button98, GTK_RESPONSE_CANCEL); GTK_WIDGET_SET_FLAGS (button98, GTK_CAN_DEFAULT); + g_signal_connect ((gpointer) SpeedHacksDlg, "close", + G_CALLBACK (On_Dialog_Close), + NULL); g_signal_connect ((gpointer) EECycleHackScale, "value_changed", G_CALLBACK (on_ee_slider_changed), NULL); @@ -866,19 +905,24 @@ create_SpeedHacksDlg (void) GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vu_cycle_stealing_label, "vu_cycle_stealing_label"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label111, "label111"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox60, "vbox60"); + GLADE_HOOKUP_OBJECT (SpeedHacksDlg, frame42, "frame42"); + GLADE_HOOKUP_OBJECT (SpeedHacksDlg, alignment37, "alignment37"); + GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox76, "vbox76"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_iop_cycle_rate, "check_iop_cycle_rate"); - GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label96, "label96"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_wait_cycles_sync_hack, "check_wait_cycles_sync_hack"); - GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label97, "label97"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_intc_sync_hack, "check_intc_sync_hack"); - GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label101, "label101"); - GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox71, "vbox71"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_idle_loop_fastforward, "check_idle_loop_fastforward"); - GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label110, "label110"); - GLADE_HOOKUP_OBJECT (SpeedHacksDlg, hseparator1, "hseparator1"); + GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label114, "label114"); + GLADE_HOOKUP_OBJECT (SpeedHacksDlg, frame41, "frame41"); + GLADE_HOOKUP_OBJECT (SpeedHacksDlg, alignment36, "alignment36"); + GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox75, "vbox75"); + GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_microvu_flag_hack, "check_microvu_flag_hack"); + GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_microvu_min_max_hack, "check_microvu_min_max_hack"); + GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label113, "label113"); GLADE_HOOKUP_OBJECT_NO_REF (SpeedHacksDlg, dialog_action_area3, "dialog_action_area3"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, button99, "button99"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, button98, "button98"); + GLADE_HOOKUP_OBJECT_NO_REF (SpeedHacksDlg, tooltips, "tooltips"); return SpeedHacksDlg; } @@ -895,6 +939,8 @@ create_GameFixDlg (void) GtkWidget *check_VU_Add_Sub; GtkWidget *check_FPU_Mul; GtkWidget *check_VU_Clip; + GtkWidget *check_DMAExec; + GtkWidget *check_XGKick; GtkWidget *label42; GtkWidget *dialog_action_area1; GtkWidget *cancelbutton1; @@ -946,6 +992,16 @@ create_GameFixDlg (void) gtk_widget_show (check_VU_Clip); gtk_box_pack_start (GTK_BOX (vbox30), check_VU_Clip, FALSE, FALSE, 0); + check_DMAExec = gtk_check_button_new_with_mnemonic (_("DMAExec Hack - Fixes Fatal Frame, possibly others.\nCauses freezing in Gust games and crashing in some TriAce games")); + gtk_widget_set_name (check_DMAExec, "check_DMAExec"); + gtk_widget_show (check_DMAExec); + gtk_box_pack_start (GTK_BOX (vbox30), check_DMAExec, FALSE, FALSE, 0); + + check_XGKick = gtk_check_button_new_with_mnemonic (_("VU XGkick Hack - Fix for Erementar Gerad. \nAdds more delay to VU XGkick instructions. Corrects the color of some graphics.")); + gtk_widget_set_name (check_XGKick, "check_XGKick"); + gtk_widget_show (check_XGKick); + gtk_box_pack_start (GTK_BOX (vbox30), check_XGKick, FALSE, FALSE, 0); + label42 = gtk_label_new (_("Some games need special settings.\nConfigure them here.")); gtk_widget_set_name (label42, "label42"); gtk_widget_show (label42); @@ -969,6 +1025,9 @@ create_GameFixDlg (void) gtk_dialog_add_action_widget (GTK_DIALOG (GameFixDlg), button83, GTK_RESPONSE_CANCEL); GTK_WIDGET_SET_FLAGS (button83, GTK_CAN_DEFAULT); + g_signal_connect ((gpointer) GameFixDlg, "close", + G_CALLBACK (On_Dialog_Close), + NULL); g_signal_connect ((gpointer) cancelbutton1, "clicked", G_CALLBACK (on_Game_Fix_OK), NULL); @@ -986,6 +1045,8 @@ create_GameFixDlg (void) GLADE_HOOKUP_OBJECT (GameFixDlg, check_VU_Add_Sub, "check_VU_Add_Sub"); GLADE_HOOKUP_OBJECT (GameFixDlg, check_FPU_Mul, "check_FPU_Mul"); GLADE_HOOKUP_OBJECT (GameFixDlg, check_VU_Clip, "check_VU_Clip"); + GLADE_HOOKUP_OBJECT (GameFixDlg, check_DMAExec, "check_DMAExec"); + GLADE_HOOKUP_OBJECT (GameFixDlg, check_XGKick, "check_XGKick"); GLADE_HOOKUP_OBJECT (GameFixDlg, label42, "label42"); GLADE_HOOKUP_OBJECT_NO_REF (GameFixDlg, dialog_action_area1, "dialog_action_area1"); GLADE_HOOKUP_OBJECT (GameFixDlg, cancelbutton1, "cancelbutton1"); @@ -2036,7 +2097,7 @@ create_ConfDlg (void) GtkWidget *hbuttonbox24; GtkWidget *GtkButton_FWconfigure; GtkWidget *GtkButton_FWtest; - GtkWidget *GtkButton_FireWireabout; + GtkWidget *GtkButton_FWabout; GtkWidget *label30; GtkWidget *GtkLabel_Bios; GtkWidget *hbox5; @@ -2385,11 +2446,11 @@ create_ConfDlg (void) gtk_container_add (GTK_CONTAINER (hbuttonbox24), GtkButton_FWtest); GTK_WIDGET_SET_FLAGS (GtkButton_FWtest, GTK_CAN_DEFAULT); - GtkButton_FireWireabout = gtk_button_new_with_mnemonic (_("About")); - gtk_widget_set_name (GtkButton_FireWireabout, "GtkButton_FireWireabout"); - gtk_widget_show (GtkButton_FireWireabout); - gtk_container_add (GTK_CONTAINER (hbuttonbox24), GtkButton_FireWireabout); - GTK_WIDGET_SET_FLAGS (GtkButton_FireWireabout, GTK_CAN_DEFAULT); + GtkButton_FWabout = gtk_button_new_with_mnemonic (_("About")); + gtk_widget_set_name (GtkButton_FWabout, "GtkButton_FWabout"); + gtk_widget_show (GtkButton_FWabout); + gtk_container_add (GTK_CONTAINER (hbuttonbox24), GtkButton_FWabout); + GTK_WIDGET_SET_FLAGS (GtkButton_FWabout, GTK_CAN_DEFAULT); label30 = gtk_label_new (_("FireWire")); gtk_widget_set_name (label30, "label30"); @@ -2518,7 +2579,7 @@ create_ConfDlg (void) g_signal_connect ((gpointer) GtkButton_FWtest, "clicked", G_CALLBACK (OnConfButton), NULL); - g_signal_connect ((gpointer) GtkButton_FireWireabout, "clicked", + g_signal_connect ((gpointer) GtkButton_FWabout, "clicked", G_CALLBACK (OnConfButton), NULL); g_signal_connect ((gpointer) GtkButton_SelectPluginsDir, "clicked", @@ -2585,7 +2646,7 @@ create_ConfDlg (void) GLADE_HOOKUP_OBJECT (ConfDlg, hbuttonbox24, "hbuttonbox24"); GLADE_HOOKUP_OBJECT (ConfDlg, GtkButton_FWconfigure, "GtkButton_FWconfigure"); GLADE_HOOKUP_OBJECT (ConfDlg, GtkButton_FWtest, "GtkButton_FWtest"); - GLADE_HOOKUP_OBJECT (ConfDlg, GtkButton_FireWireabout, "GtkButton_FireWireabout"); + GLADE_HOOKUP_OBJECT (ConfDlg, GtkButton_FWabout, "GtkButton_FWabout"); GLADE_HOOKUP_OBJECT (ConfDlg, label30, "label30"); GLADE_HOOKUP_OBJECT (ConfDlg, GtkLabel_Bios, "GtkLabel_Bios"); GLADE_HOOKUP_OBJECT (ConfDlg, hbox5, "hbox5"); @@ -3850,6 +3911,12 @@ create_CpuDlg (void) GtkWidget *GtkCheckButton_VU0rec; GtkWidget *GtkCheckButton_VU1rec; GtkWidget *label32; + GtkWidget *frame40; + GtkWidget *alignment35; + GtkWidget *vbox74; + GtkWidget *GtkCheckButton_microVU0rec; + GtkWidget *GtkCheckButton_microVU1rec; + GtkWidget *label112; GtkWidget *GtkCheckButton_MTGS; GtkWidget *vbox48; GtkWidget *frame9; @@ -3965,21 +4032,54 @@ create_CpuDlg (void) gtk_container_add (GTK_CONTAINER (frame6), vbox26); gtk_container_set_border_width (GTK_CONTAINER (vbox26), 5); - GtkCheckButton_VU0rec = gtk_check_button_new_with_mnemonic (_("VU0rec - enable recompiler for VU0 unit")); + GtkCheckButton_VU0rec = gtk_check_button_new_with_mnemonic (_("VU0rec - enable recompilers for VU0 unit")); gtk_widget_set_name (GtkCheckButton_VU0rec, "GtkCheckButton_VU0rec"); gtk_widget_show (GtkCheckButton_VU0rec); gtk_box_pack_start (GTK_BOX (vbox26), GtkCheckButton_VU0rec, FALSE, FALSE, 0); - GtkCheckButton_VU1rec = gtk_check_button_new_with_mnemonic (_("VU1rec - enable recompiler for VU1 unit")); + GtkCheckButton_VU1rec = gtk_check_button_new_with_mnemonic (_("VU1rec - enable recompilers for VU1 unit")); gtk_widget_set_name (GtkCheckButton_VU1rec, "GtkCheckButton_VU1rec"); gtk_widget_show (GtkCheckButton_VU1rec); gtk_box_pack_start (GTK_BOX (vbox26), GtkCheckButton_VU1rec, FALSE, FALSE, 0); - label32 = gtk_label_new (_("VU Recompilers - All options are set by default")); + label32 = gtk_label_new (_("VU Recompilers")); gtk_widget_set_name (label32, "label32"); gtk_widget_show (label32); gtk_frame_set_label_widget (GTK_FRAME (frame6), label32); + frame40 = gtk_frame_new (NULL); + gtk_widget_set_name (frame40, "frame40"); + gtk_widget_show (frame40); + gtk_box_pack_start (GTK_BOX (vbox47), frame40, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame40), 5); + + alignment35 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_set_name (alignment35, "alignment35"); + gtk_widget_show (alignment35); + gtk_container_add (GTK_CONTAINER (frame40), alignment35); + gtk_container_set_border_width (GTK_CONTAINER (alignment35), 5); + + vbox74 = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (vbox74, "vbox74"); + gtk_widget_show (vbox74); + gtk_container_add (GTK_CONTAINER (alignment35), vbox74); + + GtkCheckButton_microVU0rec = gtk_check_button_new_with_mnemonic (_("microVU0 - Use microVU rec instead of VU0rec. ! Beta !")); + gtk_widget_set_name (GtkCheckButton_microVU0rec, "GtkCheckButton_microVU0rec"); + gtk_widget_show (GtkCheckButton_microVU0rec); + gtk_box_pack_start (GTK_BOX (vbox74), GtkCheckButton_microVU0rec, FALSE, FALSE, 0); + + GtkCheckButton_microVU1rec = gtk_check_button_new_with_mnemonic (_("microVU1 - Use microVU rec instead of VU1rec. ! Beta !")); + gtk_widget_set_name (GtkCheckButton_microVU1rec, "GtkCheckButton_microVU1rec"); + gtk_widget_show (GtkCheckButton_microVU1rec); + gtk_box_pack_start (GTK_BOX (vbox74), GtkCheckButton_microVU1rec, FALSE, FALSE, 0); + + label112 = gtk_label_new (_("microVU Recompilers - ! Beta !")); + gtk_widget_set_name (label112, "label112"); + gtk_widget_show (label112); + gtk_frame_set_label_widget (GTK_FRAME (frame40), label112); + gtk_label_set_use_markup (GTK_LABEL (label112), TRUE); + GtkCheckButton_MTGS = gtk_check_button_new_with_mnemonic (_("Multi threaded GS mode (MTGS)\n (faster on dual core/HT CPUs, requires pcsx2 restart)")); gtk_widget_set_name (GtkCheckButton_MTGS, "GtkCheckButton_MTGS"); gtk_widget_show (GtkCheckButton_MTGS); @@ -4156,6 +4256,21 @@ create_CpuDlg (void) gtk_dialog_add_action_widget (GTK_DIALOG (CpuDlg), button97, 0); GTK_WIDGET_SET_FLAGS (button97, GTK_CAN_DEFAULT); + g_signal_connect ((gpointer) CpuDlg, "close", + G_CALLBACK (On_Dialog_Close), + NULL); + g_signal_connect ((gpointer) GtkCheckButton_VU0rec, "toggled", + G_CALLBACK (OnCpuCheckToggled), + NULL); + g_signal_connect ((gpointer) GtkCheckButton_VU1rec, "toggled", + G_CALLBACK (OnCpuCheckToggled), + NULL); + g_signal_connect ((gpointer) GtkCheckButton_microVU0rec, "toggled", + G_CALLBACK (OnCpuCheckToggled), + NULL); + g_signal_connect ((gpointer) GtkCheckButton_microVU1rec, "toggled", + G_CALLBACK (OnCpuCheckToggled), + NULL); g_signal_connect ((gpointer) button96, "clicked", G_CALLBACK (OnCpu_Ok), NULL); @@ -4182,6 +4297,12 @@ create_CpuDlg (void) GLADE_HOOKUP_OBJECT (CpuDlg, GtkCheckButton_VU0rec, "GtkCheckButton_VU0rec"); GLADE_HOOKUP_OBJECT (CpuDlg, GtkCheckButton_VU1rec, "GtkCheckButton_VU1rec"); GLADE_HOOKUP_OBJECT (CpuDlg, label32, "label32"); + GLADE_HOOKUP_OBJECT (CpuDlg, frame40, "frame40"); + GLADE_HOOKUP_OBJECT (CpuDlg, alignment35, "alignment35"); + GLADE_HOOKUP_OBJECT (CpuDlg, vbox74, "vbox74"); + GLADE_HOOKUP_OBJECT (CpuDlg, GtkCheckButton_microVU0rec, "GtkCheckButton_microVU0rec"); + GLADE_HOOKUP_OBJECT (CpuDlg, GtkCheckButton_microVU1rec, "GtkCheckButton_microVU1rec"); + GLADE_HOOKUP_OBJECT (CpuDlg, label112, "label112"); GLADE_HOOKUP_OBJECT (CpuDlg, GtkCheckButton_MTGS, "GtkCheckButton_MTGS"); GLADE_HOOKUP_OBJECT (CpuDlg, vbox48, "vbox48"); GLADE_HOOKUP_OBJECT (CpuDlg, frame9, "frame9"); @@ -4521,6 +4642,9 @@ create_Logging (void) gtk_dialog_add_action_widget (GTK_DIALOG (Logging), Logging2Cancel, GTK_RESPONSE_CANCEL); GTK_WIDGET_SET_FLAGS (Logging2Cancel, GTK_CAN_DEFAULT); + g_signal_connect ((gpointer) Logging, "close", + G_CALLBACK (On_Dialog_Close), + NULL); g_signal_connect ((gpointer) Logging_Ok, "clicked", G_CALLBACK (OnLogging_Ok), NULL); @@ -4747,6 +4871,9 @@ create_MemDlg (void) gtk_dialog_add_action_widget (GTK_DIALOG (MemDlg), okbutton1, GTK_RESPONSE_CANCEL); GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT); + g_signal_connect ((gpointer) MemDlg, "close", + G_CALLBACK (On_Dialog_Close), + NULL); g_signal_connect ((gpointer) memcardcancelbutton, "clicked", G_CALLBACK (OnMemcards_Ok), NULL); diff --git a/pcsx2/Linux/pcsx2.glade b/pcsx2/Linux/pcsx2.glade index bb90d59e3d..841d42da45 100644 --- a/pcsx2/Linux/pcsx2.glade +++ b/pcsx2/Linux/pcsx2.glade @@ -19,6 +19,7 @@ True False True + @@ -1188,6 +1189,7 @@ Denormals are Zero - Your CPU makes Floating Point Denormals become Zero, so it True False True + @@ -1392,7 +1394,7 @@ If you have problems, Disable all of these and try again. True - <b>EmotionEngine (EE) Sync Hacks</b> + EmotionEngine (EE) Sync Hacks False True GTK_JUSTIFY_LEFT @@ -1495,7 +1497,7 @@ If you have problems, Disable all of these and try again. True - <b>VU Cycle Stealing (Speedup for 3d geometry)</b> + VU Cycle Stealing (Speedup for 3d geometry) False True GTK_JUSTIFY_LEFT @@ -1536,172 +1538,122 @@ If you have problems, Disable all of these and try again. 0 - + True - True - Enable IOP x2 Cycle Rate - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - Small speedup, and works well with most games, - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - check_iop_cycle_rate - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - WaitCycles Sync Hack - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - Small speedup. Works well with most games, but it may cause certain games to crash, or freeze up during bootup or stage changes. - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - check_wait_cycles_sync_hack - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - INTC Sync Hack - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - Huge speedup in many games, and a pretty high compatibility rate (some games still work better with EE sync hacks). - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - False - 0 + 0 + 0.5 + GTK_SHADOW_ETCHED_IN - + True - True - Idle Loop Fast-Forward (experimental) - True - GTK_RELIEF_NORMAL - True - False - False - True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + True + Small speedup, and works well with most games. + True + Enable IOP x2 Cycle Rate + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + + + + + True + Small speedup. Works well with most games, but it may cause certain games to crash, or freeze up during bootup or stage changes. + True + WaitCycles Sync Hack + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + + + + + True + Huge speedup in many games, and a pretty high compatibility rate (some games still work better with EE sync hacks). + True + INTC Sync Hack + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + + + + + True + Speedup for a few games, including FFX with no known side effects. + True + Idle Loop Fast-Forward (experimental) + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + + + - - 0 - False - False - - + True - Speedup for a few games, including FFX with no known side effects. More later. + Misc Hacks False - False + True GTK_JUSTIFY_LEFT - True + False False 0.5 0.5 @@ -1713,22 +1665,108 @@ If you have problems, Disable all of these and try again. 0 - 0 - False - False + label_item 0 - True - True + False + False - + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + True + Big Speedup and high compatiblity. SuperVU does something similar by default. + True + Status Flag Hack (microVU only) + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + + + + + True + Small Speedup. May cause SPS, hanging, graphical corruption, and missing geometry. + True + Min / Max Hack (microVU only) + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + + + + + + + + + True + Vertex Unit (VU) Hacks + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + 0 @@ -1777,6 +1815,7 @@ If you have problems, Disable all of these and try again. True False True + @@ -1925,6 +1964,46 @@ If you have problems, Disable all of these and try again. False + + + + True + True + DMAExec Hack - Fixes Fatal Frame, possibly others. +Causes freezing in Gust games and crashing in some TriAce games + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + + + + + True + True + VU XGkick Hack - Fix for Erementar Gerad. +Adds more delay to VU XGkick instructions. Corrects the color of some graphics. + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + @@ -4413,7 +4492,7 @@ Configure them here.</b> - + True True True @@ -6418,6 +6497,7 @@ Version x.x True False True + @@ -6675,13 +6755,14 @@ Version x.x True True - VU0rec - enable recompiler for VU0 unit + VU0rec - enable recompilers for VU0 unit True GTK_RELIEF_NORMAL True False False True + 0 @@ -6694,13 +6775,14 @@ Version x.x True True - VU1rec - enable recompiler for VU1 unit + VU1rec - enable recompilers for VU1 unit True GTK_RELIEF_NORMAL True False False True + 0 @@ -6714,7 +6796,7 @@ Version x.x True - VU Recompilers - All options are set by default + VU Recompilers False False GTK_JUSTIFY_LEFT @@ -6741,6 +6823,107 @@ Version x.x + + + 5 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + 5 + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 0 + 0 + + + + True + False + 0 + + + + True + True + microVU0 - Use microVU rec instead of VU0rec. ! Beta ! + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + False + False + + + + + + True + True + microVU1 - Use microVU rec instead of VU1rec. ! Beta ! + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + False + False + + + + + + + + + + True + microVU Recompilers - ! Beta ! + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + False + False + + + True @@ -7295,6 +7478,7 @@ Version x.x True False True + @@ -8102,6 +8286,7 @@ Version x.x True False True + diff --git a/pcsx2/MMI.cpp b/pcsx2/MMI.cpp index 448c1bacff..1dfbf605d3 100644 --- a/pcsx2/MMI.cpp +++ b/pcsx2/MMI.cpp @@ -181,7 +181,7 @@ __forceinline void PMFHL_CLAMP(u16 dst, u16 src) { if ((int)src > (int)0x00007fff) dst = 0x7fff; - else if ((int)src < (int)0xffff8000) + else if ((int)src < (int)0xffff8000) // Ints only go up to 0x7FFFFFFF. Something's not right here. --arcum42 dst = 0x8000; else dst = (u16)src; diff --git a/pcsx2/MTGS.cpp b/pcsx2/MTGS.cpp index 72d3223137..89b7516c61 100644 --- a/pcsx2/MTGS.cpp +++ b/pcsx2/MTGS.cpp @@ -32,10 +32,6 @@ // Uncomment this to enable profiling of the GS RingBufferCopy function. //#define PCSX2_GSRING_SAMPLING_STATS -#ifdef PCSX2_GSRING_TX_STATS -#include -#endif - using namespace Threading; using namespace std; @@ -137,27 +133,32 @@ void SaveState::mtgsFreeze() static void RegHandlerSIGNAL(const u32* data) { - MTGS_LOG("MTGS SIGNAL data %x_%x CSRw %x\n",data[0], data[1], CSRw); + MTGS_LOG("MTGS SIGNAL data %x_%x CSRw %x IMR %x CSRr\n",data[0], data[1], CSRw, GSIMR, GSCSRr); GSSIGLBLID->SIGID = (GSSIGLBLID->SIGID&~data[1])|(data[0]&data[1]); - if ((CSRw & 0x1)) + if ((CSRw & 0x1)) + { + if (!(GSIMR&0x100) ) + { + gsIrq(); + } + GSCSRr |= 1; // signal - - if (!(GSIMR&0x100) ) - gsIrq(); + } } static void RegHandlerFINISH(const u32* data) { - MTGS_LOG("MTGS FINISH data %x_%x CSRw %x\n",data[0], data[1], CSRw); + MTGS_LOG("MTGS FINISH data %x_%x CSRw %x\n", params data[0], data[1], CSRw); + + if ((CSRw & 0x2)) + { + if (!(GSIMR&0x200)) + gsIrq(); - if ((CSRw & 0x2)) GSCSRr |= 2; // finish - - if (!(GSIMR&0x200) ) - gsIrq(); - + } } static void RegHandlerLABEL(const u32* data) @@ -178,7 +179,7 @@ mtgsThreadObject* mtgsThread = NULL; std::list ringposStack; #endif -#ifdef _DEBUG +#ifdef PCSX2_DEBUG // debug variable used to check for bad code bits where copies are started // but never closed, or closed without having been started. (GSRingBufCopy calls // should always be followed by a call to GSRINGBUF_DONECOPY) @@ -259,10 +260,11 @@ void mtgsThreadObject::Reset() // Used to keep interrupts in sync with the EE, while the GS itself // runs potentially several frames behind. // size - size of the packet in simd128's -__forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u8* pMem, u32 size ) +__forceinline int mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u8* pMem, u32 size ) { GIFPath& path = m_path[pathidx]; - + /* bool path1loop = false; + int startval = size;*/ #ifdef PCSX2_GSRING_SAMPLING_STATS static uptr profStartPtr = 0; static uptr profEndPtr = 0; @@ -280,23 +282,42 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u while(size > 0) { - bool eop = false; - - if(path.tag.nloop == 0) + if (path.tag.nloop == 0) { path.SetTag( pMem ); pMem += sizeof(GIFTAG); --size; - if(pathidx == 2 && path.tag.eop) - Path3transfer = FALSE; + if (pathidx == 2) + { + if (path.tag.flg != GIF_FLG_IMAGE) + Path3progress = TRANSFER_MODE; //Other mode (but not stopped, I guess?) + else + Path3progress = IMAGE_MODE; //IMAGE mode + //if(pathidx == 2) GIF_LOG("Set Giftag NLoop %d EOP %x Mode %d Path3msk %x Path3progress %x ", path.tag.nloop, path.tag.eop, path.tag.flg, vif1Regs->mskpath3, Path3progress); + } - if( pathidx == 0 ) - { + if (pathidx == 0) + { + // int transize = 0; // hack: if too much data for VU1, just ignore. // The GIF is evil : if nreg is 0, it's really 16. Otherwise it's the value in nreg. + /*const int numregs = path.tag.nreg ? path.tag.nreg : 16; + if(path.tag.flg < 2) + { + transize = (path.tag.nloop * numregs); + } + else transize = path.tag.nloop; + + if(transize > (path.tag.flg == 1 ? 0x800 : 0x400)) + { + //DevCon::Notice("Too much data"); + path.tag.nloop = 0; + if(path1loop == true)return ++size - 0x400; + else return ++size; + }*/ const int numregs = ((path.tag.nreg-1)&15)+1; if((path.tag.nloop * numregs) > (size * ((path.tag.flg == 1) ? 2 : 1))) @@ -305,42 +326,17 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u return ++size; } } - - - /*f(path.tag.pre) - { - assert(path.tag.flg != GIF_FLG_IMAGE); // kingdom hearts, ffxii, tales of abyss - - if((path.tag.flg & 2) == 0) - { - // Primitive handler... Nothing for the Dummy to do here. - - //GIFReg r; - //r.i64 = path.tag.PRIM; - //(this->*m_fpGIFRegHandlers[GIF_A_D_REG_PRIM])(&r); - } - }*/ - - if(path.tag.eop) - { - eop = true; - } - else if(path.tag.nloop == 0) - { - if(pathidx == 0) - continue; - - eop = true; - } } - - if(path.tag.nloop > 0) + else { + // NOTE: size > 0 => do {} while(size > 0); should be faster than while(size > 0) {} + + //if(pathidx == 2) GIF_LOG("PATH3 NLoop %d EOP %x Mode %d Path3msk %x Path3progress %x ", path.tag.nloop, path.tag.eop, path.tag.flg, vif1Regs->mskpath3, Path3progress); switch(path.tag.flg) { case GIF_FLG_PACKED: - while(size > 0) + do { if( path.GetReg() == 0xe ) { @@ -348,25 +344,19 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u if(handler >= 0x60 && handler < 0x63) s_GSHandlers[handler&0x3]((const u32*)pMem); } + size--; pMem += 16; // 128 bits! //sizeof(GIFPackedReg); - - if((++path.curreg & 0xf) == path.tag.nreg) - { - path.curreg = 0; - path.tag.nloop--; - - if(path.tag.nloop == 0) - break; - } } + while(path.StepReg() && size > 0); + break; case GIF_FLG_REGLIST: size *= 2; - while(size > 0) + do { const int handler = path.GetReg(); if(handler >= 0x60 && handler < 0x63) @@ -374,20 +364,11 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u size--; pMem += 8; //sizeof(GIFReg); -- 64 bits! - - if((++path.curreg & 0xf) == path.tag.nreg) - { - path.curreg = 0; - path.tag.nloop--; - - if(path.tag.nloop == 0) - { - break; - } - } } + while(path.StepReg() && size > 0); if(size & 1) pMem += 8; //sizeof(GIFReg); + size /= 2; break; @@ -412,16 +393,51 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u } } - - if(eop && ((int)size <= 0 || pathidx == 0)) + + if(path.tag.nloop == 0) { - break; - } + if(path.tag.eop) + { + if(pathidx != 1) + { + break; + } + /*if((path.tag.nloop > 0 || (!path.tag.eop && path.tag.nloop == 0)) && size == 0) + { + if(path1loop == true) return size - 0x400; + //DevCon::Notice("Looping Nloop %x, Eop %x, FLG %x", params path.tag.nloop, path.tag.eop, path.tag.flg); + size = 0x400; + pMem -= 0x4000; + path1loop = true; + }*/ + } + /*else if(size == 0 && pathidx == 0) + { + if(path1loop == true) return size - 0x400; + //DevCon::Notice("Looping Nloop %x, Eop %x, FLG %x", params path.tag.nloop, path.tag.eop, path.tag.flg); + size = 0x400; + pMem -= 0x4000; + path1loop = true; + }*/ + } + /*else if(size == 0 && pathidx == 0) + { + if(path1loop == true) return size - 0x400; + //DevCon::Notice("Looping Nloop %x, Eop %x, FLG %x", params path.tag.nloop, path.tag.eop, path.tag.flg); + size = 0x400; + pMem -= 0x4000; + path1loop = true; + }*/ } if(pathidx == 0) { - if(!path.tag.eop && path.tag.nloop > 0) + //If the XGKick has spun around the VU memory end address, we need to INCREASE the size sent. + /*if(path1loop == true) + { + return (size - 0x400); //This will cause a negative making eg. size(20) - retval(-30) = 50; + }*/ + if(size == 0 && path.tag.nloop > 0) { path.tag.nloop = 0; DevCon::Write( "path1 hack! " ); @@ -430,6 +446,23 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u // along the way (often means curreg was in a bad state or something) } } + + + if(pathidx == 2) + { + if(path.tag.nloop == 0 ) + { + //DevCon::Notice("Finishing Giftag NLoop %d EOP %x Mode %d nregs %d Path3progress %d Vifstat VGW %x", + //params path.tag.nloop, path.tag.eop, path.tag.flg, path.tag.nreg, Path3progress, vif1Regs->stat & VIF1_STAT_VGW); + if(path.tag.eop) + { + Path3progress = STOPPED_MODE; + //GIF_LOG("Set progress NLoop %d EOP %x Mode %d Path3msk %x Path3progress %x ", path.tag.nloop, path.tag.eop, path.tag.flg, vif1Regs->mskpath3, Path3progress); + } + + } + + } #ifdef PCSX2_GSRING_SAMPLING_STATS __asm { @@ -482,7 +515,7 @@ int mtgsThreadObject::Callback() { Console::WriteLn("MTGS > Thread Started, Opening GS Plugin..."); - memcpy_aligned( m_gsMem, PS2MEM_GS, sizeof(m_gsMem) ); + memcpy_aligned( m_gsMem, PS2MEM_GS, sizeof(PS2MEM_GS) ); GSsetBaseMem( m_gsMem ); GSirqCallback( NULL ); @@ -497,7 +530,7 @@ int mtgsThreadObject::Callback() Console::WriteLn( "MTGS > GSopen Finished, return code: 0x%x", params m_returncode ); - GSCSRr = 0x551B400F; // 0x55190000 + GSCSRr = 0x551B4000; // 0x55190000 m_post_InitDone.Post(); if (m_returncode != 0) { return m_returncode; } // error msg will be issued to the user by Plugins.c @@ -551,8 +584,8 @@ int mtgsThreadObject::Callback() const u128* data = m_RingBuffer.GetPtr( m_RingPos+1 ); // make sure that tag>>16 is the MAX size readable - //GSgifTransfer1(((u32*)data) - 0x1000 + 4*qsize, 0x4000-qsize*16); GSgifTransfer1((u32*)(data - 0x400 + qsize), 0x4000-qsize*16); + //GSgifTransfer1((u32*)data, qsize); ringposinc += qsize; } break; @@ -727,24 +760,25 @@ void mtgsThreadObject::SendDataPacket() jASSUME( temp <= m_RingBufferSize ); temp &= m_RingBufferMask; -#ifdef _DEBUG - if( m_packet_ringpos + m_packet_size < m_RingBufferSize ) + if( IsDebugBuild ) { - uint readpos = volatize(m_RingPos); - if( readpos != m_WritePos ) + if( m_packet_ringpos + m_packet_size < m_RingBufferSize ) { - // The writepos should never leapfrog the readpos - // since that indicates a bad write. - if( m_packet_ringpos < readpos ) - assert( temp < readpos ); - } + uint readpos = volatize(m_RingPos); + if( readpos != m_WritePos ) + { + // The writepos should never leapfrog the readpos + // since that indicates a bad write. + if( m_packet_ringpos < readpos ) + assert( temp < readpos ); + } - // Updating the writepos should never make it equal the readpos, since - // that would stop the buffer prematurely (and indicates bad code in the - // ringbuffer manager) - assert( readpos != temp ); + // Updating the writepos should never make it equal the readpos, since + // that would stop the buffer prematurely (and indicates bad code in the + // ringbuffer manager) + assert( readpos != temp ); + } } -#endif AtomicExchange( m_WritePos, temp ); @@ -807,15 +841,16 @@ static u32 GSRingBufCopySz = 0; int mtgsThreadObject::PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 size ) { #ifdef PCSX2_GSRING_TX_STATS - ringtx_s+=size; - ringtx_s_ulg+=size&0x7F; - ringtx_s_min=min(ringtx_s_min,size); - ringtx_s_max=max(ringtx_s_max,size); + ringtx_s += size; + ringtx_s_ulg += size&0x7F; + ringtx_s_min = min(ringtx_s_min,size); + ringtx_s_max = max(ringtx_s_max,size); ringtx_c++; - unsigned long tx_sz; + u32 tx_sz; + if (_BitScanReverse(&tx_sz,size)) { - unsigned long tx_algn; + u32 tx_algn; _BitScanForward(&tx_algn,size); ringtx_inf[tx_sz][tx_algn]++; ringtx_inf_s[tx_sz]+=size; @@ -875,6 +910,12 @@ int mtgsThreadObject::PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 s // enough room for size - retval: int retval = _gifTransferDummy( pathidx, srcdata, size ); + if(pathidx == 2) + { + gif->madr += (size - retval) * 16; + gif->qwc -= size - retval; + } + //if(retval < 0) DevCon::Notice("Increasing size from %x to %x path %x", params size, size-retval, pathidx+1); size = size - retval; m_packet_size = size; size++; // takes into account our command qword. @@ -1096,7 +1137,7 @@ void mtgsThreadObject::Freeze( SaveState& state ) // this function is needed because of recompiled calls from iGS.cpp // (currently used in GCC only) -void mtgsRingBufSimplePacket( s32 command, u32 data0, u32 data1, u32 data2 ) -{ - mtgsThread->SendSimplePacket( (GS_RINGTYPE)command, data0, data1, data2 ); -} +//void mtgsRingBufSimplePacket( s32 command, u32 data0, u32 data1, u32 data2 ) +//{ +// mtgsThread->SendSimplePacket( (GS_RINGTYPE)command, data0, data1, data2 ); +//} diff --git a/pcsx2/Makefile.am b/pcsx2/Makefile.am deleted file mode 100644 index 3b7e1f8eb9..0000000000 --- a/pcsx2/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -AUTOMAKE_OPTIONS = foreign -INCLUDES = -I@srcdir@/x86/ -I@srcdir@/../common/include -I@srcdir@/../3rdparty $(shell wx-config --cppflags) -noinst_LIBRARIES = libpcsx2.a - -libpcsx2_a_SOURCES = \ -CDVD.cpp CDVDiso.cpp CDVDisodrv.cpp COP0.cpp COP2.cpp Cache.cpp CdRom.cpp Console.cpp HwRead.cpp HwWrite.cpp \ -Counters.cpp Decode_XA.cpp Elfheader.cpp FPU.cpp FPU2.cpp FiFo.cpp Gif.cpp GS.cpp Hw.cpp Interpreter.cpp \ -IopBios.cpp IopCounters.cpp IopDma.cpp IopHw.cpp IopMem.cpp IopSio2.cpp MMI.cpp MTGS.cpp \ -Memory.cpp MemoryCard.cpp Misc.cpp Patch.cpp PathUtils.cpp Plugins.cpp PrecompiledHeader.cpp R3000A.cpp \ -R3000AInterpreter.cpp R3000AOpcodeTables.cpp R5900.cpp R5900OpcodeImpl.cpp R5900OpcodeTables.cpp \ -SPR.cpp SaveState.cpp Sif.cpp Sio.cpp SourceLog.cpp Stats.cpp System.cpp ThreadTools.cpp \ -VU0.cpp VU0micro.cpp VU0microInterp.cpp VU1micro.cpp VU1microInterp.cpp VUflags.cpp VUmicroMem.cpp VUops.cpp \ -Vif.cpp VifDma.cpp vssprintf.cpp vtlb.cpp xmlpatchloader.cpp AlignedMalloc.cpp \ -RecoverySystem.cpp Saveslots.cpp Dump.cpp - -libpcsx2_a_SOURCES += \ -ps2/Iop/IopHwRead.cpp ps2/Iop/IopHwWrite.cpp ps2/Iop/IopHw_Internal.h - -libpcsx2_a_SOURCES += \ -CDVD.h CDVDiso.h CDVDisodrv.h CDVDlib.h COP0.h Cache.h CdRom.h Common.h Counters.h Decode_XA.h \ -Elfheader.h Exceptions.h GS.h Hw.h IopBios.h IopBios2.h IopCounters.h IopDma.h IopHw.h IopMem.h IopSio2.h Memcpyfast.h \ -Memory.h MemoryCard.h Misc.h Patch.h Paths.h Plugins.h PrecompiledHeader.h IopCommon.h R3000A.h R5900.h R5900OpcodeTables.h \ -SPR.h SamplProf.h SaveState.h Sif.h Sifcmd.h Sio.h SafeArray.h Stats.h StringUtils.h System.h Threading.h \ -VU.h VUflags.h VUmicro.h VUops.h Vif.h VifDma.h cheatscpp.h vtlb.h NakedAsm.h R5900Exceptions.h HostGui.h Pcsx2Config.h \ -Dump.h - -SUBDIRS = x86 . DebugTools IPU RDebug tinyxml NewGUI -#Linux \ No newline at end of file diff --git a/pcsx2/Mdec.cpp b/pcsx2/Mdec.cpp index 8a8f84ddf9..c6b5da470b 100644 --- a/pcsx2/Mdec.cpp +++ b/pcsx2/Mdec.cpp @@ -18,6 +18,8 @@ /* This code was based on the FPSE v0.08 Mdec decoder*/ +#ifdef 0 + #include #include @@ -413,7 +415,7 @@ int SaveState::mdecFreeze() { return 0; } - +#endif diff --git a/pcsx2/Mdec.h b/pcsx2/Mdec.h index e54dae3a9e..5e77ec2937 100644 --- a/pcsx2/Mdec.h +++ b/pcsx2/Mdec.h @@ -94,16 +94,16 @@ void psxDma0(u32 madr, u32 bcr, u32 chcr); void psxDma1(u32 madr, u32 bcr, u32 chcr); int mdecFreeze(gzFile f, int Mode); -unsigned short* rl2blk(int *blk,unsigned short *mdec_rl); +u16* rl2blk(int *blk,u16 *mdec_rl); void iqtab_init(int *iqtab,unsigned char *iq_y); void round_init(void); void yuv2rgb24(int *blk,unsigned char *image); -void yuv2rgb15(int *blk,unsigned short *image); +void yuv2rgb15(int *blk,u16 *image); struct { - unsigned long command; - unsigned long status; - unsigned short *rl; + u32 command; + u32 status; + u16 *rl; int rlsize; } mdec; diff --git a/pcsx2/Memory.cpp b/pcsx2/Memory.cpp index 0834481d49..bd3305e343 100644 --- a/pcsx2/Memory.cpp +++ b/pcsx2/Memory.cpp @@ -117,8 +117,6 @@ void loadBiosRom( const wxChar *ext, u8 *dest, long maxSize ) fp.Read( dest, min( maxSize, filesize ) ); } -static u32 psMPWC[(Ps2MemSize::Base/32)>>12]; -static std::vector psMPWVA[Ps2MemSize::Base>>12]; u8 *psM = NULL; //32mb Main Ram u8 *psR = NULL; //4mb rom area @@ -155,6 +153,10 @@ vtlbHandler hw_by_page[0x10]; vtlbHandler gs_page_0; vtlbHandler gs_page_1; +vtlbHandler iopHw_by_page_01; +vtlbHandler iopHw_by_page_03; +vtlbHandler iopHw_by_page_08; + // Used to remap the VUmicro memory according to the VU0/VU1 dynarec setting. // (the VU memory operations are different for recs vs. interpreters) @@ -195,12 +197,6 @@ void memMapPhy() vtlb_MapHandler(tlb_fallback_2,0x1f800000,0x10000); vtlb_MapHandler(tlb_fallback_8,0x1f900000,0x10000); -#ifdef PCSX2_DEVBUILD - // Bind fallback handlers used for logging purposes only. - // In release mode the Vtlb will map these addresses directly instead of using - // the read/write handlers (which just issue logs and do normal memOps) -#endif - // map specific optimized page handlers for HW accesses vtlb_MapHandler(hw_by_page[0x0], 0x10000000, 0x01000); vtlb_MapHandler(hw_by_page[0x1], 0x10001000, 0x01000); @@ -216,6 +212,11 @@ void memMapPhy() vtlb_MapHandler(gs_page_0, 0x12000000, 0x01000); vtlb_MapHandler(gs_page_1, 0x12001000, 0x01000); + + vtlb_MapHandler(hw_by_page[0x1], 0x1f801000, 0x01000); + vtlb_MapHandler(hw_by_page[0x3], 0x1f803000, 0x01000); + vtlb_MapHandler(hw_by_page[0x8], 0x1f808000, 0x01000); + } //Why is this required ? @@ -245,8 +246,6 @@ mem8_t __fastcall _ext_memRead8 (u32 mem) { case 1: // hwm return hwRead8(mem); - case 2: // psh - return psxHwRead8(mem); case 3: // psh4 return psxHw4Read8(mem); case 6: // gsm @@ -301,8 +300,6 @@ mem32_t __fastcall _ext_memRead32(u32 mem) { switch (p) { - case 2: // psh - return psxHwRead32(mem); case 6: // gsm return gsRead32(mem); case 7: // dev9 @@ -348,14 +345,12 @@ void __fastcall _ext_memRead128(u32 mem, mem128_t *out) } template -void __fastcall _ext_memWrite8 (u32 mem, u8 value) +void __fastcall _ext_memWrite8 (u32 mem, mem8_t value) { switch (p) { case 1: // hwm hwWrite8(mem, value); return; - case 2: // psh - psxHwWrite8(mem, value); return; case 3: // psh4 psxHw4Write8(mem, value); return; case 6: // gsm @@ -370,7 +365,7 @@ void __fastcall _ext_memWrite8 (u32 mem, u8 value) cpuTlbMissW(mem, cpuRegs.branch); } template -void __fastcall _ext_memWrite16(u32 mem, u16 value) +void __fastcall _ext_memWrite16(u32 mem, mem16_t value) { switch (p) { case 1: // hwm @@ -395,11 +390,9 @@ void __fastcall _ext_memWrite16(u32 mem, u16 value) } template -void __fastcall _ext_memWrite32(u32 mem, u32 value) +void __fastcall _ext_memWrite32(u32 mem, mem32_t value) { switch (p) { - case 2: // psh - psxHwWrite32(mem, value); return; case 6: // gsm gsWrite32(mem, value); return; case 7: // dev9 @@ -412,7 +405,7 @@ void __fastcall _ext_memWrite32(u32 mem, u32 value) } template -void __fastcall _ext_memWrite64(u32 mem, const u64* value) +void __fastcall _ext_memWrite64(u32 mem, const mem64_t* value) { /*switch (p) { @@ -428,7 +421,7 @@ void __fastcall _ext_memWrite64(u32 mem, const u64* value) } template -void __fastcall _ext_memWrite128(u32 mem, const u64 *value) +void __fastcall _ext_memWrite128(u32 mem, const mem128_t *value) { /*switch (p) { //case 1: // hwm @@ -660,14 +653,13 @@ void memReset() vtlb_Init(); - tlb_fallback_0=vtlb_RegisterHandlerTempl1(_ext_mem,0); - tlb_fallback_2=vtlb_RegisterHandlerTempl1(_ext_mem,2); - tlb_fallback_3=vtlb_RegisterHandlerTempl1(_ext_mem,3); - tlb_fallback_4=vtlb_RegisterHandlerTempl1(_ext_mem,4); - tlb_fallback_5=vtlb_RegisterHandlerTempl1(_ext_mem,5); - //tlb_fallback_6=vtlb_RegisterHandlerTempl1(_ext_mem,6); - tlb_fallback_7=vtlb_RegisterHandlerTempl1(_ext_mem,7); - tlb_fallback_8=vtlb_RegisterHandlerTempl1(_ext_mem,8); + tlb_fallback_0 = vtlb_RegisterHandlerTempl1(_ext_mem,0); + tlb_fallback_3 = vtlb_RegisterHandlerTempl1(_ext_mem,3); + tlb_fallback_4 = vtlb_RegisterHandlerTempl1(_ext_mem,4); + tlb_fallback_5 = vtlb_RegisterHandlerTempl1(_ext_mem,5); + //tlb_fallback_6 = vtlb_RegisterHandlerTempl1(_ext_mem,6); + tlb_fallback_7 = vtlb_RegisterHandlerTempl1(_ext_mem,7); + tlb_fallback_8 = vtlb_RegisterHandlerTempl1(_ext_mem,8); // Dynarec versions of VUs vu0_micro_mem[0] = vtlb_RegisterHandlerTempl2(vuMicro,0,true); @@ -677,7 +669,36 @@ void memReset() vu0_micro_mem[1] = vtlb_RegisterHandlerTempl2(vuMicro,0,false); vu1_micro_mem[1] = vtlb_RegisterHandlerTempl2(vuMicro,1,false); - ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////// + // IOP's "secret" Hardware Register mapping, accessible from the EE (and meant for use + // by debugging or BIOS only). The IOP's hw regs are divided into three main pages in + // the 0x1f80 segment, and then another oddball page for CDVD in the 0x1f40 segment. + // + + using namespace IopMemory; + + tlb_fallback_2 = vtlb_RegisterHandler( + iopHwRead8_generic, iopHwRead16_generic, iopHwRead32_generic, _ext_memRead64<2>, _ext_memRead128<2>, + iopHwWrite8_generic, iopHwWrite16_generic, iopHwWrite32_generic, _ext_memWrite64<2>, _ext_memWrite128<2> + ); + + iopHw_by_page_01 = vtlb_RegisterHandler( + iopHwRead8_Page1, iopHwRead16_Page1, iopHwRead32_Page1, _ext_memRead64<2>, _ext_memRead128<2>, + iopHwWrite8_Page1, iopHwWrite16_Page1, iopHwWrite32_Page1, _ext_memWrite64<2>, _ext_memWrite128<2> + ); + + iopHw_by_page_03 = vtlb_RegisterHandler( + iopHwRead8_Page3, iopHwRead16_Page3, iopHwRead32_Page3, _ext_memRead64<2>, _ext_memRead128<2>, + iopHwWrite8_Page3, iopHwWrite16_Page3, iopHwWrite32_Page3, _ext_memWrite64<2>, _ext_memWrite128<2> + ); + + iopHw_by_page_08 = vtlb_RegisterHandler( + iopHwRead8_Page8, iopHwRead16_Page8, iopHwRead32_Page8, _ext_memRead64<2>, _ext_memRead128<2>, + iopHwWrite8_Page8, iopHwWrite16_Page8, iopHwWrite32_Page8, _ext_memWrite64<2>, _ext_memWrite128<2> + ); + + + ////////////////////////////////////////////////////////////////////////////////////////// // psHw Optimized Mappings // The HW Registers have been split into pages to improve optimization. // Anything not explicitly mapped into one of the hw_by_page handlers will be handled @@ -804,52 +825,122 @@ void memReset() loadBiosRom( L"erom", PS2MEM_EROM, Ps2MemSize::ERom ); } -int mmap_GetRamPageInfo(void* ptr) +////////////////////////////////////////////////////////////////////////////////////////// +// Memory Protection and Block Checking, vtlb Style! +// +// For the first time code is recompiled (executed), the PS2 ram page for that code is +// protected using Virtual Memory (mprotect). If the game modifies its own code then this +// protection causes an *exception* to be raised (signal in Linux), which is handled by +// unprotecting the page and switching the recompiled block to "manual" protection. +// +// Manual protection uses a simple brute-force memcmp of the recompiled code to the code +// currently in RAM for *each time* the block is executed. Fool-proof, but slow, which +// is why we default to using the exception-based protection scheme described above. +// +// Why manual blocks? Because many games contain code and data in the same 4k page, so +// we *cannot* automatically recompile and reprotect pages, lest we end up recompiling and +// reprotecting them constantly (Which would be very slow). As a counter, the R5900 side +// of the block checking code does try to periodically re-protect blocks [going from manual +// back to protected], so that blocks which underwent a single invalidation don't need to +// incur a permanent performance penalty. +// +// Page Granularity: +// Fortunately for us MIPS and x86 use the same page granularity for TLB and memory +// protection, so we can use a 1:1 correspondence when protecting pages. Page granularity +// is 4096 (4k), which is why you'll see a lot of 0xfff's, >><< 12's, and 0x1000's in the +// code below. +// + +enum vtlb_ProtectionMode { - u32 offset=((u8*)ptr-psM); - if (offset>=Ps2MemSize::Base) + ProtMode_None = 0, // page is 'unaccounted' -- neither protected nor unprotected + ProtMode_Write, // page is under write protection (exception handler) + ProtMode_Manual // page is under manual protection (self-checked at execution) +}; + +struct vtlb_PageProtectionInfo +{ + // Ram De-mapping -- used to convert fully translated/mapped offsets into psM back + // into their originating ps2 physical ram address. Values are assigned when pages + // are marked for protection. + u32 ReverseRamMap; + + vtlb_ProtectionMode Mode; +}; + +PCSX2_ALIGNED16( static vtlb_PageProtectionInfo m_PageProtectInfo[Ps2MemSize::Base >> 12] ); + + +// returns: +// -1 - unchecked block (resides in ROM, thus is integrity is constant) +// 0 - page is using Write protection +// 1 - page is using manual protection (recompiler must include execution-time +// self-checking of block integrity) +// +int mmap_GetRamPageInfo( u32 paddr ) +{ + paddr &= ~0xfff; + + uptr ptr = (uptr)PSM( paddr ); + uptr rampage = ptr - (uptr)psM; + + if (rampage >= Ps2MemSize::Base) return -1; //not in ram, no tracking done ... - offset>>=12; - return (psMPWC[(offset/32)]&(1<<(offset&31)))?1:0; + + rampage >>= 12; + return ( m_PageProtectInfo[rampage].Mode == ProtMode_Manual ) ? 1 : 0; } -void mmap_MarkCountedRamPage(void* ptr,u32 vaddr) +// paddr - physically mapped address +void mmap_MarkCountedRamPage( u32 paddr ) { - HostSys::MemProtect( ptr, 1, Protect_ReadOnly ); + paddr &= ~0xfff; - u32 offset=((u8*)ptr-psM); - offset>>=12; - psMPWC[(offset/32)] &= ~(1<<(offset&31)); + uptr ptr = (uptr)PSM( paddr ); + int rampage = (ptr - (uptr)psM) >> 12; - for (u32 i=0;i>12);i++) - { - psMPWVA[i].clear(); - } - HostSys::MemProtect( psM, Ps2MemSize::Base, Protect_ReadWrite ); + // Important: reassign paddr here, since TLB changes could alter the paddr->psM mapping + // (and clear blocks accordingly), but don't necessarily clear the protection status. + m_PageProtectInfo[rampage].ReverseRamMap = paddr; + + if( m_PageProtectInfo[rampage].Mode == ProtMode_Write ) + return; // skip town if we're already protected. + + if( m_PageProtectInfo[rampage].Mode == ProtMode_Manual ) + DbgCon::WriteLn( "dyna_page_reset @ 0x%05x", params paddr>>12 ); + else + DbgCon::WriteLn( "Write-protected page @ 0x%05x", params paddr>>12 ); + + m_PageProtectInfo[rampage].Mode = ProtMode_Write; + HostSys::MemProtect( &psM[rampage<<12], 1, Protect_ReadOnly ); } +// offset - offset of address relative to psM. The exception handler for the platform/host +// OS should ensure that only addresses within psM address space are passed. Anything else +// will produce undefined results (ie, crashes). void mmap_ClearCpuBlock( uint offset ) { - HostSys::MemProtect( &psM[offset], 1, Protect_ReadWrite ); + int rampage = offset >> 12; - offset>>=12; - psMPWC[(offset/32)]|=(1<<(offset&31)); + // Assertion: This function should never be run on a block that's already under + // manual protection. Indicates a logic error in the recompiler or protection code. + jASSUME( m_PageProtectInfo[rampage].Mode != ProtMode_Manual ); - for (u32 i=0;iClear(psMPWVA[offset][i],0x400); - } - psMPWVA[offset].clear(); + //#ifndef __LINUX__ // this function is called from the signal handler + //DbgCon::WriteLn( "Manual page @ 0x%05x", params m_PageProtectInfo[rampage].ReverseRamMap>>12 ); + //#endif + + HostSys::MemProtect( &psM[rampage<<12], 1, Protect_ReadWrite ); + m_PageProtectInfo[rampage].Mode = ProtMode_Manual; + Cpu->Clear( m_PageProtectInfo[rampage].ReverseRamMap, 0x400 ); +} + +// Clears all block tracking statuses, manual protection flags, and write protection. +// This does not clear any recompiler blocks. IT is assumed (and necessary) for the caller +// to ensure the EErec is also reset in conjunction with calling this function. +void mmap_ResetBlockTracking() +{ + DevCon::WriteLn( "vtlb/mmap: Block Tracking reset..." ); + memzero_obj( m_PageProtectInfo ); + HostSys::MemProtect( psM, Ps2MemSize::Base, Protect_ReadWrite ); } diff --git a/pcsx2/Memory.h b/pcsx2/Memory.h index 18ff8f20fc..45cb2098b3 100644 --- a/pcsx2/Memory.h +++ b/pcsx2/Memory.h @@ -23,24 +23,9 @@ #endif //#define ENABLECACHE +#include "MemoryTypes.h" #include "vtlb.h" -namespace Ps2MemSize -{ - static const uint Base = 0x02000000; // 32 MB main memory! - static const uint Rom = 0x00400000; // 4 MB main rom - static const uint Rom1 = 0x00040000; // DVD player - static const uint Rom2 = 0x00080000; // Chinese rom extension (?) - static const uint ERom = 0x001C0000; // DVD player extensions (?) - static const uint Hardware = 0x00010000; - static const uint Scratch = 0x00004000; - - static const uint IopRam = 0x00200000; // 2MB main ram on the IOP. - static const uint IopHardware = 0x00010000; - - static const uint GSregs = 0x00002000; // 8k for the GS registers and stuff. -} - extern u8 *psM; //32mb Main Ram extern u8 *psR; //4mb rom area extern u8 *psR1; //256kb rom1 area (actually 196kb, but can't mask this) @@ -56,7 +41,6 @@ extern u8 *psS; //0.015 mb, scratch pad #define PS2MEM_EROM psER #define PS2MEM_SCRATCH psS -extern u8 g_RealGSMem[Ps2MemSize::GSregs]; #define PS2MEM_GS g_RealGSMem #define PS2GS_BASE(mem) (g_RealGSMem+(mem&0x13ff)) @@ -157,8 +141,8 @@ extern void memClearPageAddr(u32 vaddr); extern void memMapVUmicro(); -extern int mmap_GetRamPageInfo(void* ptr); -extern void mmap_MarkCountedRamPage(void* ptr,u32 vaddr); +extern int mmap_GetRamPageInfo( u32 paddr ); +extern void mmap_MarkCountedRamPage( u32 paddr ); extern void mmap_ResetBlockTracking(); extern void mmap_ClearCpuBlock( uint offset ); @@ -174,34 +158,5 @@ extern void mmap_ClearCpuBlock( uint offset ); #define memWrite64 vtlb_memWrite64 #define memWrite128 vtlb_memWrite128 -#define _eeReadConstMem8 0&& -#define _eeReadConstMem16 0&& -#define _eeReadConstMem32 0&& -#define _eeReadConstMem128 0&& -#define _eeWriteConstMem8 0&& -#define _eeWriteConstMem16 0&& -#define _eeWriteConstMem32 0&& -#define _eeWriteConstMem64 0&& -#define _eeWriteConstMem128 0&& -#define _eeMoveMMREGtoR 0&& - -// extra ops -// These allow the old unused const versions of various HW accesses to continue to compile. -// (code left in for reference purposes, but is not needed by Vtlb) -#define _eeWriteConstMem16OP 0&& -#define _eeWriteConstMem32OP 0&& - -#define recMemConstRead8 0&& -#define recMemConstRead16 0&& -#define recMemConstRead32 0&& -#define recMemConstRead64 0&& -#define recMemConstRead128 0&& - -#define recMemConstWrite8 0&& -#define recMemConstWrite16 0&& -#define recMemConstWrite32 0&& -#define recMemConstWrite64 0&& -#define recMemConstWrite128 0&& - extern void loadBiosRom( const char *ext, u8 *dest, long maxSize ); extern u16 ba0R16(u32 mem); diff --git a/pcsx2/MemoryTypes.h b/pcsx2/MemoryTypes.h new file mode 100644 index 0000000000..deceae70f8 --- /dev/null +++ b/pcsx2/MemoryTypes.h @@ -0,0 +1,24 @@ + +#pragma once + +namespace Ps2MemSize +{ + static const uint Base = 0x02000000; // 32 MB main memory! + static const uint Rom = 0x00400000; // 4 MB main rom + static const uint Rom1 = 0x00040000; // DVD player + static const uint Rom2 = 0x00080000; // Chinese rom extension (?) + static const uint ERom = 0x001C0000; // DVD player extensions (?) + static const uint Hardware = 0x00010000; + static const uint Scratch = 0x00004000; + + static const uint IopRam = 0x00200000; // 2MB main ram on the IOP. + static const uint IopHardware = 0x00010000; + + static const uint GSregs = 0x00002000; // 8k for the GS registers and stuff. +} + +typedef u8 mem8_t; +typedef u16 mem16_t; +typedef u32 mem32_t; +typedef u64 mem64_t; +typedef u64 mem128_t; diff --git a/pcsx2/Misc.cpp b/pcsx2/Misc.cpp index dcc8e87dcb..b12da7c32e 100644 --- a/pcsx2/Misc.cpp +++ b/pcsx2/Misc.cpp @@ -30,11 +30,11 @@ #include "IopCommon.h" #include "HostGui.h" -#include "CDVDisodrv.h" +#include "CDVD/CDVDisodrv.h" #include "VUmicro.h" #include "VU.h" #include "iCore.h" -#include "iVUzerorec.h" +#include "sVU_zerorec.h" #include "BaseblockEx.h" // included for devbuild block dumping (which may or may not work anymore?) #include "GS.h" @@ -76,6 +76,40 @@ struct romdir } __attribute__((packed)); #endif +// ------------------------------------------------------------------------ +// Force DevAssert to *not* inline for devel/debug builds (allows using breakpoints to trap +// assertions), and force it to inline for release builds (optimizes it out completely since +// IsDevBuild is false). Since Devel builds typically aren't enabled with Global Optimization/ +// LTCG, this currently isn't even necessary. But might as well, in case we decide at a later +// date to re-enable LTCG for devel. +#ifdef PCSX2_DEVBUILD +# define DEVASSERT_INLINE __noinline +#else +# define DEVASSERT_INLINE __forceinline +#endif + +////////////////////////////////////////////////////////////////////////////////////////// +// Assertion tool for Devel builds, intended for sanity checking and/or bounds checking +// variables in areas which are not performance critical. +// +// How it works: This function throws an exception of type Exception::AssertionFailure if +// the assertion conditional is false. Typically for the end-user, this exception is handled +// by the general handler, which (should eventually) create some state dumps and other +// information for troubleshooting purposes. +// +// From a debugging environment, you can trap your DevAssert by either breakpointing the +// exception throw below, or by adding either Exception::AssertionFailure or +// Exception::LogicError to your First-Chance Exception catch list (Visual Studio, under +// the Debug->Exceptions menu/dialog). +// +DEVASSERT_INLINE void DevAssert( bool condition, const char* msg ) +{ + if( IsDevBuild && !condition ) + { + throw Exception::AssertionFailure( msg ); + } +} + u32 GetBiosVersion() { unsigned int fileOffset=0; s8 *ROMVER; @@ -360,7 +394,7 @@ void CycleFrameLimit(int dir) const char* limitMsg; u32 newOptions; u32 curFrameLimit = Config.Options & PCSX2_FRAMELIMIT_MASK; - u32 newFrameLimit; + u32 newFrameLimit = 0; static u32 oldFrameLimit = PCSX2_FRAMELIMIT_LIMIT; if( dir == 0 ) { diff --git a/pcsx2/Misc.h b/pcsx2/Misc.h index f9dd17dfbf..7a9d6d9e3e 100644 --- a/pcsx2/Misc.h +++ b/pcsx2/Misc.h @@ -39,29 +39,6 @@ int GetPS2ElfName( wxString& dest ); // Used in Misc, System, Linux, CDVD // Not sure what header these should go in. Probably not this one. void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR); extern u32 g_sseVUMXCSR, g_sseMXCSR; -extern u8 g_globalMMXSaved, g_globalXMMSaved; -extern bool g_EEFreezeRegs; - -// when using mmx/xmm regs, use; 0 is load -// freezes no matter the state -#ifndef __INTEL_COMPILER -extern "C" void FreezeXMMRegs_(int save); -extern "C" void FreezeMMXRegs_(int save); -extern "C" void FreezeRegs(int save); -#else -extern void FreezeXMMRegs_(int save); -extern void FreezeMMXRegs_(int save); -extern void FreezeRegs(int save); -#endif - -// these macros check to see if needs freezing -#define FreezeXMMRegs(save) if( g_EEFreezeRegs ) { FreezeXMMRegs_(save); } -#define FreezeMMXRegs(save) if( g_EEFreezeRegs ) { FreezeMMXRegs_(save); } - -// If we move the rest of this stuff, we can probably move these, too. -extern void InitCPUTicks(); -extern u64 GetCPUTicks(); -extern u64 GetTickFrequency(); // Used in Misc,and Windows/Linux files. extern void ProcessFKeys(int fkey, struct KeyModifiers *keymod); // processes fkey related commands value 1-12 diff --git a/pcsx2/NakedAsm.h b/pcsx2/NakedAsm.h index cf9272f74f..319343a5f9 100644 --- a/pcsx2/NakedAsm.h +++ b/pcsx2/NakedAsm.h @@ -25,20 +25,17 @@ // Common to Windows and Linux extern "C" { -// acoroutine.S -void so_call(coroutine_t coro); -void so_resume(void); -void so_exit(void); + // acoroutine.S + void so_call(coroutine_t coro); + void so_resume(void); + void so_exit(void); -// I can't find where the Linux recRecompile is defined. Is it used anymore? -// If so, namespacing might break it. :/ (air) -void recRecompile( u32 startpc ); + void recRecompile( u32 startpc ); -// aR3000A.S -void iopRecRecompile(u32 startpc); + // aR3000A.S + void iopRecRecompile(u32 startpc); } -// Linux specific #ifdef __LINUX__ PCSX2_ALIGNED16( u8 _xmm_backup[16*2] ); @@ -46,22 +43,21 @@ PCSX2_ALIGNED16( u8 _mmx_backup[8*4] ); extern "C" { -// aVUzerorec.S -void* SuperVUGetProgram(u32 startpc, int vuindex); -void SuperVUCleanupProgram(u32 startpc, int vuindex); -void svudispfn(); - -// aR3000A.S -void iopJITCompile(); -void iopJITCompileInBlock(); -void iopDispatcherReg(); - -// aR5900-32.S -void JITCompile(); -void JITCompileInBlock(); -void DispatcherReg(); - + // aVUzerorec.S + void* SuperVUGetProgram(u32 startpc, int vuindex); + void SuperVUCleanupProgram(u32 startpc, int vuindex); + void svudispfn(); + + // aR3000A.S + void iopJITCompile(); + void iopJITCompileInBlock(); + void iopDispatcherReg(); + + // aR5900-32.S + void JITCompile(); + void JITCompileInBlock(); + void DispatcherReg(); } #endif -#endif +#endif diff --git a/pcsx2/NewGUI/ConsoleLogger.cpp b/pcsx2/NewGUI/ConsoleLogger.cpp index 1492492b95..c66faac2da 100644 --- a/pcsx2/NewGUI/ConsoleLogger.cpp +++ b/pcsx2/NewGUI/ConsoleLogger.cpp @@ -19,6 +19,7 @@ #include "PrecompiledHeader.h" #include "App.h" #include "MainFrame.h" +#include "DebugTools/Debug.h" #include #include @@ -222,3 +223,72 @@ void ConsoleLogFrame::Write( const char* text ) m_TextCtrl.AppendText( wxString::FromAscii(text) ); } + +namespace Console +{ + // ------------------------------------------------------------------------ + void __fastcall SetTitle( const wxString& title ) + { + if( ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame() ) + FrameHandle->SetTitle( title ); + } + + // ------------------------------------------------------------------------ + void __fastcall SetColor( Colors color ) + { + if( ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame() ) + FrameHandle->SetColor( color ); + } + + // ------------------------------------------------------------------------ + void ClearColor() + { + if( ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame() ) + FrameHandle->ClearColor(); + } + + // ------------------------------------------------------------------------ + bool Newline() + { + if( ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame() ) + FrameHandle->Newline(); + + fputs( "\n", emuLog ); + return false; + } + + // ------------------------------------------------------------------------ + bool __fastcall Write( const char* fmt ) + { + if( ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame() ) + FrameHandle->Write( fmt ); + + fputs( fmt, emuLog ); + return false; + } + + // ------------------------------------------------------------------------ + bool __fastcall Write( const wxString& fmt ) + { + if( ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame() ) + FrameHandle->Write( fmt ); + + fputs( fmt.ToAscii().data(), emuLog ); + return false; + } +} + +namespace Msgbox +{ + bool Alert( const wxString& text ) + { + wxMessageBox( text, L"Pcsx2 Message", wxOK, wxGetApp().GetTopWindow() ); + return false; + } + + bool OkCancel( const wxString& text ) + { + int result = wxMessageBox( text, L"Pcsx2 Message", wxOK | wxCANCEL, wxGetApp().GetTopWindow() ); + return result == wxOK; + } +} diff --git a/pcsx2/NewGUI/main.cpp b/pcsx2/NewGUI/main.cpp index 9dc52a3288..f41bbebd57 100644 --- a/pcsx2/NewGUI/main.cpp +++ b/pcsx2/NewGUI/main.cpp @@ -29,8 +29,6 @@ IMPLEMENT_APP(Pcsx2App) AppConfig g_Conf; -const wxRect wxDefaultRect( wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord ); - Pcsx2App::Pcsx2App() : m_ConsoleFrame( NULL ) { diff --git a/pcsx2/Patch.cpp b/pcsx2/Patch.cpp index 363da9580d..ea878f02d8 100644 --- a/pcsx2/Patch.cpp +++ b/pcsx2/Patch.cpp @@ -56,7 +56,6 @@ PatchTextTable commands[] = // X - EE rounding mode (default is NEAR) // Y - VU rounding mode (default is CHOP) { "zerogs", 6, patchFunc_zerogs }, // zerogs=hex - { "path3hack", 7, patchFunc_path3hack }, { "vunanmode",8, patchFunc_vunanmode }, { "ffxhack",9, patchFunc_ffxhack}, { "xkickdelay",10, patchFunc_xkickdelay}, @@ -688,13 +687,10 @@ int AddPatch(int Mode, int Place, int Address, int Size, u64 data) void patchFunc_ffxhack( char * cmd, char * param ) { - //Keeping this as a dummy a while :p - //g_FFXHack = 1; } void patchFunc_xkickdelay( char * cmd, char * param ) { - g_VUGameFixes |= VUFIX_XGKICKDELAY2; } void patchFunc_fastmemory( char * cmd, char * param ) @@ -708,11 +704,6 @@ void patchFunc_vunanmode( char * cmd, char * param ) // Doesn't do anything anymore } -void patchFunc_path3hack( char * cmd, char * param ) -{ - path3hack = TRUE; -} - void patchFunc_roundmode( char * cmd, char * param ) { int index; diff --git a/pcsx2/Patch.h b/pcsx2/Patch.h index dee8a3b247..a130889e2f 100644 --- a/pcsx2/Patch.h +++ b/pcsx2/Patch.h @@ -82,7 +82,6 @@ void patchFunc_comment( char * text1, char * text2 ); void patchFunc_gametitle( char * text1, char * text2 ); void patchFunc_patch( char * text1, char * text2 ); void patchFunc_fastmemory( char * text1, char * text2 ); -void patchFunc_path3hack( char * text1, char * text2 ); void patchFunc_roundmode( char * text1, char * text2 ); void patchFunc_zerogs( char * text1, char * text2 ); void patchFunc_vunanmode( char * text1, char * text2 ); @@ -109,7 +108,6 @@ int AddPatch(int Mode, int Place, int Address, int Size, u64 data); extern void SetFastMemory(int); // iR5900LoadStore.c -extern bool path3hack; //extern int g_VUGameFixes; extern int g_ZeroGSOptions; extern u32 g_sseMXCSR; diff --git a/pcsx2/Plugins.cpp b/pcsx2/Plugins.cpp index 6c7ff2033d..9c6677c541 100644 --- a/pcsx2/Plugins.cpp +++ b/pcsx2/Plugins.cpp @@ -17,10 +17,11 @@ */ #include "PrecompiledHeader.h" -#include "RedtapeWindows.h" +#include "Utilities/RedtapeWindows.h" #include "IopCommon.h" #include "GS.h" +#include "HostGui.h" _GSinit GSinit; _GSopen GSopen; @@ -213,13 +214,43 @@ _FWfreeze FWfreeze; _FWtest FWtest; _FWabout FWabout; - DEV9handler dev9Handler; USBhandler usbHandler; uptr pDsp; #ifdef _not_wxWidgets_Land_ +enum PluginTypes +{ + GS = 0, + PAD, + PAD1, + PAD2, + SPU2, + CDVD, + DEV9, + USB, + FW +}; + +int PS2E_LT[9] = { +PS2E_LT_GS, +PS2E_LT_PAD,PS2E_LT_PAD, PS2E_LT_PAD, +PS2E_LT_SPU2, +PS2E_LT_CDVD, +PS2E_LT_DEV9, +PS2E_LT_USB, +PS2E_LT_FW}; + +int PS2E_VERSION[9] = { +PS2E_GS_VERSION, +PS2E_PAD_VERSION,PS2E_PAD_VERSION, PS2E_PAD_VERSION, +PS2E_SPU2_VERSION, +PS2E_CDVD_VERSION, +PS2E_DEV9_VERSION, +PS2E_USB_VERSION, +PS2E_FW_VERSION}; + #define Sfy(x) #x #define Strfy(x) Sfy(x) #define MapSymbolVarType(var,type,name) var = (type)SysLoadSym(drv,Strfy(name)) @@ -237,13 +268,13 @@ uptr pDsp; #define MapSymbol_Error(name) MapSymbolVar_Error(name,name) // for pad1/2 -#define MapSymbolPAD(var,sym,name) MapSymbolVar(var##name,sym##name) -#define MapSymbolPAD_Fallback(var,sym,name) if((MapSymbolVarType(var##name,_##sym##name,sym##name))==NULL) var##name = var##_##name -#define MapSymbolPAD_Error(var,sym,name) MapSymbolVar_Error(var##name,sym##name) +#define MapSymbolPAD(var,name) MapSymbolVar(var##name,PAD##name) +#define MapSymbolPAD_Fallback(var,name) if((MapSymbolVarType(var##name,_PAD##name,PAD##name))==NULL) var##name = var##_##name +#define MapSymbolPAD_Error(var,name) MapSymbolVar_Error(var##name,PAD##name) -#define TestPS2Esyms(type) if(_TestPS2Esyms(drv,PS2E_LT_##type,PS2E_##type##_VERSION,filename) < 0) return -1; +void *GSplugin; -int _TestPS2Esyms(void* drv, int type, int expected_version, const wxString& filename) +static int _TestPS2Esyms(void* drv, int type, int expected_version, const wxString& filename) { _PS2EgetLibType PS2EgetLibType; _PS2EgetLibVersion2 PS2EgetLibVersion2; @@ -263,10 +294,11 @@ int _TestPS2Esyms(void* drv, int type, int expected_version, const wxString& fil return 0; } -//static const char *err; -//static int errval; - -void *GSplugin; +static __forceinline bool TestPS2Esyms(void* &drv, PluginTypes type, const string& filename) +{ + if (_TestPS2Esyms(drv, PS2E_LT[type],PS2E_VERSION[type],filename) < 0) return false; + return true; +} void CALLBACK GS_printf(int timeout, char *fmt, ...) { va_list list; @@ -294,7 +326,7 @@ int LoadGSplugin(const wxString& filename) GSplugin = SysLoadLibrary(filename.c_str()); if (GSplugin == NULL) { Msgbox::Alert ("Could Not Load GS Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = GSplugin; - TestPS2Esyms(GS); + if (!TestPS2Esyms(drv, GS, filename)) return -1; MapSymbol_Error(GSinit); MapSymbol_Error(GSshutdown); MapSymbol_Error(GSopen); @@ -349,24 +381,24 @@ int LoadPAD1plugin(const wxString& filename) { PAD1plugin = SysLoadLibrary(filename.c_str()); if (PAD1plugin == NULL) { Msgbox::Alert("Could Not Load PAD1 Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = PAD1plugin; - TestPS2Esyms(PAD); - MapSymbolPAD_Error(PAD1,PAD,init); - MapSymbolPAD_Error(PAD1,PAD,shutdown); - MapSymbolPAD_Error(PAD1,PAD,open); - MapSymbolPAD_Error(PAD1,PAD,close); - MapSymbolPAD_Error(PAD1,PAD,keyEvent); - MapSymbolPAD_Error(PAD1,PAD,startPoll); - MapSymbolPAD_Error(PAD1,PAD,poll); - MapSymbolPAD_Error(PAD1,PAD,query); - MapSymbolPAD(PAD1,PAD,update); + if (!TestPS2Esyms(drv, PAD, filename)) return -1; + MapSymbolPAD_Error(PAD1,init); + MapSymbolPAD_Error(PAD1,shutdown); + MapSymbolPAD_Error(PAD1,open); + MapSymbolPAD_Error(PAD1,close); + MapSymbolPAD_Error(PAD1,keyEvent); + MapSymbolPAD_Error(PAD1,startPoll); + MapSymbolPAD_Error(PAD1,poll); + MapSymbolPAD_Error(PAD1,query); + MapSymbolPAD(PAD1,update); - MapSymbolPAD(PAD1,PAD,gsDriverInfo); - MapSymbolPAD_Fallback(PAD1,PAD,configure); - MapSymbolPAD_Fallback(PAD1,PAD,about); - MapSymbolPAD_Fallback(PAD1,PAD,test); - MapSymbolPAD_Fallback(PAD1,PAD,freeze); - MapSymbolPAD_Fallback(PAD1,PAD,setSlot); - MapSymbolPAD_Fallback(PAD1,PAD,queryMtap); + MapSymbolPAD(PAD1,gsDriverInfo); + MapSymbolPAD_Fallback(PAD1,configure); + MapSymbolPAD_Fallback(PAD1,about); + MapSymbolPAD_Fallback(PAD1,test); + MapSymbolPAD_Fallback(PAD1,freeze); + MapSymbolPAD_Fallback(PAD1,setSlot); + MapSymbolPAD_Fallback(PAD1,queryMtap); return 0; } @@ -386,24 +418,24 @@ int LoadPAD2plugin(const wxString& filename) { PAD2plugin = SysLoadLibrary(filename.c_str()); if (PAD2plugin == NULL) { Msgbox::Alert("Could Not Load PAD2 Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = PAD2plugin; - TestPS2Esyms(PAD); - MapSymbolPAD_Error(PAD2,PAD,init); - MapSymbolPAD_Error(PAD2,PAD,shutdown); - MapSymbolPAD_Error(PAD2,PAD,open); - MapSymbolPAD_Error(PAD2,PAD,close); - MapSymbolPAD_Error(PAD2,PAD,keyEvent); - MapSymbolPAD_Error(PAD2,PAD,startPoll); - MapSymbolPAD_Error(PAD2,PAD,poll); - MapSymbolPAD_Error(PAD2,PAD,query); - MapSymbolPAD(PAD2,PAD,update); + if (!TestPS2Esyms(drv, PAD, filename)) return -1; + MapSymbolPAD_Error(PAD2,init); + MapSymbolPAD_Error(PAD2,shutdown); + MapSymbolPAD_Error(PAD2,open); + MapSymbolPAD_Error(PAD2,close); + MapSymbolPAD_Error(PAD2,keyEvent); + MapSymbolPAD_Error(PAD2,startPoll); + MapSymbolPAD_Error(PAD2,poll); + MapSymbolPAD_Error(PAD2,query); + MapSymbolPAD(PAD2,update); - MapSymbolPAD(PAD2,PAD,gsDriverInfo); - MapSymbolPAD_Fallback(PAD2,PAD,configure); - MapSymbolPAD_Fallback(PAD2,PAD,about); - MapSymbolPAD_Fallback(PAD2,PAD,test); - MapSymbolPAD_Fallback(PAD2,PAD,freeze); - MapSymbolPAD_Fallback(PAD2,PAD,setSlot); - MapSymbolPAD_Fallback(PAD2,PAD,queryMtap); + MapSymbolPAD(PAD2,gsDriverInfo); + MapSymbolPAD_Fallback(PAD2,configure); + MapSymbolPAD_Fallback(PAD2,about); + MapSymbolPAD_Fallback(PAD2,test); + MapSymbolPAD_Fallback(PAD2,freeze); + MapSymbolPAD_Fallback(PAD2,setSlot); + MapSymbolPAD_Fallback(PAD2,queryMtap); return 0; } @@ -421,7 +453,7 @@ int LoadSPU2plugin(const wxString& filename) { SPU2plugin = SysLoadLibrary(filename.c_str()); if (SPU2plugin == NULL) { Msgbox::Alert("Could Not Load SPU2 Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = SPU2plugin; - TestPS2Esyms(SPU2); + if (!TestPS2Esyms(drv, SPU2, filename)) return -1; MapSymbol_Error(SPU2init); MapSymbol_Error(SPU2shutdown); MapSymbol_Error(SPU2open); @@ -464,7 +496,7 @@ int LoadCDVDplugin(const wxString& filename) { CDVDplugin = SysLoadLibrary(filename.c_str()); if (CDVDplugin == NULL) { Msgbox::Alert("Could Not Load CDVD Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = CDVDplugin; - TestPS2Esyms(CDVD); + if (!TestPS2Esyms(drv, CDVD, filename)) return -1; MapSymbol_Error(CDVDinit); MapSymbol_Error(CDVDshutdown); MapSymbol_Error(CDVDopen); @@ -501,7 +533,7 @@ int LoadDEV9plugin(const wxString& filename) { DEV9plugin = SysLoadLibrary(filename.c_str()); if (DEV9plugin == NULL) { Msgbox::Alert("Could Not Load DEV9 Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = DEV9plugin; - TestPS2Esyms(DEV9); + if (!TestPS2Esyms(drv, DEV9, filename)) return -1; MapSymbol_Error(DEV9init); MapSymbol_Error(DEV9shutdown); MapSymbol_Error(DEV9open); @@ -538,7 +570,7 @@ int LoadUSBplugin(const wxString& filename) { USBplugin = SysLoadLibrary(filename.c_str()); if (USBplugin == NULL) { Msgbox::Alert("Could Not Load USB Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = USBplugin; - TestPS2Esyms(USB); + if (!TestPS2Esyms(drv, USB, filename)) return -1; MapSymbol_Error(USBinit); MapSymbol_Error(USBshutdown); MapSymbol_Error(USBopen); @@ -575,7 +607,7 @@ int LoadFWplugin(const wxString& filename) { FWplugin = SysLoadLibrary(filename.c_str()); if (FWplugin == NULL) { Msgbox::Alert("Could Not Load FW Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = FWplugin; - TestPS2Esyms(FW); + if (!TestPS2Esyms(drv, FW, filename)) return -1; MapSymbol_Error(FWinit); MapSymbol_Error(FWshutdown); MapSymbol_Error(FWopen); @@ -607,12 +639,13 @@ struct PluginOpenStatusFlags static PluginOpenStatusFlags OpenStatus = {0}; -static bool loadp = false; -static bool initp = false; +static bool plugins_loaded = false; +static bool plugins_initialized = false; +static bool only_loading_elf = false; int LoadPlugins() { - if( loadp ) return 0; + if (plugins_loaded) return 0; if (LoadGSplugin( Path::Combine( Config.PluginsDir, Config.GS )) == -1) return -1; if (LoadPAD1plugin( Path::Combine( Config.PluginsDir, Config.PAD1 )) == -1) return -1; @@ -623,204 +656,240 @@ int LoadPlugins() if (LoadUSBplugin( Path::Combine( Config.PluginsDir, Config.USB )) == -1) return -1; if (LoadFWplugin( Path::Combine( Config.PluginsDir, Config.FW )) == -1) return -1; - loadp = true; + plugins_loaded = true; return 0; } +bool ReportError(int err, const char *str) +{ + if (err != 0) + { + Msgbox::Alert("%s error: %d", params str, err); + return true; + } + return false; +} + +bool ReportError2(int err, const char *str) +{ + if (err != 0) + { + Msgbox::Alert("Error Opening %s Plugin", params str, err); + return true; + } + return false; +} int InitPlugins() { - if( initp ) return 0; + if (plugins_initialized) return 0; // Ensure plugins have been loaded.... - if( LoadPlugins() == -1 ) return -1; + if (LoadPlugins() == -1) return -1; - //if( !loadp ) - // throw Exception::InvalidOperation( "Bad coder mojo - InitPlugins called prior to plugins having been loaded." ); + //if( !plugins_loaded ) throw Exception::InvalidOperation( "Bad coder mojo - InitPlugins called prior to plugins having been loaded." ); -#ifndef _WIN32 - chdir(MAIN_DIR); -#endif - int ret; + if (ReportError(GSinit(), "GSinit")) return -1; + if (ReportError(PAD1init(1), "PAD1init")) return -1; + if (ReportError(PAD2init(2), "PAD2init")) return -1; + if (ReportError(SPU2init(), "SPU2init")) return -1; + if (ReportError(CDVDinit(), "CDVDinit")) return -1; + if (ReportError(DEV9init(), "DEV9init")) return -1; + if (ReportError(USBinit(), "USBinit")) return -1; + if (ReportError(FWinit(), "FWinit")) return -1; - ret = GSinit(); - if (ret != 0) { Msgbox::Alert("GSinit error: %d", params ret); return -1; } - ret = PAD1init(1); - if (ret != 0) { Msgbox::Alert("PAD1init error: %d", params ret); return -1; } - ret = PAD2init(2); - if (ret != 0) { Msgbox::Alert("PAD2init error: %d", params ret); return -1; } - ret = SPU2init(); - if (ret != 0) { Msgbox::Alert("SPU2init error: %d", params ret); return -1; } - ret = CDVDinit(); - if (ret != 0) { Msgbox::Alert("CDVDinit error: %d", params ret); return -1; } - ret = DEV9init(); - if (ret != 0) { Msgbox::Alert("DEV9init error: %d", params ret); return -1; } - ret = USBinit(); - if (ret != 0) { Msgbox::Alert("USBinit error: %d", params ret); return -1; } - ret = FWinit(); - if (ret != 0) { Msgbox::Alert("FWinit error: %d", params ret); return -1; } - - initp = true; + only_loading_elf = false; + plugins_initialized = true; return 0; } void ShutdownPlugins() { - if( !initp ) return; + if (!plugins_initialized) return; mtgsWaitGS(); ClosePlugins( true ); - if( GSshutdown != NULL ) - GSshutdown(); + if (GSshutdown != NULL) GSshutdown(); - if( PAD1shutdown != NULL ) - PAD1shutdown(); - if( PAD2shutdown != NULL ) - PAD2shutdown(); + if (PAD1shutdown != NULL) PAD1shutdown(); + if (PAD2shutdown != NULL) PAD2shutdown(); - if( SPU2shutdown != NULL ) - SPU2shutdown(); + if (SPU2shutdown != NULL) SPU2shutdown(); + if (CDVDshutdown != NULL) CDVDshutdown(); + if (DEV9shutdown != NULL) DEV9shutdown(); + if (USBshutdown != NULL) USBshutdown(); + if (FWshutdown != NULL) FWshutdown(); - if( CDVDshutdown != NULL ) - CDVDshutdown(); - - if( DEV9shutdown != NULL ) - DEV9shutdown(); - - if( USBshutdown != NULL ) - USBshutdown(); - - if( FWshutdown != NULL ) - FWshutdown(); - - initp = false; + plugins_initialized = false; } extern void spu2DMA4Irq(); extern void spu2DMA7Irq(); extern void spu2Irq(); -int OpenPlugins(const char* pTitleFilename) +bool OpenGS() { GSdriverInfo info; - int ret; - - if ( !initp ) + + if (!OpenStatus.GS) { - if( InitPlugins() == -1 ) return -1; - } + if (ReportError2(gsOpen(), "GS")) + { + ClosePlugins(true); + return false; + } -#ifndef _WIN32 - // change dir so that CDVD can find its config file - char file[255], pNewTitle[255]; - chdir(MAIN_DIR); - chdir(Config.PluginsDir); - - if( pTitleFilename != NULL && pTitleFilename[0] != '/' ) - { - // because we are changing the dir, we have to set a new title if it is a relative dir - sprintf(pNewTitle, "%s/%s", file, pTitleFilename); - pTitleFilename = pNewTitle; - } -#endif - - if( !OpenStatus.CDVD ) - { - //first we need the data - if (CDVDnewDiskCB) CDVDnewDiskCB(cdvdNewDiskCB); - - ret = CDVDopen(pTitleFilename); - - if (ret != 0) { Msgbox::Alert("Error Opening CDVD Plugin"); goto OpenError; } - OpenStatus.CDVD = true; - cdvdNewDiskCB(); - } - - if( !OpenStatus.GS ) { - ret = gsOpen(); - if (ret != 0) { Msgbox::Alert("Error Opening GS Plugin"); goto OpenError; } - OpenStatus.GS = true; - - //then the user input - if (GSgetDriverInfo) { + //Get the user input. + if (GSgetDriverInfo) + { GSgetDriverInfo(&info); if (PAD1gsDriverInfo) PAD1gsDriverInfo(&info); if (PAD2gsDriverInfo) PAD2gsDriverInfo(&info); } + OpenStatus.GS = true; } + return true; +} - if( !OpenStatus.PAD1 ) +bool OpenCDVD(const char* pTitleFilename) +{ + // Don't repetitively open the CDVD plugin if directly loading an elf file and open failed once already. + if (!OpenStatus.CDVD && !only_loading_elf) { - ret = PAD1open((void *)&pDsp); - if (ret != 0) { Msgbox::Alert("Error Opening PAD1 Plugin"); goto OpenError; } + //First, we need the data. + if (CDVDnewDiskCB) CDVDnewDiskCB(cdvdNewDiskCB); + + if (CDVDopen(pTitleFilename) != 0) + { + if (g_Startup.BootMode != BootMode_Elf) + { + Msgbox::Alert("Error Opening CDVD Plugin"); + ClosePlugins(true); + return false; + } + else + { + Console::Notice("Running ELF File Without CDVD Plugin Support!"); + only_loading_elf = true; + } + } + OpenStatus.CDVD = true; + } + return true; +} + +bool OpenPAD1() +{ + if (!OpenStatus.PAD1) + { + if (ReportError2(PAD1open((void *)&pDsp), "PAD1")) + { + ClosePlugins(true); + return false; + } OpenStatus.PAD1 = true; } + return true; +} - if( !OpenStatus.PAD2 ) +bool OpenPAD2() +{ + if (!OpenStatus.PAD2) { - ret = PAD2open((void *)&pDsp); - if (ret != 0) { Msgbox::Alert("Error Opening PAD2 Plugin"); goto OpenError; } + if (ReportError2(PAD2open((void *)&pDsp), "PAD2")) + { + ClosePlugins(true); + return false; + } OpenStatus.PAD2 = true; } + return true; +} - //the sound - - if( !OpenStatus.SPU2 ) +bool OpenSPU2() +{ + if (!OpenStatus.SPU2) { SPU2irqCallback(spu2Irq,spu2DMA4Irq,spu2DMA7Irq); - if( SPU2setDMABaseAddr != NULL ) - SPU2setDMABaseAddr((uptr)psxM); + + if (SPU2setDMABaseAddr != NULL) SPU2setDMABaseAddr((uptr)psxM); + if (SPU2setClockPtr != NULL) SPU2setClockPtr(&psxRegs.cycle); - if(SPU2setClockPtr != NULL) - SPU2setClockPtr(&psxRegs.cycle); - - ret = SPU2open((void*)&pDsp); - if (ret != 0) { Msgbox::Alert("Error Opening SPU2 Plugin"); goto OpenError; } + if (ReportError2(SPU2open((void*)&pDsp), "SPU2")) + { + ClosePlugins(true); + return false; + } OpenStatus.SPU2 = true; } + return true; +} - //and last the dev9 - if( !OpenStatus.DEV9 ) +bool OpenDEV9() +{ + if (!OpenStatus.DEV9) { DEV9irqCallback(dev9Irq); dev9Handler = DEV9irqHandler(); - ret = DEV9open(&psxRegs.pc); //((void *)&pDsp); - if (ret != 0) { Msgbox::Alert("Error Opening DEV9 Plugin"); goto OpenError; } + + if (ReportError2(DEV9open(&psxRegs.pc)/*((void *)&pDsp)*/, "DEV9")) + { + ClosePlugins(true); + return false; + } OpenStatus.DEV9 = true; } - - if( !OpenStatus.USB ) + return true; +} +bool OpenUSB() +{ + if (!OpenStatus.USB) { USBirqCallback(usbIrq); usbHandler = USBirqHandler(); USBsetRAM(psxM); - ret = USBopen((void *)&pDsp); - if (ret != 0) { Msgbox::Alert("Error Opening USB Plugin"); goto OpenError; } + + if (ReportError2(USBopen((void *)&pDsp), "USB")) + { + ClosePlugins(true); + return false; + } OpenStatus.USB = true; } + return true; +} - if( !OpenStatus.FW ) +bool OpenFW() +{ + if (!OpenStatus.FW) { FWirqCallback(fwIrq); - ret = FWopen((void *)&pDsp); - if (ret != 0) { Msgbox::Alert("Error Opening FW Plugin"); goto OpenError; } + + if (ReportError2(FWopen((void *)&pDsp), "FW")) + { + ClosePlugins(true); + return false; + } OpenStatus.FW = true; } + return true; +} -#ifndef _WIN32 - chdir(MAIN_DIR); -#endif +int OpenPlugins(const char* pTitleFilename) +{ + if (!plugins_initialized) + { + if( InitPlugins() == -1 ) return -1; + } + + if ((!OpenCDVD(pTitleFilename)) || (!OpenGS()) || (!OpenPAD1()) || (!OpenPAD2()) || + (!OpenSPU2()) || (!OpenDEV9()) || (!OpenUSB()) || (!OpenFW())) + return -1; + + if (!only_loading_elf) cdvdNewDiskCB(); return 0; - -OpenError: - ClosePlugins( true ); -#ifndef _WIN32 - chdir(MAIN_DIR); -#endif - - return -1; } @@ -833,7 +902,7 @@ OpenError: void ClosePlugins( bool closegs ) { - // Close pads first since they attatch to the GS's window. + // Close pads first since they attach to the GS's window. CLOSE_PLUGIN( PAD1 ); CLOSE_PLUGIN( PAD2 ); @@ -850,7 +919,9 @@ void ClosePlugins( bool closegs ) OpenStatus.GS = false; } else + { mtgsWaitGS(); + } } CLOSE_PLUGIN( CDVD ); @@ -858,16 +929,6 @@ void ClosePlugins( bool closegs ) CLOSE_PLUGIN( USB ); CLOSE_PLUGIN( FW ); CLOSE_PLUGIN( SPU2 ); - - // More special treatment for the GS. It needs a complete shutdown and re-init - // or else it will tend to error out when we try to use it again. - if( 0 ) //closegs ) - { - GSshutdown(); - - int ret = GSinit(); - if (ret != 0) { Msgbox::Alert("GSinit error: %d", params ret); } - } } //used to close the GS plugin window and pads, to switch gsdx renderer @@ -887,11 +948,11 @@ void CloseGS() void ReleasePlugins() { - if (!loadp) return; + if (!plugins_loaded) return; - if (GSplugin == NULL || PAD1plugin == NULL || PAD2plugin == NULL || - SPU2plugin == NULL || CDVDplugin == NULL || DEV9plugin == NULL || - USBplugin == NULL || FWplugin == NULL) return; + if ((GSplugin == NULL) || (PAD1plugin == NULL) || (PAD2plugin == NULL) || + (SPU2plugin == NULL) || (CDVDplugin == NULL) || (DEV9plugin == NULL) || + (USBplugin == NULL) || (FWplugin == NULL)) return; ShutdownPlugins(); @@ -903,7 +964,8 @@ void ReleasePlugins() SysCloseLibrary(DEV9plugin); DEV9plugin = NULL; SysCloseLibrary(USBplugin); USBplugin = NULL; SysCloseLibrary(FWplugin); FWplugin = NULL; - loadp = false; + + plugins_loaded = false; } void PluginsResetGS() diff --git a/pcsx2/PrecompiledHeader.h b/pcsx2/PrecompiledHeader.h index ef3d4f5109..dce1f937de 100644 --- a/pcsx2/PrecompiledHeader.h +++ b/pcsx2/PrecompiledHeader.h @@ -3,28 +3,8 @@ //#pragma once -////////////////////////////////////////////////////////////////////////////////////////// -// Microsoft specific STL extensions for bounds checking and stuff: Enabled in devbuilds, -// disabled in release builds. :) - -#ifdef _MSC_VER -#ifdef PCSX2_DEVBUILD -# define _SECURE_SCL 1 -# define _SECURE_SCL_THROWS 1 -#else -# define _SECURE_SCL 0 -#endif -#endif - #define NOMINMAX // Disables other libs inclusion of their own min/max macros (we use std instead) -#ifdef _WIN32 -// disable warning C4244: '=' : conversion from 'big' to 'small', possible loss of data -# pragma warning(disable:4244) -#else -# include // Non-Windows platforms need this -#endif - ////////////////////////////////////////////////////////////////////////////////////////// // Welcome wxWidgets to the party! @@ -35,8 +15,6 @@ #include #include -extern const wxRect wxDefaultRect; // wxWidgets lacks one of its own. - ////////////////////////////////////////////////////////////////////////////////////////// // Include the STL junk that's actually handy. @@ -71,9 +49,6 @@ typedef int BOOL; #define TRUE 1 #define FALSE 0 -// This should prove useful.... -#define wxsFormat wxString::Format - // macro provided for tagging translation strings, without actually running them through the // translator (which the _() does automatically, and sometimes we don't want that) #define wxLt(a) a @@ -89,10 +64,11 @@ typedef int BOOL; #include "Pcsx2Defs.h" #include "Paths.h" #include "Config.h" -#include "StringUtils.h" -#include "Exceptions.h" -#include "MemcpyFast.h" - +#include "Utilities/Console.h" +#include "Utilities/Exceptions.h" +#include "Utilities/MemcpyFast.h" +#include "Utilities/General.h" +#include "x86emitter/tools.h" //////////////////////////////////////////////////////////////////// // Compiler/OS specific macros and defines -- Begin Section @@ -112,13 +88,6 @@ typedef int BOOL; # define __declspec(x) # endif -static __forceinline u32 timeGetTime() -{ - struct timeb t; - ftime(&t); - return (u32)(t.time*1000+t.millitm); -} - # ifndef strnicmp # define strnicmp strncasecmp # endif @@ -129,42 +98,4 @@ static __forceinline u32 timeGetTime() #endif // end GCC/Linux stuff -// compile-time assert -#ifndef C_ASSERT -# define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] -#endif - -#ifndef __LINUX__ -# define __unused -#endif - -////////////////////////////////////////////////////////////////////////////////////////// -// Forceinline macro that is enabled for RELEASE/PUBLIC builds ONLY. (non-inline in devel) -// This is useful because forceinline can make certain types of debugging problematic since -// functions that look like they should be called won't breakpoint since their code is inlined. -// Henceforth, use release_inline for things which we want inlined on public/release builds but -// *not* in devel builds. - -#ifdef PCSX2_DEVBUILD -# define __releaseinline -#else -# define __releaseinline __forceinline -#endif - -////////////////////////////////////////////////////////////////////////////////////////// -// Dev / Debug conditionals -- -// Consts for using if() statements instead of uglier #ifdef macros. - -#ifdef PCSX2_DEVBUILD -static const bool IsDevBuild = true; -#else -static const bool IsDevBuild = false; -#endif - -#ifdef _DEBUG -static const bool IsDebugBuild = true; -#else -static const bool IsDebugBuild = false; -#endif - #endif \ No newline at end of file diff --git a/pcsx2/R3000A.cpp b/pcsx2/R3000A.cpp index c821733549..015a259803 100644 --- a/pcsx2/R3000A.cpp +++ b/pcsx2/R3000A.cpp @@ -164,7 +164,7 @@ __forceinline int psxTestCycle( u32 startCycle, s32 delta ) __forceinline void PSX_INT( IopEventId n, s32 ecycle ) { // Generally speaking games shouldn't throw ints that haven't been cleared yet. - // It's usually indicative os something amiss in our emulation, so uncomment this + // It's usually indicative of something amiss in our emulation, so uncomment this // code to help trap those sort of things. // Exception: IRQ16 - SIO - it drops ints like crazy when handling PAD stuff. @@ -231,10 +231,13 @@ __releaseinline void psxBranchTest() psxRcntUpdate(); iopBranchAction = true; } - + else + { // start the next branch at the next counter event by default // the interrupt code below will assign nearer branches if needed. - g_psxNextBranchCycle = psxNextsCounter+psxNextCounter; + g_psxNextBranchCycle = psxNextsCounter+psxNextCounter; + } + if (psxRegs.interrupt) { diff --git a/pcsx2/R3000AInterpreter.cpp b/pcsx2/R3000AInterpreter.cpp index ec321c609c..4c64e2a682 100644 --- a/pcsx2/R3000AInterpreter.cpp +++ b/pcsx2/R3000AInterpreter.cpp @@ -465,11 +465,6 @@ static void intExecute() { for (;;) execI(); } -#ifdef _DEBUG -extern u32 psxdump; -extern void iDumpPsxRegisters(u32,u32); -#endif - static s32 intExecuteBlock( s32 eeCycles ) { psxBreak = 0; diff --git a/pcsx2/RDebug/Makefile.am b/pcsx2/RDebug/Makefile.am deleted file mode 100644 index 7d1ae75af0..0000000000 --- a/pcsx2/RDebug/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -INCLUDES = -I@srcdir@/../ -I@srcdir@/../../common/include -I@srcdir@/../../3rdparty $(shell wx-config --cppflags) -noinst_LIBRARIES = libRDebug.a - -libRDebug_a_SOURCES = \ -deci2.cpp deci2_dcmp.cpp deci2_drfp.h deci2_iloadp.h deci2_ttyp.cpp \ -deci2_dbgp.cpp deci2_dcmp.h deci2.h deci2_netmp.cpp deci2_ttyp.h \ -deci2_dbgp.h deci2_iloadp.cpp deci2_netmp.h \ No newline at end of file diff --git a/pcsx2/RDebug/deci2.h b/pcsx2/RDebug/deci2.h index b35bfb9ba0..a01f84f334 100644 --- a/pcsx2/RDebug/deci2.h +++ b/pcsx2/RDebug/deci2.h @@ -54,13 +54,13 @@ struct DECI2_DBGP_BRK{ #define RUN 1 extern DECI2_DBGP_BRK ebrk[32], ibrk[32]; -extern int ebrk_count, ibrk_count; +extern s32 ebrk_count, ibrk_count; extern volatile long runStatus; -extern int runCode, runCount; +extern s32 runCode, runCount; extern Threading::Semaphore* runEvent; -extern int connected; +extern s32 connected; //when add linux code this might change int writeData(const u8 *result); diff --git a/pcsx2/RecoverySystem.cpp b/pcsx2/RecoverySystem.cpp index 54c19fdd71..1a23e99965 100644 --- a/pcsx2/RecoverySystem.cpp +++ b/pcsx2/RecoverySystem.cpp @@ -180,7 +180,7 @@ namespace StateRecovery { try { - g_RecoveryState = new SafeArray( "Memory Savestate Recovery" ); + g_RecoveryState = new SafeArray( L"Memory Savestate Recovery" ); RecoveryMemSavingState().FreezeAll(); safe_delete( g_gsRecoveryState ); g_EmulationInProgress = false; diff --git a/pcsx2/RedtapeWindows.h b/pcsx2/RedtapeWindows.h deleted file mode 100644 index 91b6cece7c..0000000000 --- a/pcsx2/RedtapeWindows.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2002-2009 Pcsx2 Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ - -////////////////////////////////////////////////////////////////////////////////////////// -// Windows Redtape! No windows.h should be included without it! -// -// This header's purpose is to include windows.h with the correct OS version info, and -// to undefine some of windows.h's more evil macros (min/max). It also does a _WIN32 -// check, so that we don't have to do it explicitly in every instance where it might -// be needed from non-Win32-specific files (ie, ix86_cpudetect.cpp) - -#ifndef _REDTAPE_WINDOWS_H_ -#define _REDTAPE_WINDOWS_H_ - -#define NOMINMAX // Disables other libs inclusion of their own min/max macros (we use std instead) - -#ifdef _WIN32 - -// Force availability of to WinNT APIs (change to 0x600 to enable XP-specific APIs) -#ifndef WINVER -#define WINVER 0x0501 -#define _WIN32_WINNT 0x0501 -#endif - -#include - -// disable Windows versions of min/max -- we'll use the typesafe STL versions instead. -#undef min -#undef max - -#endif -#endif diff --git a/pcsx2/SPR.cpp b/pcsx2/SPR.cpp index 5c5291fad0..cb607ef85e 100644 --- a/pcsx2/SPR.cpp +++ b/pcsx2/SPR.cpp @@ -227,7 +227,7 @@ void SPRFROMinterrupt() //Console::WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", params gif->chcr, gif->madr, gif->tadr); mfifoGIFtransfer(mfifotransferred); mfifotransferred = 0; - return; + if(gif->chcr & 0x100)return; } else if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) // VIF1 MFIFO { @@ -236,12 +236,12 @@ void SPRFROMinterrupt() //Console::WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", params vif1ch->chcr, vif1ch->madr, vif1ch->tadr); mfifoVIF1transfer(mfifotransferred); mfifotransferred = 0; - return; + if(vif1ch->chcr & 0x100)return; } } if (spr0finished == 0) return; spr0->chcr &= ~0x100; - hwDmacIrq(8); + hwDmacIrq(DMAC_FROM_SPR); } @@ -347,7 +347,7 @@ void _dmaSPR1() // toSPR work function { Console::WriteLn("SPR1 Tag BUSERR"); spr1->chcr = (spr1->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15 - psHu32(DMAC_STAT) |= 1 << 15; //If yes, set BEIS (BUSERR) in DMAC_STAT register + psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register done = TRUE; spr1finished = (done) ? 1: 0; return; @@ -418,7 +418,7 @@ void SPRTOinterrupt() _dmaSPR1(); if (spr1finished == 0) return; spr1->chcr &= ~0x100; - hwDmacIrq(9); + hwDmacIrq(DMAC_TO_SPR); } void SaveState::sprFreeze() diff --git a/pcsx2/SaveState.cpp b/pcsx2/SaveState.cpp index af06a65112..cc7d47498a 100644 --- a/pcsx2/SaveState.cpp +++ b/pcsx2/SaveState.cpp @@ -21,11 +21,11 @@ #include "IopCommon.h" #include "SaveState.h" -#include "CDVDisodrv.h" +#include "CDVD/CDVDisodrv.h" #include "VUmicro.h" #include "VU.h" #include "iCore.h" -#include "iVUzerorec.h" +#include "sVU_zerorec.h" #include "GS.h" #include "COP0.h" diff --git a/pcsx2/Sif.cpp b/pcsx2/Sif.cpp index 23576f767f..d6b9469d9d 100644 --- a/pcsx2/Sif.cpp +++ b/pcsx2/Sif.cpp @@ -209,9 +209,10 @@ __forceinline void SIF0Dma() SIF0read((u32*)ptag, readSize << 2); - Cpu->Clear(sif0dma->madr, readSize*4); + // Clearing handled by vtlb memory protection and manual blocks. + //Cpu->Clear(sif0dma->madr, readSize*4); - cycles += readSize * BIAS; // fixme : BIAS is factored in below + cycles += readSize; // fixme : BIAS is factored in below sif0dma->qwc -= readSize; sif0dma->madr += readSize << 4; } @@ -363,7 +364,7 @@ __forceinline void SIF1Dma() SIF1write(data, qwTransfer << 2); sif1dma->madr += qwTransfer << 4; - cycles += qwTransfer * BIAS; // fixme : BIAS is factored in above + cycles += qwTransfer; // fixme : BIAS is factored in above sif1dma->qwc -= qwTransfer; } } @@ -451,15 +452,15 @@ __forceinline void dmaSIF0() SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos"); } - psHu32(0x1000F240) |= 0x2000; + psHu32(SBUS_F240) |= 0x2000; eesifbusy[0] = 1; if (iopsifbusy[0] == 1) { FreezeXMMRegs(1); hwIntcIrq(INTC_SBUS); SIF0Dma(); - psHu32(0x1000F240) &= ~0x20; - psHu32(0x1000F240) &= ~0x2000; + psHu32(SBUS_F240) &= ~0x20; + psHu32(SBUS_F240) &= ~0x2000; FreezeXMMRegs(0); } } @@ -474,15 +475,15 @@ __forceinline void dmaSIF1() SIF_LOG("warning, sif1.fifoReadPos != sif1.fifoWritePos"); } - psHu32(0x1000F240) |= 0x4000; + psHu32(SBUS_F240) |= 0x4000; eesifbusy[1] = 1; if (iopsifbusy[1] == 1) { FreezeXMMRegs(1); SIF1Dma(); - psHu32(0x1000F240) &= ~0x40; - psHu32(0x1000F240) &= ~0x100; - psHu32(0x1000F240) &= ~0x4000; + psHu32(SBUS_F240) &= ~0x40; + psHu32(SBUS_F240) &= ~0x100; + psHu32(SBUS_F240) &= ~0x4000; FreezeXMMRegs(0); } @@ -494,7 +495,7 @@ __forceinline void dmaSIF2() sif2dma->chcr, sif2dma->madr, sif2dma->qwc); sif2dma->chcr &= ~0x100; - hwDmacIrq(7); + hwDmacIrq(DMAC_SIF2); Console::WriteLn("*PCSX2*: dmaSIF2"); } diff --git a/pcsx2/Sio.cpp b/pcsx2/Sio.cpp index 52687d7698..d944ebd299 100644 --- a/pcsx2/Sio.cpp +++ b/pcsx2/Sio.cpp @@ -20,6 +20,7 @@ #include "IopCommon.h" #include "MemoryCard.h" +#include "sio_internal.h" _sio sio; diff --git a/pcsx2/Sio.h b/pcsx2/Sio.h index c3ec7c74bb..541f583143 100644 --- a/pcsx2/Sio.h +++ b/pcsx2/Sio.h @@ -16,27 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#ifndef _SIO_H_ -#define _SIO_H_ - -// SIO IRQ Timings... -// Scheduling ints into the future is a purist approach to emulation, and -// is mostly cosmetic since the emulator itself performs all actions instantly -// (as far as the emulated CPU is concerned). In some cases this can actually -// cause more sync problems than it supposedly solves, due to accumulated -// delays incurred by the recompiler's low cycle update rate and also Pcsx2 -// failing to properly handle pre-emptive DMA/IRQs or cpu exceptions. - -// The SIO is one of these cases, where-by many games seem to be a lot happier -// if the SIO handles its IRQs instantly instead of scheduling them. -// Uncomment the line below for SIO instant-IRQ mode. It improves responsiveness -// considerably, fixes PAD latency problems in some games, and may even reduce the -// chance of saves getting corrupted (untested). But it lacks the purist touch, -// so it's not enabled by default. - -//#define SIO_INLINE_IRQS - +#pragma once struct _sio { u16 StatReg; @@ -79,27 +59,6 @@ struct _sio { extern _sio sio; -// Status Flags -#define TX_RDY 0x0001 -#define RX_RDY 0x0002 -#define TX_EMPTY 0x0004 -#define PARITY_ERR 0x0008 -#define RX_OVERRUN 0x0010 -#define FRAMING_ERR 0x0020 -#define SYNC_DETECT 0x0040 -#define DSR 0x0080 -#define CTS 0x0100 -#define IRQ 0x0200 - -// Control Flags -#define TX_PERM 0x0001 -#define DTR 0x0002 -#define RX_PERM 0x0004 -#define BREAK 0x0008 -#define RESET_ERR 0x0010 -#define RTS 0x0020 -#define SIO_RESET 0x0040 - extern void sioInit(); extern void sioShutdown(); extern void psxSIOShutdown(); @@ -110,21 +69,3 @@ extern void sioInterrupt(); extern void InitializeSIO(u8 value); extern void sioEjectCard( uint mcdId ); -#ifdef _MSC_VER -#pragma pack(1) -#endif -struct mc_command_0x26_tag{ - u8 field_151; //+02 flags - u16 sectorSize; //+03 divide to it - u16 field_2C; //+05 divide to it - u32 mc_size; //+07 - u8 mc_xor; //+0b don't forget to recalculate it!!! - u8 Z; //+0c -#ifdef _MSC_VER -}; -#pragma pack() -#else -} __attribute__((packed)); -#endif - -#endif diff --git a/pcsx2/StringUtils.h b/pcsx2/StringUtils.h index 2f328dc5c1..dce35af69f 100644 --- a/pcsx2/StringUtils.h +++ b/pcsx2/StringUtils.h @@ -16,8 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef _PCSX2_STRINGUTILS_H_ -#define _PCSX2_STRINGUTILS_H_ +#pragma once #include #include @@ -35,58 +34,3 @@ std::string to_string(const T& value) return oss.str(); } -////////////////////////////////////////////////////////////////////////////////////////// -// Helpers for wxWidgets stuff! -// -extern wxString ToString( const wxPoint& src, const wxString& separator=L"," ); -extern wxString ToString( const wxSize& src, const wxString& separator=L"," ); -extern wxString ToString( const wxRect& src, const wxString& separator=L"," ); - -extern bool TryParse( wxPoint& dest, const wxStringTokenizer& parts ); -extern bool TryParse( wxSize& dest, const wxStringTokenizer& parts ); - -extern bool TryParse( wxPoint& dest, const wxString& src, const wxPoint& defval=wxDefaultPosition, const wxString& separators=L","); -extern bool TryParse( wxSize& dest, const wxString& src, const wxSize& defval=wxDefaultSize, const wxString& separators=L","); -extern bool TryParse( wxRect& dest, const wxString& src, const wxRect& defval=wxDefaultRect, const wxString& separators=L","); - - -////////////////////////////////////////////////////////////////////////////////////////// -// dummy structure used to type-guard the dummy parameter that's been inserted to -// allow us to use the va_list feature on references. -struct _VARG_PARAM -{ - // just some value to make the struct length 32bits instead of 8 bits, so that the - // compiler generates somewhat more efficient code. - uint someval; -}; - -#ifdef _DEBUG - -#define params va_arg_dummy, -#define varg_assert() // jASSUME( dummy == &va_arg_dummy ); -// typedef the Va-Arg value to be a value type in debug builds. The value -// type requires a little more overhead in terms of code generation, but is always -// type-safe. The compiler will generate errors for any forgotten params value. -typedef _VARG_PARAM VARG_PARAM; - -#else - -#define params NULL, // using null is faster / more compact! -#define varg_assert() jASSUME( dummy == NULL ); -// typedef the Va-Arg value to be a pointer in release builds. Pointers -// generate more compact code by a small margin, but aren't entirely type safe since -// the compiler won't generate errors if you pass NULL or other values. -typedef _VARG_PARAM const * VARG_PARAM; - -#endif - -extern const _VARG_PARAM va_arg_dummy; - -extern void ssprintf(std::string& dest, const char* fmt, ...); -extern void ssappendf( std::string& dest, const char* format, ...); -extern void vssprintf(std::string& dest, const char* format, va_list args); -extern void vssappendf(std::string& dest, const char* format, va_list args); - -extern std::string fmt_string( const char* fmt, ... ); -extern std::string vfmt_string( const char* fmt, va_list args ); -#endif diff --git a/pcsx2/System.cpp b/pcsx2/System.cpp index 4ce47c73d8..c145ce865d 100644 --- a/pcsx2/System.cpp +++ b/pcsx2/System.cpp @@ -25,7 +25,7 @@ #include "iR5900.h" #include "R3000A.h" #include "IopMem.h" -#include "iVUzerorec.h" // for SuperVUReset +#include "sVU_zerorec.h" // for SuperVUReset #include "R5900Exceptions.h" @@ -407,8 +407,11 @@ void SysPrepareExecution( const wxString& elf_file, bool use_bios ) return; } - if (OpenPlugins(NULL) == -1) - return; + g_Startup.BootMode = (elf_file) ? BootMode_Elf : BootMode_Normal; + + if (OpenPlugins(NULL) == -1) { + return; + } if( elf_file.IsEmpty() ) { @@ -428,7 +431,6 @@ void SysPrepareExecution( const wxString& elf_file, bool use_bios ) { // Custom ELF specified (not using CDVD). // Run the BIOS and load the ELF. - loadElfFile( elf_file ); } } diff --git a/pcsx2/System.h b/pcsx2/System.h index 24e81d64c0..b03cfc2b7d 100644 --- a/pcsx2/System.h +++ b/pcsx2/System.h @@ -18,42 +18,11 @@ #pragma once -#include "Pcsx2Defs.h" #include "Paths.h" #include "Pcsx2Config.h" -#include "SafeArray.h" +#include "Utilities/SafeArray.h" +#include "Utilities/Threading.h" // to use threading stuff, include the Threading namespace in your file. #include "Misc.h" -#include "Threading.h" // to use threading stuff, include the Threading namespace in your file. - -enum PageProtectionMode -{ - Protect_NoAccess = 0, - Protect_ReadOnly, - Protect_ReadWrite -}; - -////////////////////////////////////////////////////////////////////////////////////////// -// HostSys - Namespace housing general system-level implementations relating to loading -// plugins and allocating memory. For now, these functions are all accessed via Sys* -// versions defined in System.h/cpp. -namespace HostSys -{ - // Maps a block of memory for use as a recompiled code buffer. - // The allocated block has code execution privileges. - // Returns NULL on allocation failure. - extern void *Mmap(uptr base, u32 size); - - // Unmaps a block allocated by SysMmap - extern void Munmap(uptr base, u32 size); - - extern void MemProtect( void* baseaddr, size_t size, PageProtectionMode mode, bool allowExecution=false ); - - static __forceinline void Munmap( void* base, u32 size ) - { - Munmap( (uptr)base, size ); - } -} - extern void SysDetect(); // Detects cpu type and fills cpuInfo structs. extern void SysReset(); // Resets the various PS2 cpus, sub-systems, and recompilers. @@ -86,103 +55,11 @@ extern void vSyncDebugStuff( uint frame ); ////////////////////////////////////////////////////////////////////////////////////////// -// Console Namespace -- Replacements for SysPrintf. -// SysPrintf is depreciated -- We should phase these in over time. -namespace Console -{ - enum Colors - { - Color_Black = 0, - Color_Red, - Color_Green, - Color_Yellow, - Color_Blue, - Color_Magenta, - Color_Cyan, - Color_White - }; - - // va_args version of WriteLn, mostly for internal use only. - extern void __fastcall _WriteLn( Colors color, const char* fmt, va_list args ); - - extern void __fastcall SetTitle( const wxString& title ); - - // Changes the active console color. - // This color will be unset by calls to colored text methods - // such as ErrorMsg and Notice. - extern void __fastcall SetColor( Colors color ); - - // Restores the console color to default (usually low-intensity white on Win32) - extern void ClearColor(); - - // The following Write functions return bool so that we can use macros to exclude - // them from different build types. The return values are always zero. - - // Writes a newline to the console. - extern bool Newline(); - - // Writes an unformatted string of text to the console (fast!) - // No newline is appended. - extern bool __fastcall Write( const char* text ); - - // Writes an unformatted string of text to the console (fast!) - // A newline is automatically appended, and the console color reset to default - // after the log is written. - extern bool __fastcall Write( Colors color, const char* text ); - - // Writes an unformatted string of text to the console (fast!) - // A newline is automatically appended. - extern bool __fastcall WriteLn( const char* text ); - - // Writes an unformatted string of text to the console (fast!) - // A newline is automatically appended, and the console color reset to default - // after the log is written. - extern bool __fastcall WriteLn( Colors color, const char* text ); - - // Writes a line of colored text to the console, with automatic newline appendage. - // The console color is reset to default when the operation is complete. - extern bool WriteLn( Colors color, const char* fmt, VARG_PARAM dummy, ... ); - - // Writes a formatted message to the console, with appended newline. - extern bool WriteLn( const char* fmt, VARG_PARAM dummy, ... ); - - // Writes a line of colored text to the console (no newline). - // The console color is reset to default when the operation is complete. - extern bool Write( Colors color, const char* fmt, VARG_PARAM dummy, ... ); - - // Writes a formatted message to the console (no newline) - extern bool Write( const char* fmt, VARG_PARAM dummy, ... ); - - // Displays a message in the console with red emphasis. - // Newline is automatically appended. - extern bool Error( const char* fmt, VARG_PARAM dummy, ... ); - extern bool __fastcall Error( const char* text ); - - // Displays a message in the console with yellow emphasis. - // Newline is automatically appended. - extern bool Notice( const char* fmt, VARG_PARAM dummy, ... ); - extern bool __fastcall Notice( const char* text ); - - // Displays a message in the console with yellow emphasis. - // Newline is automatically appended. - extern bool Status( const char* fmt, VARG_PARAM dummy, ... ); - extern bool __fastcall Status( const char* text ); - - - extern bool __fastcall Write( const wxString& text ); - extern bool __fastcall Write( Colors color, const wxString& text ); - extern bool __fastcall WriteLn( const wxString& text ); - extern bool __fastcall WriteLn( Colors color, const wxString& text ); - - extern bool __fastcall Error( const wxString& text ); - extern bool __fastcall Notice( const wxString& text ); - extern bool __fastcall Status( const wxString& text ); -} - // Different types of message boxes that the emulator can employ from the friendly confines // of it's blissful unawareness of whatever GUI it runs under. :) All message boxes exhibit // blocking behavior -- they prompt the user for action and only return after the user has // responded to the prompt. +// namespace Msgbox { // Pops up an alert Dialog Box with a singular "OK" button. @@ -194,30 +71,3 @@ namespace Msgbox extern bool OkCancel( const wxString& text ); } -using Console::Color_Red; -using Console::Color_Green; -using Console::Color_Blue; -using Console::Color_Magenta; -using Console::Color_Cyan; -using Console::Color_Yellow; -using Console::Color_White; - - -////////////////////////////////////////////////////////////////////////////////////////// -// Dev / Debug conditionals -- -// Consts for using if() statements instead of uglier #ifdef macros. -// Abbreviated macros for dev/debug only consoles and msgboxes. - -#ifdef PCSX2_DEVBUILD -# define DevCon Console -# define DevMsg MsgBox -#else -# define DevCon 0&&Console -# define DevMsg -#endif - -#ifdef _DEBUG -# define DbgCon Console -#else -# define DbgCon 0&&Console -#endif diff --git a/pcsx2/VU.h b/pcsx2/VU.h index fb9602afe7..c339c4cf9b 100644 --- a/pcsx2/VU.h +++ b/pcsx2/VU.h @@ -196,10 +196,3 @@ static __forceinline u32* GET_VU_MEM(VURegs* VU, u32 addr) return (u32*)(VU0.Mem+(addr&0x0fff)); // for addr 0x0000 to 0x4000 just wrap around } - - -// various fixes to enable per game (all are off by default) -#define VUFIX_SIGNEDZERO 1 -#define VUFIX_EXTRAFLAGS 2 -#define VUFIX_XGKICKDELAY2 4 -extern int g_VUGameFixes; diff --git a/pcsx2/VU0.cpp b/pcsx2/VU0.cpp index 2b6c831f6d..a017527406 100644 --- a/pcsx2/VU0.cpp +++ b/pcsx2/VU0.cpp @@ -108,7 +108,7 @@ namespace OpcodeImpl // Asadr.Changed //TODO: check this - // HUH why ? doesn;t make any sense ... + // HUH why ? doesn't make any sense ... void SQC2() { u32 addr = _Imm_ + cpuRegs.GPR.r[_Rs_].UL[0]; //memWrite64(addr, VU0.VF[_Ft_].UD[0]); diff --git a/pcsx2/VU0micro.cpp b/pcsx2/VU0micro.cpp index 772d8ecda3..1502e2cdb2 100644 --- a/pcsx2/VU0micro.cpp +++ b/pcsx2/VU0micro.cpp @@ -32,7 +32,7 @@ #include "VUflags.h" #include "VUops.h" -#include "iVUzerorec.h" +#include "sVU_zerorec.h" using namespace R5900; diff --git a/pcsx2/VU0microInterp.cpp b/pcsx2/VU0microInterp.cpp index cf70894bd1..da5c9b8bcd 100644 --- a/pcsx2/VU0microInterp.cpp +++ b/pcsx2/VU0microInterp.cpp @@ -220,18 +220,11 @@ namespace VU0micro { int i; - #ifdef _DEBUG - int prevbranch; - #endif - for (i = 128; i--;) { if ((VU0.VI[REG_VPU_STAT].UL & 0x1) == 0) break; - #ifdef _DEBUG - prevbranch = vu0branch; - #endif vu0Exec(&VU0); } diff --git a/pcsx2/VU1micro.cpp b/pcsx2/VU1micro.cpp index dfc3151127..0f8098947c 100644 --- a/pcsx2/VU1micro.cpp +++ b/pcsx2/VU1micro.cpp @@ -27,12 +27,12 @@ #include "VU.h" #include "VUops.h" #include "VUmicro.h" -#include "iVUmicro.h" -#include "iVUzerorec.h" +#include "sVU_Micro.h" +#include "sVU_zerorec.h" VURegs* g_pVU1; -#ifdef _DEBUG +#ifdef PCSX2_DEBUG u32 vudump = 0; #endif diff --git a/pcsx2/VU1microInterp.cpp b/pcsx2/VU1microInterp.cpp index fc8f7f793a..8ec7bc3cca 100644 --- a/pcsx2/VU1microInterp.cpp +++ b/pcsx2/VU1microInterp.cpp @@ -205,17 +205,11 @@ namespace VU1micro static void intExecuteBlock() { int i; - #ifdef _DEBUG - int prevbranch; - #endif for (i = 128; i--;) { if ((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0) break; - #ifdef _DEBUG - prevbranch = vu1branch; - #endif vu1Exec(&VU1); } diff --git a/pcsx2/VUflags.h b/pcsx2/VUflags.h index 4b04a2c012..e0eaad2acf 100644 --- a/pcsx2/VUflags.h +++ b/pcsx2/VUflags.h @@ -16,9 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef __VUFLAGS_H__ -#define __VUFLAGS_H__ - +#pragma once #include "VU.h" void vuUpdateDI(VURegs * VU); @@ -33,7 +31,3 @@ __forceinline void VU_MACz_CLEAR(VURegs * VU); __forceinline void VU_MACw_CLEAR(VURegs * VU); void VU_STAT_UPDATE(VURegs * VU); - -#endif - - diff --git a/pcsx2/VUmicro.h b/pcsx2/VUmicro.h index 18bb18a384..2a88d9ce4d 100644 --- a/pcsx2/VUmicro.h +++ b/pcsx2/VUmicro.h @@ -16,9 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef __VUMICRO_H__ -#define __VUMICRO_H__ - +#pragma once #include "VU.h" struct VUmicroCpu @@ -72,6 +70,16 @@ void vuMicroMemReset(); // the CHECK_VU0REC / CHECK_VU1REC config options. void vuMicroCpuReset(); +///////////////////////////////////////////////////////////////// +// microVU Rec Stuff +// +extern void initVUrec(VURegs* vuRegs, const int vuIndex); +extern void closeVUrec(const int vuIndex); +extern void resetVUrec(const int vuIndex); +extern void vsyncVUrec(const int vuIndex); +extern void __fastcall clearVUrec(u32 addr, u32 size, const int vuIndex); +extern void __fastcall runVUrec(u32 startPC, u32 cycles, const int vuIndex); + ///////////////////////////////////////////////////////////////// // Everything else does stuff on a per-VU basis. // @@ -1305,6 +1313,3 @@ void (*PREFIX##_LOWER_OPCODE[128])(_VURegsNum *VUregsn) = { \ #endif #include "VUops.h" - -#endif - diff --git a/pcsx2/VUmicroMem.cpp b/pcsx2/VUmicroMem.cpp index 59ed7cd653..907d15a8ae 100644 --- a/pcsx2/VUmicroMem.cpp +++ b/pcsx2/VUmicroMem.cpp @@ -18,13 +18,10 @@ #include "PrecompiledHeader.h" -#include - #include "Common.h" #include "R5900.h" #include "VUmicro.h" - -#include "iVUzerorec.h" +#include "sVU_zerorec.h" // The following CpuVU objects are value types instead of handles or pointers because they are // modified on the fly to implement VU1 Skip. diff --git a/pcsx2/VUops.cpp b/pcsx2/VUops.cpp index c0341158b7..b257ae0ec2 100644 --- a/pcsx2/VUops.cpp +++ b/pcsx2/VUops.cpp @@ -30,6 +30,9 @@ #define _Ft_ ((VU->code >> 16) & 0x1F) // The rt part of the instruction register #define _Fs_ ((VU->code >> 11) & 0x1F) // The rd part of the instruction register #define _Fd_ ((VU->code >> 6) & 0x1F) // The sa part of the instruction register +#define _It_ (_Ft_ & 0xF) +#define _Is_ (_Fs_ & 0xF) +#define _Id_ (_Fd_ & 0xF) #define _X ((VU->code>>24) & 0x1) #define _Y ((VU->code>>23) & 0x1) @@ -1508,38 +1511,38 @@ void _vuRSQRT(VURegs * VU) { void _vuIADDI(VURegs * VU) { s16 imm = ((VU->code >> 6) & 0x1f); imm = ((imm & 0x10 ? 0xfff0 : 0) | (imm & 0xf)); - if(_Ft_ == 0) return; - VU->VI[_Ft_].SS[0] = VU->VI[_Fs_].SS[0] + imm; + if(_It_ == 0) return; + VU->VI[_It_].SS[0] = VU->VI[_Is_].SS[0] + imm; }//last checked 17/05/03 shadow NOTE: not quite sure about that void _vuIADDIU(VURegs * VU) { - if(_Ft_ == 0) return; - VU->VI[_Ft_].SS[0] = VU->VI[_Fs_].SS[0] + (((VU->code >> 10) & 0x7800) | (VU->code & 0x7ff)); + if(_It_ == 0) return; + VU->VI[_It_].SS[0] = VU->VI[_Is_].SS[0] + (((VU->code >> 10) & 0x7800) | (VU->code & 0x7ff)); }//last checked 17/05/03 shadow void _vuIADD(VURegs * VU) { - if(_Fd_ == 0) return; - VU->VI[_Fd_].SS[0] = VU->VI[_Fs_].SS[0] + VU->VI[_Ft_].SS[0]; + if(_Id_ == 0) return; + VU->VI[_Id_].SS[0] = VU->VI[_Is_].SS[0] + VU->VI[_It_].SS[0]; }//last checked 17/05/03 shadow void _vuIAND(VURegs * VU) { - if(_Fd_ == 0) return; - VU->VI[_Fd_].US[0] = VU->VI[_Fs_].US[0] & VU->VI[_Ft_].US[0]; + if(_Id_ == 0) return; + VU->VI[_Id_].US[0] = VU->VI[_Is_].US[0] & VU->VI[_It_].US[0]; }//last checked 17/05/03 shadow void _vuIOR(VURegs * VU) { - if(_Fd_ == 0) return; - VU->VI[_Fd_].US[0] = VU->VI[_Fs_].US[0] | VU->VI[_Ft_].US[0]; + if(_Id_ == 0) return; + VU->VI[_Id_].US[0] = VU->VI[_Is_].US[0] | VU->VI[_It_].US[0]; } void _vuISUB(VURegs * VU) { - if(_Fd_ == 0) return; - VU->VI[_Fd_].SS[0] = VU->VI[_Fs_].SS[0] - VU->VI[_Ft_].SS[0]; + if(_Id_ == 0) return; + VU->VI[_Id_].SS[0] = VU->VI[_Is_].SS[0] - VU->VI[_It_].SS[0]; } void _vuISUBIU(VURegs * VU) { - if(_Ft_ == 0) return; - VU->VI[_Ft_].SS[0] = VU->VI[_Fs_].SS[0] - (((VU->code >> 10) & 0x7800) | (VU->code & 0x7ff)); + if(_It_ == 0) return; + VU->VI[_It_].SS[0] = VU->VI[_Is_].SS[0] - (((VU->code >> 10) & 0x7800) | (VU->code & 0x7ff)); } void _vuMOVE(VURegs * VU) { @@ -1554,16 +1557,16 @@ void _vuMOVE(VURegs * VU) { void _vuMFIR(VURegs * VU) { if (_Ft_ == 0) return; - if (_X) VU->VF[_Ft_].SL[0] = (s32)VU->VI[_Fs_].SS[0]; - if (_Y) VU->VF[_Ft_].SL[1] = (s32)VU->VI[_Fs_].SS[0]; - if (_Z) VU->VF[_Ft_].SL[2] = (s32)VU->VI[_Fs_].SS[0]; - if (_W) VU->VF[_Ft_].SL[3] = (s32)VU->VI[_Fs_].SS[0]; + if (_X) VU->VF[_Ft_].SL[0] = (s32)VU->VI[_Is_].SS[0]; + if (_Y) VU->VF[_Ft_].SL[1] = (s32)VU->VI[_Is_].SS[0]; + if (_Z) VU->VF[_Ft_].SL[2] = (s32)VU->VI[_Is_].SS[0]; + if (_W) VU->VF[_Ft_].SL[3] = (s32)VU->VI[_Is_].SS[0]; } // Big bug!!! mov from fs to ft not ft to fs. asadr void _vuMTIR(VURegs * VU) { - if(_Ft_ == 0) return; - VU->VI[_Ft_].US[0] = *(u16*)&VU->VF[_Fs_].F[_Fsf_]; + if(_It_ == 0) return; + VU->VI[_It_].US[0] = *(u16*)&VU->VF[_Fs_].F[_Fsf_]; } void _vuMR32(VURegs * VU) { @@ -1585,7 +1588,7 @@ void _vuLQ(VURegs * VU) { if (_Ft_ == 0) return; imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); - addr = ((imm + VU->VI[_Fs_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff); + addr = ((imm + VU->VI[_Is_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff); ptr = (u32*)GET_VU_MEM(VU, addr); if (_X) VU->VF[_Ft_].UL[0] = ptr[0]; @@ -1598,10 +1601,10 @@ void _vuLQD( VURegs * VU ) { u32 addr; u32 *ptr; - if (_Fs_ != 0) VU->VI[_Fs_].US[0]--; + if (_Is_ != 0) VU->VI[_Is_].US[0]--; if (_Ft_ == 0) return; - addr = (VU->VI[_Fs_].US[0] * 16) & (VU == &VU1 ? 0x3fff : 0xfff); + addr = (VU->VI[_Is_].US[0] * 16) & (VU == &VU1 ? 0x3fff : 0xfff); ptr = (u32*)GET_VU_MEM(VU, addr); if (_X) VU->VF[_Ft_].UL[0] = ptr[0]; if (_Y) VU->VF[_Ft_].UL[1] = ptr[1]; @@ -1614,14 +1617,14 @@ void _vuLQI(VURegs * VU) { u32 addr; u32 *ptr; - addr = (VU->VI[_Fs_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff); + addr = (VU->VI[_Is_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff); ptr = (u32*)GET_VU_MEM(VU, addr); if (_X) VU->VF[_Ft_].UL[0] = ptr[0]; if (_Y) VU->VF[_Ft_].UL[1] = ptr[1]; if (_Z) VU->VF[_Ft_].UL[2] = ptr[2]; if (_W) VU->VF[_Ft_].UL[3] = ptr[3]; } - if (_Fs_ != 0) VU->VI[_Fs_].US[0]++; + if (_Fs_ != 0) VU->VI[_Is_].US[0]++; } /* addr is now signed. Asadr */ @@ -1631,7 +1634,7 @@ void _vuSQ(VURegs * VU) { u32 *ptr; imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); - addr = ((imm + VU->VI[_Ft_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff); + addr = ((imm + VU->VI[_It_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff); ptr = (u32*)GET_VU_MEM(VU, addr); if (_X) ptr[0] = VU->VF[_Fs_].UL[0]; if (_Y) ptr[1] = VU->VF[_Fs_].UL[1]; @@ -1643,8 +1646,8 @@ void _vuSQD(VURegs * VU) { u32 addr; u32 *ptr; - if(_Ft_ != 0) VU->VI[_Ft_].US[0]--; - addr = (VU->VI[_Ft_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff); + if(_Ft_ != 0) VU->VI[_It_].US[0]--; + addr = (VU->VI[_It_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff); ptr = (u32*)GET_VU_MEM(VU, addr); if (_X) ptr[0] = VU->VF[_Fs_].UL[0]; if (_Y) ptr[1] = VU->VF[_Fs_].UL[1]; @@ -1656,13 +1659,13 @@ void _vuSQI(VURegs * VU) { u32 addr; u32 *ptr; - addr = (VU->VI[_Ft_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff); + addr = (VU->VI[_It_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff); ptr = (u32*)GET_VU_MEM(VU, addr); if (_X) ptr[0] = VU->VF[_Fs_].UL[0]; if (_Y) ptr[1] = VU->VF[_Fs_].UL[1]; if (_Z) ptr[2] = VU->VF[_Fs_].UL[2]; if (_W) ptr[3] = VU->VF[_Fs_].UL[3]; - if(_Ft_ != 0) VU->VI[_Ft_].US[0]++; + if(_Ft_ != 0) VU->VI[_It_].US[0]++; } /* addr now signed. asadr */ @@ -1670,15 +1673,15 @@ void _vuILW(VURegs * VU) { s16 imm; u16 addr; u16 *ptr; - if (_Ft_ == 0) return; + if (_It_ == 0) return; imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); - addr = ((imm + VU->VI[_Fs_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff); + addr = ((imm + VU->VI[_Is_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff); ptr = (u16*)GET_VU_MEM(VU, addr); - if (_X) VU->VI[_Ft_].US[0] = ptr[0]; - if (_Y) VU->VI[_Ft_].US[0] = ptr[2]; - if (_Z) VU->VI[_Ft_].US[0] = ptr[4]; - if (_W) VU->VI[_Ft_].US[0] = ptr[6]; + if (_X) VU->VI[_It_].US[0] = ptr[0]; + if (_Y) VU->VI[_It_].US[0] = ptr[2]; + if (_Z) VU->VI[_It_].US[0] = ptr[4]; + if (_W) VU->VI[_It_].US[0] = ptr[6]; } void _vuISW(VURegs * VU) { @@ -1687,37 +1690,37 @@ void _vuISW(VURegs * VU) { u16 *ptr; imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); - addr = ((imm + VU->VI[_Fs_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff); + addr = ((imm + VU->VI[_Is_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff); ptr = (u16*)GET_VU_MEM(VU, addr); - if (_X) { ptr[0] = VU->VI[_Ft_].US[0]; ptr[1] = 0; } - if (_Y) { ptr[2] = VU->VI[_Ft_].US[0]; ptr[3] = 0; } - if (_Z) { ptr[4] = VU->VI[_Ft_].US[0]; ptr[5] = 0; } - if (_W) { ptr[6] = VU->VI[_Ft_].US[0]; ptr[7] = 0; } + if (_X) { ptr[0] = VU->VI[_It_].US[0]; ptr[1] = 0; } + if (_Y) { ptr[2] = VU->VI[_It_].US[0]; ptr[3] = 0; } + if (_Z) { ptr[4] = VU->VI[_It_].US[0]; ptr[5] = 0; } + if (_W) { ptr[6] = VU->VI[_It_].US[0]; ptr[7] = 0; } } void _vuILWR(VURegs * VU) { u32 addr; u16 *ptr; - if (_Ft_ == 0) return; + if (_It_ == 0) return; - addr = (VU->VI[_Fs_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff); + addr = (VU->VI[_Is_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff); ptr = (u16*)GET_VU_MEM(VU, addr); - if (_X) VU->VI[_Ft_].US[0] = ptr[0]; - if (_Y) VU->VI[_Ft_].US[0] = ptr[2]; - if (_Z) VU->VI[_Ft_].US[0] = ptr[4]; - if (_W) VU->VI[_Ft_].US[0] = ptr[6]; + if (_X) VU->VI[_It_].US[0] = ptr[0]; + if (_Y) VU->VI[_It_].US[0] = ptr[2]; + if (_Z) VU->VI[_It_].US[0] = ptr[4]; + if (_W) VU->VI[_It_].US[0] = ptr[6]; } void _vuISWR(VURegs * VU) { u32 addr; u16 *ptr; - addr = (VU->VI[_Fs_].US[0] * 16) & (VU == &VU1 ? 0x3fff : 0xfff); + addr = (VU->VI[_Is_].US[0] * 16) & (VU == &VU1 ? 0x3fff : 0xfff); ptr = (u16*)GET_VU_MEM(VU, addr); - if (_X) { ptr[0] = VU->VI[_Ft_].US[0]; ptr[1] = 0; } - if (_Y) { ptr[2] = VU->VI[_Ft_].US[0]; ptr[3] = 0; } - if (_Z) { ptr[4] = VU->VI[_Ft_].US[0]; ptr[5] = 0; } - if (_W) { ptr[6] = VU->VI[_Ft_].US[0]; ptr[7] = 0; } + if (_X) { ptr[0] = VU->VI[_It_].US[0]; ptr[1] = 0; } + if (_Y) { ptr[2] = VU->VI[_It_].US[0]; ptr[3] = 0; } + if (_Z) { ptr[4] = VU->VI[_It_].US[0]; ptr[5] = 0; } + if (_W) { ptr[6] = VU->VI[_It_].US[0]; ptr[7] = 0; } } /* code contributed by _Riff_ @@ -1780,23 +1783,23 @@ void _vuWAITQ(VURegs * VU) { void _vuFSAND(VURegs * VU) { u16 imm; imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); - if(_Ft_ == 0) return; - VU->VI[_Ft_].US[0] = (VU->VI[REG_STATUS_FLAG].US[0] & 0xFFF) & imm; + if(_It_ == 0) return; + VU->VI[_It_].US[0] = (VU->VI[REG_STATUS_FLAG].US[0] & 0xFFF) & imm; } void _vuFSEQ(VURegs * VU) { u16 imm; imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); - if(_Ft_ == 0) return; - if((VU->VI[REG_STATUS_FLAG].US[0] & 0xFFF) == imm) VU->VI[_Ft_].US[0] = 1; - else VU->VI[_Ft_].US[0] = 0; + if(_It_ == 0) return; + if((VU->VI[REG_STATUS_FLAG].US[0] & 0xFFF) == imm) VU->VI[_It_].US[0] = 1; + else VU->VI[_It_].US[0] = 0; } void _vuFSOR(VURegs * VU) { u16 imm; imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); - if(_Ft_ == 0) return; - VU->VI[_Ft_].US[0] = (VU->VI[REG_STATUS_FLAG].US[0] & 0xFFF) | imm; + if(_It_ == 0) return; + VU->VI[_It_].US[0] = (VU->VI[REG_STATUS_FLAG].US[0] & 0xFFF) | imm; } void _vuFSSET(VURegs * VU) { @@ -1806,19 +1809,19 @@ void _vuFSSET(VURegs * VU) { } void _vuFMAND(VURegs * VU) { - if(_Ft_ == 0) return; - VU->VI[_Ft_].US[0] = VU->VI[_Fs_].US[0] & (VU->VI[REG_MAC_FLAG].UL & 0xFFFF); + if(_It_ == 0) return; + VU->VI[_It_].US[0] = VU->VI[_Is_].US[0] & (VU->VI[REG_MAC_FLAG].UL & 0xFFFF); } void _vuFMEQ(VURegs * VU) { - if(_Ft_ == 0) return; - if((VU->VI[REG_MAC_FLAG].UL & 0xFFFF) == VU->VI[_Fs_].US[0]){ - VU->VI[_Ft_].US[0] =1;} else { VU->VI[_Ft_].US[0] =0; } + if(_It_ == 0) return; + if((VU->VI[REG_MAC_FLAG].UL & 0xFFFF) == VU->VI[_Is_].US[0]){ + VU->VI[_It_].US[0] =1;} else { VU->VI[_It_].US[0] =0; } } void _vuFMOR(VURegs * VU) { - if(_Ft_ == 0) return; - VU->VI[_Ft_].US[0] = (VU->VI[REG_MAC_FLAG].UL & 0xFFFF) | VU->VI[_Fs_].US[0]; + if(_It_ == 0) return; + VU->VI[_It_].US[0] = (VU->VI[REG_MAC_FLAG].UL & 0xFFFF) | VU->VI[_Is_].US[0]; } void _vuFCAND(VURegs * VU) { @@ -1843,8 +1846,8 @@ void _vuFCSET(VURegs * VU) { } void _vuFCGET(VURegs * VU) { - if(_Ft_ == 0) return; - VU->VI[_Ft_].US[0] = VU->VI[REG_CLIP_FLAG].UL & 0x0FFF; + if(_It_ == 0) return; + VU->VI[_It_].US[0] = VU->VI[REG_CLIP_FLAG].UL & 0x0FFF; } s32 _branchAddr(VURegs * VU) { @@ -1859,42 +1862,42 @@ void _setBranch(VURegs * VU, u32 bpc) { } void _vuIBEQ(VURegs * VU) { - if (VU->VI[_Ft_].US[0] == VU->VI[_Fs_].US[0]) { + if (VU->VI[_It_].US[0] == VU->VI[_Is_].US[0]) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } } void _vuIBGEZ(VURegs * VU) { - if (VU->VI[_Fs_].SS[0] >= 0) { + if (VU->VI[_Is_].SS[0] >= 0) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } } void _vuIBGTZ(VURegs * VU) { - if (VU->VI[_Fs_].SS[0] > 0) { + if (VU->VI[_Is_].SS[0] > 0) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } } void _vuIBLEZ(VURegs * VU) { - if (VU->VI[_Fs_].SS[0] <= 0) { + if (VU->VI[_Is_].SS[0] <= 0) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } } void _vuIBLTZ(VURegs * VU) { - if (VU->VI[_Fs_].SS[0] < 0) { + if (VU->VI[_Is_].SS[0] < 0) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } } void _vuIBNE(VURegs * VU) { - if (VU->VI[_Ft_].US[0] != VU->VI[_Fs_].US[0]) { + if (VU->VI[_It_].US[0] != VU->VI[_Is_].US[0]) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } @@ -1908,19 +1911,19 @@ void _vuB(VURegs * VU) { void _vuBAL(VURegs * VU) { s32 bpc = _branchAddr(VU); - if (_Ft_) VU->VI[_Ft_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; + if (_It_) VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; _setBranch(VU, bpc); } void _vuJR(VURegs * VU) { - u32 bpc = VU->VI[_Fs_].US[0] * 8; + u32 bpc = VU->VI[_Is_].US[0] * 8; _setBranch(VU, bpc); } void _vuJALR(VURegs * VU) { - u32 bpc = VU->VI[_Fs_].US[0] * 8; - if (_Ft_) VU->VI[_Ft_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; + u32 bpc = VU->VI[_Is_].US[0] * 8; + if (_It_) VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; _setBranch(VU, bpc); } @@ -2039,14 +2042,14 @@ void _vuEEXP(VURegs * VU) { } void _vuXITOP(VURegs * VU) { - if (_Ft_ == 0) return; - VU->VI[_Ft_].US[0] = VU->vifRegs->itop; + if (_It_ == 0) return; + VU->VI[_It_].US[0] = VU->vifRegs->itop; } void _vuXGKICK(VURegs * VU) { - u32* ptr = (u32*)GET_VU_MEM(VU, (VU->VI[_Fs_].US[0]*16) & (VU == &VU1 ? 0x3fff : 0xfff)); -// int temp = 0x4000 - ((VU->VI[_Fs_].US[0]*16) & 0x3fff); + u32* ptr = (u32*)GET_VU_MEM(VU, (VU->VI[_Is_].US[0]*16) & (VU == &VU1 ? 0x3fff : 0xfff)); +// int temp = 0x4000 - ((VU->VI[_Is_].US[0]*16) & 0x3fff); // u32 tempmem[0x8000]; // flush all pipelines first (in the right order) @@ -2056,14 +2059,40 @@ void _vuXGKICK(VURegs * VU) /* memset(tempmem, 0, sizeof(tempmem)); memcpy(tempmem, ptr, temp); ptr = (u32*)GET_VU_MEM(VU, 0); - memcpy(&tempmem[temp], ptr, ((VU->VI[_Fs_].US[0]*16) & 0x3fff)); + memcpy(&tempmem[temp], ptr, ((VU->VI[_Is_].US[0]*16) & 0x3fff)); GSGIFTRANSFER1((u32*)&tempmem[0], 0); - } else*/ GSGIFTRANSFER1((u32*)VU->Mem, (VU->VI[_Fs_].US[0]*16) & 0x3fff); + } else*/ + //DevCon::Notice("Addr %x", params VU->VI[_Is_].US[0] & 0x3fff); + if( mtgsThread != NULL ) + { + u32* data = (u32*)((u8*)VU->Mem + ((VU->VI[_Is_].US[0]*16) & 0x3fff)); + u32 size; + size = mtgsThread->PrepDataPacket( GIF_PATH_1, data, (0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff)) >> 4); + { + u8* pmem = mtgsThread->GetDataPacketPtr(); + + /* if((size << 4) > (u32)(0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff))) + { + //DevCon::Notice("addr + Size = 0x%x, transferring %x then doing %x", params ((VU->VI[_Is_].US[0]*16) & 0x3fff) + (size << 4), (0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff)) >> 4, size - (0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff) >> 4)); + memcpy_aligned(pmem, (u8*)VU->Mem+((VU->VI[_Is_].US[0]*16) & 0x3fff), 0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff)); + size -= (0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff)) >> 4; + //DevCon::Notice("Size left %x", params size); + pmem += 0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff); + memcpy_aligned(pmem, (u8*)VU->Mem, size<<4); + } + else + {*/ + memcpy_aligned(pmem, (u8*)VU->Mem+((VU->VI[_Is_].US[0]*16) & 0x3fff), size<<4); + //} + mtgsThread->SendDataPacket(); + } + + }else GSGIFTRANSFER1((u32*)VU->Mem, (VU->VI[_Is_].US[0]*16) & 0x3fff); } void _vuXTOP(VURegs * VU) { - if(_Ft_ == 0) return; - VU->VI[_Ft_].US[0] = (u16)VU->vifRegs->top; + if(_It_ == 0) return; + VU->VI[_It_].US[0] = (u16)VU->vifRegs->top; } #define GET_VF0_FLAG(reg) (((reg)==0)?(1<VFwrite = 0; \ VUregsn->VFread0 = 0; \ VUregsn->VFread1 = 0; \ - VUregsn->VIwrite = 1 << _Fd_; \ - VUregsn->VIread = (1 << _Fs_) | (1 << _Ft_); \ + VUregsn->VIwrite = 1 << _Id_; \ + VUregsn->VIread = (1 << _Is_) | (1 << _It_); \ VUregsn->cycles = 0; \ } @@ -2209,8 +2238,8 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ VUregsn->VFwrite = 0; \ VUregsn->VFread0 = 0; \ VUregsn->VFread1 = 0; \ - VUregsn->VIwrite = 1 << _Ft_; \ - VUregsn->VIread = 1 << _Fs_; \ + VUregsn->VIwrite = 1 << _It_; \ + VUregsn->VIread = 1 << _Is_; \ VUregsn->cycles = 0; \ } @@ -2512,7 +2541,7 @@ void _vuRegsMFIR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = 1 << _Fs_; + VUregsn->VIread = 1 << _Is_; } void _vuRegsMTIR(VURegs * VU, _VURegsNum *VUregsn) { @@ -2521,7 +2550,7 @@ void _vuRegsMTIR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = _Fs_; VUregsn->VFr0xyzw= 1 << (3-_Fsf_); VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; + VUregsn->VIwrite = 1 << _It_; VUregsn->VIread = GET_VF0_FLAG(_Fs_); } @@ -2544,7 +2573,7 @@ void _vuRegsLQ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = 1 << _Fs_; + VUregsn->VIread = 1 << _Is_; } void _vuRegsLQD(VURegs * VU, _VURegsNum *VUregsn) { @@ -2553,8 +2582,8 @@ void _vuRegsLQD(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwxyzw = _XYZW; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Fs_; - VUregsn->VIread = 1 << _Fs_; + VUregsn->VIwrite = 1 << _Is_; + VUregsn->VIread = 1 << _Is_; } void _vuRegsLQI(VURegs * VU, _VURegsNum *VUregsn) { @@ -2563,8 +2592,8 @@ void _vuRegsLQI(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwxyzw = _XYZW; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Fs_; - VUregsn->VIread = 1 << _Fs_; + VUregsn->VIwrite = 1 << _Is_; + VUregsn->VIread = 1 << _Is_; } void _vuRegsSQ(VURegs * VU, _VURegsNum *VUregsn) { @@ -2574,7 +2603,7 @@ void _vuRegsSQ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFr0xyzw= _XYZW; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = (1 << _Ft_)|GET_VF0_FLAG(_Fs_); + VUregsn->VIread = 1 << _It_; } void _vuRegsSQD(VURegs * VU, _VURegsNum *VUregsn) { @@ -2583,8 +2612,8 @@ void _vuRegsSQD(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = _Fs_; VUregsn->VFr0xyzw= _XYZW; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; - VUregsn->VIread = (1 << _Ft_)|GET_VF0_FLAG(_Fs_); + VUregsn->VIwrite = 1 << _It_; + VUregsn->VIread = 1 << _It_; } void _vuRegsSQI(VURegs * VU, _VURegsNum *VUregsn) { @@ -2593,8 +2622,8 @@ void _vuRegsSQI(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = _Fs_; VUregsn->VFr0xyzw= _XYZW; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; - VUregsn->VIread = (1 << _Ft_)|GET_VF0_FLAG(_Fs_); + VUregsn->VIwrite = 1 << _It_; + VUregsn->VIread = 1 << _It_; } void _vuRegsILW(VURegs * VU, _VURegsNum *VUregsn) { @@ -2602,8 +2631,8 @@ void _vuRegsILW(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; - VUregsn->VIread = 1 << _Fs_; + VUregsn->VIwrite = 1 << _It_; + VUregsn->VIread = 1 << _Is_; VUregsn->cycles = 3; } @@ -2613,7 +2642,7 @@ void _vuRegsISW(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = (1 << _Fs_) | (1 << _Ft_); + VUregsn->VIread = (1 << _Is_) | (1 << _It_); } void _vuRegsILWR(VURegs * VU, _VURegsNum *VUregsn) { @@ -2621,8 +2650,8 @@ void _vuRegsILWR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = (1 << _Ft_); - VUregsn->VIread = (1 << _Fs_); + VUregsn->VIwrite = (1 << _It_); + VUregsn->VIread = (1 << _Is_); VUregsn->cycles = 3; } @@ -2632,7 +2661,7 @@ void _vuRegsISWR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = (1 << _Fs_) | (1 << _Ft_); + VUregsn->VIread = (1 << _Is_) | (1 << _It_); } void _vuRegsRINIT(VURegs * VU, _VURegsNum *VUregsn) { @@ -2689,7 +2718,7 @@ void _vuRegsFSAND(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; + VUregsn->VIwrite = 1 << _It_; VUregsn->VIread = 1 << REG_STATUS_FLAG; } @@ -2698,7 +2727,7 @@ void _vuRegsFSEQ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; + VUregsn->VIwrite = 1 << _It_; VUregsn->VIread = 1 << REG_STATUS_FLAG; } @@ -2707,7 +2736,7 @@ void _vuRegsFSOR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; + VUregsn->VIwrite = 1 << _It_; VUregsn->VIread = 1 << REG_STATUS_FLAG; } @@ -2725,8 +2754,8 @@ void _vuRegsFMAND(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; - VUregsn->VIread = (1 << REG_MAC_FLAG) | (1 << _Fs_); + VUregsn->VIwrite = 1 << _It_; + VUregsn->VIread = (1 << REG_MAC_FLAG) | (1 << _Is_); } void _vuRegsFMEQ(VURegs * VU, _VURegsNum *VUregsn) { @@ -2734,8 +2763,8 @@ void _vuRegsFMEQ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; - VUregsn->VIread = (1 << REG_MAC_FLAG) | (1 << _Fs_); + VUregsn->VIwrite = 1 << _It_; + VUregsn->VIread = (1 << REG_MAC_FLAG) | (1 << _Is_); } void _vuRegsFMOR(VURegs * VU, _VURegsNum *VUregsn) { @@ -2743,8 +2772,8 @@ void _vuRegsFMOR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; - VUregsn->VIread = (1 << REG_MAC_FLAG) | (1 << _Fs_); + VUregsn->VIwrite = 1 << _It_; + VUregsn->VIread = (1 << REG_MAC_FLAG) | (1 << _Is_); } void _vuRegsFCAND(VURegs * VU, _VURegsNum *VUregsn) { @@ -2788,7 +2817,7 @@ void _vuRegsFCGET(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; + VUregsn->VIwrite = 1 << _It_; VUregsn->VIread = 1 << REG_CLIP_FLAG; } @@ -2798,7 +2827,7 @@ void _vuRegsIBEQ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = (1 << _Fs_) | (1 << _Ft_); + VUregsn->VIread = (1 << _Is_) | (1 << _It_); } void _vuRegsIBGEZ(VURegs * VU, _VURegsNum *VUregsn) { @@ -2807,7 +2836,7 @@ void _vuRegsIBGEZ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = 1 << _Fs_; + VUregsn->VIread = 1 << _Is_; } void _vuRegsIBGTZ(VURegs * VU, _VURegsNum *VUregsn) { @@ -2816,7 +2845,7 @@ void _vuRegsIBGTZ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = 1 << _Fs_; + VUregsn->VIread = 1 << _Is_; } void _vuRegsIBLEZ(VURegs * VU, _VURegsNum *VUregsn) { @@ -2825,7 +2854,7 @@ void _vuRegsIBLEZ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = 1 << _Fs_; + VUregsn->VIread = 1 << _Is_; } void _vuRegsIBLTZ(VURegs * VU, _VURegsNum *VUregsn) { @@ -2834,7 +2863,7 @@ void _vuRegsIBLTZ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = 1 << _Fs_; + VUregsn->VIread = 1 << _Is_; } void _vuRegsIBNE(VURegs * VU, _VURegsNum *VUregsn) { @@ -2843,7 +2872,7 @@ void _vuRegsIBNE(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = (1 << _Fs_) | (1 << _Ft_); + VUregsn->VIread = (1 << _Is_) | (1 << _It_); } void _vuRegsB(VURegs * VU, _VURegsNum *VUregsn) { @@ -2860,7 +2889,7 @@ void _vuRegsBAL(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; + VUregsn->VIwrite = 1 << _It_; VUregsn->VIread = 0; } @@ -2870,7 +2899,7 @@ void _vuRegsJR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = 1 << _Fs_; + VUregsn->VIread = 1 << _Is_; } void _vuRegsJALR(VURegs * VU, _VURegsNum *VUregsn) { @@ -2878,8 +2907,8 @@ void _vuRegsJALR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; - VUregsn->VIread = 1 << _Fs_; + VUregsn->VIwrite = 1 << _It_; + VUregsn->VIread = 1 << _Is_; } void _vuRegsMFP(VURegs * VU, _VURegsNum *VUregsn) { @@ -2920,7 +2949,7 @@ void _vuRegsXITOP(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; + VUregsn->VIwrite = 1 << _It_; VUregsn->VIread = 0; VUregsn->cycles = 0; } @@ -2931,7 +2960,7 @@ void _vuRegsXGKICK(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; VUregsn->VIwrite = 0; - VUregsn->VIread = 1 << _Fs_; + VUregsn->VIread = 1 << _Is_; } void _vuRegsXTOP(VURegs * VU, _VURegsNum *VUregsn) { @@ -2939,7 +2968,7 @@ void _vuRegsXTOP(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; VUregsn->VFread1 = 0; - VUregsn->VIwrite = 1 << _Ft_; + VUregsn->VIwrite = 1 << _It_; VUregsn->VIread = 0; VUregsn->cycles = 0; } diff --git a/pcsx2/VUops.h b/pcsx2/VUops.h index 2512002169..c19e021279 100644 --- a/pcsx2/VUops.h +++ b/pcsx2/VUops.h @@ -16,9 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef __VU1OPS_H__ -#define __VU1OPS_H__ - +#pragma once #include "VU.h" extern __forceinline u32 VU_MAC_UPDATE( int shift, VURegs * VU, float f); @@ -395,5 +393,3 @@ void _vuRegsEEXP(VURegs * VU, _VURegsNum *VUregsn); void _vuRegsXITOP(VURegs * VU, _VURegsNum *VUregsn); void _vuRegsXGKICK(VURegs * VU, _VURegsNum *VUregsn); void _vuRegsXTOP(VURegs * VU, _VURegsNum *VUregsn); - -#endif diff --git a/pcsx2/Vif.cpp b/pcsx2/Vif.cpp index 0da6e70175..f16a8e2cda 100644 --- a/pcsx2/Vif.cpp +++ b/pcsx2/Vif.cpp @@ -397,7 +397,7 @@ static __forceinline int mfifo_VIF1chain() /* Is QWC = 0? if so there is nothing to transfer */ if ((vif1ch->qwc == 0) && (!vif1.vifstalled)) { - vif1.inprogress = 0; + vif1.inprogress &= ~1; return 0; } @@ -451,7 +451,7 @@ void mfifoVIF1transfer(int qwc) mfifodmairq = false; //Clear any previous TIE interrupt - if (vif1ch->qwc == 0) + if (vif1ch->qwc == 0 && vifqwc > 0) { ptag = (u32*)dmaGetAddr(vif1ch->tadr); @@ -533,13 +533,28 @@ void vifMFIFOInterrupt() { g_vifCycles = 0; + if(schedulepath3msk) Vif1MskPath3(); + + if((vif1Regs->stat & VIF1_STAT_VGW)) + { + if(gif->chcr & 0x100) + { + CPU_INT(10, 16); + return; + } + else vif1Regs->stat &= ~VIF1_STAT_VGW; + + } + if((spr0->chcr & 0x100) && spr0->qwc == 0) { spr0->chcr &= ~0x100; - hwDmacIrq(8); + hwDmacIrq(DMAC_FROM_SPR); } - if (vif1.inprogress == 1) mfifo_VIF1chain(); + + + if (vif1.irq && vif1.tag.size == 0) { @@ -554,33 +569,45 @@ void vifMFIFOInterrupt() } } - if (!vif1.done || vif1.inprogress & 1) + if (vif1.done == false || vif1ch->qwc) { - if (vifqwc <= 0) - { - //Console::WriteLn("Empty 1"); - vif1.inprogress |= 0x10; - vif1Regs->stat &= ~0x1F000000; // FQC=0 - hwDmacIrq(14); - return; - } - if (!(vif1.inprogress & 0x1)) mfifoVIF1transfer(0); - - if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR))) - CPU_INT(10, 0); - else - CPU_INT(10, vif1ch->qwc * BIAS); - + + switch(vif1.inprogress & 1) + { + case 0: //Set up transfer + if (vif1ch->tadr == spr0->madr) + { + // Console::WriteLn("Empty 1"); + vifqwc = 0; + vif1.inprogress |= 0x10; + vif1Regs->stat &= ~0x1F000000; // FQC=0 + hwDmacIrq(DMAC_14); + return; + } + + mfifoVIF1transfer(0); + if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR))) + CPU_INT(10, 0); + else + CPU_INT(10, vif1ch->qwc * BIAS); + + return; + case 1: //Transfer data + mfifo_VIF1chain(); + CPU_INT(10, 0); + return; + } return; - } - else if (vifqwc <= 0) + } + + /*if (vifqwc <= 0) { //Console::WriteLn("Empty 2"); - vif1.inprogress |= 0x10; + //vif1.inprogress |= 0x10; vif1Regs->stat &= ~0x1F000000; // FQC=0 - hwDmacIrq(14); - } + hwDmacIrq(DMAC_14); + }*/ //On a TIE break we do not clear the MFIFO (Art of Fighting) //If we dont clear it on MFIFO end, Tekken Tag breaks, understandably (Refraction) diff --git a/pcsx2/Vif.h b/pcsx2/Vif.h index 2f84369b5a..64335c4dde 100644 --- a/pcsx2/Vif.h +++ b/pcsx2/Vif.h @@ -92,16 +92,16 @@ static __forceinline u32 setVifRowRegs(u32 reg, u32 data) switch (reg) { case 0: - vifRegs->r0 += data; + vifRegs->r0 = data; break; case 1: - vifRegs->r1 += data; + vifRegs->r1 = data; break; case 2: - vifRegs->r2 += data; + vifRegs->r2 = data; break; case 3: - vifRegs->r3 += data; + vifRegs->r3 = data; break; jNO_DEFAULT; } diff --git a/pcsx2/VifDma.cpp b/pcsx2/VifDma.cpp index 37c25ed4e3..7552899a5e 100644 --- a/pcsx2/VifDma.cpp +++ b/pcsx2/VifDma.cpp @@ -58,8 +58,7 @@ static const unsigned int VIF0dmanum = 0; static const unsigned int VIF1dmanum = 1; int g_vifCycles = 0; -bool path3hack = false; -bool Path3transfer = false; +Path3Modes Path3progress = STOPPED_MODE; u32 splittransfer[4]; u32 splitptr = 0; @@ -329,6 +328,10 @@ static void ProcessMemSkip(int size, unsigned int unpackType, const unsigned int VIFUNPACK_LOG("addr aligned to %x", vif->tag.addr); vif->tag.addr = (vif->tag.addr & ~0xf) + (vifRegs->offset * 4); } + if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) + { + vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff); + } } @@ -340,9 +343,8 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int const VIFUnpackFuncTable *ft; VURegs * VU; u8 *cdata = (u8*)data; - - -#ifdef _DEBUG + +#ifdef PCSX2_DEBUG u32 memsize = VIFdmanum ? 0x4000 : 0x1000; #endif @@ -353,7 +355,6 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int vifMaskRegs = g_vif0Masks; vif = &vif0; vifRow = g_vifRow0; - assert(v->addr < memsize); } else { @@ -362,8 +363,8 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int vifMaskRegs = g_vif1Masks; vif = &vif1; vifRow = g_vifRow1; - assert(v->addr < memsize); } + assert(v->addr < memsize); dest = (u32*)(VU->Mem + v->addr); @@ -378,7 +379,7 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int size <<= 2; -#ifdef _DEBUG +#ifdef PCSX2_DEBUG memsize = size; #endif @@ -394,14 +395,11 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int VIFUNPACK_LOG("Aligning packet size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr); - if(((size / ft->dsize) + vifRegs->offset) < (u32)ft->qsize) - VIFUNPACK_LOG("Warning! Size needed to align %x size chunks available %x offset %x", ft->qsize - ((size / ft->dsize) + vifRegs->offset), vifRegs->offset); - if (((u32)size / (u32)ft->dsize) < ((u32)ft->qsize - vifRegs->offset)) { DevCon::Error("Wasn't enough left size/dsize = %x left to write %x", params(size / ft->dsize), (ft->qsize - vifRegs->offset)); } - unpacksize = min(((u32)size / (u32)ft->dsize), ((u32)ft->qsize - vifRegs->offset)); + unpacksize = min((size / ft->dsize), (ft->qsize - vifRegs->offset)); VIFUNPACK_LOG("Increasing dest by %x from offset %x", (4 - ft->qsize) + unpacksize, vifRegs->offset); @@ -409,8 +407,17 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int func(dest, (u32*)cdata, unpacksize); size -= unpacksize * ft->dsize; - vifRegs->num--; - ++vif->cl; + if(vifRegs->offset == 0) + { + vifRegs->num--; + ++vif->cl; + } + else + { + DevCon::Notice("Offset = %x", params vifRegs->offset); + vif->tag.addr += unpacksize * 4; + return size>>2; + } if (vif->cl == vifRegs->cycle.wl) { @@ -454,12 +461,11 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int VIFUNPACK_LOG("Aligning packet done size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr); } } - if (vif->cl != 0 || (size & 0xf)) //Check alignment for SSE unpacks { -#ifdef _DEBUG +#ifdef PCSX2_DEBUG static int s_count = 0; #endif @@ -545,7 +551,6 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int return size>>2; } - static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned int VIFdmanum) { u32 *dest; @@ -555,9 +560,10 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i VURegs * VU; u8 *cdata = (u8*)data; u32 tempsize = 0; + const u32 memlimit = (VIFdmanum ? 0x4000 : 0x1000); -#ifdef _DEBUG - u32 memsize = VIFdmanum ? 0x4000 : 0x1000; +#ifdef PCSX2_DEBUG + u32 memsize = memlimit; #endif _mm_prefetch((char*)data, _MM_HINT_NTA); @@ -599,45 +605,55 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i size <<= 2; -#ifdef _DEBUG +#ifdef PCSX2_DEBUG memsize = size; #endif if (vifRegs->cycle.cl >= vifRegs->cycle.wl) // skipping write { -#ifdef _DEBUG +#ifdef PCSX2_DEBUG static int s_count = 0; #endif - if(v->addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) + if (v->addr >= memlimit) { //DevCon::Notice("Overflown at the start"); - v->addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff); + v->addr &= (memlimit - 1); dest = (u32*)(VU->Mem + v->addr); } - tempsize = min(vifRegs->num, (size / ft->gsize)); - tempsize = (vif->tag.addr + (size / (ft->gsize * vifRegs->cycle.wl)) * - ((vifRegs->cycle.cl - vifRegs->cycle.wl) * 16)) + (tempsize * 16); + size = min(size, (int)vifRegs->num * ft->gsize); //size will always be the same or smaller + tempsize = vif->tag.addr + ((((vifRegs->num-1) / vifRegs->cycle.wl) * + (vifRegs->cycle.cl - vifRegs->cycle.wl)) * 16) + (vifRegs->num * 16); + + /*tempsize = vif->tag.addr + (((size / (ft->gsize * vifRegs->cycle.wl)) * + (vifRegs->cycle.cl - vifRegs->cycle.wl)) * 16) + (vifRegs->num * 16);*/ + + //Sanity Check (memory overflow) - if(tempsize > (u32)(VIFdmanum ? 0x4000 : 0x1000)) + if (tempsize > memlimit) { - - //DevCon::Notice("VIF%x Unpack ending %x > %x", params VIFdmanum, tempsize, VIFdmanum ? 0x4000 : 0x1000); - if(vifRegs->cycle.cl == 1 && ((u32)(VIFdmanum ? 0x4000 : 0x1000) + ((vifRegs->cycle.cl - vifRegs->cycle.wl) * 16)) == tempsize - || tempsize == (u32)(VIFdmanum ? 0x4000 : 0x1000)) + if (((vifRegs->cycle.cl != vifRegs->cycle.wl) && + ((memlimit + (vifRegs->cycle.cl - vifRegs->cycle.wl) * 16) == tempsize) || + (tempsize == memlimit))) { //Its a red herring! so ignore it! SSE unpacks will be much quicker tempsize = 0; } else { + //DevCon::Notice("VIF%x Unpack ending %x > %x", params VIFdmanum, tempsize, VIFdmanum ? 0x4000 : 0x1000); tempsize = size; size = 0; } - } else tempsize = 0; - + } + else + { + tempsize = 0; //Commenting out this then + //tempsize = size; // -\_uncommenting these Two enables non-SSE unpacks + //size = 0; // -/ + } if (size >= ft->gsize) { @@ -673,14 +689,13 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i } #endif - if ((vifRegs->cycle.cl == 0) || (vifRegs->cycle.wl == 0) || ((vifRegs->cycle.cl == vifRegs->cycle.wl) && !(vifRegs->code & 0x10000000))) + if ((vifRegs->cycle.cl == 0) || (vifRegs->cycle.wl == 0) || + ((vifRegs->cycle.cl == vifRegs->cycle.wl) && !(vifRegs->code & 0x10000000))) { oldcycle = *(u32*) & vifRegs->cycle; vifRegs->cycle.cl = vifRegs->cycle.wl = 1; } - size = min(size, (int)vifRegs->num * ft->gsize); //size will always be the same or smaller - pfn = vif->usn ? VIFfuncTableSSE[unpackType].funcU : VIFfuncTableSSE[unpackType].funcS; writemask = VIFdmanum ? g_vif1HasMask3[min(vifRegs->cycle.wl,(u8)3)] : g_vif0HasMask3[min(vifRegs->cycle.wl,(u8)3)]; writemask = pfn[(((vifRegs->code & 0x10000000)>>28)<mode](dest, (u32*)cdata, size); @@ -709,7 +724,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i if (size >= ft->dsize && vifRegs->num > 0) { - //VIF_LOG("warning, end with size = %d", size); + VIF_LOG("warning, end with size = %d", size); /* unpack one qword */ //vif->tag.addr += (size / ft->dsize) * 4; @@ -739,15 +754,17 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i { int incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4; size = 0; + int addrstart = v->addr; if((tempsize >> 2) != vif->tag.size) DevCon::Notice("split when size != tagsize"); VIFUNPACK_LOG("sorting tempsize :p, size %d, vifnum %d, addr %x", tempsize, vifRegs->num, vif->tag.addr); while ((tempsize >= ft->gsize) && (vifRegs->num > 0)) { - if(v->addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) + if(v->addr >= memlimit) { - v->addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff); + DevCon::Notice("Mem limit ovf"); + v->addr &= (memlimit - 1); dest = (u32*)(VU->Mem + v->addr); } @@ -778,17 +795,18 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i vifRow[2] = vifRegs->r2; vifRow[3] = vifRegs->r3; } - if(v->addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) + if(v->addr >= memlimit) { - v->addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff); + v->addr &= (memlimit - 1); dest = (u32*)(VU->Mem + v->addr); } + v->addr = addrstart; if(tempsize > 0) size = tempsize; } if (size >= ft->dsize && vifRegs->num > 0) //Else write what we do have { - //VIF_LOG("warning, end with size = %d", size); + VIF_LOG("warning, end with size = %d", size); /* unpack one qword */ //vif->tag.addr += (size / ft->dsize) * 4; @@ -813,7 +831,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i if((u32)(((size / ft->gsize) / vifRegs->cycle.cl) * vifRegs->cycle.wl) < vifRegs->num) DevCon::Notice("Filling write warning! %x < %x and CL = %x WL = %x", params (size / ft->gsize), vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl); - DevCon::Notice("filling write %d cl %d, wl %d mask %x mode %x unpacktype %x addr %x", params vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mask, vifRegs->mode, unpackType, vif->tag.addr); + //DevCon::Notice("filling write %d cl %d, wl %d mask %x mode %x unpacktype %x addr %x", params vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mask, vifRegs->mode, unpackType, vif->tag.addr); while (vifRegs->num > 0) { if (vif->cl == vifRegs->cycle.wl) @@ -828,11 +846,13 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i VIF_LOG("Out of Filling write data"); break; } + func(dest, (u32*)cdata, ft->qsize); cdata += ft->gsize; size -= ft->gsize; vif->cl++; vifRegs->num--; + if (vif->cl == vifRegs->cycle.wl) { vif->cl = 0; @@ -866,6 +886,7 @@ static void vuExecMicro(u32 addr, const u32 VIFdmanum) VU = &VU1; vif1FLUSH(); } + if (VU->vifRegs->itops > (VIFdmanum ? 0x3ffu : 0xffu)) Console::WriteLn("VIF%d ITOP overrun! %x", params VIFdmanum, VU->vifRegs->itops); @@ -912,8 +933,6 @@ void vif0Init() static __forceinline void vif0UNPACK(u32 *data) { int vifNum; - int vl, vn; - int len; if (vif0Regs->cycle.wl == 0 && vif0Regs->cycle.wl < vif0Regs->cycle.cl) { @@ -924,9 +943,7 @@ static __forceinline void vif0UNPACK(u32 *data) vif0FLUSH(); - vl = (vif0.cmd) & 0x3; - vn = (vif0.cmd >> 2) & 0x3; - vif0.tag.addr = (vif0Regs->code & 0x3ff) << 4; + vif0.tag.addr = (vif0Regs->code & 0xff) << 4; vif0.usn = (vif0Regs->code >> 14) & 0x1; vifNum = (vif0Regs->code >> 16) & 0xff; if (vifNum == 0) vifNum = 256; @@ -934,20 +951,18 @@ static __forceinline void vif0UNPACK(u32 *data) if (vif0Regs->cycle.wl <= vif0Regs->cycle.cl) { - len = (((32 >> vl) * (vn + 1)) * vifNum + 31) >> 5; + vif0.tag.size = ((vifNum * VIFfuncTable[ vif0.cmd & 0xf ].gsize) + 3) >> 2; } else { int n = vif0Regs->cycle.cl * (vifNum / vif0Regs->cycle.wl) + _limit(vifNum % vif0Regs->cycle.wl, vif0Regs->cycle.cl); - len = ((((32 >> vl) * (vn + 1)) * n) + 31) >> 5; + vif0.tag.size = ((n * VIFfuncTable[ vif0.cmd & 0xf ].gsize) + 3) >> 2; } vif0.cl = 0; vif0.tag.cmd = vif0.cmd; - vif0.tag.addr &= 0xfff; - vif0.tag.size = len; vif0Regs->offset = 0; @@ -1060,19 +1075,24 @@ static int __fastcall Vif0TransMPG(u32 *data) // MPG if (vif0.vifpacketsize < vif0.tag.size) { if((vif0.tag.addr + vif0.vifpacketsize) > 0x1000) DevCon::Notice("Vif0 MPG Split Overflow"); + vif0mpgTransfer(vif0.tag.addr, data, vif0.vifpacketsize); vif0.tag.addr += vif0.vifpacketsize << 2; vif0.tag.size -= vif0.vifpacketsize; + return vif0.vifpacketsize; } else { int ret; + if((vif0.tag.addr + vif0.tag.size) > 0x1000) DevCon::Notice("Vif0 MPG Overflow"); + vif0mpgTransfer(vif0.tag.addr, data, vif0.tag.size); ret = vif0.tag.size; vif0.tag.size = 0; vif0.cmd = 0; + return ret; } } @@ -1090,10 +1110,13 @@ static int __fastcall Vif0TransUnpack(u32 *data) // UNPACK vif0.tag.size -= vif0.vifpacketsize - VIFalign(data, &vif0.tag, vif0.vifpacketsize, VIF0dmanum); ret = ret - vif0.tag.size; data += ret; + if(vif0.vifpacketsize > 0) VIFunpack(data, &vif0.tag, vif0.vifpacketsize - ret, VIF0dmanum); + ProcessMemSkip((vif0.vifpacketsize - ret) << 2, (vif0.cmd & 0xf), VIF0dmanum); vif0.tag.size -= (vif0.vifpacketsize - ret); FreezeXMMRegs(0); + return vif0.vifpacketsize; } /* size is less that the total size, transfer is 'in pieces' */ @@ -1337,7 +1360,13 @@ int _VIF0chain() if ((vif0ch->qwc == 0) && !vif0.vifstalled) return 0; pMem = (u32*)dmaGetAddr(vif0ch->madr); - if (pMem == NULL) return -1; + if (pMem == NULL) + { + vif0.cmd = 0; + vif0.tag.size = 0; + vif0ch->qwc = 0; + return 0; + } if (vif0.vifstalled) ret = VIF0transfer(pMem + vif0.irqoffset, vif0ch->qwc * 4 - vif0.irqoffset, 0); @@ -1356,7 +1385,7 @@ int _chainVIF0() { Console::Error("Vif0 Tag BUSERR"); vif0ch->chcr = (vif0ch->chcr & 0xFFFF) | ((*vif0ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15 - psHu32(DMAC_STAT) |= 1 << 15; //If yes, set BEIS (BUSERR) in DMAC_STAT register + psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register return -1; //Return -1 as an error has occurred } @@ -1391,10 +1420,9 @@ int _chainVIF0() { VIF_LOG("dmaIrq Set\n"); - vif0.done = true; - return (vif0.done)?1:0; //End Transfer + vif0.done = true; //End Transfer } - return (vif0.done)?1:0; //Return Done + return (vif0.done) ? 1: 0; //Return Done } void vif0Interrupt() @@ -1414,6 +1442,7 @@ void vif0Interrupt() vif0ch->chcr &= ~0x100; return; } + if (vif0ch->qwc > 0 || vif0.irqoffset > 0) { if (vif0.stallontag) @@ -1448,6 +1477,7 @@ void vif0Interrupt() if (vif0ch->qwc > 0) Console::WriteLn("VIF0 Ending with QWC left"); if (vif0.cmd != 0) Console::WriteLn("vif0.cmd still set %x", params vif0.cmd); + vif0ch->chcr &= ~0x100; hwDmacIrq(DMAC_VIF0); vif0Regs->stat &= ~0xF000000; // FQC=0 @@ -1508,6 +1538,7 @@ void dmaVIF0() vif0.vifstalled = true; return; } + vif0.done = true; CPU_INT(0, g_vifCycles); return; @@ -1522,7 +1553,7 @@ void vif0Write32(u32 mem, u32 value) { switch (mem) { - case 0x10003830: // MARK + case VIF0_MARK: VIF_LOG("VIF0_MARK write32 0x%8.8x", value); /* Clear mark flag in VIF0_STAT and set mark with 'value' */ @@ -1530,7 +1561,7 @@ void vif0Write32(u32 mem, u32 value) vif0Regs->mark = value; break; - case 0x10003810: // FBRST + case VIF0_FBRST: VIF_LOG("VIF0_FBRST write32 0x%8.8x", value); if (value & 0x1) @@ -1540,12 +1571,13 @@ void vif0Write32(u32 mem, u32 value) memzero_obj(vif0); vif0ch->qwc = 0; //? cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's - psHu64(0x10004000) = 0; - psHu64(0x10004008) = 0; + psHu64(VIF0_FIFO) = 0; + psHu64(0x10004008) = 0; // VIF0_FIFO + 8 vif0.done = true; vif0Regs->err = 0; vif0Regs->stat &= ~(0xF000000 | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0 } + if (value & 0x2) { /* Force Break the VIF */ @@ -1555,7 +1587,8 @@ void vif0Write32(u32 mem, u32 value) vif0Regs->stat &= ~VIF0_STAT_VPS; vif0.vifstalled = true; Console::WriteLn("vif0 force break"); - } + } + if (value & 0x4) { /* Stop VIF */ @@ -1565,6 +1598,7 @@ void vif0Write32(u32 mem, u32 value) vif0Regs->stat &= ~VIF0_STAT_VPS; vif0.vifstalled = true; } + if (value & 0x8) { bool cancel = false; @@ -1594,7 +1628,7 @@ void vif0Write32(u32 mem, u32 value) } break; - case 0x10003820: + case VIF0_ERR: // ERR VIF_LOG("VIF0_ERR write32 0x%8.8x", value); @@ -1602,22 +1636,25 @@ void vif0Write32(u32 mem, u32 value) vif0Regs->err = value; break; + case VIF0_R0: + case VIF0_R1: + case VIF0_R2: + case VIF0_R3: + assert((mem&0xf) == 0); + g_vifRow0[(mem>>4) & 3] = value; + break; + + case VIF0_C0: + case VIF0_C1: + case VIF0_C2: + case VIF0_C3: + assert((mem&0xf) == 0); + g_vifCol0[(mem>>4) & 3] = value; + break; + default: Console::WriteLn("Unknown Vif0 write to %x", params mem); - if (mem >= 0x10003900 && mem < 0x10003980) - { - assert((mem&0xf) == 0); - - if (mem < 0x10003940) - g_vifRow0[(mem>>4)&3] = value; - else - g_vifCol0[(mem>>4)&3] = value; - - } - else - { - psHu32(mem) = value; - } + psHu32(mem) = value; break; } /* Other registers are read-only so do nothing for them */ @@ -1629,8 +1666,8 @@ void vif0Reset() memzero_obj(vif0); memzero_obj(*vif0Regs); SetNewMask(g_vif0Masks, g_vif0HasMask3, 0, 0xffffffff); - psHu64(0x10004000) = 0; - psHu64(0x10004008) = 0; + psHu64(VIF0_FIFO) = 0; + psHu64(0x10004008) = 0; // VIF0_FIFO + 8 vif0Regs->stat &= ~VIF0_STAT_VPS; vif0.done = true; vif0Regs->stat &= ~0xF000000; // FQC=0 @@ -1668,7 +1705,6 @@ void vif1Init() static __forceinline void vif1UNPACK(u32 *data) { int vifNum; - int vl, vn; if (vif1Regs->cycle.wl == 0) { @@ -1679,10 +1715,7 @@ static __forceinline void vif1UNPACK(u32 *data) return; } } - vif1FLUSH(); - - vl = (vif1.cmd) & 0x3; - vn = (vif1.cmd >> 2) & 0x3; + //vif1FLUSH(); vif1.usn = (vif1Regs->code >> 14) & 0x1; vifNum = (vif1Regs->code >> 16) & 0xff; @@ -1692,14 +1725,16 @@ static __forceinline void vif1UNPACK(u32 *data) if (vif1Regs->cycle.wl <= vif1Regs->cycle.cl) { - vif1.tag.size = (((32 >> vl) * (vn + 1)) * vifNum + 31) >> 5; + vif1.tag.size = ((vifNum * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2; } else { int n = vif1Regs->cycle.cl * (vifNum / vif1Regs->cycle.wl) + _limit(vifNum % vif1Regs->cycle.wl, vif1Regs->cycle.cl); - vif1.tag.size = ((((32 >> vl) * (vn + 1)) * n) + 31) >> 5; - } + + vif1.tag.size = ((n * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2; + } + if ((vif1Regs->code >> 15) & 0x1) vif1.tag.addr = (vif1Regs->code + vif1Regs->tops) & 0x3ff; else @@ -1773,7 +1808,7 @@ static int __fastcall Vif1TransSTRow(u32 *data) pmem[0] = data[0]; pmem2[0] = data[0]; break; - jNO_DEFAULT; + jNO_DEFAULT; } vif1.tag.addr += ret; vif1.tag.size -= ret; @@ -1838,6 +1873,17 @@ static int __fastcall Vif1TransDirectHL(u32 *data) { int ret = 0; + if ((vif1.cmd & 0x7f) == 0x51) + { + if (gif->chcr & 0x100 && (!vif1Regs->mskpath3 && (Path3progress == IMAGE_MODE))) //PATH3 is in image mode, so wait for end of transfer + { + vif1Regs->stat |= VIF1_STAT_VGW; + return 0; + } + } + + psHu32(GIF_STAT) |= (GIF_STAT_APATH2 | GIF_STAT_OPH); + if (splitptr > 0) //Leftover data from the last packet, filling the rest and sending to the GS { if ((splitptr < 4) && (vif1.vifpacketsize >= (4 - splitptr))) @@ -1891,6 +1937,7 @@ static int __fastcall Vif1TransDirectHL(u32 *data) } else { + psHu32(GIF_STAT) &= ~(GIF_STAT_APATH2 | GIF_STAT_OPH); ret = vif1.tag.size; vif1.tag.size = 0; vif1.cmd = 0; @@ -1973,18 +2020,19 @@ static int __fastcall Vif1TransUnpack(u32 *data) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Vif1 CMD Base Commands //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// fixme: Global variables should not have the same name as local variables, and this probably shouldn't be local anyways. -int transferred = 0; + static void Vif1CMDNop() // NOP { vif1.cmd &= ~0x7f; } + static void Vif1CMDSTCycl() // STCYCL { vif1Regs->cycle.cl = (u8)vif1Regs->code; vif1Regs->cycle.wl = (u8)(vif1Regs->code >> 8); vif1.cmd &= ~0x7f; } + static void Vif1CMDOffset() // OFFSET { vif1Regs->ofst = vif1Regs->code & 0x3ff; @@ -1992,11 +2040,13 @@ static void Vif1CMDOffset() // OFFSET vif1Regs->tops = vif1Regs->base; vif1.cmd &= ~0x7f; } + static void Vif1CMDBase() // BASE { vif1Regs->base = vif1Regs->code & 0x3ff; vif1.cmd &= ~0x7f; } + static void Vif1CMDITop() // ITOP { vif1Regs->itops = vif1Regs->code & 0x3ff; @@ -2009,82 +2059,85 @@ static void Vif1CMDSTMod() // STMOD vif1.cmd &= ~0x7f; } -static void Vif1CMDMskPath3() // MSKPATH3 -{ +u8 schedulepath3msk = 0; - vif1Regs->mskpath3 = (vif1Regs->code >> 15) & 0x1; +void Vif1MskPath3() // MSKPATH3 +{ + vif1Regs->mskpath3 = schedulepath3msk & 0x1; //Console::WriteLn("VIF MSKPATH3 %x", params vif1Regs->mskpath3); -#ifdef GSPATH3FIX - if ((vif1Regs->code >> 15) & 0x1) - { - while ((gif->chcr & 0x100)) //Can be done 2 different ways, depends on the game/company - { - if (!path3hack && !Path3transfer && (gif->qwc == 0)) break; - - gsInterrupt(); - - if (path3hack && (gif->qwc == 0)) break; //add games not working with it to elfheader.c to enable this instead - } - psHu32(GIF_STAT) |= 0x2; - } - else - { - // fixme: This is the *only* reason 'transferred' is global. Otherwise it'd be local to Vif1Transfer. - if (gif->chcr & 0x100) CPU_INT(2, (transferred >> 2) * BIAS); // Restart Path3 on its own, time it right! - psHu32(GIF_STAT) &= ~0x2; - } -#else if (vif1Regs->mskpath3) { - if (gif->qwc) _GIFchain(); // Finish the transfer first psHu32(GIF_STAT) |= 0x2; } else { + //Let the Gif know it can transfer again (making sure any vif stall isnt unset prematurely) + Path3progress = TRANSFER_MODE; psHu32(GIF_STAT) &= ~0x2; - if (gif->qwc) _GIFchain(); // Finish the transfer first + CPU_INT(2, 4); + } + + schedulepath3msk = 0; +} +static void Vif1CMDMskPath3() // MSKPATH3 +{ + if(vif1ch->chcr & 0x100) + { + schedulepath3msk = 0x10 | ((vif1Regs->code >> 15) & 0x1); + vif1.vifstalled = true; + } + else + { + schedulepath3msk = (vif1Regs->code >> 15) & 0x1; + Vif1MskPath3(); } -#endif vif1.cmd &= ~0x7f; } + static void Vif1CMDMark() // MARK { vif1Regs->mark = (u16)vif1Regs->code; vif1Regs->stat |= VIF1_STAT_MRK; vif1.cmd &= ~0x7f; } + static void Vif1CMDFlush() // FLUSH/E/A { - vif1FLUSH(); if ((vif1.cmd & 0x7f) == 0x13) { - while ((gif->chcr & 0x100)) - { - if (!Path3transfer && gif->qwc == 0) break; - gsInterrupt(); + // Gif is already transferring so wait for it. + if (((Path3progress != STOPPED_MODE) || !vif1Regs->mskpath3) && gif->chcr & 0x100) + { + vif1Regs->stat |= VIF1_STAT_VGW; + CPU_INT(2, 4); } } vif1.cmd &= ~0x7f; } + static void Vif1CMDMSCALF() //MSCAL/F { + vif1FLUSH(); vuExecMicro((u16)(vif1Regs->code) << 3, VIF1dmanum); vif1.cmd &= ~0x7f; } + static void Vif1CMDMSCNT() // MSCNT { vuExecMicro(-1, VIF1dmanum); vif1.cmd &= ~0x7f; } + static void Vif1CMDSTMask() // STMASK { vif1.tag.size = 1; } + static void Vif1CMDSTRowCol() // STROW / STCOL { vif1.tag.addr = 0; @@ -2094,7 +2147,7 @@ static void Vif1CMDSTRowCol() // STROW / STCOL static void Vif1CMDMPGTransfer() // MPG { int vifNum; - vif1FLUSH(); + //vif1FLUSH(); vifNum = (u8)(vif1Regs->code >> 16); if (vifNum == 0) vifNum = 256; @@ -2102,6 +2155,7 @@ static void Vif1CMDMPGTransfer() // MPG vif1.tag.addr = (u16)((vif1Regs->code) << 3) & 0x3fff; vif1.tag.size = vifNum * 2; } + static void Vif1CMDDirectHL() // DIRECT/HL { int vifImm; @@ -2111,12 +2165,8 @@ static void Vif1CMDDirectHL() // DIRECT/HL vif1.tag.size = 65536 << 2; else vif1.tag.size = vifImm << 2; - - while ((gif->chcr & 0x100) && (vif1.cmd & 0x7f) == 0x51) - { - gsInterrupt(); //DirectHL flushes the lot - } } + static void Vif1CMDNull() // invalid opcode { // if ME1, then force the vif to interrupt @@ -2175,7 +2225,7 @@ void (*Vif1CMDTLB[82])() = int VIF1transfer(u32 *data, int size, int istag) { int ret; - transferred = vif1.vifstalled ? vif1.irqoffset : 0; // irqoffset necessary to add up the right qws, or else will spin (spiderman) + int transferred = vif1.vifstalled ? vif1.irqoffset : 0; // irqoffset necessary to add up the right qws, or else will spin (spiderman) VIF_LOG("VIF1transfer: size %x (vif1.cmd %x)", size, vif1.cmd); @@ -2185,7 +2235,9 @@ int VIF1transfer(u32 *data, int size, int istag) vif1.vifpacketsize = size; while (vif1.vifpacketsize > 0) - { + { + if(vif1Regs->stat & VIF1_STAT_VGW) break; + if (vif1.cmd) { vif1Regs->stat |= VIF1_STAT_VPS_T; //Decompression has started @@ -2245,6 +2297,9 @@ int VIF1transfer(u32 *data, int size, int istag) } } + if(!vif1.cmd) vif1Regs->stat &= ~VIF1_STAT_VPS_D; + + if((vif1Regs->stat & VIF1_STAT_VGW) || vif1.vifstalled == true) break; } // End of Transfer loop transferred += size - vif1.vifpacketsize; @@ -2255,10 +2310,10 @@ int VIF1transfer(u32 *data, int size, int istag) { vif1.vifstalled = true; - if (((vif1Regs->code >> 24) & 0x7f) != 0x7)vif1Regs->stat |= VIF1_STAT_VIS; // Note: commenting this out fixes WALL-E + if (((vif1Regs->code >> 24) & 0x7f) != 0x7) vif1Regs->stat |= VIF1_STAT_VIS; // Note: commenting this out fixes WALL-E if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1)) - vif1.inprogress = 0; + vif1.inprogress &= ~0x1; // spiderman doesn't break on qw boundaries if (istag) return -2; @@ -2282,10 +2337,16 @@ int VIF1transfer(u32 *data, int size, int istag) vif1ch->qwc -= transferred; } - if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1)) - vif1.inprogress = 0; + if(vif1Regs->stat & VIF1_STAT_VGW) + { + vif1.vifstalled = true; + } + - return 0; + if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1)) + vif1.inprogress &= ~0x1; + + return vif1.vifstalled ? -2 : 0; } void vif1TransferFromMemory() @@ -2297,7 +2358,7 @@ void vif1TransferFromMemory() if (pMem == NULL) //Is vif0ptag empty? { Console::WriteLn("Vif1 Tag BUSERR"); - psHu32(DMAC_STAT) |= 1 << 15; //If yes, set BEIS (BUSERR) in DMAC_STAT register + psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register vif1.done = true; vif1Regs->stat &= ~0x1f000000; vif1ch->qwc = 0; @@ -2311,6 +2372,7 @@ void vif1TransferFromMemory() // completely and execute the transfer there-after. FreezeXMMRegs(1); + if (GSreadFIFO2 == NULL) { for (size = vif1ch->qwc; size > 0; --size) @@ -2334,9 +2396,9 @@ void vif1TransferFromMemory() psHu64(0x5000) = pMem[2*vif1ch->qwc-2]; psHu64(0x5008) = pMem[2*vif1ch->qwc-1]; } + FreezeXMMRegs(0); - - if (vif1Regs->mskpath3 == 0)vif1Regs->stat &= ~0x1f000000; + g_vifCycles += vif1ch->qwc * 2; vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes vif1ch->qwc = 0; @@ -2353,7 +2415,7 @@ int _VIF1chain() return 0; } - if (vif1.dmamode == 1) + if (vif1.dmamode == VIF_NORMAL_MEM_MODE) { vif1TransferFromMemory(); vif1.inprogress = 0; @@ -2361,7 +2423,13 @@ int _VIF1chain() } pMem = (u32*)dmaGetAddr(vif1ch->madr); - if (pMem == NULL) return -1; + if (pMem == NULL) + { + vif1.cmd = 0; + vif1.tag.size = 0; + vif1ch->qwc = 0; + return 0; + } VIF_LOG("VIF1chain size=%d, madr=%lx, tadr=%lx", vif1ch->qwc, vif1ch->madr, vif1ch->tadr); @@ -2383,13 +2451,14 @@ __forceinline void vif1SetupTransfer() { switch (vif1.dmamode) { - case 0: //Normal - case 1: //Normal (From memory) + case VIF_NORMAL_MODE: //Normal + case VIF_NORMAL_MEM_MODE: //Normal (From memory) vif1.inprogress = 1; vif1.done = true; + g_vifCycles = 2; break; - case 2: //Chain + case VIF_CHAIN_MODE: //Chain int id; int ret; @@ -2398,7 +2467,7 @@ __forceinline void vif1SetupTransfer() { Console::Error("Vif1 Tag BUSERR"); vif1ch->chcr = (vif1ch->chcr & 0xFFFF) | ((*vif1ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15 - psHu32(DMAC_STAT) |= 1 << 15; //If yes, set BEIS (BUSERR) in DMAC_STAT register + psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register return; //Return -1 as an error has occurred } @@ -2421,7 +2490,7 @@ __forceinline void vif1SetupTransfer() if ((vif1ch->madr + vif1ch->qwc * 16) >= psHu32(DMAC_STADR)) { // stalled - hwDmacIrq(13); + hwDmacIrq(DMAC_13); return; } } @@ -2436,7 +2505,7 @@ __forceinline void vif1SetupTransfer() else ret = VIF1transfer(vif1ptag + 2, 2, 1); //Transfer Tag - if (ret < 0) + if (ret < 0 && vif1.irqoffset < 2) { vif1.inprogress = 0; //Better clear this so it has to do it again (Jak 1) return; //There has been an error or an interrupt @@ -2463,6 +2532,19 @@ __forceinline void vif1Interrupt() g_vifCycles = 0; + if(schedulepath3msk) Vif1MskPath3(); + + if((vif1Regs->stat & VIF1_STAT_VGW)) + { + if(gif->chcr & 0x100) + { + CPU_INT(1, gif->qwc * BIAS); + return; + } + else vif1Regs->stat &= ~VIF1_STAT_VGW; + + } + if ((vif1ch->chcr & 0x100) == 0) Console::WriteLn("Vif1 running when CHCR == %x", params vif1ch->chcr); if (vif1.irq && vif1.tag.size == 0) @@ -2487,7 +2569,12 @@ __forceinline void vif1Interrupt() } } - if (vif1.inprogress) _VIF1chain(); + if (vif1.inprogress) + { + _VIF1chain(); + CPU_INT(1, g_vifCycles); + return; + } if ((!vif1.done) || (vif1.inprogress & 0x1)) { @@ -2500,7 +2587,7 @@ __forceinline void vif1Interrupt() if ((vif1.inprogress & 0x1) == 0) vif1SetupTransfer(); - CPU_INT(1, vif1ch->qwc * BIAS); + CPU_INT(1, g_vifCycles); return; } @@ -2511,18 +2598,23 @@ __forceinline void vif1Interrupt() } #ifdef PCSX2_DEVBUILD if (vif1ch->qwc > 0) Console::WriteLn("VIF1 Ending with %x QWC left"); - if (vif1.cmd != 0) Console::WriteLn("vif1.cmd still set %x", params vif1.cmd); + if (vif1.cmd != 0) Console::WriteLn("vif1.cmd still set %x tag size %x", params vif1.cmd, vif1.tag.size); #endif + vif1Regs->stat &= ~VIF1_STAT_VPS; //Vif goes idle as the stall happened between commands; vif1ch->chcr &= ~0x100; g_vifCycles = 0; hwDmacIrq(DMAC_VIF1); - if (vif1Regs->mskpath3 == 0 || (vif1ch->chcr & 0x1) == 0x1)vif1Regs->stat &= ~0x1F000000; // FQC=0 + + //Im not totally sure why Path3 Masking makes it want to see stuff in the fifo + //Games effected by setting, Fatal Frame, KH2, Shox, Crash N Burn, GT3/4 possibly + //Im guessing due to the full gs fifo before the reverse? (Refraction) + //Note also this is only the condition for reverse fifo mode, normal direction clears it as normal + if(!vif1Regs->mskpath3 || (vif1ch->chcr & 0x1))vif1Regs->stat &= ~0x1F000000; // FQC=0 } void dmaVIF1() { - VIF_LOG("dmaVIF1 chcr = %lx, madr = %lx, qwc = %lx\n" " tadr = %lx, asr0 = %lx, asr1 = %lx", vif1ch->chcr, vif1ch->madr, vif1ch->qwc, @@ -2530,9 +2622,7 @@ void dmaVIF1() g_vifCycles = 0; vif1.inprogress = 0; - - vif1Regs->stat |= 0x10000000; // FQC=16 - + if (((psHu32(DMAC_CTRL) & 0xC) == 0x8)) // VIF MFIFO { //Console::WriteLn("VIFMFIFO\n"); @@ -2548,7 +2638,6 @@ void dmaVIF1() } #endif - if (!(vif1ch->chcr & 0x4) || vif1ch->qwc > 0) // Normal Mode { @@ -2556,26 +2645,30 @@ void dmaVIF1() Console::WriteLn("DMA Stall Control on VIF1 normal"); if ((vif1ch->chcr & 0x1)) // to Memory - vif1.dmamode = 0; + vif1.dmamode = VIF_NORMAL_MODE; else - vif1.dmamode = 1; + vif1.dmamode = VIF_NORMAL_MEM_MODE; } else { - vif1.dmamode = 2; + vif1.dmamode = VIF_CHAIN_MODE; } + if(vif1.dmamode != VIF_NORMAL_MEM_MODE) + vif1Regs->stat |= 0x10000000; // FQC=16 + else + vif1Regs->stat |= min((u16)16, vif1ch->qwc) << 24; // FQC=16 + // Chain Mode vif1.done = false; - CPU_INT(1, 0); + vif1Interrupt(); } - void vif1Write32(u32 mem, u32 value) { switch (mem) { - case 0x10003c30: // MARK + case VIF1_MARK: VIF_LOG("VIF1_MARK write32 0x%8.8x", value); /* Clear mark flag in VIF1_STAT and set mark with 'value' */ @@ -2583,7 +2676,7 @@ void vif1Write32(u32 mem, u32 value) vif1Regs->mark = value; break; - case 0x10003c10: // FBRST + case VIF1_FBRST: // FBRST VIF_LOG("VIF1_FBRST write32 0x%8.8x", value); if (value & 0x1) @@ -2592,13 +2685,20 @@ void vif1Write32(u32 mem, u32 value) memzero_obj(vif1); cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's vif1ch->qwc = 0; //? - psHu64(0x10005000) = 0; - psHu64(0x10005008) = 0; + psHu64(VIF1_FIFO) = 0; + psHu64(0x10005008) = 0; // VIF1_FIFO + 8 vif1.done = true; + if(vif1Regs->mskpath3) + { + vif1Regs->mskpath3 = 0; + psHu32(GIF_STAT) &= ~0x2; + if(gif->chcr & 0x100) CPU_INT(2, 4); + } vif1Regs->err = 0; vif1.inprogress = 0; vif1Regs->stat &= ~(0x1F800000 | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS); // FQC=0 } + if (value & 0x2) { /* Force Break the VIF */ @@ -2609,6 +2709,7 @@ void vif1Write32(u32 mem, u32 value) vif1.vifstalled = true; Console::WriteLn("vif1 force break"); } + if (value & 0x4) { /* Stop VIF */ @@ -2619,6 +2720,7 @@ void vif1Write32(u32 mem, u32 value) cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's vif1.vifstalled = true; } + if (value & 0x8) { bool cancel = false; @@ -2654,15 +2756,15 @@ void vif1Write32(u32 mem, u32 value) } break; - case 0x10003c20: // ERR + case VIF1_ERR: // ERR VIF_LOG("VIF1_ERR write32 0x%8.8x", value); /* Set VIF1_ERR with 'value' */ vif1Regs->err = value; break; - case 0x10003c00: // STAT - VIF_LOG("VIF1_STAT write32 0x%8.8x", value); + case VIF1_STAT: // STAT + VIF_LOG("VIF1_STAT write32 0x%8.8x", value); #ifdef PCSX2_DEVBUILD /* Only FDR bit is writable, so mask the rest */ @@ -2679,7 +2781,7 @@ void vif1Write32(u32 mem, u32 value) vif1Regs->stat = (vif1Regs->stat & ~VIF1_STAT_FDR) | (value & VIF1_STAT_FDR); if (vif1Regs->stat & VIF1_STAT_FDR) { - vif1Regs->stat |= 0x01000000; + vif1Regs->stat |= 0x01000000; // FQC=1 - hack but it checks this is true before tranfer? (fatal frame) } else { @@ -2690,24 +2792,29 @@ void vif1Write32(u32 mem, u32 value) } break; - case 0x10003c50: // MODE + case VIF1_MODE: // MODE vif1Regs->mode = value; break; + case VIF1_R0: + case VIF1_R1: + case VIF1_R2: + case VIF1_R3: + assert((mem&0xf) == 0); + g_vifRow1[(mem>>4) & 3] = value; + break; + + case VIF1_C0: + case VIF1_C1: + case VIF1_C2: + case VIF1_C3: + assert((mem&0xf) == 0); + g_vifCol1[(mem>>4) & 3] = value; + break; + default: Console::WriteLn("Unknown Vif1 write to %x", params mem); - if ((mem >= 0x10003d00) && (mem < 0x10003d80)) - { - assert((mem&0xf) == 0); - if (mem < 0x10003d40) - g_vifRow1[(mem>>4)&3] = value; - else - g_vifCol1[(mem>>4)&3] = value; - } - else - { - psHu32(mem) = value; - } + psHu32(mem) = value; break; } @@ -2720,8 +2827,8 @@ void vif1Reset() memzero_obj(vif1); memzero_obj(*vif1Regs); SetNewMask(g_vif1Masks, g_vif1HasMask3, 0, 0xffffffff); - psHu64(0x10005000) = 0; - psHu64(0x10005008) = 0; + psHu64(VIF1_FIFO) = 0; + psHu64(0x10005008) = 0; // VIF1_FIFO + 8 vif1Regs->stat &= ~VIF1_STAT_VPS; vif1.done = true; cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's diff --git a/pcsx2/VifDma.h b/pcsx2/VifDma.h index 21d45e4a4e..627a5386e5 100644 --- a/pcsx2/VifDma.h +++ b/pcsx2/VifDma.h @@ -18,6 +18,20 @@ #ifndef __VIFDMA_H__ #define __VIFDMA_H__ +enum VifModes +{ + VIF_NORMAL_MODE = 0, + VIF_NORMAL_MEM_MODE = 1, + VIF_CHAIN_MODE = 2 +}; + +enum Path3Modes //0 = Image Mode (DirectHL), 1 = transferring, 2 = Stopped at End of Packet +{ + IMAGE_MODE = 0, + TRANSFER_MODE = 1, + STOPPED_MODE = 2 +}; + struct vifCode { u32 addr; u32 size; @@ -47,7 +61,8 @@ struct vifStruct { }; extern vifStruct vif0, vif1; -extern bool Path3transfer; +extern Path3Modes Path3progress; +extern u8 schedulepath3msk; void __fastcall UNPACK_S_32( u32 *dest, u32 *data, int size ); @@ -88,6 +103,7 @@ void vif0Init(); void vif1Init(); extern void vif0Interrupt(); extern void vif1Interrupt(); +extern void Vif1MskPath3(); void vif0Write32(u32 mem, u32 value); void vif1Write32(u32 mem, u32 value); diff --git a/pcsx2/build.sh b/pcsx2/build.sh index 0734960074..436a2b82e4 100644 --- a/pcsx2/build.sh +++ b/pcsx2/build.sh @@ -18,7 +18,7 @@ # #Normal -#export PCSX2OPTIONS="--enable-debug --enable-devbuild --enable-sse3 --enable-sse4 --prefix `pwd`" +#export PCSX2OPTIONS="--prefix `pwd`" #export PCSX2OPTIONS="--with-wx" echo --------------- diff --git a/pcsx2/configure.ac b/pcsx2/configure.ac deleted file mode 100644 index acccd29958..0000000000 --- a/pcsx2/configure.ac +++ /dev/null @@ -1,167 +0,0 @@ -AC_INIT(pcsx2,0.9.6,zerofrog@gmail.com) -AM_INIT_AUTOMAKE(pcsx2,0.9.6) - -AC_PROG_CC([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) -AC_PROG_CXX([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) -AC_PROG_CPP([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) - -AC_PROG_RANLIB - -dnl necessary for compiling assembly -AM_PROG_AS - -svnrev="`svn info | grep Revision:`" - -if test -n "${svnrev}" ; then - AC_REVISION("${svnrev}") - AC_DEFINE_UNQUOTED(SVN_REV,"${svnrev}", - [Define to be the subversion revision number]) -else - AC_REVISION([$Revision: 0 $]) - AC_DEFINE(SVN_REV,"$Revision: 0 $", - [Define to be the subversion revision number]) -fi - -AC_ARG_ENABLE(customcflags, AC_HELP_STRING([--enable-customcflags], [Use custom CFLAGS]), -customcflags=$enableval,customcflags=no) - -if test "x$customcflags" == xno -then -CFLAGS= -CPPFLAGS= -CXXFLAGS= -CCASFLAGS= -else -DEBUG_FLAGS=" -O0 -g " -fi - -WARNING_FLAGS="-Wno-format -Wno-unused-parameter -Wno-unused-value -Wunused-variable " -EXTRA_WARNING_FLAGS="-Wall -Wextra" -NORMAL_FLAGS=" -pipe -msse -msse2 -O2 ${WARNING_FLAGS}" -# These optimizations seem to cause issues with GCC 4.3.3, so we'll turn them off. Comment if not on 4.3+ -NORMAL_FLAGS+=" -fno-guess-branch-probability -fno-dse -fno-tree-dse " - -DEBUG_FLAGS+=" -g -msse -msse2 ${EXTRA_WARNING_FLAGS} ${WARNING_FLAGS} " - -dnl Check for debug build -AC_MSG_CHECKING(debug build) -AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [debug build]), - debug=$enableval,debug=no) -if test "x$debug" == xyes -then - AC_DEFINE(_DEBUG,1,[_DEBUG]) - CFLAGS+=" ${DEBUG_FLAGS} -Xlinker -zmuldefs " - CXXFLAGS+=" ${DEBUG_FLAGS} -fpermissive -Xlinker -zmuldefs " - CCASFLAGS+=" -D_DEBUG ${DEBUG_FLAGS} " - MYOBJDIR="Debug" -else - AC_DEFINE(NDEBUG,1,[NDEBUG]) - CFLAGS+=" ${NORMAL_FLAGS}" - CXXFLAGS+=" ${NORMAL_FLAGS} -fpermissive -Xlinker -zmuldefs " - MYOBJDIR="Release" -fi -AC_MSG_RESULT($debug) - -AC_CHECK_FUNCS([ _aligned_malloc _aligned_free ], AC_DEFINE(HAVE_ALIGNED_MALLOC)) - -#AC_MSG_CHECKING(turn on memcpy_fast_) -#AC_ARG_ENABLE(memcpyfast, AC_HELP_STRING([--enable-memcpyfast], [Turns on memcpy_fast - EXPERIMENTAL]), -#memcpyfast=$enableval,memcpyfast=no) -#if test "x$memcpyfast" == xyes -#then -# AC_DEFINE(LINUX_USE_FAST_MEMORY,1,[LINUX_USE_FAST_MEMORY]) -#fi -#AC_MSG_RESULT($memcpyfast) - -#AC_MSG_CHECKING(turn on microVU) -#AC_ARG_ENABLE(microVU, AC_HELP_STRING([--enable-microVU], [Turns on the currently incomplete microVU files - Not a good idea]), -# microVU=$enableval,microVU=no) -#if test "x$microVU" == xyes -#then -# AC_DEFINE(PCSX2_MICROVU,1,[PCSX2_MICROVU]) -#fi -#AC_MSG_RESULT($microVU) - -dnl Check for dev build -AC_MSG_CHECKING(for development build) -AC_ARG_ENABLE(devbuild, AC_HELP_STRING([--enable-devbuild], [Special Build for developers that simplifies testing and adds extra checks]), - devbuild=$enableval,devbuild=no) -if test "x$devbuild" == xyes -then - AC_DEFINE(PCSX2_DEVBUILD,1,[PCSX2_DEVBUILD]) - MYOBJDIR=$MYOBJDIR"Dev" -fi -AC_MSG_RESULT($devbuild) - -dnl gtk -AC_MSG_CHECKING(gtk+) -AC_CHECK_PROG(GTK_CONFIG, pkg-config, pkg-config) -LIBS+=$(pkg-config --libs gtk+-2.0 gthread-2.0) - -# Check for wxWidgets -AC_ARG_WITH( - [wx], - AC_HELP_STRING( - [--with-wx=dir], - [use wxWidgets configuration program wx-config in dir] - ) -) -if test $with_wx; then - AC_CHECK_PROG([WX_CONFIG],[wx-config],[$with_wx/wx-config],[],[$with_wx]) -else - AC_CHECK_PROG([WX_CONFIG],[wx-config],[wx-config]) -fi -if test $WX_CONFIG; then - USE_WX=1 - MYGUIDIR="NewGUI" - LIBS+=$(wx-config --libs) - else - MYGUIDIR="Linux" -fi -AC_SUBST([USE_WX],[]) -AC_SUBST([WX_CONFIG],[]) -AC_SUBST([WX_CPPFLAGS],[]) -AC_SUBST([WX_LDFLAGS],[]) - -dnl AC_CHECK_LIB(pthread,main,[LIBS="$LIBS -lpthread"]) -AC_CHECK_LIB(stdc++,main,[LIBS="$LIBS -lstdc++"]) -AC_CHECK_LIB(z,main,[LIBS="$LIBS -lz"]) - -AC_ARG_ENABLE(nls, AC_HELP_STRING([--disable-nls], [Disable nls support]), -nls=$enableval,nls=yes) -if test "x$nls" == xyes -then -AC_CHECK_HEADER([libintl.h], [AC_DEFINE(ENABLE_NLS,1,[__x86_64__])]) -fi - -AC_ARG_ENABLE(local-inis, AC_HELP_STRING([--enable-local-inis], [Enable local plugin inis]), -localinis=$enableval, localinis=no) -if test "x$localinis" == xyes -then -AC_DEFINE(LOCAL_PLUGIN_INIS) -fi - -AC_OUTPUT([ - Makefile - DebugTools/Makefile - NewGUI/Makefile - IPU/Makefile - IPU/mpeg2lib/Makefile - RDebug/Makefile - tinyxml/Makefile - x86/Makefile - x86/ix86/Makefile - ../3rdparty/zlib/Makefile - ]) - -dnl bindir = pcsx2exe - -echo "Configuration:" -echo " Target system type: $target" -echo " Debug build? $debug" -echo " Dev build? $devbuild" -echo " nls support? $nls" -echo " local plugin inis? $localinis" -echo " custom cflags? $customcflags" -#echo " memcpy_fast? $memcpyfast" -#echo " microVU? $microVU" diff --git a/pcsx2/ps2/Iop/IopHwRead.cpp b/pcsx2/ps2/Iop/IopHwRead.cpp index 85202e74c3..455691fe24 100644 --- a/pcsx2/ps2/Iop/IopHwRead.cpp +++ b/pcsx2/ps2/Iop/IopHwRead.cpp @@ -25,14 +25,14 @@ using namespace Internal; ////////////////////////////////////////////////////////////////////////////////////////// // -u8 __fastcall iopHwRead8_Page1( u32 addr ) +mem8_t __fastcall iopHwRead8_Page1( u32 addr ) { // all addresses are assumed to be prefixed with 0x1f801xxx: jASSUME( (addr >> 12) == 0x1f801 ); u32 masked_addr = addr & 0x0fff; - u8 ret; // using a return var can be helpful in debugging. + mem8_t ret; // using a return var can be helpful in debugging. switch( masked_addr ) { mcase(HW_SIO_DATA): ret = sioRead8(); break; @@ -50,63 +50,63 @@ u8 __fastcall iopHwRead8_Page1( u32 addr ) default: if( masked_addr >= 0x100 && masked_addr < 0x130 ) { - DevCon::Notice( "*Hardware Read8 from Counter16 [ignored] [addr=0x%02x]", params addr, psxHu8(addr) ); + DevCon::Notice( "HwRead8 from Counter16 [ignored], addr 0x%08x = 0x%02x", params addr, psxHu8(addr) ); ret = psxHu8( addr ); } else if( masked_addr >= 0x480 && masked_addr < 0x4a0 ) { - DevCon::Notice( "*Hardware Read8 from Counter32 [ignored] [addr=0x%02x]", params addr, psxHu8(addr) ); + DevCon::Notice( "HwRead8 from Counter32 [ignored], addr 0x%08x = 0x%02x", params addr, psxHu8(addr) ); ret = psxHu8( addr ); } else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) ) { ret = USBread8( addr ); - PSXHW_LOG( "Hardware Read8 from USB: addr 0x%08x = 0x%02x", addr, ret ); + PSXHW_LOG( "HwRead8 from USB, addr 0x%08x = 0x%02x", addr, ret ); } else { ret = psxHu8(addr); - PSXHW_LOG( "*Unknown Hardware Read8 from addr 0x%08x = 0x%02x", addr, ret ); + PSXHW_LOG( "HwRead8 from Unknown, addr 0x%08x = 0x%02x", addr, ret ); } return ret; } - PSXHW_LOG( "*Hardware Read8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, ret ); + PSXHW_LOG( "HwRead8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, ret ); return ret; } ////////////////////////////////////////////////////////////////////////////////////////// // -u8 __fastcall iopHwRead8_Page3( u32 addr ) +mem8_t __fastcall iopHwRead8_Page3( u32 addr ) { // all addresses are assumed to be prefixed with 0x1f803xxx: jASSUME( (addr >> 12) == 0x1f803 ); - u8 ret; + mem8_t ret; if( addr == 0x1f803100 ) // PS/EE/IOP conf related ret = 0x10; // Dram 2M else ret = psxHu8( addr ); - PSXHW_LOG( "Hardware Read8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, psxHu8(addr) ); + PSXHW_LOG( "HwRead8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, psxHu8(addr) ); return ret; } ////////////////////////////////////////////////////////////////////////////////////////// // -u8 __fastcall iopHwRead8_Page8( u32 addr ) +mem8_t __fastcall iopHwRead8_Page8( u32 addr ) { // all addresses are assumed to be prefixed with 0x1f808xxx: jASSUME( (addr >> 12) == 0x1f808 ); - u8 ret; + mem8_t ret; if( addr == HW_SIO2_FIFO ) ret = sio2_fifoOut();//sio2 serial data feed/fifo_out else ret = psxHu8( addr ); - PSXHW_LOG( "Hardware Read8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, psxHu8(addr) ); + PSXHW_LOG( "HwRead8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, psxHu8(addr) ); return ret; } @@ -215,7 +215,7 @@ static __forceinline T _HwRead_16or32_Page1( u32 addr ) ret = SPU2read( addr ); else { - DevCon::Notice( "*PCSX2* SPU2 Hardware Read32 (addr=0x%08X)? What manner of trickery is this?!", params addr ); + DevCon::Notice( "HwRead32 from SPU2? (addr=0x%08X) .. What manner of trickery is this?!", params addr ); ret = psxHu32(addr); } } @@ -311,7 +311,7 @@ static __forceinline T _HwRead_16or32_Page1( u32 addr ) } } - PSXHW_LOG( "Hardware Read%s from %s, addr 0x%08x = 0x%04x", + PSXHW_LOG( "HwRead%s from %s, addr 0x%08x = 0x%04x", (sizeof(T) == 2) ? "16" : "32", _log_GetIopHwName( addr ), addr, ret ); return ret; @@ -323,62 +323,62 @@ static __forceinline T _HwRead_16or32_Page1( u32 addr ) ////////////////////////////////////////////////////////////////////////////////////////// // -u16 __fastcall iopHwRead16_Page1( u32 addr ) +mem16_t __fastcall iopHwRead16_Page1( u32 addr ) { - return _HwRead_16or32_Page1( addr ); + return _HwRead_16or32_Page1( addr ); } ////////////////////////////////////////////////////////////////////////////////////////// // -u16 __fastcall iopHwRead16_Page3( u32 addr ) +mem16_t __fastcall iopHwRead16_Page3( u32 addr ) { // all addresses are assumed to be prefixed with 0x1f803xxx: jASSUME( (addr >> 12) == 0x1f803 ); - u16 ret = psxHu16(addr); - PSXHW_LOG( "Hardware Read16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, ret ); + mem16_t ret = psxHu16(addr); + PSXHW_LOG( "HwRead16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, ret ); return ret; } ////////////////////////////////////////////////////////////////////////////////////////// // -u16 __fastcall iopHwRead16_Page8( u32 addr ) +mem16_t __fastcall iopHwRead16_Page8( u32 addr ) { // all addresses are assumed to be prefixed with 0x1f808xxx: jASSUME( (addr >> 12) == 0x1f808 ); - u16 ret = psxHu16(addr); - PSXHW_LOG( "Hardware Read16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, ret ); + mem16_t ret = psxHu16(addr); + PSXHW_LOG( "HwRead16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, ret ); return ret; } ////////////////////////////////////////////////////////////////////////////////////////// // -u32 __fastcall iopHwRead32_Page1( u32 addr ) +mem32_t __fastcall iopHwRead32_Page1( u32 addr ) { - return _HwRead_16or32_Page1( addr ); + return _HwRead_16or32_Page1( addr ); } ////////////////////////////////////////////////////////////////////////////////////////// // -u32 __fastcall iopHwRead32_Page3( u32 addr ) +mem32_t __fastcall iopHwRead32_Page3( u32 addr ) { // all addresses are assumed to be prefixed with 0x1f803xxx: jASSUME( (addr >> 12) == 0x1f803 ); - const u32 ret = psxHu32(addr); - PSXHW_LOG( "Hardware Read32 from %s, addr 0x%08x = 0x%08x", _log_GetIopHwName( addr ), addr, ret ); + const mem32_t ret = psxHu32(addr); + PSXHW_LOG( "HwRead32 from %s, addr 0x%08x = 0x%08x", _log_GetIopHwName( addr ), addr, ret ); return ret; } ////////////////////////////////////////////////////////////////////////////////////////// // -u32 __fastcall iopHwRead32_Page8( u32 addr ) +mem32_t __fastcall iopHwRead32_Page8( u32 addr ) { // all addresses are assumed to be prefixed with 0x1f808xxx: jASSUME( (addr >> 12) == 0x1f808 ); u32 masked_addr = addr & 0x0fff; - u32 ret; + mem32_t ret; if( masked_addr >= 0x200 ) { @@ -395,49 +395,42 @@ u32 __fastcall iopHwRead32_Page8( u32 addr ) const int parm = (masked_addr-0x240) / 8; ret = (masked_addr & 4) ? sio2_getSend2( parm ) : sio2_getSend1( parm ); } - else + else if( masked_addr <= 0x280 ) { switch( masked_addr ) { - mcase(0x1f801264): // unknown / reserved. + mcase(HW_SIO2_CTRL): ret = sio2_getCtrl(); break; + mcase(HW_SIO2_RECV1): ret = sio2_getRecv1(); break; + mcase(HW_SIO2_RECV2): ret = sio2_getRecv2(); break; + mcase(HW_SIO2_RECV3): ret = sio2_getRecv3(); break; + mcase(0x1f808278): ret = sio2_get8278(); break; + mcase(0x1f80827C): ret = sio2_get827C(); break; + mcase(HW_SIO2_INTR): ret = sio2_getIntr(); break; + + // HW_SIO2_FIFO -- A yet unknown: Should this be ignored on 32 bit writes, or handled as a + // 4-byte FIFO input? + // The old IOP system just ignored it, so that's what we do here. I've included commented code + // for treating it as a 16/32 bit write though [which si what the SIO does, for example). + mcase(HW_SIO2_FIFO): + //ret = sio2_fifoOut(); + //ret |= sio2_fifoOut() << 8; + //ret |= sio2_fifoOut() << 16; + //ret |= sio2_fifoOut() << 24; + //break; + + default: ret = psxHu32(addr); break; - - mcase(HW_SIO2_CTRL): - ret = sio2_getCtrl(); - break; - - mcase(HW_SIO2_RECV1): - ret = sio2_getRecv1(); - break; - - mcase(HW_SIO2_RECV2): - ret = sio2_getRecv2(); - break; - - mcase(HW_SIO2_RECV3): - ret = sio2_getRecv3(); - break; - - mcase(0x1f808278): - ret = sio2_get8278(); - break; - - mcase(0x1f80827C): - ret = sio2_get827C(); - break; - - mcase(HW_SIO2_INTR): - ret = sio2_getIntr(); - break; - - jNO_DEFAULT; } } + else if( masked_addr >= pgmsk(HW_FW_START) && masked_addr <= pgmsk(HW_FW_END) ) + { + ret = FWread32( addr ); + } } else ret = psxHu32(addr); - PSXHW_LOG( "Hardware Read32 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, ret ); + PSXHW_LOG( "HwRead32 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, ret ); return ret; } diff --git a/pcsx2/ps2/Iop/IopHwWrite.cpp b/pcsx2/ps2/Iop/IopHwWrite.cpp index 04c5e61ce0..0a05edf598 100644 --- a/pcsx2/ps2/Iop/IopHwWrite.cpp +++ b/pcsx2/ps2/Iop/IopHwWrite.cpp @@ -23,9 +23,44 @@ namespace IopMemory { using namespace Internal; +// Template-compatible version of the psxHu macro. Used for writing. +#define psxHu(mem) (*(u32*)&psxH[(mem) & 0xffff]) + + ////////////////////////////////////////////////////////////////////////////////////////// // -void __fastcall iopHwWrite8_Page1( u32 addr, u8 val ) +template< typename T > +static __forceinline void _generic_write( u32 addr, T val ) +{ + int bitsize = (sizeof(T) == 1) ? 8 : ( (sizeof(T) == 2) ? 16 : 32 ); + PSXHW_LOG( "HwWrite%d to %s, addr 0x%08x = 0x%08x\n", bitsize, _log_GetIopHwName(addr), addr, val ); + psxHu(addr) = val; +} + +void __fastcall iopHwWrite8_generic( u32 addr, mem8_t val ) { _generic_write( addr, val ); } +void __fastcall iopHwWrite16_generic( u32 addr, mem16_t val ) { _generic_write( addr, val ); } +void __fastcall iopHwWrite32_generic( u32 addr, mem32_t val ) { _generic_write( addr, val ); } + +////////////////////////////////////////////////////////////////////////////////////////// +// +template< typename T > +static __forceinline T _generic_read( u32 addr ) +{ + int bitsize = (sizeof(T) == 1) ? 8 : ( (sizeof(T) == 2) ? 16 : 32 ); + + T ret = psxHu(addr); + PSXHW_LOG( "HwRead%d from %s, addr 0x%08x = 0x%08x\n", bitsize, _log_GetIopHwName(addr), addr, ret ); + return ret; +} + +mem8_t __fastcall iopHwRead8_generic( u32 addr ) { return _generic_read( addr ); } +mem16_t __fastcall iopHwRead16_generic( u32 addr ) { return _generic_read( addr ); } +mem32_t __fastcall iopHwRead32_generic( u32 addr ) { return _generic_read( addr ); } + + +////////////////////////////////////////////////////////////////////////////////////////// +// +void __fastcall iopHwWrite8_Page1( u32 addr, mem8_t val ) { // all addresses are assumed to be prefixed with 0x1f801xxx: jASSUME( (addr >> 12) == 0x1f801 ); @@ -49,12 +84,12 @@ void __fastcall iopHwWrite8_Page1( u32 addr, u8 val ) default: if( masked_addr >= 0x100 && masked_addr < 0x130 ) { - DevCon::Notice( "*Hardware Write8 to Counter16 [ignored] [addr=0x%02x]", params addr, psxHu8(addr) ); + DevCon::Notice( "HwWrite8 to Counter16 [ignored], addr 0x%08x = 0x%02x", params addr, psxHu8(addr) ); psxHu8( addr ) = val; } else if( masked_addr >= 0x480 && masked_addr < 0x4a0 ) { - DevCon::Notice( "*Hardware Write8 to Counter32 [ignored] [addr=0x%02x]", params addr, psxHu8(addr) ); + DevCon::Notice( "HwWrite8 to Counter32 [ignored], addr 0x%08x = 0x%02x", params addr, psxHu8(addr) ); psxHu8( addr ) = val; } else if( masked_addr >= pgmsk(HW_USB_START) && masked_addr < pgmsk(HW_USB_END) ) @@ -68,13 +103,13 @@ void __fastcall iopHwWrite8_Page1( u32 addr, u8 val ) break; } - PSXHW_LOG( "*Hardware Write8 to %s, addr 0x%08x = 0x%02x\n", _log_GetIopHwName(addr), addr, val ); + PSXHW_LOG( "HwWrite8 to %s, addr 0x%08x = 0x%02x\n", _log_GetIopHwName(addr), addr, val ); } static char g_pbuf[1024]; static int g_pbufi; -void __fastcall iopHwWrite8_Page3( u32 addr, u8 val ) +void __fastcall iopHwWrite8_Page3( u32 addr, mem8_t val ) { // all addresses are assumed to be prefixed with 0x1f803xxx: jASSUME( (addr >> 12) == 0x1f803 ); @@ -98,11 +133,11 @@ void __fastcall iopHwWrite8_Page3( u32 addr, u8 val ) } } - PSXHW_LOG( "Hardware Write8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName(addr), addr, psxHu8(addr) ); + PSXHW_LOG( "HwWrite8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName(addr), addr, psxHu8(addr) ); psxHu8( addr ) = val; } -void __fastcall iopHwWrite8_Page8( u32 addr, u8 val ) +void __fastcall iopHwWrite8_Page8( u32 addr, mem8_t val ) { // all addresses are assumed to be prefixed with 0x1f808xxx: jASSUME( (addr >> 12) == 0x1f808 ); @@ -112,13 +147,10 @@ void __fastcall iopHwWrite8_Page8( u32 addr, u8 val ) else psxHu8( addr ) = val; - PSXHW_LOG( "Hardware Write8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName(addr), addr, psxHu8(addr) ); + PSXHW_LOG( "HwWrite8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName(addr), addr, psxHu8(addr) ); } -// Template-compatible version of the psxHu macro. Used for writing. -#define psxHu(mem) (*(u32*)&psxH[(mem) & 0xffff]) - ////////////////////////////////////////////////////////////////////////////////////////// // Templated handler for both 32 and 16 bit write operations, to Page 1 registers. // @@ -210,7 +242,7 @@ static __forceinline void _HwWrite_16or32_Page1( u32 addr, T val ) SPU2write( addr, val ); else { - DevCon::Notice( "*PCSX2* SPU2 Hardware Write32 (addr=0x%08X)? What manner of trickery is this?!", params addr ); + DevCon::Notice( "HwWrite32 to SPU2? (addr=0x%08X) .. What manner of trickery is this?!", params addr ); //psxHu(addr) = val; } } @@ -423,7 +455,7 @@ static __forceinline void _HwWrite_16or32_Page1( u32 addr, T val ) } } - PSXHW_LOG( "Hardware Write%s to %s, addr 0x%08x = 0x%04x", + PSXHW_LOG( "HwWrite%s to %s, addr 0x%08x = 0x%04x", sizeof(T) == 2 ? "16" : "32", _log_GetIopHwName( addr ), addr, val ); } @@ -431,43 +463,43 @@ static __forceinline void _HwWrite_16or32_Page1( u32 addr, T val ) ////////////////////////////////////////////////////////////////////////////////////////// // -void __fastcall iopHwWrite16_Page1( u32 addr, u16 val ) +void __fastcall iopHwWrite16_Page1( u32 addr, mem16_t val ) { - _HwWrite_16or32_Page1( addr, val ); + _HwWrite_16or32_Page1( addr, val ); } -void __fastcall iopHwWrite16_Page3( u32 addr, u16 val ) +void __fastcall iopHwWrite16_Page3( u32 addr, mem16_t val ) { // all addresses are assumed to be prefixed with 0x1f803xxx: jASSUME( (addr >> 12) == 0x1f803 ); psxHu16(addr) = val; - PSXHW_LOG( "Hardware Write16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, val ); + PSXHW_LOG( "HwWrite16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, val ); } -void __fastcall iopHwWrite16_Page8( u32 addr, u16 val ) +void __fastcall iopHwWrite16_Page8( u32 addr, mem16_t val ) { // all addresses are assumed to be prefixed with 0x1f808xxx: jASSUME( (addr >> 12) == 0x1f808 ); psxHu16(addr) = val; - PSXHW_LOG( "Hardware Write16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, val ); + PSXHW_LOG( "HwWrite16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, val ); } ////////////////////////////////////////////////////////////////////////////////////////// // -void __fastcall iopHwWrite32_Page1( u32 addr, u32 val ) +void __fastcall iopHwWrite32_Page1( u32 addr, mem32_t val ) { - _HwWrite_16or32_Page1( addr, val ); + _HwWrite_16or32_Page1( addr, val ); } -void __fastcall iopHwWrite32_Page3( u32 addr, u32 val ) +void __fastcall iopHwWrite32_Page3( u32 addr, mem32_t val ) { // all addresses are assumed to be prefixed with 0x1f803xxx: jASSUME( (addr >> 12) == 0x1f803 ); psxHu16(addr) = val; - PSXHW_LOG( "Hardware Write32 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, val ); + PSXHW_LOG( "HwWrite32 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, val ); } -void __fastcall iopHwWrite32_Page8( u32 addr, u32 val ) +void __fastcall iopHwWrite32_Page8( u32 addr, mem32_t val ) { // all addresses are assumed to be prefixed with 0x1f808xxx: jASSUME( (addr >> 12) == 0x1f808 ); @@ -489,41 +521,29 @@ void __fastcall iopHwWrite32_Page8( u32 addr, u32 val ) const int parm = (masked_addr-0x240) / 8; if(masked_addr & 4) sio2_setSend2( parm, val ); else sio2_setSend1( parm, val ); } - else + else if( masked_addr <= 0x280 ) { switch( masked_addr ) { - case 0x264: // unknown / reserved. - case 0x26C: // recv1 [read-only] - case 0x270: // recv2 [read-only] - case 0x274: // recv3 [read-only] + mcase(HW_SIO2_CTRL): sio2_setCtrl( val ); break; + mcase(0x1f808278): sio2_set8278( val ); break; + mcase(0x1f80827C): sio2_set827C( val ); break; + mcase(HW_SIO2_INTR): sio2_setIntr( val ); break; + + // Other SIO2 registers are read-only, no-ops on write. + default: psxHu32(addr) = val; - break; - - case 0x268: - sio2_setCtrl( val ); - break; - - case 0x278: - sio2_set8278( val ); - break; - - case 0x27C: - sio2_set827C( val ); - break; - - case 0x280: - sio2_setIntr( val ); - break; - - jNO_DEFAULT; + break; } } + else if( masked_addr >= pgmsk(HW_FW_START) && masked_addr <= pgmsk(HW_FW_END) ) + { + FWwrite32( addr, val ); + } } else psxHu32(addr) = val; - PSXHW_LOG( "Hardware Write32 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, val ); - + PSXHW_LOG( "HwWrite32 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, val ); } } diff --git a/pcsx2/ps2/Iop/IopHw_Internal.h b/pcsx2/ps2/Iop/IopHw_Internal.h index 1a78d64bec..a4eaab9252 100644 --- a/pcsx2/ps2/Iop/IopHw_Internal.h +++ b/pcsx2/ps2/Iop/IopHw_Internal.h @@ -190,15 +190,15 @@ static __forceinline const char* _log_GetIopHwName( u32 addr ) { return "SPU2"; } - else if( addr >= 0x1f808200 ) + else if( addr >= pgmsk(HW_FW_START) && addr <= pgmsk(HW_FW_END) ) { - if( addr < 0x1f808240 ) - return "SIO2 param"; - else if( addr < 0x260 ) - return "SIO2 send"; + return "FW"; } + else if( addr >= 0x1f808200 && addr < 0x1f808240 ) { return "SIO2 param"; } + else if( addr >= 0x1f808240 && addr < 0x1f808260 ) { return "SIO2 send"; } + return "Unknown"; } } -} }; \ No newline at end of file +} }; diff --git a/pcsx2/sio_internal.h b/pcsx2/sio_internal.h new file mode 100644 index 0000000000..3a10d2c232 --- /dev/null +++ b/pcsx2/sio_internal.h @@ -0,0 +1,62 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +// sio_internal.h -- contains defines and structs used by sio and sio2, which +// are of little or no use to the rest of the world. + +// Status Flags +static const int + TX_RDY = 0x0001, + RX_RDY = 0x0002, + TX_EMPTY = 0x0004, + PARITY_ERR = 0x0008, + RX_OVERRUN = 0x0010, + FRAMING_ERR = 0x0020, + SYNC_DETECT = 0x0040, + DSR = 0x0080, + CTS = 0x0100, + IRQ = 0x0200; + +// Control Flags +static const int + TX_PERM = 0x0001, + DTR = 0x0002, + RX_PERM = 0x0004, + BREAK = 0x0008, + RESET_ERR = 0x0010, + RTS = 0x0020, + SIO_RESET = 0x0040; + +#ifdef _MSC_VER +#pragma pack(1) +#endif +struct mc_command_0x26_tag{ + u8 field_151; //+02 flags + u16 sectorSize; //+03 divide to it + u16 field_2C; //+05 divide to it + u32 mc_size; //+07 + u8 mc_xor; //+0b don't forget to recalculate it!!! + u8 Z; //+0c +#ifdef _MSC_VER +}; +#pragma pack() +#else +} __attribute__((packed)); +#endif diff --git a/pcsx2/tinyxml/tinyxml.h b/pcsx2/tinyxml/tinyxml.h index 5391236e68..cdec7f3cf5 100644 --- a/pcsx2/tinyxml/tinyxml.h +++ b/pcsx2/tinyxml/tinyxml.h @@ -39,7 +39,7 @@ distribution. #include // Help out windows: -#if defined( _DEBUG ) && !defined( DEBUG ) +#if defined( PCSX2_DEBUG ) && !defined( DEBUG ) #define DEBUG #endif diff --git a/pcsx2/vtlb.cpp b/pcsx2/vtlb.cpp index 13fd893068..3b58228151 100644 --- a/pcsx2/vtlb.cpp +++ b/pcsx2/vtlb.cpp @@ -61,30 +61,6 @@ vtlbHandler UnmappedVirtHandler1; vtlbHandler UnmappedPhyHandler0; vtlbHandler UnmappedPhyHandler1; - /* - __asm - { - mov eax,ecx; - shr ecx,12; - mov ecx,[ecx*4+vmap]; //translate - add ecx,eax; //transform - - js callfunction; //if <0 its invalid ptr :) - - mov eax,[ecx]; - mov [edx],eax; - xor eax,eax; - ret; - -callfunction: - xchg eax,ecx; - shr eax,12; //get the 'ppn' - - //ecx = original addr - //eax = function entry + 0x800000 - //edx = data ptr - jmp [readfunctions8-0x800000+eax]; - }*/ ////////////////////////////////////////////////////////////////////////////////////////// // Interpreter Implementations of VTLB Memory Operations. @@ -347,6 +323,12 @@ vtlbHandler vtlb_RegisterHandler( vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMemR32FP { //write the code :p vtlbHandler rv=vtlbHandlerCount++; + + vtlbdata.RWFT[0][0][rv] = (r8!=0) ? (void*)(r8): (void*)vtlbDefaultPhyRead8; + vtlbdata.RWFT[1][0][rv] = (r16!=0) ? (void*)r16: (void*)vtlbDefaultPhyRead16; + vtlbdata.RWFT[2][0][rv] = (r32!=0) ? (void*)r32: (void*)vtlbDefaultPhyRead32; + vtlbdata.RWFT[3][0][rv] = (r64!=0) ? (void*)r64: (void*)vtlbDefaultPhyRead64; + vtlbdata.RWFT[4][0][rv] = (r128!=0) ? (void*)r128: (void*)vtlbDefaultPhyRead128; vtlbdata.RWFT[0][0][rv] = (r8!=0) ? (void*)r8:(void*)vtlbDefaultPhyRead8; vtlbdata.RWFT[1][0][rv] = (r16!=0) ? (void*)r16:(void*)vtlbDefaultPhyRead16; @@ -516,22 +498,27 @@ void vtlb_Init() //the physical address space can be 'compressed' to just 29 bits.However, to properly handle exceptions //there must be a way to get the full address back.Thats why i use these 2 functions and encode the hi bit directly into em :) - UnmappedVirtHandler0=vtlb_RegisterHandler(vtlbUnmappedVRead8<0>,vtlbUnmappedVRead16<0>,vtlbUnmappedVRead32<0>,vtlbUnmappedVRead64<0>,vtlbUnmappedVRead128<0>, - vtlbUnmappedVWrite8<0>,vtlbUnmappedVWrite16<0>,vtlbUnmappedVWrite32<0>,vtlbUnmappedVWrite64<0>,vtlbUnmappedVWrite128<0>); + UnmappedVirtHandler0 = vtlb_RegisterHandler( + vtlbUnmappedVRead8<0>,vtlbUnmappedVRead16<0>,vtlbUnmappedVRead32<0>,vtlbUnmappedVRead64<0>,vtlbUnmappedVRead128<0>, + vtlbUnmappedVWrite8<0>,vtlbUnmappedVWrite16<0>,vtlbUnmappedVWrite32<0>,vtlbUnmappedVWrite64<0>,vtlbUnmappedVWrite128<0> + ); - UnmappedVirtHandler1=vtlb_RegisterHandler(vtlbUnmappedVRead8<0x80000000>,vtlbUnmappedVRead16<0x80000000>,vtlbUnmappedVRead32<0x80000000>, - vtlbUnmappedVRead64<0x80000000>,vtlbUnmappedVRead128<0x80000000>, - vtlbUnmappedVWrite8<0x80000000>,vtlbUnmappedVWrite16<0x80000000>,vtlbUnmappedVWrite32<0x80000000>, - vtlbUnmappedVWrite64<0x80000000>,vtlbUnmappedVWrite128<0x80000000>); + UnmappedVirtHandler1 = vtlb_RegisterHandler( + vtlbUnmappedVRead8<0x80000000>,vtlbUnmappedVRead16<0x80000000>,vtlbUnmappedVRead32<0x80000000>, vtlbUnmappedVRead64<0x80000000>,vtlbUnmappedVRead128<0x80000000>, + vtlbUnmappedVWrite8<0x80000000>,vtlbUnmappedVWrite16<0x80000000>,vtlbUnmappedVWrite32<0x80000000>, vtlbUnmappedVWrite64<0x80000000>,vtlbUnmappedVWrite128<0x80000000> + ); - UnmappedPhyHandler0=vtlb_RegisterHandler(vtlbUnmappedPRead8<0>,vtlbUnmappedPRead16<0>,vtlbUnmappedPRead32<0>,vtlbUnmappedPRead64<0>,vtlbUnmappedPRead128<0>, - vtlbUnmappedPWrite8<0>,vtlbUnmappedPWrite16<0>,vtlbUnmappedPWrite32<0>,vtlbUnmappedPWrite64<0>,vtlbUnmappedPWrite128<0>); + UnmappedPhyHandler0 = vtlb_RegisterHandler( + vtlbUnmappedPRead8<0>,vtlbUnmappedPRead16<0>,vtlbUnmappedPRead32<0>,vtlbUnmappedPRead64<0>,vtlbUnmappedPRead128<0>, + vtlbUnmappedPWrite8<0>,vtlbUnmappedPWrite16<0>,vtlbUnmappedPWrite32<0>,vtlbUnmappedPWrite64<0>,vtlbUnmappedPWrite128<0> + ); - UnmappedPhyHandler1=vtlb_RegisterHandler(vtlbUnmappedPRead8<0x80000000>,vtlbUnmappedPRead16<0x80000000>,vtlbUnmappedPRead32<0x80000000>, - vtlbUnmappedPRead64<0x80000000>,vtlbUnmappedPRead128<0x80000000>, - vtlbUnmappedPWrite8<0x80000000>,vtlbUnmappedPWrite16<0x80000000>,vtlbUnmappedPWrite32<0x80000000>, - vtlbUnmappedPWrite64<0x80000000>,vtlbUnmappedPWrite128<0x80000000>); - DefaultPhyHandler=vtlb_RegisterHandler(0,0,0,0,0,0,0,0,0,0); + UnmappedPhyHandler1 = vtlb_RegisterHandler( + vtlbUnmappedPRead8<0x80000000>,vtlbUnmappedPRead16<0x80000000>,vtlbUnmappedPRead32<0x80000000>, vtlbUnmappedPRead64<0x80000000>,vtlbUnmappedPRead128<0x80000000>, + vtlbUnmappedPWrite8<0x80000000>,vtlbUnmappedPWrite16<0x80000000>,vtlbUnmappedPWrite32<0x80000000>, vtlbUnmappedPWrite64<0x80000000>,vtlbUnmappedPWrite128<0x80000000> + ); + + DefaultPhyHandler = vtlb_RegisterHandler(0,0,0,0,0,0,0,0,0,0); //done ! @@ -542,6 +529,9 @@ void vtlb_Init() vtlb_VMapUnmap(0,(VTLB_VMAP_ITEMS-1)*VTLB_PAGE_SIZE); //yeah i know, its stupid .. but this code has to be here for now ;p vtlb_VMapUnmap((VTLB_VMAP_ITEMS-1)*VTLB_PAGE_SIZE,VTLB_PAGE_SIZE); + + extern void vtlb_dynarec_init(); + vtlb_dynarec_init(); } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/pcsx2/vtlb.h b/pcsx2/vtlb.h index b1674fc79d..bcb0489ef5 100644 --- a/pcsx2/vtlb.h +++ b/pcsx2/vtlb.h @@ -1,11 +1,5 @@ -#ifndef _VTLB_H_ -#define _VTLB_H_ -typedef u8 mem8_t; -typedef u16 mem16_t; -typedef u32 mem32_t; -typedef u64 mem64_t; -typedef u64 mem128_t; +#pragma once // Specialized function pointers for each read type typedef mem8_t __fastcall vtlbMemR8FP(u32 addr); @@ -48,13 +42,13 @@ extern void vtlb_VMapUnmap(u32 vaddr,u32 sz); //Memory functions -extern u8 __fastcall vtlb_memRead8(u32 mem); -extern u16 __fastcall vtlb_memRead16(u32 mem); +extern mem8_t __fastcall vtlb_memRead8(u32 mem); +extern mem16_t __fastcall vtlb_memRead16(u32 mem); extern u32 __fastcall vtlb_memRead32(u32 mem); extern void __fastcall vtlb_memRead64(u32 mem, u64 *out); extern void __fastcall vtlb_memRead128(u32 mem, u64 *out); -extern void __fastcall vtlb_memWrite8 (u32 mem, u8 value); -extern void __fastcall vtlb_memWrite16(u32 mem, u16 value); +extern void __fastcall vtlb_memWrite8 (u32 mem, mem8_t value); +extern void __fastcall vtlb_memWrite16(u32 mem, mem16_t value); extern void __fastcall vtlb_memWrite32(u32 mem, u32 value); extern void __fastcall vtlb_memWrite64(u32 mem, const u64* value); extern void __fastcall vtlb_memWrite128(u32 mem, const u64* value); @@ -95,5 +89,3 @@ namespace vtlb_private PCSX2_ALIGNED_EXTERN( 64, MapData vtlbdata ); } - -#endif diff --git a/pcsx2/windows/CpuDlg.cpp b/pcsx2/windows/CpuDlg.cpp deleted file mode 100644 index 84c1789a3f..0000000000 --- a/pcsx2/windows/CpuDlg.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "Win32.h" - -#include "Common.h" -#include "Counters.h" -#include "VUmicro.h" -#include "Plugins.h" - -#include "ix86/ix86.h" - -static void EnableDlgItem( HWND hwndDlg, uint itemidx, bool enabled ) -{ - EnableWindow( GetDlgItem( hwndDlg, itemidx ), enabled ); -} - -BOOL CALLBACK CpuDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - char cpuspeedc[20]; - char features[256]; - char cfps[20]; - char cFrameskip[20]; - char cConsecutiveFrames[20]; - char cConsecutiveSkip[20]; - u32 newopts; - - switch(uMsg) { - case WM_INITDIALOG: - SetWindowText(hW, "Cpu Config"); - SetDlgItemText(hW, IDC_VENDORINPUT,cpuinfo.x86ID ); - SetDlgItemText(hW, IDC_FAMILYINPUT, cpuinfo.x86Fam); - sprintf(cpuspeedc,"%d MHZ",cpuinfo.cpuspeed); - SetDlgItemText(hW, IDC_CPUSPEEDINPUT, cpuspeedc); - Static_SetText(GetDlgItem(hW, IDC_VENDORNAME), "CPU Vendor"); - Static_SetText(GetDlgItem(hW, IDC_FAMILYNAME), "Family"); - Static_SetText(GetDlgItem(hW, IDC_CPUSPEEDNAME), "CPU Speed"); - Static_SetText(GetDlgItem(hW, IDC_FEATURESNAME), "Features"); - Static_SetText(GetDlgItem(hW, IDC_CPU_EEREC), "EERec - EE/IOP recompiler (need MMX/SSE)"); - Static_SetText(GetDlgItem(hW, IDC_CPU_VUGROUP), "VU Recompilers - All options are set by default"); - Static_SetText(GetDlgItem(hW, IDC_CPU_VU0REC), "VU0rec - enable recompiler for VU0 unit"); - Static_SetText(GetDlgItem(hW, IDC_CPU_VU1REC), "VU1rec - enable recompiler for VU1 unit"); - Static_SetText(GetDlgItem(hW, IDC_CPU_GSMULTI), "Multi threaded GS mode (MTGS)\n(faster on dual core/HT procs, requires pcsx2 restart)"); - Static_SetText(GetDlgItem(hW, IDC_FRAMELIMIT), "Frame Limiting (F4 key switches the mode in-game!)"); - Static_SetText(GetDlgItem(hW, IDC_CPU_FL_NORMAL), "Normal - All frames are rendered as fast as possible."); - Static_SetText(GetDlgItem(hW, IDC_CPU_FL_LIMIT), "Limit - Force frames to normal speeds if too fast."); - Static_SetText(GetDlgItem(hW, IDC_CPU_FL_SKIP), "Frame Skip - In order to achieve normal speeds,\nsome frames are skipped (fast).\nFps displayed counts skipped frames too."); - Static_SetText(GetDlgItem(hW, IDC_CPU_FL_SKIPVU), "VU Skip - Same as 'Frame Skip', but tries to skip more.\nArtifacts might be present, but will be faster."); - Static_SetText(GetDlgItem(hW, IDC_CUSTOM_FPS), "Custom FPS Limit (0=auto):"); - Static_SetText(GetDlgItem(hW, IDC_FRAMESKIP_LABEL1), "Skip Frames when slower than:\n(See Note 1)"); - Static_SetText(GetDlgItem(hW, IDC_FRAMESKIP_LABEL2), "Consecutive Frames before skipping:\n(See Note 2)"); - Static_SetText(GetDlgItem(hW, IDC_FRAMESKIP_LABEL3), "*Note 1: Will only skip when slower than this fps number.\n (0 = Auto) ; (9999 = Forced-Frameskip regardless of speed.)\n (e.g. If set to 45, will only skip when slower than 45fps.)"); - Static_SetText(GetDlgItem(hW, IDC_FRAMESKIP_LABEL4), "*Note 2: Will render this number of consecutive frames before\n skipping the next frame. (0=default)\n (e.g. If set to 2, will render 2 frames before skipping 1.)"); - Static_SetText(GetDlgItem(hW, IDC_FRAMESKIP_LABEL5), "Consecutive Frames to skip:\n(See Note 3)"); - Static_SetText(GetDlgItem(hW, IDC_FRAMESKIP_LABEL6), "*Note 3: Will skip this number of frames before\n rendering the next sequence of frames. (0=default)\n (e.g. If set to 2, will skip 2 consecutive frames whenever its time\n to skip.)"); - - Button_SetText(GetDlgItem(hW, IDOK), "OK"); - Button_SetText(GetDlgItem(hW, IDCANCEL), "Cancel"); - - //features[0]=':'; - //strcat(features,""); - strcpy(features,""); - if(cpucaps.hasMultimediaExtensions) strcat(features,"MMX"); - if(cpucaps.hasStreamingSIMDExtensions) strcat(features,",SSE"); - if(cpucaps.hasStreamingSIMD2Extensions) strcat(features,",SSE2"); - if(cpucaps.hasStreamingSIMD3Extensions) strcat(features,",SSE3"); - if(cpucaps.hasSupplementalStreamingSIMD3Extensions) strcat(features,",SSSE3"); - if(cpucaps.hasStreamingSIMD4Extensions) strcat(features,",SSE4.1"); -// if(cpucaps.has3DNOWInstructionExtensions) strcat(features,",3DNOW"); -// if(cpucaps.has3DNOWInstructionExtensionsExt)strcat(features,",3DNOW+"); -// if(cpucaps.hasAMD64BitArchitecture) strcat(features,",x86-64"); - SetDlgItemText(hW, IDC_FEATURESINPUT, features); - - CheckDlgButton(hW, IDC_CPU_EEREC, !!(Config.Options&PCSX2_EEREC)); - CheckDlgButton(hW, IDC_CPU_VU0REC, !!(Config.Options&PCSX2_VU0REC)); - CheckDlgButton(hW, IDC_CPU_VU1REC, !!(Config.Options&PCSX2_VU1REC)); - - EnableDlgItem( hW, IDC_CPU_EEREC, !g_Session.ForceDisableEErec ); - EnableDlgItem( hW, IDC_CPU_VU0REC, !g_Session.ForceDisableVU0rec ); - EnableDlgItem( hW, IDC_CPU_VU1REC, !g_Session.ForceDisableVU1rec ); - - CheckDlgButton(hW, IDC_CPU_GSMULTI, !!CHECK_MULTIGS); - - CheckRadioButton(hW,IDC_CPU_FL_NORMAL, IDC_CPU_FL_NORMAL+3, IDC_CPU_FL_NORMAL+(CHECK_FRAMELIMIT>>10)); - - sprintf(cfps,"%d",Config.CustomFps); - SetDlgItemText(hW, IDC_CUSTOMFPS, cfps); - - sprintf(cFrameskip,"%d",Config.CustomFrameSkip); - SetDlgItemText(hW, IDC_CUSTOM_FRAMESKIP, cFrameskip); - - sprintf(cConsecutiveFrames,"%d",Config.CustomConsecutiveFrames); - SetDlgItemText(hW, IDC_CUSTOM_CONSECUTIVE_FRAMES, cConsecutiveFrames); - - sprintf(cConsecutiveSkip,"%d",Config.CustomConsecutiveSkip); - SetDlgItemText(hW, IDC_CUSTOM_CONSECUTIVE_SKIP, cConsecutiveSkip); - - //EnableWindow( GetDlgItem( hW, IDC_CPU_GSMULTI ), !g_GameInProgress ); - - return TRUE; - - case WM_COMMAND: - switch(LOWORD(wParam)) - { - case IDCANCEL: - EndDialog(hW, FALSE); - return FALSE; - - case IDOK: - newopts = 0; - - if( SendDlgItemMessage(hW,IDC_CPU_EEREC,BM_GETCHECK,0,0) ) newopts |= PCSX2_EEREC; - - if( SendDlgItemMessage(hW,IDC_CPU_VU0REC,BM_GETCHECK,0,0) ) newopts |= PCSX2_VU0REC; - if( SendDlgItemMessage(hW,IDC_CPU_VU1REC,BM_GETCHECK,0,0) ) newopts |= PCSX2_VU1REC; - - if( SendDlgItemMessage(hW,IDC_CPU_GSMULTI,BM_GETCHECK,0,0) ) newopts |= PCSX2_GSMULTITHREAD; - - if( SendDlgItemMessage(hW,IDC_CPU_FL_NORMAL,BM_GETCHECK,0,0) ) newopts |= PCSX2_FRAMELIMIT_NORMAL; - else if( SendDlgItemMessage(hW,IDC_CPU_FL_LIMIT,BM_GETCHECK,0,0) ) newopts |= PCSX2_FRAMELIMIT_LIMIT; - else if( SendDlgItemMessage(hW,IDC_CPU_FL_SKIP,BM_GETCHECK,0,0) ) newopts |= PCSX2_FRAMELIMIT_SKIP; - - GetDlgItemText(hW, IDC_CUSTOMFPS, cfps, 20); - Config.CustomFps = atoi(cfps); - - GetDlgItemText(hW, IDC_CUSTOM_FRAMESKIP, cFrameskip, 20); - Config.CustomFrameSkip = atoi(cFrameskip); - - GetDlgItemText(hW, IDC_CUSTOM_CONSECUTIVE_FRAMES, cConsecutiveFrames, 20); - Config.CustomConsecutiveFrames = atoi(cConsecutiveFrames); - - GetDlgItemText(hW, IDC_CUSTOM_CONSECUTIVE_SKIP, cConsecutiveSkip, 20); - Config.CustomConsecutiveSkip = atoi(cConsecutiveSkip); - - EndDialog(hW, TRUE); - - if( Config.Options != newopts ) - { - SysRestorableReset(); - - if( (Config.Options&PCSX2_GSMULTITHREAD) ^ (newopts&PCSX2_GSMULTITHREAD) ) - { - // Need the MTGS setting to take effect, so close out the plugins: - PluginsResetGS(); - if( CHECK_MULTIGS ) - Console::Notice( "MTGS mode disabled.\n\tEnjoy the fruits of single-threaded simpicity." ); - else - Console::Notice( "MTGS mode enabled.\n\tWelcome to multi-threaded awesomeness." ); - } - Config.Options = newopts; - } - else if( Cpu != NULL ) - UpdateVSyncRate(); - - SaveConfig(); - - return FALSE; - } - return TRUE; - } - return FALSE; -} diff --git a/pcsx2/windows/SamplProf.cpp b/pcsx2/windows/SamplProf.cpp index 976f0d04c7..f1a0247f59 100644 --- a/pcsx2/windows/SamplProf.cpp +++ b/pcsx2/windows/SamplProf.cpp @@ -1,6 +1,6 @@ #include "PrecompiledHeader.h" -#include "RedtapeWindows.h" +#include "Utilities/RedtapeWindows.h" #include "SamplProf.h" #include diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index b6474938c6..fbbc6438d4 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -22,7 +22,7 @@ Name="Debug|Win32" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" - InheritedPropertySheets=".\vsprops\common.vsprops;..\..\..\common\vsprops\BaseProperties.vsprops;..\..\..\common\vsprops\3rdpartyDeps.vsprops;.\vsprops\debug.vsprops;.\vsprops\devbuild.vsprops;..\..\..\common\vsprops\pthreads.vsprops;..\..\..\common\vsprops\IncrementalLinking.vsprops" + InheritedPropertySheets=".\vsprops\common.vsprops;..\..\..\common\vsprops\BaseProperties.vsprops;..\..\..\common\vsprops\3rdpartyDeps.vsprops;..\..\..\common\vsprops\pthreads.vsprops;.\vsprops\devbuild.vsprops;..\..\..\common\vsprops\CodeGen_Debug.vsprops;..\..\..\common\vsprops\IncrementalLinking.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" CharacterSet="1" @@ -55,7 +55,6 @@ AdditionalIncludeDirectories=""$(ProjectRootDir)/NewGUI"" PreprocessorDefinitions="wxUSE_UNICODE=1" ExceptionHandling="2" - SmallerTypeCheck="false" UsePrecompiledHeader="2" PrecompiledHeaderThrough="PrecompiledHeader.h" PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch" @@ -100,8 +99,9 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + @@ -305,6 +341,10 @@ RelativePath="..\..\HashTools.cpp" > + + @@ -325,10 +365,6 @@ RelativePath="..\..\Patch.h" > - - @@ -348,6 +384,14 @@ UsePrecompiledHeader="1" /> + + + @@ -385,10 +429,6 @@ RelativePath="..\..\SourceLog.cpp" > - - @@ -779,18 +819,6 @@ RelativePath="..\..\x86\aVUzerorec.S" > - - - - - - - - - - - - - - @@ -1264,7 +1276,6 @@ > @@ -1464,6 +1475,10 @@ RelativePath="..\..\x86\ir5900tables.cpp" > + + @@ -1520,27 +1535,311 @@ > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - @@ -1628,6 +1927,14 @@ + + + + @@ -1641,6 +1948,30 @@ > + + + + + + + + + + + + - - - @@ -1742,37 +2065,9 @@ - - - - - - - - - - - - - - @@ -1786,154 +2081,6 @@ > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1949,10 +2096,6 @@ RelativePath="..\..\DebugTools\DisR3000A.cpp" > - - @@ -1978,496 +2121,9 @@ > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -2578,6 +2238,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcsx2/windows/Win32.h b/pcsx2/windows/Win32.h index fc9e629844..d8626fc05c 100644 --- a/pcsx2/windows/Win32.h +++ b/pcsx2/windows/Win32.h @@ -18,11 +18,9 @@ #pragma once -#include "RedtapeWindows.h" // our "safe" include of windows (sets version and undefs uselessness) +#include "Utilities/RedtapeWindows.h" // our "safe" include of windows (sets version and undefs uselessness) #include -#include "PrecompiledHeader.h" - #include #include diff --git a/pcsx2/windows/WinCompressNTFS.cpp b/pcsx2/windows/WinCompressNTFS.cpp index f98d0b1334..9064007129 100644 --- a/pcsx2/windows/WinCompressNTFS.cpp +++ b/pcsx2/windows/WinCompressNTFS.cpp @@ -15,7 +15,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - +#include "PrecompiledHeader.h" #include "Win32.h" // Translates an Errno code into an exception. diff --git a/pcsx2/windows/WinMain.cpp b/pcsx2/windows/WinMain.cpp deleted file mode 100644 index 96b811599c..0000000000 --- a/pcsx2/windows/WinMain.cpp +++ /dev/null @@ -1,1075 +0,0 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "PrecompiledHeader.h" -#include "win32.h" - -#include -#include - -#include - -#include "Common.h" -#include "debugger.h" -#include "rdebugger.h" -#include "AboutDlg.h" -#include "McdsDlg.h" - -#include "Patch.h" -#include "cheats/cheats.h" - -#include "Paths.h" -#include "SamplProf.h" - -#include "implement.h" // pthreads-win32 defines for startup/shutdown - -unsigned int langsMax; -static bool m_RestartGui = false; // used to signal a GUI restart after DestroyWindow() -static HBITMAP hbitmap_background = NULL; - - -struct _langs { - TCHAR lang[256]; -}; - -_langs *langs = NULL; - - -//2002-09-20 (Florin) -BOOL APIENTRY CmdlineProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);//forward def -//------------------- - -static const char* phelpmsg = - "pcsx2 [options] [cdimage/elf file]\n\n" - "\t-cfg [file] {configuration file}\n" - "\t-bootmode [mode] {0 - quick (default), 1 - bios, 2 - load elf}\n" - "\t-nogui {disables display of the gui - skips right to opening the GS window}" - "\t-help {display this help file}\n" - "\t-loadgs [file] {Loads a gsstate}\n\n" - "Run without GUI Options:\n" - "\n" - - "Plugin Overrides (specified dlls will be used in place of configured dlls):\n" - "\t-cdvd [dllpath] {specifies an override for the CDVD plugin}\n" - "\t-gs [dllpath] {specifies an override for the GS plugin}\n" - "\t-spu [dllpath] {specifies an override for the SPU2 plugin}\n" - "\t-pad [dllpath] {specifies an override for *both* pad plugins}\n" - "\t-pad1 [dllpath] {specifies an override for the PAD1 plugin only}\n" - "\t-pad2 [dllpath] {specifies an override for the PAD2 plugin only}\n" - "\t-dev9 [dllpath] {specifies an override for the DEV9 plugin}\n" - "\n"; - -/// This code is courtesy of http://alter.org.ua/en/docs/win/args/ -static PTCHAR* _CommandLineToArgv( const TCHAR *CmdLine, int* _argc ) -{ - PTCHAR* argv; - PTCHAR _argv; - ULONG len; - ULONG argc; - TCHAR a; - ULONG i, j; - - BOOLEAN in_QM; - BOOLEAN in_TEXT; - BOOLEAN in_SPACE; - - len = _tcslen( CmdLine ); - i = ((len+2)/2)*sizeof(PVOID) + sizeof(PVOID); - - argv = (PTCHAR*)GlobalAlloc(GMEM_FIXED, - i + (len+2)*sizeof(a)); - - _argv = (PTCHAR)(((PUCHAR)argv)+i); - - argc = 0; - argv[argc] = _argv; - in_QM = FALSE; - in_TEXT = FALSE; - in_SPACE = TRUE; - i = 0; - j = 0; - - while( a = CmdLine[i] ) { - if(in_QM) { - if(a == '\"') { - in_QM = FALSE; - } else { - _argv[j] = a; - j++; - } - } else { - switch(a) { - case '\"': - in_QM = TRUE; - in_TEXT = TRUE; - if(in_SPACE) { - argv[argc] = _argv+j; - argc++; - } - in_SPACE = FALSE; - break; - case ' ': - case '\t': - case '\n': - case '\r': - if(in_TEXT) { - _argv[j] = '\0'; - j++; - } - in_TEXT = FALSE; - in_SPACE = TRUE; - break; - default: - in_TEXT = TRUE; - if(in_SPACE) { - argv[argc] = _argv+j; - argc++; - } - _argv[j] = a; - j++; - in_SPACE = FALSE; - break; - } - } - i++; - } - _argv[j] = '\0'; - argv[argc] = NULL; - - (*_argc) = argc; - return argv; -} - -void WinClose() -{ - cpuShutdown(); - - // Don't check Config.Profiler here -- the Profiler will know if it's running or not. - ProfilerTerm(); - - ReleasePlugins(); - //Console::Close(); - - pthread_win32_process_detach_np(); - - SysShutdownDynarecs(); - SysShutdownMem(); -} - -BOOL SysLoggedSetLockPagesPrivilege ( HANDLE hProcess, BOOL bEnable); - -static void _doPluginOverride( const char* name, const char* src, char (&dest)[g_MaxPath] ) -{ - if( src == NULL || src[0] == 0 ) return; - - _tcscpy_s( dest, src ); - Console::Notice( "* %s plugin override: \n\t%s\n", params name, dest); -} - -void WinRun() -{ - // Load the command line overrides for plugins. - // Back up the user's preferences in winConfig. - - memcpy( &winConfig, &Config, sizeof( PcsxConfig ) ); - - _doPluginOverride( "GS", g_Startup.gsdll, Config.GS ); - _doPluginOverride( "CDVD", g_Startup.cdvddll, Config.CDVD ); - _doPluginOverride( "SPU2", g_Startup.spudll, Config.SPU2 ); - _doPluginOverride( "PAD1", g_Startup.pad1dll, Config.PAD1 ); - _doPluginOverride( "PAD2", g_Startup.pad2dll, Config.PAD2 ); - _doPluginOverride( "DEV9", g_Startup.dev9dll, Config.DEV9 ); - - - if( Config.Profiler ) - ProfilerInit(); - - InitCPUTicks(); - - while (LoadPlugins() == -1) - { - if (Pcsx2Configure(NULL) == FALSE) return; - } - -#ifdef PCSX2_DEVBUILD - if( g_pRunGSState ) { - LoadGSState(g_pRunGSState); - return; - } -#endif - - if( Config.PsxOut ) - { - // output the help commands - Console::SetColor( Console::Color_White ); - - Console::WriteLn( "Hotkeys:" ); - - Console::WriteLn( - "\tF1 - save state\n" - "\t(Shift +) F2 - cycle states\n" - "\tF3 - load state" - ); - - DevCon::WriteLn( - //"\tF10 - dump performance counters\n" - "\tF11 - save GS state\n" - //"\tF12 - dump hardware registers" - ); - Console::ClearColor(); - } - - RunGui(); -} - -/*int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) -{ - char *lang; - int i; - - CreateDirectory(LOGS_DIR, NULL); - - InitCommonControls(); - pInstance=hInstance; - FirstShow=true; // this is used by cheats.cpp to search for stuff (broken?) - - pthread_win32_process_attach_np(); - - gApp.hInstance = hInstance; - gApp.hMenu = NULL; - gApp.hWnd = NULL; - -#ifdef ENABLE_NLS - bindtextdomain(PACKAGE, "Langs\\"); - textdomain(PACKAGE); -#endif - - _getcwd( g_WorkingFolder, g_MaxPath ); - - int argc; - TCHAR *const *const argv = _CommandLineToArgv( lpCmdLine, &argc ); - - if( argv == NULL ) - { - Msgbox::Alert( "A fatal error occurred while attempting to parse the command line.\n" ); - return 2; - } - - switch( ParseCommandLine( argc, argv ) ) - { - case 1: // display help and exit: - printf( "%s", phelpmsg ); - MessageBox( NULL, phelpmsg, "Pcsx2 Help", MB_OK); - - case -1: // exit... - return 0; - } - - try - { - bool needsToConfig = !LoadConfig(); - - // Enumerate available translations - - if (needsToConfig || Config.Lang[0] == 0) { - strcpy(Config.Lang, "en_US"); - } - - langs = (_langs*)malloc(sizeof(_langs)); - strcpy(langs[0].lang, "en_US"); - InitLanguages(); i=1; - while ((lang = GetLanguageNext()) != NULL) { - langs = (_langs*)realloc(langs, sizeof(_langs)*(i+1)); - strcpy(langs[i].lang, lang); - i++; - } - CloseLanguages(); - langsMax = i; - - // automatically and always open the console for first-time uses (no ini file) - if(needsToConfig || Config.PsxOut ) - Console::Open(); - - // Important! Always allocate dynarecs before loading plugins, to give the dynarecs - // the best possible chance of claiming ideal memory space! - - HostGuiInit(); - - if( needsToConfig ) - { - // Prompt the user for a valid configuration before starting the program. - Msgbox::Alert( _( "Pcsx2 needs to be configured." ) ); - Pcsx2Configure( NULL ); - LoadConfig(); // forces re-loading of language and stuff. - } - - if( Config.PsxOut ) - Console::Open(); - else - Console::Close(); - - WinRun(); - } - catch( Exception::BaseException& ex ) - { - Msgbox::Alert( - "An unhandled or unrecoverable exception occurred, with the message:\n\n" - "%s" - "\n\nPcsx2 will now close. More details may be available via the emuLog.txt file.", params - ex.cMessage() - ); - } - catch( std::exception& ex ) - { - Msgbox::Alert( - "An unhandled or unrecoverable exception occurred, with the message:\n\n" - "%s" - "\n\nPcsx2 will now close. More details may be available via the emuLog.txt file.", params - ex.what() - ); - } - - WinClose(); - - return 0; -}*/ - -static std::string str_Default( "default" ); - -void RunGui() -{ - MSG msg; - - PCSX2_MEM_PROTECT_BEGIN(); - - LoadPatch( str_Default ); - - if( g_Startup.NoGui || g_Startup.Enabled ) - { - // Initially bypass GUI and start PCSX2 directly. - // Manually load plugins using the user's configured image (if non-elf). - - if( g_Startup.Enabled && (g_Startup.BootMode != BootMode_Elf) ) - { - if (OpenPlugins(g_Startup.ImageName) == -1) - return; - } - - SysPrepareExecution( - (g_Startup.BootMode == BootMode_Elf) ? g_Startup.ImageName : NULL, - (g_Startup.BootMode == BootMode_Bios) - ); - } - - do - { - CreateMainWindow(); - m_RestartGui = false; - - while( true ) - { - if( PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) != 0 ) - { - if( msg.message == WM_QUIT ) - { - gApp.hWnd = NULL; - break; - } - - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - Sleep(10); - } - } while( m_RestartGui ); - - PCSX2_MEM_PROTECT_END(); -} - -BOOL Open_File_Proc( std::string& outstr ) -{ - OPENFILENAME ofn; - char szFileName[ g_MaxPath ]; - char szFileTitle[ g_MaxPath ]; - char * filter = "ELF Files (*.ELF)\0*.ELF\0ALL Files (*.*)\0*.*\0"; - - memzero_obj( szFileName ); - memzero_obj( szFileTitle ); - - ofn.lStructSize = sizeof( OPENFILENAME ); - ofn.hwndOwner = gApp.hWnd; - ofn.lpstrFilter = filter; - ofn.lpstrCustomFilter = NULL; - ofn.nMaxCustFilter = 0; - ofn.nFilterIndex = 1; - ofn.lpstrFile = szFileName; - ofn.nMaxFile = g_MaxPath; - ofn.lpstrInitialDir = NULL; - ofn.lpstrFileTitle = szFileTitle; - ofn.nMaxFileTitle = g_MaxPath; - ofn.lpstrTitle = NULL; - ofn.lpstrDefExt = "ELF"; - ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER; - - if (GetOpenFileName(&ofn)) { - struct stat buf; - - if (stat(szFileName, &buf) != 0) { - return FALSE; - } - - outstr = szFileName; - return TRUE; - } - - return FALSE; -} - -//2002-09-20 (Florin) -BOOL APIENTRY CmdlineProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case WM_INITDIALOG: - SetWindowText(hDlg, _("Program arguments")); - - Button_SetText(GetDlgItem(hDlg, IDOK), _("OK")); - Button_SetText(GetDlgItem(hDlg, IDCANCEL), _("Cancel")); - Static_SetText(GetDlgItem(hDlg, IDC_TEXT), _("Fill in the command line arguments for opened program:")); - Static_SetText(GetDlgItem(hDlg, IDC_TIP), _("Tip: If you don't know what to write\nleave it blank")); - - SetDlgItemText(hDlg, IDC_CMDLINE, args); - return TRUE; - - case WM_COMMAND: - if (LOWORD(wParam) == IDOK) - { - char tmp[256]; - - GetDlgItemText(hDlg, IDC_CMDLINE, tmp, 256); - - strcpy_s(args, 256, tmp); - - EndDialog(hDlg, TRUE); - } else if (LOWORD(wParam) == IDCANCEL) { - EndDialog(hDlg, TRUE); - } - return TRUE; - } - - return FALSE; -} - - -#ifdef PCSX2_DEVBUILD - -BOOL APIENTRY LogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - int i; - - // Note: varLog layout has been changed, so this code won't be applicable to the new wx version - // of this dialog box. - - switch (message) { - case WM_INITDIALOG: - //for (i=0; i<32; i++) - // if (varLog & (1<= ID_LANGS && LOWORD(wParam) <= (ID_LANGS + langsMax)) - { - m_RestartGui = true; - DestroyWindow(gApp.hWnd); - ChangeLanguage(langs[LOWORD(wParam) - ID_LANGS].lang); - break; - } - return TRUE; - } - return FALSE; - - case WM_DESTROY: - if( hbitmap_background != NULL ) - { - DeleteObject( hbitmap_background ); - hbitmap_background = NULL; - } - gApp.hWnd = NULL; - break; - - case WM_NCDESTROY: - PostQuitMessage(0); - break; - - - // Explicit handling of WM_CLOSE. - // This is Windows default behavior, but we handle it here sot hat we might add a - // user confirmation prompt prior to exit (someday!) - case WM_CLOSE: - DestroyWindow( hWnd ); - return TRUE; - - case WM_SYSCOMMAND: - if( nDisableSC && (wParam== SC_SCREENSAVE || wParam == SC_MONITORPOWER) ) { - return FALSE; - } - break; - } - - return DefWindowProc(hWnd, msg, wParam, lParam); -} - -// fixme - this looks like the beginnings of a dynamic "list of valid saveslots" -// feature. Too bad it's never called and CheckState was old/dead code. -/*void UpdateMenuSlots() { - char str[g_MaxPath]; - int i; - - for (i=0; i<5; i++) { - sprintf_s (str, g_MaxPath, "sstates\\%8.8X.%3.3d", ElfCRC, i); - Slots[i] = CheckState(str); - } -}*/ - - -#define _ADDSUBMENU(menu, menun, string) \ - submenu[menun] = CreatePopupMenu(), \ - AppendMenu(menu, MF_STRING | MF_POPUP, (UINT)submenu[menun], string) - -#define ADDSUBMENU(menun, string) \ - _ADDSUBMENU(gApp.hMenu, menun, string); - -#define ADDSUBMENUS(submn, menun, string) \ - submenu[menun] = CreatePopupMenu(), \ - InsertMenu(submenu[submn], 0, MF_BYPOSITION | MF_STRING | MF_POPUP, (UINT)submenu[menun], string) - -#define ADDMENUITEM(menun, string, id) \ - item.fType = MFT_STRING, \ - item.fMask = MIIM_STATE | MIIM_TYPE | MIIM_ID, \ - item.fState = MFS_ENABLED, \ - item.wID = id, \ - sprintf(buf, string), \ - InsertMenuItem(submenu[menun], 0, TRUE, &item) - -#define ADDMENUITEMC(menun, string, id) \ - item.fType = MFT_STRING, \ - item.fMask = MIIM_STATE | MIIM_TYPE | MIIM_ID, \ - item.fState = MFS_ENABLED | MFS_CHECKED, \ - item.wID = id, \ - sprintf(buf, string), \ - InsertMenuItem(submenu[menun], 0, TRUE, &item) - -#define ADDSEPARATOR(menun) \ - item.fMask = MIIM_TYPE, \ - item.fType = MFT_SEPARATOR, \ - InsertMenuItem(submenu[menun], 0, TRUE, &item) - -void CreateMainMenu() { - MENUITEMINFO item; - HMENU submenu[5]; - char buf[256]; - int i; - - item.cbSize = sizeof(MENUITEMINFO); - item.dwTypeData = buf; - item.cch = 256; - - gApp.hMenu = CreateMenu(); - - //submenu = CreatePopupMenu(); - //AppendMenu(gApp.hMenu, MF_STRING | MF_POPUP, (UINT)submenu, _("&File")); - ADDSUBMENU(0, _("&File")); - ADDMENUITEM(0, _("E&xit"), ID_FILE_EXIT); - ADDSEPARATOR(0); - ADDSUBMENUS(0, 1, _("&States")); - ADDSEPARATOR(0); - ADDMENUITEM(0, _("&Open ELF File"), ID_FILEOPEN); - ADDMENUITEM(0, _("&Run CD/DVD"), ID_FILE_RUNCD); - ADDSUBMENUS(1, 3, _("&Save")); - ADDSUBMENUS(1, 2, _("&Load")); - ADDMENUITEM(2, _("&Other..."), ID_FILE_STATES_LOAD_OTHER); - ADDMENUITEM(2, _("Slot &4"), ID_FILE_STATES_LOAD_SLOT5); - ADDMENUITEM(2, _("Slot &3"), ID_FILE_STATES_LOAD_SLOT4); - ADDMENUITEM(2, _("Slot &2"), ID_FILE_STATES_LOAD_SLOT3); - ADDMENUITEM(2, _("Slot &1"), ID_FILE_STATES_LOAD_SLOT2); - ADDMENUITEM(2, _("Slot &0"), ID_FILE_STATES_LOAD_SLOT1); - ADDMENUITEM(3, _("&Other..."), ID_FILE_STATES_SAVE_OTHER); - ADDMENUITEM(3, _("Slot &4"), ID_FILE_STATES_SAVE_SLOT5); - ADDMENUITEM(3, _("Slot &3"), ID_FILE_STATES_SAVE_SLOT4); - ADDMENUITEM(3, _("Slot &2"), ID_FILE_STATES_SAVE_SLOT3); - ADDMENUITEM(3, _("Slot &1"), ID_FILE_STATES_SAVE_SLOT2); - ADDMENUITEM(3, _("Slot &0"), ID_FILE_STATES_SAVE_SLOT1); - - ADDSUBMENU(0, _("&Run")); - - if( IsDevBuild ) - ADDMENUITEM(0,_("&Arguments"), ID_RUN_CMDLINE); - - ADDMENUITEM(0,_("Re&set"), ID_RUN_RESET); - ADDMENUITEM(0,_("E&xecute"), ID_RUN_EXECUTE); - - ADDSUBMENU(0,_("&Config")); - ADDMENUITEM(0,_("Advanced"), ID_ADVANCED_OPTIONS); - ADDMENUITEM(0,_("Speed &Hacks"), ID_HACKS); - ADDMENUITEM(0,_("Gamefixes"), ID_GAMEFIXES); - ADDMENUITEM(0,_("&Patches"), ID_PATCHBROWSER); - ADDMENUITEM(0,_("C&pu"), ID_CONFIG_CPU); - ADDMENUITEM(0,_("&Memcards"), ID_CONFIG_MEMCARDS); - ADDSEPARATOR(0); - ADDMENUITEM(0,_("Fire&Wire"), ID_CONFIG_FW); - ADDMENUITEM(0,_("U&SB"), ID_CONFIG_USB); - ADDMENUITEM(0,_("D&ev9"), ID_CONFIG_DEV9); - ADDMENUITEM(0,_("C&dvdrom"), ID_CONFIG_CDVDROM); - ADDMENUITEM(0,_("&Sound"), ID_CONFIG_SOUND); - ADDMENUITEM(0,_("C&ontrollers"), ID_CONFIG_CONTROLLERS); - ADDMENUITEM(0,_("&Graphics"), ID_CONFIG_GRAPHICS); - ADDSEPARATOR(0); - ADDMENUITEM(0,_("&Configure"), ID_CONFIG_CONFIGURE); - - ADDSUBMENU(0,_("&Language")); - - /*for (i=langsMax-1; i>=0; i--) - { - if (!strcmp(Config.Lang, langs[i].lang)) - ADDMENUITEMC(0,ParseLang(langs[i].lang), ID_LANGS + i); - else - ADDMENUITEM(0,ParseLang(langs[i].lang), ID_LANGS + i); - }*/ - -#ifdef PCSX2_DEVBUILD - ADDSUBMENU(0, _("&Debug")); - ADDMENUITEM(0,_("&Logging"), ID_DEBUG_LOGGING); - ADDMENUITEM(0,_("Memory Dump"), ID_DEBUG_MEMORY_DUMP); - ADDMENUITEM(0,_("&Remote Debugging"), ID_DEBUG_REMOTEDEBUGGING); - ADDMENUITEM(0,_("Enter &Debugger..."), ID_DEBUG_ENTERDEBUGGER); -#endif - - ADDSUBMENU(0, _("&Misc")); - ADDMENUITEM(0,_("Print cdvd &Info"), ID_CDVDPRINT); - ADDMENUITEM(0,_("Close GS Window on Esc"), ID_CLOSEGS); - ADDSEPARATOR(0); - ADDMENUITEM(0,_("Enable &Profiler"), ID_PROFILER); - ADDMENUITEM(0,_("Enable &Patches"), ID_PATCHES); - ADDMENUITEM(0,_("Enable &Console"), ID_CONSOLE); - ADDSEPARATOR(0); - ADDMENUITEM(0,_("Patch &Finder..."), ID_CHEAT_FINDER_SHOW); - ADDMENUITEM(0,_("Patch &Browser..."), ID_CHEAT_BROWSER_SHOW); - - - ADDSUBMENU(0, _("&Help")); - ADDMENUITEM(0,_("&Pcsx2 Website..."), ID_HELP_HELP); - ADDMENUITEM(0,_("&About..."), ID_HELP_ABOUT); - - if( !IsDevBuild ) - EnableMenuItem(GetSubMenu(gApp.hMenu, 4), ID_DEBUG_LOGGING, MF_GRAYED); -} - -void CreateMainWindow() -{ - WNDCLASS wc; - HWND hWnd; - char buf[256]; - char COMPILER[20]=""; - BITMAP bm; - RECT rect; - int w, h; - -#ifdef _MSC_VER - sprintf(COMPILER, "(VC%d)", (_MSC_VER+100)/200);//hacky:) works for VC6 & VC.NET -#elif __BORLANDC__ - sprintf(COMPILER, "(BC)"); -#endif - /* Load Background Bitmap from the ressource */ - if( hbitmap_background == NULL ) - hbitmap_background = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(SPLASH_LOGO)); - - wc.lpszClassName = "PCSX2 Main"; - wc.lpfnWndProc = MainWndProc; - wc.style = 0; - wc.hInstance = gApp.hInstance; - wc.hIcon = LoadIcon(gApp.hInstance, MAKEINTRESOURCE(IDI_ICON)); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)(COLOR_MENUTEXT); - wc.lpszMenuName = 0; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - - RegisterClass(&wc); - GetObject(hbitmap_background, sizeof(bm), &bm); - -#ifdef PCSX2_DEVBUILD - sprintf(buf, _("PCSX2 %s - Compile Date - %s %s"), PCSX2_VERSION, COMPILEDATE, COMPILER); -#else - sprintf(buf, _("PCSX2 %s"), PCSX2_VERSION); -#endif - - hWnd = CreateWindow( - "PCSX2 Main", - buf, WS_OVERLAPPED | WS_SYSMENU, - 20, 20, 320, 240, - NULL, NULL, - gApp.hInstance, NULL - ); - - gApp.hWnd = hWnd; - HostGui::ResetMenuSlots(); - CreateMainMenu(); - - SetMenu(gApp.hWnd, gApp.hMenu); - if(Config.PsxOut) CheckMenuItem(gApp.hMenu,ID_CONSOLE,MF_CHECKED); - if(Config.Patch) CheckMenuItem(gApp.hMenu,ID_PATCHES,MF_CHECKED); - if(Config.Profiler) CheckMenuItem(gApp.hMenu,ID_PROFILER,MF_CHECKED); - if(Config.cdvdPrint)CheckMenuItem(gApp.hMenu,ID_CDVDPRINT,MF_CHECKED); - if(Config.closeGSonEsc)CheckMenuItem(gApp.hMenu,ID_CLOSEGS,MF_CHECKED); - - hStatusWnd = CreateStatusWindow(WS_CHILD | WS_VISIBLE, "", hWnd, 100); - - w = bm.bmWidth; h = bm.bmHeight; - GetWindowRect(hStatusWnd, &rect); - h+= rect.bottom - rect.top; - GetMenuItemRect(hWnd, gApp.hMenu, 0, &rect); - h+= rect.bottom - rect.top; - MoveWindow(hWnd, 60, 60, w, h, TRUE); - SendMessage( hStatusWnd, WM_SIZE, 0, 0 ); - - HostGui::SetStatusMsg("F1 - save, F2 - next state, Shift+F2 - prev state, F3 - load, F8 - snapshot"); - - ShowWindow(hWnd, true); - SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); -} - diff --git a/pcsx2/windows/ini.cpp b/pcsx2/windows/ini.cpp index 991ac8e42a..0d374ec2bf 100644 --- a/pcsx2/windows/ini.cpp +++ b/pcsx2/windows/ini.cpp @@ -228,11 +228,13 @@ void IniFile::DoConfig( PcsxConfig& Conf ) Entry("EECycleRate", Config.Hacks.EECycleRate); if (Config.Hacks.EECycleRate > 2) Config.Hacks.EECycleRate = 2; - Entry("IOPCycleDouble", Config.Hacks.IOPCycleDouble); - Entry("WaitCycleExt", Config.Hacks.WaitCycleExt); - Entry("INTCSTATSlow", Config.Hacks.INTCSTATSlow); - Entry("VUCycleSteal", Config.Hacks.VUCycleSteal); - Entry("IdleLoopFF", Config.Hacks.IdleLoopFF); + Entry("IOPCycleDouble", Config.Hacks.IOPCycleDouble); + Entry("WaitCycleExt", Config.Hacks.WaitCycleExt); + Entry("INTCSTATSlow", Config.Hacks.INTCSTATSlow); + Entry("VUCycleSteal", Config.Hacks.VUCycleSteal); + Entry("vuFlagHack", Config.Hacks.vuFlagHack); + Entry("vuMinMax", Config.Hacks.vuMinMax); + Entry("IdleLoopFF", Config.Hacks.IdleLoopFF); if (Conf.Hacks.VUCycleSteal < 0 || Conf.Hacks.VUCycleSteal > 4) Conf.Hacks.VUCycleSteal = 0; Entry("ESCExits", Config.Hacks.ESCExits); diff --git a/pcsx2/windows/pcsx2.rc b/pcsx2/windows/pcsx2.rc index e1013f35db..9f6d38bfbc 100644 --- a/pcsx2/windows/pcsx2.rc +++ b/pcsx2/windows/pcsx2.rc @@ -74,23 +74,26 @@ LANGUAGE LANG_GERMAN, SUBLANG_GERMAN // Dialog // -IDD_GAMEFIXES DIALOGEX 0, 0, 279, 123 +IDD_GAMEFIXES DIALOGEX 0, 0, 279, 154 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Game Special Fixes" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - DEFPUSHBUTTON "OK",IDOK,87,96,50,14 - PUSHBUTTON "Cancel",IDCANCEL,142,96,50,14 + DEFPUSHBUTTON "OK",IDOK,86,133,50,14 + PUSHBUTTON "Cancel",IDCANCEL,142,133,50,14 CTEXT "Some games need special settings.\nConfigure them here.",IDC_STATIC,7,7,265,17 - GROUPBOX "PCSX2 Gamefixes",IDC_STATIC,7,22,265,94 + GROUPBOX "PCSX2 Gamefixes",IDC_STATIC,7,22,265,104 CONTROL "FPU Compare Hack - Special fix for Digimon Rumble Arena 2.",IDC_GAMEFIX3, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,36,249,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,51,249,10 CONTROL "VU Add Hack - Special fix for Tri-Ace games!",IDC_GAMEFIX2, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,65,252,10 - CONTROL "VU Clip Hack - Fixes missing ground geometry in Persona.",IDC_GAMEFIX4, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,79,238,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,80,252,10 + CONTROL "VU Clip Hack - Fixes missing ground geometry in Persona. (Super VU)",IDC_GAMEFIX4, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,94,238,10 CONTROL "FPU Mul Hack - Special fix for Tales of Destiny.",IDC_GAMEFIX5, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,50,249,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,65,249,10 + CONTROL "DMA Execution Hack - Special fix for Fatal Frame.",IDC_GAMEFIX6, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,37,238,10 + CONTROL "VU XGkick Hack - Special fix for Erementar Gerad.",IDC_GAMEFIX8, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,108,238,10 END @@ -108,8 +111,7 @@ BEGIN RIGHTMARGIN, 272 VERTGUIDE, 14 TOPMARGIN, 7 - BOTTOMMARGIN, 116 - HORZGUIDE, 103 + BOTTOMMARGIN, 147 END END #endif // APSTUDIO_INVOKED @@ -344,7 +346,7 @@ BEGIN CTEXT "Pcsx2 Official Website and Forums",IDC_LINK_WEBSITE,79,151,273,10,SS_NOPREFIX | SS_NOTIFY END -IDD_HACKS DIALOGEX 0, 0, 335, 263 +IDD_HACKS DIALOGEX 0, 0, 543, 229 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "PCSX2 Speed Hacks" FONT 8, "MS Shell Dlg", 400, 0, 0x1 @@ -352,29 +354,35 @@ BEGIN CONTROL "Default Cycle Rate",IDC_EESYNC_DEFAULT,"Button",BS_AUTORADIOBUTTON,13,44,87,10 CONTROL "Use x1.5 Cycle Rate",IDC_EESYNC1,"Button",BS_AUTORADIOBUTTON,13,79,87,10 CONTROL "Use x2 Cycle Rate",IDC_EESYNC2,"Button",BS_AUTORADIOBUTTON,13,113,83,10 - CONTROL "Enable IOP x2 Cycle Rate",IDC_IOPSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,88,98,10 - CONTROL "WaitCycles Sync Hack",IDC_WAITCYCLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,127,90,10 - CONTROL "Escape Hack - Use Esc key to fully exit PCSX2.",IDC_ESCHACK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,238,180,10 - DEFPUSHBUTTON "OK",IDOK,217,242,50,14 - PUSHBUTTON "Cancel",IDCANCEL,278,242,50,14 - CTEXT "These hacks will speed up emulation but reduce emulation compatibility or cause visual errors. If you have problems, disable all these and try again!",IDC_HACKDESC,18,7,286,19 - GROUPBOX "EmotionEngine (EE) Sync Hacks",IDC_STATIC,7,31,159,143 - GROUPBOX "Miscellaneous",IDC_STATIC,7,223,194,33 - LTEXT "Important: the X2 sync hack *will* cause choppy/skippy audio on many FMV movies.",IDC_STATIC,13,149,137,22 + CONTROL "Enable IOP x2 Cycle Rate",IDC_IOPSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,88,98,10 + CONTROL "WaitCycles Sync Hack",IDC_WAITCYCLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,127,90,10 + CONTROL "Esc Hack - Use Esc key to fully exit PCSX2.",IDC_ESCHACK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,197,152,10 + DEFPUSHBUTTON "OK",IDOK,424,208,50,14 + PUSHBUTTON "Cancel",IDCANCEL,486,208,50,14 + CTEXT "These hacks will speed up emulation but reduce emulation compatibility or cause visual errors.\nIf you have problems, disable all these and try again!",IDC_HACKDESC,7,7,529,19 + GROUPBOX "EmotionEngine (EE) Sync Hacks",IDC_STATIC,7,26,162,148 + GROUPBOX "Miscellaneous",IDC_STATIC,7,184,162,33 + LTEXT "Important: the X2 sync hack *will* cause choppy/skippy audio on many FMV movies.",IDC_STATIC,13,146,137,25 LTEXT "Big speedup! Works well with many games.",IDC_STATIC,25,124,125,19 LTEXT "Most compatible option - recommended for everyone with high-end machines.",IDC_STATIC,25,55,136,19 - LTEXT "Small speedup and works well with most games.",IDC_STATIC,186,100,134,22 - LTEXT "Small speedup. Works well with most games, but may cause certain games to crash or freeze up during bootup or stage changes.",IDC_STATIC,186,139,141,39 + LTEXT "Small speedup and works well with most games.",IDC_STATIC,200,100,134,22 + LTEXT "Small speedup. Works well with most games, but may cause certain games to crash or freeze up during bootup or stage changes.",IDC_STATIC,200,139,141,39 LTEXT "Moderate speedup and works well with most games.",IDC_STATIC,25,90,129,19 - CONTROL "INTC Sync Hack",IDC_INTCSTATHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,43,127,10 - LTEXT "Huge speedup in many games, and a pretty high compatibility rate (some games still work better with EE sync hacks).",IDC_STATIC,186,55,140,28 - CONTROL "",IDC_VUCYCLE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,13,178,36,15 - LTEXT "This space intentionally left blank",IDC_VUCYCLEDESC,25,196,142,24 - LTEXT "VU Cycle Stealing (experimental)",IDC_STATIC,49,183,105,8 + CONTROL "INTC Sync Hack",IDC_INTCSTATHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,43,127,10 + LTEXT "Huge speedup in many games, and a pretty high compatibility rate (some games still work better with EE sync hacks).",IDC_STATIC,200,55,140,28 + CONTROL "",IDC_VUCYCLE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,372,141,36,15 + LTEXT "This space intentionally left blank",IDC_VUCYCLEDESC,383,160,142,26 + LTEXT "VU Cycle Stealing (experimental)",IDC_STATIC,408,146,105,8 CONTROL "Idle Loop Fast-Forward (experimental)",IDC_IDLELOOPFF, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,179,139,10 - LTEXT "Speedup for a few games, including FFX with no known side effects. More later.",IDC_STATIC,186,193,142,26 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,179,139,10 + LTEXT "Speedup for a few games, including FFX with no known side effects.",IDC_STATIC,200,193,144,23 + GROUPBOX "EmotionEngine (EE) Misc Hacks",IDC_STATIC,177,26,179,192 + GROUPBOX "Vector Unit (VU) Hacks",IDC_STATIC,363,26,173,173 + CONTROL "Status Flag Hack (microVU only)",IDC_VUHACK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,372,42,155,12 + LTEXT "Big Speedup and high compatibility.\nSuperVU does something similar by default.",IDC_STATIC,383,55,144,20 + CONTROL "Min / Max Hack (microVU only)",IDC_VUHACK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,372,85,156,12 + LTEXT "Small Speedup. May cause SPS, hanging, graphical corruption, and missing geometry.",IDC_STATIC,383,99,143,28 END @@ -395,12 +403,16 @@ BEGIN IDD_HACKS, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 328 + RIGHTMARGIN, 536 VERTGUIDE, 13 - VERTGUIDE, 174 - VERTGUIDE, 186 + VERTGUIDE, 177 + VERTGUIDE, 187 + VERTGUIDE, 200 + VERTGUIDE, 372 + VERTGUIDE, 383 TOPMARGIN, 7 - BOTTOMMARGIN, 256 + BOTTOMMARGIN, 222 + HORZGUIDE, 26 END END #endif // APSTUDIO_INVOKED @@ -757,6 +769,7 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_ICON ICON "Cdrom02.ico" +IDI_UNINSTALL_ICON ICON "uninstall.ico" #endif // Spanish (Argentina) resources ///////////////////////////////////////////////////////////////////////////// @@ -834,12 +847,12 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN CONTROL "EERec - EE/IOP recompiler (need MMX/SSE/SSE2)",IDC_CPU_EEREC, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,100,265,18 - CONTROL "VU0rec - enable recompiler for VU0 unit",IDC_CPU_VU0REC, + CONTROL "VU0rec - Enable recompiler for VU0 unit.",IDC_CPU_VU0REC, "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,127,219,18 - CONTROL "VU1rec - enable recompiler for VU1 unit",IDC_CPU_VU1REC, + CONTROL "VU1rec - Enable recompiler for VU1 unit.",IDC_CPU_VU1REC, "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,143,214,18 CONTROL "Multi threaded GS mode (MTGS)\n (faster on dual core/HT procs, requires pcsx2 restart)",IDC_CPU_GSMULTI, - "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,166,231,30 + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,232,231,30 CONTROL "Normal - All frames are rendered as fast as possible.",IDC_CPU_FL_NORMAL, "Button",BS_AUTORADIOBUTTON | BS_MULTILINE | WS_GROUP,309,17,221,17 CONTROL "Limit - Force frames to normal speeds if too fast.\n (You can set a custom FPS limit below.)",IDC_CPU_FL_LIMIT, @@ -855,7 +868,7 @@ BEGIN LTEXT "",IDC_FAMILYINPUT,112,41,124,8 LTEXT "",IDC_FEATURESINPUT,111,79,124,8 LTEXT "",IDC_CPUSPEEDINPUT,111,61,124,8 - GROUPBOX "VU Recompilers - All options are set by default",IDC_CPU_VUGROUP,7,119,265,46 + GROUPBOX "VU Recompilers",IDC_CPU_VUGROUP,7,119,265,108 LTEXT "Features",IDC_FEATURESNAME,12,78,88,8 GROUPBOX "",IDC_STATIC,7,7,265,90 LTEXT "Custom FPS Limit (0=auto):",IDC_CUSTOM_FPS,327,103,124,12 @@ -871,6 +884,11 @@ BEGIN EDITTEXT IDC_CUSTOM_CONSECUTIVE_SKIP,456,157,53,13,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Consecutive Frames to skip:\n(See Note 3)",IDC_FRAMESKIP_LABEL5,327,157,121,17 LTEXT "*Note 3: Will skip this number of frames before\n rendering the next sequence of frames. (0=default)\n (e.g. If set to 2, will skip 2 consecutive frames whenever its time\n to skip.)",IDC_FRAMESKIP_LABEL6,318,234,217,32 + GROUPBOX "Use microVU?",IDC_CPU_VUGROUP2,14,167,235,47 + CONTROL "microVU0 - Use microVU rec for VU0 recompilation. ! Beta !",IDC_CPU_MVU0, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,24,180,215,13 + CONTROL "microVU1 - Use microVU rec for VU1 recompilation. ! Beta !",IDC_CPU_MVU1, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,24,195,215,13 END @@ -894,6 +912,7 @@ BEGIN BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 558 + VERTGUIDE, 24 TOPMARGIN, 7 END END diff --git a/pcsx2/windows/resource.h b/pcsx2/windows/resource.h index e519a3275a..4aa25813f4 100644 --- a/pcsx2/windows/resource.h +++ b/pcsx2/windows/resource.h @@ -26,6 +26,7 @@ #define IDD_ADDRAW 178 #define IDD_PNACHWRITER 179 #define IDD_CONF_MEMCARD 180 +#define IDI_UNINSTALL_ICON 181 #define IDC_MEM_SCROLL 1001 #define IDC_MCD2 1004 #define IDC_MCD1 1005 @@ -176,8 +177,8 @@ #define IDC_CPU_FL_NORMAL 1265 #define IDC_CPU_FL_LIMIT 1266 #define IDC_CPU_FL_SKIP 1267 -#define IDC_CPU_FL_SKIPVU 1268 #define IDC_CPU_VUGROUP 1269 +#define IDC_CPU_VUGROUP2 1270 #define IDC_GROUPS 1272 #define IDC_PATCHES 1273 #define IDC_CUSTOMFPS 1275 @@ -236,7 +237,9 @@ #define IDC_EE_ROUNDMODE0 1305 #define IDC_FCOR 1305 #define IDC_GAMEFIX7 1305 +#define IDC_GAMEFIX6 1305 #define IDC_EE_ROUNDMODE1 1306 +#define IDC_GAMEFIX8 1306 #define IDC_EE_ROUNDMODE2 1307 #define IDC_EE_ROUNDMODE3 1308 #define IDC_EESYNC_DEFAULT 1308 @@ -275,7 +278,13 @@ #define IDC_SLIDER1 1327 #define IDC_VUCYCLE 1327 #define IDC_VUCYCLEDESC 1328 +#define IDC_VUHACK1 1329 #define IDC_IDLELOOPFF 1330 +#define IDC_VUHACK2 1331 +#define IDC_INTCSTATHACK4 1332 +#define IDC_VUHACK3 1332 +#define IDC_CPU_MVU0 1335 +#define IDC_CPU_MVU1 1336 #define IDC_CPULOG 1500 #define IDC_MEMLOG 1501 #define IDC_HWLOG 1502 @@ -407,7 +416,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 141 +#define _APS_NEXT_RESOURCE_VALUE 182 #define _APS_NEXT_COMMAND_VALUE 40018 #define _APS_NEXT_CONTROL_VALUE 1331 #define _APS_NEXT_SYMED_VALUE 104 diff --git a/pcsx2/windows/uninstall.ico b/pcsx2/windows/uninstall.ico new file mode 100644 index 0000000000..f2308d021f Binary files /dev/null and b/pcsx2/windows/uninstall.ico differ diff --git a/pcsx2/x86/BaseblockEx.cpp b/pcsx2/x86/BaseblockEx.cpp index bb933f301d..f660e19944 100644 --- a/pcsx2/x86/BaseblockEx.cpp +++ b/pcsx2/x86/BaseblockEx.cpp @@ -21,9 +21,6 @@ BASEBLOCKEX* BaseBlocks::New(u32 startpc, uptr fnptr) { - if (blocks.size() == size) - return 0; - BASEBLOCKEX newblock; std::vector::iterator iter; memset(&newblock, 0, sizeof newblock); @@ -93,12 +90,13 @@ BASEBLOCKEX* BaseBlocks::GetByX86(uptr ip) return &blocks[imin]; } -void BaseBlocks::Link(u32 pc, uptr jumpptr) +void BaseBlocks::Link(u32 pc, s32* jumpptr) { BASEBLOCKEX *targetblock = Get(pc); if (targetblock && targetblock->startpc == pc) - *(u32*)jumpptr = targetblock->fnptr - (jumpptr + 4); + *jumpptr = (s32)(targetblock->fnptr - (sptr)(jumpptr + 1)); else - *(u32*)jumpptr = recompiler - (jumpptr + 4); - links.insert(std::pair(pc, jumpptr)); -} \ No newline at end of file + *jumpptr = (s32)(recompiler - (sptr)(jumpptr + 1)); + links.insert(std::pair(pc, (uptr)jumpptr)); +} + diff --git a/pcsx2/x86/BaseblockEx.h b/pcsx2/x86/BaseblockEx.h index fa38d61891..db8466b44b 100644 --- a/pcsx2/x86/BaseblockEx.h +++ b/pcsx2/x86/BaseblockEx.h @@ -53,17 +53,15 @@ private: // switch to a hash map later? std::multimap links; typedef std::multimap::iterator linkiter_t; - unsigned long size; uptr recompiler; std::vector blocks; public: - BaseBlocks(unsigned long size_, uptr recompiler_) : - size(size_), + BaseBlocks(uptr recompiler_) : recompiler(recompiler_), blocks(0) { - blocks.reserve(size); + blocks.reserve(0x4000); } BASEBLOCKEX* New(u32 startpc, uptr fnptr); @@ -117,7 +115,7 @@ public: blocks.erase(blocks.begin() + idx); } - void Link(u32 pc, uptr jumpptr); + void Link(u32 pc, s32* jumpptr); __forceinline void Reset() { diff --git a/pcsx2/x86/Makefile.am b/pcsx2/x86/Makefile.am deleted file mode 100644 index 99c84f5f99..0000000000 --- a/pcsx2/x86/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -INCLUDES = -I@srcdir@/../ -I@srcdir@/../../common/include -I@srcdir@/../IPU/ -I@srcdir@/../../3rdparty $(shell wx-config --cppflags) -noinst_LIBRARIES = libx86recomp.a - -# have to add the sources instead of making a library since the linking is complicated - -archfiles = ix86-32/iR5900-32.cpp ix86-32/iR5900AritImm.cpp ix86-32/iR5900Jump.cpp ix86-32/iR5900Move.cpp \ -ix86-32/iR5900Shift.cpp ix86-32/iR5900Arit.cpp ix86-32/iR5900Branch.cpp ix86-32/iR5900LoadStore.cpp \ -ix86-32/iR5900MultDiv.cpp ix86-32/iCore-32.cpp ix86-32/aR5900-32.S ix86-32/iR5900Templates.cpp ix86-32/recVTLB.cpp - -libx86recomp_a_SOURCES = \ -BaseblockEx.cpp iCore.cpp iMMI.h iR5900AritImm.h iR5900MultDiv.h ir5900tables.cpp \ -BaseblockEx.h iCore.h iPsxMem.cpp iR5900Branch.h iR5900Shift.h \ -iFPU.cpp iR3000A.h iR5900Jump.h iVUops.h iR3000A.cpp \ -iCOP0.cpp iFPU.h iR3000Atables.cpp iR5900LoadStore.h iVU1micro.cpp iVUzerorec.cpp \ -iCOP0.h iFPUd.cpp iR5900.h iR5900Misc.cpp iVUzerorec.h \ -iCOP2.cpp iMMI.cpp iR5900Arit.h iR5900Move.h iVif.cpp \ - fast_routines.S aR3000A.S aVUzerorec.S aVif.S $(archfiles) - -#ifdef PCSX2_MICROVU -#libx86recomp_a_SOURCES += \ -#microVU.cpp microVU_Alloc.cpp microVU_Compile.cpp microVU_Lower.cpp microVU_Misc.cpp microVU_Upper.cpp aMicroVU.S \ -#microVU.h microVU_Alloc.h microVU_Misc.h microVU_Tables.h -#endif - -libx86recomp_a_DEPENDENCIES = ix86/libix86.a - -SUBDIRS = ix86 \ No newline at end of file diff --git a/pcsx2/x86/README b/pcsx2/x86/README deleted file mode 100644 index 8d82c5e482..0000000000 --- a/pcsx2/x86/README +++ /dev/null @@ -1,12 +0,0 @@ -PCSX2 x86 Recompilers - zerofrog(@gmail.com) - -There are two types of x86 recompilers: x86-32 and x86-64. The code that both of them share is in the x86/ directory. Code for x86-32 is in the ix86-32/ and same goes for x86-64. The ix86/ dirctory contains the low level translation of x86 instructions to actual code, it is written to be used for both architectures. There are a lot of places where it was hard to separate 32bit from 64bit recompilers, so a lot of functions are surrounded by "#if(n)def __x86_64__" statements. - -It would be simple if the story ended here, but hte x86 recompilers use a lot of low level assembly routines, meaning that assembly has to be compiled for both windows x32/x64 versions and linux x32/x64 versions. - -For windows, the masm assembler is used (*.asm files) -For linux, gcc is used (*.S files) - -Both assemblers use very different syntax, also some routines in x86-64 differ a lot from their 32bit counterparts. Therefore, you might see the same function implemented up to 4 times in assembly. - -(no, it's not fun maintaining 4 versions of the same thing... and it might be easier to use nasm, but that probably has its own unforseeable problems) \ No newline at end of file diff --git a/pcsx2/x86/aMicroVU.S b/pcsx2/x86/aMicroVU.S deleted file mode 100644 index 04bce4fd11..0000000000 --- a/pcsx2/x86/aMicroVU.S +++ /dev/null @@ -1,62 +0,0 @@ -// microVU.cpp assembly routines -// arcum42(@gmail.com) -.intel_syntax noprefix - -.extern mVUexecuteVU0 -.extern mVUexecuteVU1 -.extern g_sseVUMXCSR -.extern g_sseMXCSR - -//------------------------------------------------------------------ -// Dispatcher Functions -//------------------------------------------------------------------ - -// Runs VU0 for number of cycles -// __fastcall = The first two DWORD or smaller arguments are passed in ECX and EDX registers; all other arguments are passed right to left. -//void __fastcall startVU0(u32 startPC, u32 cycles) -.globl startVU0 -startVU0: - call mVUexecuteVU0 - - // backup cpu state - push ebx - push ebp - push esi - push edi - - ldmxcsr g_sseVUMXCSR - // Should set xmmZ? - jmp eax - -// Runs VU1 for number of cycles -// void __fastcall startVU1(u32 startPC, u32 cycles) -.globl startVU1 -startVU01: - call mVUexecuteVU1 - - // backup cpu state - push ebx - push ebp - push esi - push edi - - ldmxcsr g_sseVUMXCSR - - jmp eax - -// Exit point -// void __fastcall endVU0(u32 startPC, u32 cycles) -.globl endVU0 -endVU0: - //call mVUcleanUpVU0 - - /*restore cpu state*/ - pop edi; - pop esi; - pop ebp; - pop ebx; - - ldmxcsr g_sseMXCSR - - ret - \ No newline at end of file diff --git a/pcsx2/x86/aVUzerorec.S b/pcsx2/x86/aVUzerorec.S index 251a3327f0..26ecdb375e 100644 --- a/pcsx2/x86/aVUzerorec.S +++ b/pcsx2/x86/aVUzerorec.S @@ -26,7 +26,7 @@ SuperVUExecuteProgram: mov s_vu1esi, esi mov s_vuedi, edi mov s_vuebx, ebx -#ifdef _DEBUG +#ifdef PCSX2_DEBUG mov s_vu1esp, esp #endif @@ -44,7 +44,7 @@ SuperVUEndProgram: mov edi, s_vuedi mov ebx, s_vuebx -#ifdef _DEBUG +#ifdef PCSX2_DEBUG sub s_vu1esp, esp #endif diff --git a/pcsx2/x86/iCOP2.cpp b/pcsx2/x86/iCOP2.cpp index 564ebc4fa2..dabe4440f6 100644 --- a/pcsx2/x86/iCOP2.cpp +++ b/pcsx2/x86/iCOP2.cpp @@ -27,7 +27,7 @@ #include "R5900.h" #include "R5900OpcodeTables.h" #include "VUmicro.h" -#include "iVUmicro.h" +#include "sVU_Micro.h" extern void _vu0WaitMicro(); diff --git a/pcsx2/x86/iCore.cpp b/pcsx2/x86/iCore.cpp index 97600e541f..48c94d210e 100644 --- a/pcsx2/x86/iCore.cpp +++ b/pcsx2/x86/iCore.cpp @@ -36,10 +36,6 @@ u32 g_cpuRegHasSignExt = 0, g_cpuPrevRegHasSignExt = 0; // set if upper 32 bits // use FreezeMMXRegs, FreezeXMMRegs u32 g_recWriteback = 0; -#ifdef _DEBUG -char g_globalXMMLocked = 0; -#endif - _xmmregs xmmregs[iREGCNT_XMM], s_saveXMMregs[iREGCNT_XMM]; // X86 caching diff --git a/pcsx2/x86/iCore.h b/pcsx2/x86/iCore.h index 1352be4157..05897c981b 100644 --- a/pcsx2/x86/iCore.h +++ b/pcsx2/x86/iCore.h @@ -19,8 +19,8 @@ #ifndef _PCSX2_CORE_RECOMPILER_ #define _PCSX2_CORE_RECOMPILER_ -#include "ix86/ix86.h" -#include "iVUmicro.h" +#include "x86emitter/x86emitter.h" +#include "sVU_Micro.h" // Namespace Note : iCore32 contains all of the Register Allocation logic, in addition to a handful // of utility functions for emitting frequent code. @@ -292,10 +292,6 @@ extern _xmmregs xmmregs[iREGCNT_XMM], s_saveXMMregs[iREGCNT_XMM]; extern u16 g_x86AllocCounter; extern u16 g_xmmAllocCounter; -#ifdef _DEBUG -extern char g_globalXMMLocked; -#endif - // allocates only if later insts use XMM, otherwise checks int _allocCheckGPRtoXMM(EEINST* pinst, int gprreg, int mode); int _allocCheckFPUtoXMM(EEINST* pinst, int fpureg, int mode); diff --git a/pcsx2/x86/iFPUd.cpp b/pcsx2/x86/iFPUd.cpp index 33a9693cc3..fc4f889a2b 100644 --- a/pcsx2/x86/iFPUd.cpp +++ b/pcsx2/x86/iFPUd.cpp @@ -20,7 +20,7 @@ #include "Common.h" #include "R5900OpcodeTables.h" -#include "ix86/ix86.h" +#include "x86emitter/x86emitter.h" #include "iR5900.h" #include "iFPU.h" @@ -34,7 +34,7 @@ #define FPU_FLAGS_UNDERFLOW 1 //if 1, result is not clamped (Gives correct results as in PS2, -//but can cause problems due to insuffecient clamping levels in the VUs) +//but can cause problems due to insufficient clamping levels in the VUs) #define FPU_RESULT 1 //set I&D flags. also impacts other aspects of DIV/R/SQRT correctness diff --git a/pcsx2/x86/iMisc.cpp b/pcsx2/x86/iMisc.cpp new file mode 100644 index 0000000000..5119f20c17 --- /dev/null +++ b/pcsx2/x86/iMisc.cpp @@ -0,0 +1,55 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" +#include "Pcsx2Config.h" + +u32 g_sseMXCSR = DEFAULT_sseMXCSR; +u32 g_sseVUMXCSR = DEFAULT_sseVUMXCSR; + +////////////////////////////////////////////////////////////////////////////////////////// +// SetCPUState -- for assignment of SSE roundmodes and clampmodes. +// +void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR) +{ + //Msgbox::Alert("SetCPUState: Config.sseMXCSR = %x; Config.sseVUMXCSR = %x \n", Config.sseMXCSR, Config.sseVUMXCSR); + // SSE STATE // + // WARNING: do not touch unless you know what you are doing + + sseMXCSR &= 0xffff; // clear the upper 16 bits since they shouldn't be set + sseVUMXCSR &= 0xffff; + + if( !cpucaps.hasStreamingSIMD2Extensions ) + { + // SSE1 cpus do not support Denormals Are Zero flag (throws an exception + // if we don't mask them off) + + sseMXCSR &= ~0x0040; + sseVUMXCSR &= ~0x0040; + } + + g_sseMXCSR = sseMXCSR; + g_sseVUMXCSR = sseVUMXCSR; + +#ifdef _MSC_VER + __asm ldmxcsr g_sseMXCSR; // set the new sse control +#else + __asm__("ldmxcsr %[g_sseMXCSR]" : : [g_sseMXCSR]"m"(g_sseMXCSR) ); +#endif + //g_sseVUMXCSR = g_sseMXCSR|0x6000; +} diff --git a/pcsx2/x86/iR3000A.cpp b/pcsx2/x86/iR3000A.cpp index ffb4b7f143..bdd2f7f574 100644 --- a/pcsx2/x86/iR3000A.cpp +++ b/pcsx2/x86/iR3000A.cpp @@ -39,6 +39,8 @@ #include "SamplProf.h" #include "NakedAsm.h" +using namespace x86Emitter; + extern u32 g_psxNextBranchCycle; extern void psxBREAK(); extern void zeroEx(); @@ -51,19 +53,58 @@ uptr psxhwLUT[0x10000]; #define HWADDR(mem) (psxhwLUT[mem >> 16] + (mem)) -#define PSX_NUMBLOCKS (1<<12) #define MAPBASE 0x48000000 #define RECMEM_SIZE (8*1024*1024) // R3000A statics int psxreclog = 0; +#ifdef _MSC_VER + +static u32 g_temp; + +// The address for all cleared blocks. It recompiles the current pc and then +// dispatches to the recompiled block address. +static __declspec(naked) void iopJITCompile() +{ + __asm { + mov esi, dword ptr [psxRegs.pc] + push esi + call iopRecRecompile + add esp, 4 + mov ebx, esi + shr esi, 16 + mov ecx, dword ptr [psxRecLUT+esi*4] + jmp dword ptr [ecx+ebx] + } +} + +static __declspec(naked) void iopJITCompileInBlock() +{ + __asm { + jmp iopJITCompile + } +} + +// called when jumping to variable psxpc address +static __declspec(naked) void iopDispatcherReg() +{ + __asm { + mov eax, dword ptr [psxRegs.pc] + mov ebx, eax + shr eax, 16 + mov ecx, dword ptr [psxRecLUT+eax*4] + jmp dword ptr [ecx+ebx] + } +} +#endif // _MSC_VER + + static u8 *recMem = NULL; // the recompiled blocks will be here static BASEBLOCK *recRAM = NULL; // and the ptr to the blocks here static BASEBLOCK *recROM = NULL; // and here static BASEBLOCK *recROM1 = NULL; // also here -void iopJITCompile(); -static BaseBlocks recBlocks(PSX_NUMBLOCKS, (uptr)iopJITCompile); +static BaseBlocks recBlocks((uptr)iopJITCompile); static u8 *recPtr = NULL; u32 psxpc; // recompiler psxpc int psxbranch; // set for branch @@ -92,11 +133,7 @@ void rpsxpropBSC(EEINST* prev, EEINST* pinst); static void iopClearRecLUT(BASEBLOCK* base, int count); -#ifdef _DEBUG -u32 psxdump = 0; -#else -#define psxdump 0 -#endif +static u32 psxdump = 0; #define PSX_GETBLOCK(x) PC_GETBLOCK_(x, psxRecLUT) @@ -105,7 +142,6 @@ u32 psxdump = 0; psxRecClearMem(mem) : 4) //////////////////////////////////////////////////// -#ifdef _DEBUG using namespace R3000A; #include "Utilities/AsciiFile.h" @@ -122,9 +158,9 @@ static void iIopDumpBlock( int startpc, u8 * ptr ) wxString filename( Path::Combine( g_Conf.Folders.Dumps, wxsFormat( L"psxdump%.8X.txt", startpc ) ) ); AsciiFile f( filename, wxFile::write ); - for ( i = startpc; i < s_nEndBlock; i += 4 ) { + /*for ( i = startpc; i < s_nEndBlock; i += 4 ) { f.Printf("%s\n", disR3000Fasm( iopMemRead32( i ), i ) ); - } + }*/ // write the instruction info f.Printf("\n\nlive0 - %x, lastuse - %x used - %x\n", EEINST_LIVE0, EEINST_LASTUSE, EEINST_USED); @@ -180,7 +216,6 @@ static void iIopDumpBlock( int startpc, u8 * ptr ) //f = fopen( filename.c_str(), "a+" ); #endif } -#endif u8 _psxLoadWritesRs(u32 tempcode) { @@ -264,19 +299,9 @@ void _psxFlushConstRegs() MOV32ItoM((uptr)&psxRegs.GPR.r[i], g_psxConstRegs[i]); g_psxFlushedConstReg |= 1<>26) == 9 ) { //ADDIU, call bios -#ifdef _DEBUG - MOV32ItoM( (uptr)&psxRegs.code, psxRegs.code ); - MOV32ItoM( (uptr)&psxRegs.pc, psxpc ); - _psxFlushCall(FLUSH_NODESTROY); - CALLFunc((uptr)zeroEx); -#endif + if( IsDebugBuild ) + { + MOV32ItoM( (uptr)&psxRegs.code, psxRegs.code ); + MOV32ItoM( (uptr)&psxRegs.pc, psxpc ); + _psxFlushCall(FLUSH_NODESTROY); + CALLFunc((uptr)zeroEx); + } // Bios Call: Force the IOP to do a Branch Test ASAP. // Important! This helps prevent game freeze-ups during boot-up and stage loads. // Note: Fixes to cdvd have removed the need for this code. @@ -595,46 +621,6 @@ static void recShutdown() u32 g_psxlastpc = 0; -#ifdef _MSC_VER - -static u32 g_temp; - -// The address for all cleared blocks. It recompiles the current pc and then -// dispatches to the recompiled block address. -static __declspec(naked) void iopJITCompile() -{ - __asm { - mov esi, dword ptr [psxRegs.pc] - push esi - call iopRecRecompile - add esp, 4 - mov ebx, esi - shr esi, 16 - mov ecx, dword ptr [psxRecLUT+esi*4] - jmp dword ptr [ecx+ebx] - } -} - -static __declspec(naked) void iopJITCompileInBlock() -{ - __asm { - jmp iopJITCompile - } -} - -// called when jumping to variable psxpc address -static __declspec(naked) void iopDispatcherReg() -{ - __asm { - mov eax, dword ptr [psxRegs.pc] - mov ebx, eax - shr eax, 16 - mov ecx, dword ptr [psxRecLUT+eax*4] - jmp dword ptr [ecx+ebx] - } -} -#endif // _MSC_VER - static void iopClearRecLUT(BASEBLOCK* base, int count) { for (int i = 0; i < count; i++) @@ -777,7 +763,6 @@ void psxSetBranchReg(u32 reg) void psxSetBranchImm( u32 imm ) { - u32* ptr; psxbranch = 1; assert( imm ); @@ -786,16 +771,9 @@ void psxSetBranchImm( u32 imm ) _psxFlushCall(FLUSH_EVERYTHING); iPsxBranchTest(imm, imm <= psxpc); - ptr = JMP32(0); - recBlocks.Link(HWADDR(imm), (uptr)ptr); + recBlocks.Link(HWADDR(imm), xJcc32()); } -//fixme : this is all a huge hack, we base the counter advancements on the average an opcode should take (wtf?) -// If that wasn't bad enough we have default values like 9/8 which will get cast to int later -// (yeah, that means all sync code couldn't have worked to begin with) -// So for now these are new settings that work. -// (rama) - static __forceinline u32 psxScaleBlockCycles() { return s_psxBlockCycles * (Config.Hacks.IOPCycleDouble ? 2 : 1); @@ -894,25 +872,16 @@ void psxRecompileNextInstruction(int delayslot) { static u8 s_bFlushReg = 1; + // pblock isn't used elsewhere in this function. BASEBLOCK* pblock = PSX_GETBLOCK(psxpc); -#ifdef _DEBUG - MOV32ItoR(EAX, psxpc); -#endif + if( IsDebugBuild ) + MOV32ItoR(EAX, psxpc); psxRegs.code = iopMemRead32( psxpc ); s_psxBlockCycles++; psxpc += 4; -//#ifdef _DEBUG -// CMP32ItoM((uptr)s_pCode, psxRegs.code); -// j8Ptr[0] = JE8(0); -// MOV32ItoR(EAX, psxpc); -// CALLFunc((uptr)checkcodefn); -// x86SetJ8( j8Ptr[ 0 ] ); -//#endif - - g_pCurInstInfo++; g_iopCyclePenalty = 0; @@ -930,9 +899,9 @@ void psxRecompileNextInstruction(int delayslot) _clearNeededX86regs(); } -#ifdef _DEBUG static void printfn() { +#ifdef PCSX2_DEBUG extern void iDumpPsxRegisters(u32 startpc, u32 temp); static int lastrec = 0; @@ -952,8 +921,8 @@ static void printfn() lastrec = g_psxlastpc; } -} #endif +} void iopRecRecompile(u32 startpc) { @@ -961,12 +930,11 @@ void iopRecRecompile(u32 startpc) u32 branchTo; u32 willbranch3 = 0; -#ifdef _DEBUG - extern void iDumpPsxRegisters(u32 startpc, u32 temp); - - if( psxdump & 4 ) + if( IsDebugBuild && (psxdump & 4) ) + { + extern void iDumpPsxRegisters(u32 startpc, u32 temp); iDumpPsxRegisters(startpc, 0); -#endif + } assert( startpc ); @@ -984,18 +952,10 @@ void iopRecRecompile(u32 startpc) || s_pCurBlock->GetFnptr() == (uptr)iopJITCompileInBlock); s_pCurBlockEx = recBlocks.Get(HWADDR(startpc)); - if(!s_pCurBlockEx || s_pCurBlockEx->startpc != HWADDR(startpc)) { + if(!s_pCurBlockEx || s_pCurBlockEx->startpc != HWADDR(startpc)) s_pCurBlockEx = recBlocks.New(HWADDR(startpc), (uptr)recPtr); - if( s_pCurBlockEx == NULL ) { - DevCon::WriteLn("IOP Recompiler data reset"); - recResetIOP(); - x86SetPtr( recPtr ); - s_pCurBlockEx = recBlocks.New(HWADDR(startpc), (uptr)recPtr); - } - } - - psxbranch = 0; + psxbranch = 0; s_pCurBlock->SetFnptr( (uptr)x86Ptr ); s_psxBlockCycles = 0; @@ -1006,11 +966,11 @@ void iopRecRecompile(u32 startpc) _initX86regs(); -#ifdef _DEBUG - // for debugging purposes - MOV32ItoM((uptr)&g_psxlastpc, psxpc); - CALLFunc((uptr)printfn); -#endif + if( IsDebugBuild ) + { + MOV32ItoM((uptr)&g_psxlastpc, psxpc); + CALLFunc((uptr)printfn); + } // go until the next branch i = startpc; @@ -1094,27 +1054,26 @@ StartRecomp: } } -#ifdef _DEBUG // dump code - for(i = 0; i < ArraySize(s_psxrecblocks); ++i) { + if( IsDebugBuild ) + { + for(i = 0; i < ArraySize(s_psxrecblocks); ++i) { if( startpc == s_psxrecblocks[i] ) { iIopDumpBlock(startpc, recPtr); + } } - } - if( (psxdump & 1) ) - iIopDumpBlock(startpc, recPtr); -#endif + if( (psxdump & 1) ) + iIopDumpBlock(startpc, recPtr); + } g_pCurInstInfo = s_pInstCache; while (!psxbranch && psxpc < s_nEndBlock) { psxRecompileNextInstruction(0); } -#ifdef _DEBUG - if( (psxdump & 1) ) + if( IsDebugBuild && (psxdump & 1) ) iIopDumpBlock(startpc, recPtr); -#endif assert( (psxpc-startpc)>>2 <= 0xffff ); s_pCurBlockEx->size = (psxpc-startpc)>>2; @@ -1146,8 +1105,7 @@ StartRecomp: assert( psxpc == s_nEndBlock ); _psxFlushCall(FLUSH_EVERYTHING); MOV32ItoM((uptr)&psxRegs.pc, psxpc); - u32 *ptr = JMP32(0); - recBlocks.Link(HWADDR(s_nEndBlock), (uptr)ptr); + recBlocks.Link(HWADDR(s_nEndBlock), xJcc32() ); psxbranch = 3; } } diff --git a/pcsx2/x86/iR3000A.h b/pcsx2/x86/iR3000A.h index 220eb33ff0..1870b4af88 100644 --- a/pcsx2/x86/iR3000A.h +++ b/pcsx2/x86/iR3000A.h @@ -18,8 +18,7 @@ #ifndef _R3000A_SUPERREC_ #define _R3000A_SUPERREC_ -#include "ix86/ix86.h" - +#include "x86emitter/x86emitter.h" #include "R3000A.h" #include "iCore.h" diff --git a/pcsx2/x86/iR3000Atables.cpp b/pcsx2/x86/iR3000Atables.cpp index fddd6f9690..75b3732054 100644 --- a/pcsx2/x86/iR3000Atables.cpp +++ b/pcsx2/x86/iR3000Atables.cpp @@ -1567,9 +1567,10 @@ void rpsxBGEZAL() _psxFlushAllUnused(); if( PSX_IS_CONST1(_Rs_) ) { - if( g_psxConstRegs[_Rs_] < 0 ) + if( (int)g_psxConstRegs[_Rs_] < 0 ) branchTo = psxpc+4; - else MOV32ItoM((uptr)&psxRegs.GPR.r[31], psxpc+4); + else + MOV32ItoM((uptr)&psxRegs.GPR.r[31], psxpc+4); psxRecompileNextInstruction(1); psxSetBranchImm( branchTo ); diff --git a/pcsx2/x86/iR5900.h b/pcsx2/x86/iR5900.h index af168fc238..5ae91988b1 100644 --- a/pcsx2/x86/iR5900.h +++ b/pcsx2/x86/iR5900.h @@ -19,8 +19,8 @@ #ifndef __IR5900_H__ #define __IR5900_H__ -#include "ix86/ix86.h" -#include "ix86/ix86_sse_helpers.h" +#include "x86emitter/x86emitter.h" +#include "x86emitter/sse_helpers.h" #include "R5900.h" #include "VU.h" #include "iCore.h" @@ -90,7 +90,6 @@ void LoadBranchState(); void recompileNextInstruction(int delayslot); void SetBranchReg( u32 reg ); void SetBranchImm( u32 imm ); -u32 eeScaleBlockCycles(); void iFlushCall(int flushtype); void recBranchCall( void (*func)() ); diff --git a/pcsx2/x86/iR5900Misc.cpp b/pcsx2/x86/iR5900Misc.cpp index e496a1d311..28bdae4b03 100644 --- a/pcsx2/x86/iR5900Misc.cpp +++ b/pcsx2/x86/iR5900Misc.cpp @@ -8,7 +8,7 @@ namespace R5900 { namespace Dynarec { -// R5900 branch hepler! +// R5900 branch helper! // Recompiles code for a branch test and/or skip, complete with delay slot // handling. Note, for "likely" branches use iDoBranchImm_Likely instead, which // handles delay slots differently. diff --git a/pcsx2/x86/iVU0micro.cpp b/pcsx2/x86/iVU0micro.cpp index 1a2ee09ea7..02b8ed4773 100644 --- a/pcsx2/x86/iVU0micro.cpp +++ b/pcsx2/x86/iVU0micro.cpp @@ -21,83 +21,44 @@ #include "Common.h" #include "iR5900.h" #include "VUmicro.h" -#include "iVUzerorec.h" +#include "sVU_zerorec.h" -#ifndef PCSX2_MICROVU_ -namespace VU0micro -{ - void recAlloc() - { - SuperVUAlloc(0); - } - - void __fastcall recClear(u32 Addr, u32 Size) - { - SuperVUClear(Addr, Size, 0); // Size should be a multiple of 8 bytes! - } - - void recShutdown() - { - SuperVUDestroy( 0 ); - } - - static void recReset() - { - SuperVUReset(0); - - // this shouldn't be needed, but shouldn't hurt anything either. - x86FpuState = FPU_STATE; - } - - static void recStep() - { - } - - static void recExecuteBlock() - { - if((VU0.VI[REG_VPU_STAT].UL & 1) == 0) - return; - - FreezeXMMRegs(1); - SuperVUExecuteProgram(VU0.VI[ REG_TPC ].UL & 0xfff, 0); - FreezeXMMRegs(0); - } -} -#else - -extern void initVUrec(VURegs* vuRegs, const int vuIndex); -extern void closeVUrec(const int vuIndex); -extern void resetVUrec(const int vuIndex); -extern void clearVUrec(u32 addr, u32 size, const int vuIndex); -extern void runVUrec(u32 startPC, u32 cycles, const int vuIndex); +#define useMVU0 CHECK_MICROVU0 namespace VU0micro { - void recAlloc() { initVUrec(&VU0, 0); } - void __fastcall recClear(u32 Addr, u32 Size) { clearVUrec(Addr, Size, 0); } - void recShutdown() { closeVUrec(0); } - static void recReset() { resetVUrec(0); x86FpuState = FPU_STATE; } - static void recStep() {} - static void recExecuteBlock() - { - if((VU0.VI[REG_VPU_STAT].UL & 1) == 0) return; + void recAlloc() { SuperVUAlloc(0); initVUrec(&VU0, 0); } + void recShutdown() { SuperVUDestroy(0); closeVUrec(0); } - FreezeXMMRegs(1); - FreezeMMXRegs(1); - runVUrec(VU0.VI[REG_TPC].UL, 5000, 0); - FreezeXMMRegs(0); - FreezeMMXRegs(0); + void __fastcall recClear(u32 Addr, u32 Size) { + if (useMVU0) clearVUrec(Addr, Size, 0); + else SuperVUClear(Addr, Size, 0); } + static void recReset() { + if (useMVU0) resetVUrec(0); + else SuperVUReset(0); + x86FpuState = FPU_STATE; + } + + static void recStep() {} + static void recExecuteBlock() + { + if ((VU0.VI[REG_VPU_STAT].UL & 1) == 0) return; + + FreezeXMMRegs(1); + if (useMVU0) runVUrec(VU0.VI[REG_TPC].UL, 0x300, 0); + else SuperVUExecuteProgram(VU0.VI[REG_TPC].UL & 0xfff, 0); + FreezeXMMRegs(0); + } } -#endif using namespace VU0micro; const VUmicroCpu recVU0 = { - recReset -, recStep -, recExecuteBlock -, recClear + recReset + , recStep + , recExecuteBlock + , recClear }; diff --git a/pcsx2/x86/iVU1micro.cpp b/pcsx2/x86/iVU1micro.cpp index d282778f4c..16f2bdf99d 100644 --- a/pcsx2/x86/iVU1micro.cpp +++ b/pcsx2/x86/iVU1micro.cpp @@ -18,134 +18,271 @@ #include "PrecompiledHeader.h" -#include - #include "Common.h" -#include "R5900OpcodeTables.h" #include "iR5900.h" #include "VUmicro.h" -#include "iVUzerorec.h" +#include "sVU_zerorec.h" -#ifdef _DEBUG -extern u32 vudump; -#endif -#ifndef PCSX2_MICROVU_ -namespace VU1micro -{ - void recAlloc() - { - SuperVUAlloc(1); +#define useMVU1 CHECK_MICROVU1 + +int mVUdebugNow = 0; + +//#define DEBUG_COMPARE // Run sVU or mVU and print results +//#define DEBUG_COMPARE2 // Runs both VU recs and breaks when results differ + +#ifdef DEBUG_COMPARE + +#include +static int runAmount = 0; + +void VUtestPause() { + + runAmount++; + if (runAmount < 654) return; + + if (useMVU1) SysPrintf("Micro VU - Pass %d\n", runAmount); + else SysPrintf("Super VU - Pass %d\n", runAmount); + + for (int i = 0; i < 32; i++) { + SysPrintf("VF%02d = {%f, %f, %f, %f}\n", i, VU1.VF[i].F[0], VU1.VF[i].F[1], VU1.VF[i].F[2], VU1.VF[i].F[3]); } - void __fastcall recClear( u32 Addr, u32 Size ) - { - assert( (Addr&7) == 0 ); - SuperVUClear(Addr, Size, 1); // Size should be a multiple of 8 bytes! + SysPrintf("ACC = {%f, %f, %f, %f}\n", VU1.ACC.F[0], VU1.ACC.F[1], VU1.ACC.F[2], VU1.ACC.F[3]); + + for (int i = 0; i < 16; i++) { + SysPrintf("VI%02d = % 8d ($%08x)\n", i, (s16)VU1.VI[i].UL, (s16)VU1.VI[i].UL); } - void recShutdown() - { - SuperVUDestroy( 1 ); + SysPrintf("Stat = % 8d ($%08x)\n", (s16)VU1.VI[REG_STATUS_FLAG].UL, (s16)VU1.VI[REG_STATUS_FLAG].UL); + SysPrintf("MAC = % 8d ($%08x)\n", (s16)VU1.VI[REG_MAC_FLAG].UL, (s16)VU1.VI[REG_MAC_FLAG].UL); + SysPrintf("CLIP = % 8d ($%08x)\n", (s16)VU1.VI[REG_CLIP_FLAG].UL, (s16)VU1.VI[REG_CLIP_FLAG].UL); + + SysPrintf("Q-reg = %f ($%08x)\n", VU1.VI[REG_Q].F, (s32)VU1.VI[REG_Q].UL); + SysPrintf("P-reg = %f ($%08x)\n", VU1.VI[REG_P].F, (s32)VU1.VI[REG_P].UL); + SysPrintf("I-reg = %f ($%08x)\n", VU1.VI[REG_I].F, (s32)VU1.VI[REG_I].UL); + + SysPrintf("_Stat = % 8d ($%08x)\n", (s16)VU1.statusflag, (s16)VU1.statusflag); + SysPrintf("_MAC = % 8d ($%08x)\n", (s16)VU1.macflag, (s16)VU1.macflag); + SysPrintf("_CLIP = % 8d ($%08x)\n", (s16)VU1.clipflag, (s16)VU1.clipflag); + + u32 j = 0; + for (int i = 0; i < (0x4000 / 4); i++) { + j ^= ((u32*)(VU1.Mem))[i]; } + SysPrintf("VU Mem CRC = 0x%08x\n", j); + SysPrintf("EndPC = 0x%04x\n", VU1.VI[REG_TPC].UL); - // commented out because I'm not sure it actually works anymore with SuperVU (air) - /*static void iVU1DumpBlock() - { - FILE *f; - char filename[ g_MaxPath ]; - u32 *mem; - u32 i; - - #ifdef _WIN32 - CreateDirectory("dumps", NULL); - sprintf_s( filename, g_MaxPath, "dumps\\vu%.4X.txt", VU1.VI[ REG_TPC ].UL ); - #else - mkdir("dumps", 0755); - sprintf( filename, "dumps/vu%.4X.txt", VU1.VI[ REG_TPC ].UL ); - #endif - Console::WriteLn( "dump1 %x => %x (%s)", params VU1.VI[ REG_TPC ].UL, pc, filename ); - - f = fopen( filename, "wb" ); - for ( i = VU1.VI[REG_TPC].UL; i < pc; i += 8 ) { - char* pstr; - mem = (u32*)&VU1.Micro[i]; - - pstr = disVU1MicroUF( mem[1], i+4 ); - fprintf(f, "%x: %-40s ", i, pstr); - - pstr = disVU1MicroLF( mem[0], i ); - fprintf(f, "%s\n", pstr); - } - fclose( f ); - }*/ - - static void recReset() - { - SuperVUReset(1); - - // these shouldn't be needed, but shouldn't hurt anything either. - x86FpuState = FPU_STATE; - } - - static void recStep() - { - } - - static void recExecuteBlock(void) - { - #ifdef _DEBUG - static u32 vuprogcount = 0; - vuprogcount++; - if( vudump & 8 ) __Log("start vu1: %x %x", VU1.VI[ REG_TPC ].UL, vuprogcount); - #endif - - if((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0){ - //Console::WriteLn("Execute block VU1, VU1 not busy"); - return; - } - - if (VU1.VI[REG_TPC].UL >= VU1.maxmicro) - { - Console::Error("VU1 memory overflow!!: %x", params VU1.VI[REG_TPC].UL); - /*VU0.VI[REG_VPU_STAT].UL&= ~0x100; - VU1.cycle++; - return;*/ - } - - assert( (VU1.VI[ REG_TPC ].UL&7) == 0 ); - - FreezeXMMRegs(1); - do { // while loop needed since not always will return finished - SuperVUExecuteProgram(VU1.VI[ REG_TPC ].UL & 0x3fff, 1); - } while( VU0.VI[ REG_VPU_STAT ].UL&0x100 ); - FreezeXMMRegs(0); + for (int i = 0; i < 10000000; i++) { + Sleep(1000); } } #else +void VUtestPause() {} +#endif -extern void initVUrec(VURegs* vuRegs, const int vuIndex); -extern void closeVUrec(const int vuIndex); -extern void resetVUrec(const int vuIndex); -extern void clearVUrec(u32 addr, u32 size, const int vuIndex); -extern void runVUrec(u32 startPC, u32 cycles, const int vuIndex); +#ifdef PCSX2_DEBUG +extern u32 vudump; +#endif + +#ifdef DEBUG_COMPARE2 + +#ifndef DEBUG_COMPARE +#include +#endif + +PCSX2_ALIGNED16(u8 backVUregs[sizeof(VURegs)]); +PCSX2_ALIGNED16(u8 cmpVUregs [sizeof(VURegs)]); +PCSX2_ALIGNED16(u8 backVUmem [0x4000]); +PCSX2_ALIGNED16(u8 cmpVUmem [0x4000]); +static u32 runCount = 0; +#define VU3 ((VURegs)*((VURegs*)cmpVUregs)) +#define cmpA Console::Error +#define cmpB Console::WriteLn +#define cmpPrint(cond) { \ + if (cond) { \ + cmpA("%s", params str1); \ + cmpA("%s", params str2); \ + } \ + else { \ + cmpB("%s", params str1); \ + cmpB("%s", params str2); \ + } \ +} namespace VU1micro { - void recAlloc() { initVUrec(&VU1, 1); } - void __fastcall recClear(u32 Addr, u32 Size) { clearVUrec(Addr, Size, 1); } - void recShutdown() { closeVUrec(1); } - static void recReset() { resetVUrec(1); x86FpuState = FPU_STATE; } - static void recStep() {} - static void recExecuteBlock() { + void recAlloc() { SuperVUAlloc(1); initVUrec(&VU1, 1); } + void __fastcall recClear(u32 Addr, u32 Size) { SuperVUClear(Addr, Size, 1); clearVUrec(Addr, Size, 1); } + void recShutdown() { SuperVUDestroy(1); closeVUrec(1); } + static void recReset() { SuperVUReset(1); resetVUrec(1); x86FpuState = FPU_STATE; } + static void recStep() {} + static void recExecuteBlock(void) + { if((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0) return; - assert( (VU1.VI[REG_TPC].UL&7) == 0 ); + assert((VU1.VI[ REG_TPC ].UL&7) == 0); + if (VU1.VI[REG_TPC].UL >= VU1.maxmicro) { Console::Error("VU1 memory overflow!!: %x", params VU1.VI[REG_TPC].UL); } + +#ifdef DEBUG_COMPARE + SysPrintf("(%08d) StartPC = 0x%04x\n", runAmount, VU1.VI[REG_TPC].UL); +#endif FreezeXMMRegs(1); - FreezeMMXRegs(1); - runVUrec(VU1.VI[REG_TPC].UL, 5000, 1); + + runCount++; + memcpy_fast((u8*)backVUregs, (u8*)&VU1, sizeof(VURegs)); + memcpy_fast((u8*)backVUmem, (u8*)VU1.Mem, 0x4000); + + do { // while loop needed since not always will return finished + SuperVUExecuteProgram(VU1.VI[ REG_TPC ].UL & 0x3fff, 1); + } while( VU0.VI[ REG_VPU_STAT ].UL&0x100 ); + + memcpy_fast((u8*)cmpVUregs, (u8*)&VU1, sizeof(VURegs)); + memcpy_fast((u8*)cmpVUmem, (u8*)VU1.Mem, 0x4000); + memcpy_fast((u8*)&VU1, (u8*)backVUregs, sizeof(VURegs)); + memcpy_fast((u8*)VU1.Mem, (u8*)backVUmem, 0x4000); + + //Currently breaking mVU execution is disabled. Check mVUtestCycles() in microVU_Compile.inl + runVUrec(VU1.VI[REG_TPC].UL, 300000 /*0x7fffffff*/, 1); + + if ((memcmp((u8*)cmpVUregs, (u8*)&VU1, (16*32) + (16*16))) || (memcmp((u8*)cmpVUmem, (u8*)VU1.Mem, 0x4000))) { + char str1[150]; + char str2[150]; + SysPrintf("\n\n"); + SysPrintf("-----------------------------------------------\n"); + Console::Notice("Problem Occurred!"); + SysPrintf("-----------------------------------------------\n"); + SysPrintf("runCount = %d\n", runCount); + SysPrintf("StartPC [%04x]\n", ((VURegs*)backVUregs)->VI[REG_TPC].UL); + SysPrintf("-----------------------------------------------\n\n"); + + SysPrintf("-----------------------------------------------\n"); + Console::Notice("Super VU / Micro VU"); + SysPrintf("-----------------------------------------------\n"); + + for (int i = 0; i < 32; i++) { + sprintf(str1, "VF%02d = {%f, %f, %f, %f}", i, VU3.VF[i].F[0], VU3.VF[i].F[1], VU3.VF[i].F[2], VU3.VF[i].F[3]); + sprintf(str2, "VF%02d = {%f, %f, %f, %f}", i, VU1.VF[i].F[0], VU1.VF[i].F[1], VU1.VF[i].F[2], VU1.VF[i].F[3]); + cmpPrint(((VU1.VF[i].UL[0] != VU3.VF[i].UL[0]) || (VU1.VF[i].UL[1] != VU3.VF[i].UL[1]) || (VU1.VF[i].UL[2] != VU3.VF[i].UL[2]) || (VU1.VF[i].UL[3] != VU3.VF[i].UL[3]))); + } + + sprintf(str1, "ACC = {%f, %f, %f, %f}", VU3.ACC.F[0], VU3.ACC.F[1], VU3.ACC.F[2], VU3.ACC.F[3]); + sprintf(str2, "ACC = {%f, %f, %f, %f}", VU1.ACC.F[0], VU1.ACC.F[1], VU1.ACC.F[2], VU1.ACC.F[3]); + cmpPrint(((VU1.ACC.F[0] != VU3.ACC.F[0]) || (VU1.ACC.F[1] != VU3.ACC.F[1]) || (VU1.ACC.F[2] != VU3.ACC.F[2]) || (VU1.ACC.F[3] != VU3.ACC.F[3]))); + + for (int i = 0; i < 16; i++) { + sprintf(str1, "VI%02d = % 8d ($%08x)", i, (s16)VU3.VI[i].UL, VU3.VI[i].UL); + sprintf(str2, "VI%02d = % 8d ($%08x)", i, (s16)VU1.VI[i].UL, VU1.VI[i].UL); + cmpPrint((VU1.VI[i].UL != VU3.VI[i].UL)); + } + + sprintf(str1, "Stat = % 8d ($%08x)", (s16)VU3.VI[REG_STATUS_FLAG].UL, VU3.VI[REG_STATUS_FLAG].UL); + sprintf(str2, "Stat = % 8d ($%08x)", (s16)VU1.VI[REG_STATUS_FLAG].UL, VU1.VI[REG_STATUS_FLAG].UL); + cmpPrint((VU1.VI[REG_STATUS_FLAG].UL != VU3.VI[REG_STATUS_FLAG].UL)); + + sprintf(str1, "MAC = % 8d ($%08x)", (s16)VU3.VI[REG_MAC_FLAG].UL, VU3.VI[REG_MAC_FLAG].UL); + sprintf(str2, "MAC = % 8d ($%08x)", (s16)VU1.VI[REG_MAC_FLAG].UL, VU1.VI[REG_MAC_FLAG].UL); + cmpPrint((VU1.VI[REG_MAC_FLAG].UL != VU3.VI[REG_MAC_FLAG].UL)); + + sprintf(str1, "CLIP = % 8d ($%08x)", (s16)VU3.VI[REG_CLIP_FLAG].UL, VU3.VI[REG_CLIP_FLAG].UL); + sprintf(str2, "CLIP = % 8d ($%08x)", (s16)VU1.VI[REG_CLIP_FLAG].UL, VU1.VI[REG_CLIP_FLAG].UL); + cmpPrint((VU1.VI[REG_CLIP_FLAG].UL != VU3.VI[REG_CLIP_FLAG].UL)); + + sprintf(str1, "Q-reg = %f ($%08x)", VU3.VI[REG_Q].F, VU3.VI[REG_Q].UL); + sprintf(str2, "Q-reg = %f ($%08x)", VU1.VI[REG_Q].F, VU1.VI[REG_Q].UL); + cmpPrint((VU1.VI[REG_Q].UL != VU3.VI[REG_Q].UL)); + + sprintf(str1, "P-reg = %f ($%08x)", VU3.VI[REG_P].F, VU3.VI[REG_P].UL); + sprintf(str2, "P-reg = %f ($%08x)", VU1.VI[REG_P].F, VU1.VI[REG_P].UL); + cmpPrint((VU1.VI[REG_P].UL != VU3.VI[REG_P].UL)); + + sprintf(str1, "I-reg = %f ($%08x)", VU3.VI[REG_I].F, VU3.VI[REG_I].UL); + sprintf(str2, "I-reg = %f ($%08x)", VU1.VI[REG_I].F, VU1.VI[REG_I].UL); + cmpPrint((VU1.VI[REG_I].UL != VU3.VI[REG_I].UL)); + + sprintf(str1, "_Stat = % 8d ($%08x)", (s16)VU3.statusflag, VU3.statusflag); + sprintf(str2, "_Stat = % 8d ($%08x)", (s16)VU1.statusflag, VU1.statusflag); + cmpPrint((VU1.statusflag != VU3.statusflag)); + + sprintf(str1, "_MAC = % 8d ($%08x)", (s16)VU3.macflag, VU3.macflag); + sprintf(str2, "_MAC = % 8d ($%08x)", (s16)VU1.macflag, VU1.macflag); + cmpPrint((VU1.macflag != VU3.macflag)); + + sprintf(str1, "_CLIP = % 8d ($%08x)", (s16)VU3.clipflag, VU3.clipflag); + sprintf(str2, "_CLIP = % 8d ($%08x)", (s16)VU1.clipflag, VU1.clipflag); + cmpPrint((VU1.clipflag != VU3.clipflag)); + + u32 j = 0; + u32 z = 0; + for (int i = 0; i < (0x4000 / 4); i++) { + j ^= ((u32*)(cmpVUmem))[i]; + z ^= ((u32*)(VU1.Mem)) [i]; + } + sprintf(str1, "VU Mem CRC = 0x%08x", j); + sprintf(str2, "VU Mem CRC = 0x%08x", z); + cmpPrint((j != z)); + + sprintf(str1, "EndPC = 0x%04x", VU3.VI[REG_TPC].UL); + sprintf(str2, "EndPC = 0x%04x", VU1.VI[REG_TPC].UL); + cmpPrint((VU1.VI[REG_TPC].UL != VU3.VI[REG_TPC].UL)); + + SysPrintf("-----------------------------------------------\n\n"); + + mVUdebugNow = 1; + resetVUrec(1); + memcpy_fast((u8*)&VU1, (u8*)backVUregs, sizeof(VURegs)); + memcpy_fast((u8*)VU1.Mem, (u8*)backVUmem, 0x4000); + + runVUrec(VU1.VI[REG_TPC].UL, 300000 /*0x7fffffff*/, 1); + + for (int i = 0; i < 10000000; i++) { + Sleep(1000); + } + } + VUtestPause(); FreezeXMMRegs(0); - FreezeMMXRegs(0); + } +} +#else + +namespace VU1micro +{ + void recAlloc() { SuperVUAlloc(1); initVUrec(&VU1, 1); } + void recShutdown() { SuperVUDestroy(1); closeVUrec(1);} + + void __fastcall recClear(u32 Addr, u32 Size) { + if (useMVU1) clearVUrec(Addr, Size, 1); + else SuperVUClear(Addr, Size, 1); + } + + static void recReset() { + if (useMVU1) resetVUrec(1); + else SuperVUReset(1); + x86FpuState = FPU_STATE; + } + + static void recStep() {} + static void recExecuteBlock() { + + if ((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0) return; + assert( (VU1.VI[REG_TPC].UL&7) == 0 ); + +#ifdef DEBUG_COMPARE + SysPrintf("(%08d) StartPC = 0x%04x\n", runAmount, VU1.VI[REG_TPC].UL); +#endif + + FreezeXMMRegs(1); + if (useMVU1) runVUrec(VU1.VI[REG_TPC].UL, 3000000, 1); + else { + if (VU1.VI[REG_TPC].UL >= VU1.maxmicro) { + Console::Error("VU1 memory overflow!!: %x", params VU1.VI[REG_TPC].UL); + } + do { // while loop needed since not always will return finished + SuperVUExecuteProgram(VU1.VI[REG_TPC].UL & 0x3fff, 1); + } while( VU0.VI[REG_VPU_STAT].UL&0x100 ); + } + FreezeXMMRegs(0); + VUtestPause(); } } #endif diff --git a/pcsx2/x86/iVUzerorec.cpp b/pcsx2/x86/iVUzerorec.cpp deleted file mode 100644 index 8864548175..0000000000 --- a/pcsx2/x86/iVUzerorec.cpp +++ /dev/null @@ -1,4199 +0,0 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -// Super VU recompiler - author: zerofrog(@gmail.com) - -#include "PrecompiledHeader.h" - -#include -#include -#include - -#include "Utilities/AsciiFile.h" - -#ifndef _WIN32 -#include -#endif - -#include "Common.h" - -#include "GS.h" -#include "R5900.h" -#include "VU.h" -#include "iR5900.h" - -#include "iVUzerorec.h" -#include "SamplProf.h" -#include "NakedAsm.h" - -using namespace std; - -// temporary externs -extern void iDumpVU0Registers(); -extern void iDumpVU1Registers(); - -// SuperVURec optimization options, uncomment only for debugging purposes -#define SUPERVU_CACHING // vu programs are saved and queried via memcompare (should be no reason to disable this) -#define SUPERVU_WRITEBACKS // don't flush the writebacks after every block -#define SUPERVU_X86CACHING // use x86reg caching (faster) (not really. rather lots slower :p (rama) ) -#define SUPERVU_VIBRANCHDELAY // when integers are modified right before a branch that uses the integer, - // the old integer value is used in the branch - // fixes kh2 - -#define SUPERVU_PROPAGATEFLAGS // the correct behavior of VUs, for some reason superman breaks gfx with it on... - -#ifndef _DEBUG -//#define SUPERVU_INTERCACHING // registers won't be flushed at block boundaries (faster) (nothing noticable speed-wise, causes SPS in Ratchet and clank (Nneeve) ) -#endif - -#define SUPERVU_CHECKCONDITION 0 // has to be 0!! - -#define VU_EXESIZE 0x00800000 - -#define _Imm11_ (s32)( (vucode & 0x400) ? (0xfffffc00 | (vucode & 0x3ff)) : (vucode & 0x3ff) ) -#define _UImm11_ (s32)(vucode & 0x7ff) - -#define _Ft_ ((VU->code >> 16) & 0x1F) // The rt part of the instruction register -#define _Fs_ ((VU->code >> 11) & 0x1F) // The rd part of the instruction register -#define _Fd_ ((VU->code >> 6) & 0x1F) // The sa part of the instruction register - -static const u32 QWaitTimes[] = { 6, 12 }; -static const u32 PWaitTimes[] = { 53, 43, 28, 23, 17, 11, 10 }; - -static u32 s_vuInfo; // info passed into rec insts - -static const u32 s_MemSize[2] = {VU0_MEMSIZE, VU1_MEMSIZE}; -static u8* s_recVUMem = NULL, *s_recVUPtr = NULL; - -// tables which are defined at the bottom of this massive file. -extern void (*recVU_UPPER_OPCODE[64])( VURegs* VU, s32 info ); -extern void (*recVU_LOWER_OPCODE[128])( VURegs* VU, s32 info ); - -#define INST_Q_READ 0x0001 // flush Q -#define INST_P_READ 0x0002 // flush P -#define INST_BRANCH_DELAY 0x0004 -#define INST_CLIP_WRITE 0x0040 // inst writes CLIP in the future -#define INST_STATUS_WRITE 0x0080 -#define INST_MAC_WRITE 0x0100 -#define INST_Q_WRITE 0x0200 -#define INST_CACHE_VI 0x0400 // write old vi value to s_VIBranchDelay - -// Let's tempt fate by defining two different constants with almost identical names -#define INST_DUMMY_ 0x8000 -#define INST_DUMMY 0x83c0 - -#define VFFREE_INVALID0 0x80000000 // (vffree[i]&0xf) is invalid - -#define FORIT(it, v) for(it = (v).begin(); it != (v).end(); ++(it)) - -#ifdef _DEBUG -u32 s_vucount=0; - -static u32 g_vu1lastrec = 0, skipparent = -1; -static u32 s_svulast = 0, s_vufnheader; -static u32 badaddrs[][2] = {0,0xffff}; -#endif - -union VURecRegs -{ - struct { - u16 reg; - u16 type; - }; - u32 id; -}; - -#define SUPERVU_XGKICKDELAY 1 // yes this is needed as default (wipeout) - -class VuBaseBlock; - -struct VuFunctionHeader -{ - struct RANGE - { - RANGE() : pmem(NULL) {} - - u16 start, size; - void* pmem; // all the mem - }; - - VuFunctionHeader() : pprogfunc(NULL), startpc(0xffffffff) {} - ~VuFunctionHeader() { - for(vector::iterator it = ranges.begin(); it != ranges.end(); ++it) { - free(it->pmem); - } - } - - // returns true if the checksum for the current mem is the same as this fn - bool IsSame(void* pmem); - - u32 startpc; - void* pprogfunc; - - vector ranges; -}; - -struct VuBlockHeader -{ - VuBaseBlock* pblock; - u32 delay; -}; - -// one vu inst (lower and upper) -class VuInstruction -{ -public: - VuInstruction() { memzero_obj(*this); nParentPc = -1; vicached = -1; } - - int nParentPc; // used for syncing with flag writes, -1 for no parent - - _vuopinfo info; - - _VURegsNum regs[2]; // [0] - lower, [1] - upper - u32 livevars[2]; // live variables right before this inst, [0] - inst, [1] - float - u32 addvars[2]; // live variables to add - u32 usedvars[2]; // set if var is used in the future including vars used in this inst - u32 keepvars[2]; - u16 pqcycles; // the number of cycles to stall if function writes to the regs - u16 type; // INST_ - - u32 pClipWrite, pMACWrite, pStatusWrite; // addrs to write the flags - u32 vffree[2]; - s8 vfwrite[2], vfread0[2], vfread1[2], vfacc[2]; - s8 vfflush[2]; // extra flush regs - s8 vicached; // if >= 0, then use the cached integer s_VIBranchDelay - VuInstruction *pPrevInst; - - int SetCachedRegs(int upper, u32 vuxyz); - void Recompile(list::iterator& itinst, u32 vuxyz); -}; - -#define BLOCKTYPE_EOP 0x01 // at least one of the children of the block contains eop (or the block itself) -#define BLOCKTYPE_FUNCTION 0x02 -#define BLOCKTYPE_HASEOP 0x04 // last inst of block is an eop -#define BLOCKTYPE_MACFLAGS 0x08 -#define BLOCKTYPE_ANALYZED 0x40 -#define BLOCKTYPE_IGNORE 0x80 // special for recursive fns -#define BLOCKTYPE_ANALYZEDPARENT 0x100 - -// base block used when recompiling -class VuBaseBlock -{ -public: - typedef list LISTBLOCKS; - - VuBaseBlock(); - - // returns true if the leads to a EOP (ALL VU blocks must ret true) - void AssignVFRegs(); - void AssignVIRegs(int parent); - - list::iterator GetInstIterAtPc(int instpc); - void GetInstsAtPc(int instpc, list& listinsts); - - void Recompile(); - - u16 type; // BLOCKTYPE_ - u16 id; - u16 startpc; - u16 endpc; // first inst not in block - void* pcode; // x86 code pointer - void* pendcode; // end of the x86 code pointer - int cycles; - list insts; - list parents; - LISTBLOCKS blocks; // blocks branches to - u32* pChildJumps[4]; // addrs that need to be filled with the children's start addrs - // if highest bit is set, addr needs to be relational - u32 vuxyz; // corresponding bit is set if reg's xyz channels are used only - u32 vuxy; // corresponding bit is set if reg's xyz channels are used only - - _xmmregs startregs[iREGCNT_XMM], endregs[iREGCNT_XMM]; - int nStartx86, nEndx86; // indices into s_vecRegArray - - int allocX86Regs; - int prevFlagsOutOfBlock; -}; - -struct WRITEBACK -{ - WRITEBACK() : nParentPc(0), cycle(0) //, pStatusWrite(NULL), pMACWrite(NULL) - { - viwrite[0] = viwrite[1] = 0; - viread[0] = viread[1] = 0; - } - - void InitInst(VuInstruction* pinst, int cycle) const - { - u32 write = viwrite[0]|viwrite[1]; - pinst->type = ((write&(1<nParentPc = nParentPc; - pinst->info.cycle = cycle; - for(int i = 0; i < 2; ++i) { - pinst->regs[i].VIwrite = viwrite[i]; - pinst->regs[i].VIread = viread[i]; - } - } - - static int SortWritebacks(const WRITEBACK& w1, const WRITEBACK& w2) { - return w1.cycle < w2.cycle; - } - - int nParentPc; - int cycle; - u32 viwrite[2]; - u32 viread[2]; -}; - -struct VUPIPELINES -{ - fmacPipe fmac[8]; - fdivPipe fdiv; - efuPipe efu; - ialuPipe ialu[8]; - list< WRITEBACK > listWritebacks; -}; - -VuBaseBlock::VuBaseBlock() -{ - type = 0; endpc = 0; cycles = 0; pcode = NULL; id = 0; - memzero_obj(pChildJumps); - memzero_obj(startregs); - memzero_obj(endregs); - allocX86Regs = nStartx86 = nEndx86 = -1; - prevFlagsOutOfBlock = 0; -} - -#define SUPERVU_STACKSIZE 0x1000 - -static list s_listVUHeaders[2]; -static list* s_plistCachedHeaders[2] = {NULL, NULL}; -static VuFunctionHeader** recVUHeaders[2] = {NULL,NULL}; -static VuBlockHeader* recVUBlocks[2] = {NULL,NULL}; -static u8* recVUStack = NULL, *recVUStackPtr = NULL; -static vector<_x86regs> s_vecRegArray(128); - -static VURegs* VU = NULL; -static list s_listBlocks; -static u32 s_vu = 0; -static u32 s_UnconditionalDelay = 0; // 1 if there are two sequential branches and the last is unconditional -static u32 g_nLastBlockExecuted = 0; - -static VuFunctionHeader* SuperVURecompileProgram(u32 startpc, int vuindex); -static VuBaseBlock* SuperVUBuildBlocks(VuBaseBlock* parent, u32 startpc, const VUPIPELINES& pipes); -static void SuperVUInitLiveness(VuBaseBlock* pblock); -static void SuperVULivenessAnalysis(); -static void SuperVUEliminateDeadCode(); -static void SuperVUAssignRegs(); - -//void SuperVUFreeXMMreg(int xmmreg, int xmmtype, int reg); -#define SuperVUFreeXMMreg 0&& -void SuperVUFreeXMMregs(u32* livevars); - -static u32* SuperVUStaticAlloc(u32 size); -static void SuperVURecompile(); - -// allocate VU resources -void SuperVUAlloc(int vuindex) -{ - // The old -1 crap has been depreciated on this function. Please - // specify either 0 or 1, thanks. - jASSUME( vuindex >= 0 ); - - // upper 4 bits must be zero! - if( s_recVUMem == NULL ) - { - // upper 4 bits must be zero! - // Changed "first try base" to 0xb800000, since 0x0c000000 liked to fail a lot. (air) - s_recVUMem = SysMmapEx(0x0e000000, VU_EXESIZE, 0x10000000, "SuperVUAlloc"); - - if( s_recVUMem == NULL ) - { - throw Exception::OutOfMemory( - // untranslated diagnostic msg, use exception's default for translation - wxsFormat( L"Error > SuperVU failed to allocate recompiler memory (addr: 0x%x)", (u32)s_recVUMem ) - ); - } - - ProfilerRegisterSource( "VURec", s_recVUMem, VU_EXESIZE); - - if( recVUStack == NULL ) recVUStack = new u8[SUPERVU_STACKSIZE * 4]; - } - - if( vuindex >= 0 ) - { - jASSUME( s_recVUMem != NULL ); - - if( recVUHeaders[vuindex] == NULL ) - recVUHeaders[vuindex] = new VuFunctionHeader* [s_MemSize[vuindex]/8]; - if( recVUBlocks[vuindex] == NULL ) - recVUBlocks[vuindex] = new VuBlockHeader[s_MemSize[vuindex]/8]; - if( s_plistCachedHeaders[vuindex] == NULL ) - s_plistCachedHeaders[vuindex] = new list[s_MemSize[vuindex]/8]; - } -} - -// destroy VU resources -void SuperVUDestroy(int vuindex) -{ - list::iterator it; - - if( vuindex < 0 ) - { - SuperVUDestroy(0); - SuperVUDestroy(1); - ProfilerTerminateSource( "VURec" ); - SafeSysMunmap(s_recVUMem, VU_EXESIZE); - safe_delete_array( recVUStack ); - } - else - { - safe_delete_array( recVUHeaders[vuindex] ); - safe_delete_array( recVUBlocks[vuindex] ); - - if( s_plistCachedHeaders[vuindex] != NULL ) { - for(u32 j = 0; j < s_MemSize[vuindex]/8; ++j) { - FORIT(it, s_plistCachedHeaders[vuindex][j]) delete *it; - s_plistCachedHeaders[vuindex][j].clear(); - } - safe_delete_array( s_plistCachedHeaders[vuindex] ); - } - - FORIT(it, s_listVUHeaders[vuindex]) delete *it; - s_listVUHeaders[vuindex].clear(); - } -} - -// reset VU -void SuperVUReset(int vuindex) -{ -#ifdef _DEBUG - s_vucount = 0; -#endif - - if( s_recVUMem == NULL ) - return; - - //jASSUME( s_recVUMem != NULL ); - - if( vuindex < 0 ) - { - DbgCon::Status( "SuperVU reset > Resetting recompiler memory and structures." ); - - // Does this cause problems on VU recompiler resets? It could, if the VU works like - // the EE used to, and actually tries to re-enter the recBlock after issuing a clear. (air) - - //memset_8<0xcd, VU_EXESIZE>(s_recVUMem); - memzero_ptr(recVUStack); - - s_recVUPtr = s_recVUMem; - } - else - { - DbgCon::Status( "SuperVU reset [VU%d] > Resetting the recs and junk", params vuindex ); - list::iterator it; - if( recVUHeaders[vuindex] ) memset( recVUHeaders[vuindex], 0, sizeof(VuFunctionHeader*) * (s_MemSize[vuindex]/8) ); - if( recVUBlocks[vuindex] ) memset( recVUBlocks[vuindex], 0, sizeof(VuBlockHeader) * (s_MemSize[vuindex]/8) ); - - if( s_plistCachedHeaders[vuindex] != NULL ) { - for(u32 j = 0; j < s_MemSize[vuindex]/8; ++j) { - FORIT(it, s_plistCachedHeaders[vuindex][j]) delete *it; - s_plistCachedHeaders[vuindex][j].clear(); - } - } - - FORIT(it, s_listVUHeaders[vuindex]) delete *it; - s_listVUHeaders[vuindex].clear(); - } -} - -// clear the block and any joining blocks -void __fastcall SuperVUClear(u32 startpc, u32 size, int vuindex) -{ - vector::iterator itrange; - list::iterator it = s_listVUHeaders[vuindex].begin(); - u32 endpc = startpc+(size+(8-(size&7))); // Adding this code to ensure size is always a multiple of 8, it can be simplified to startpc+size if size is always a multiple of 8 (cottonvibes) - while( it != s_listVUHeaders[vuindex].end() ) { - - // for every fn, check if it has code in the range - FORIT(itrange, (*it)->ranges) { - if( startpc < (u32)itrange->start+itrange->size && itrange->start < endpc ) - break; - } - - if( itrange != (*it)->ranges.end() ) { - recVUHeaders[vuindex][(*it)->startpc/8] = NULL; -#ifdef SUPERVU_CACHING - list* plist = &s_plistCachedHeaders[vuindex][(*it)->startpc/8]; - plist->push_back(*it); - if( plist->size() > 30 ) { - // list is too big, delete - //Console::Notice("Performance warning: deleting cached VU program!"); - delete plist->front(); - plist->pop_front(); - } - it = s_listVUHeaders[vuindex].erase(it); -#else - delete *it; - it = s_listVUHeaders[vuindex].erase(it); -#endif - } - else ++it; - } -} - -static VuFunctionHeader* s_pFnHeader = NULL; -static VuBaseBlock* s_pCurBlock = NULL; -static VuInstruction* s_pCurInst = NULL; -static u32 s_StatusRead = 0, s_MACRead = 0, s_ClipRead = 0; // read addrs -static u32 s_PrevStatusWrite = 0, s_PrevMACWrite = 0, s_PrevClipWrite = 0, s_PrevIWrite = 0; -static u32 s_WriteToReadQ = 0; - -static u32 s_VIBranchDelay = 0; //Value of register to use in a vi branch delayed situation - - -u32 s_TotalVUCycles; // total cycles since start of program execution - - -u32 SuperVUGetVIAddr(int reg, int read) -{ - assert( s_pCurInst != NULL ); - - switch(reg) { - case REG_STATUS_FLAG: - { - u32 addr = (read==2) ? s_PrevStatusWrite : (read ? s_StatusRead : s_pCurInst->pStatusWrite); - assert(!read || addr != 0); - return addr; - } - case REG_MAC_FLAG: - { - return (read==2) ? s_PrevMACWrite : (read ? s_MACRead : s_pCurInst->pMACWrite); - } - case REG_CLIP_FLAG: - { - u32 addr = (read==2) ? s_PrevClipWrite : (read ? s_ClipRead : s_pCurInst->pClipWrite); - assert( !read || addr != 0 ); - return addr; - } - case REG_Q: return (read || s_WriteToReadQ) ? (uptr)&VU->VI[REG_Q] : (uptr)&VU->q; - case REG_P: return read ? (uptr)&VU->VI[REG_P] : (uptr)&VU->p; - case REG_I: return s_PrevIWrite; - } - -#ifdef SUPERVU_VIBRANCHDELAY - if( (read != 0) && (s_pCurInst->regs[0].pipe == VUPIPE_BRANCH) && (s_pCurInst->vicached >= 0) && (s_pCurInst->vicached == reg) ) { - return (uptr)&s_VIBranchDelay; // test for branch delays - } -#endif - - return (uptr)&VU->VI[reg]; -} - -void SuperVUDumpBlock(list& blocks, int vuindex) -{ - u32 *mem; - u32 i; - - g_Conf.Folders.Dumps.Mkdir(); - AsciiFile eff( - Path::Combine( g_Conf.Folders.Dumps, wxsFormat(L"svu%cdump%.4X.txt", s_vu?L'0':L'1', s_pFnHeader->startpc) ), - wxFile::write - ); - - eff.Printf("Format: upper_inst lower_inst\ntype f:vf_live_vars vf_used_vars i:vi_live_vars vi_used_vars inst_cycle pq_inst\n"); - eff.Printf("Type: %.2x - qread, %.2x - pread, %.2x - clip_write, %.2x - status_write\n" - "%.2x - mac_write, %.2x -qflush\n", - INST_Q_READ, INST_P_READ, INST_CLIP_WRITE, INST_STATUS_WRITE, INST_MAC_WRITE, INST_Q_WRITE); - eff.Printf("XMM: Upper: read0 read1 write acc temp; Lower: read0 read1 write acc temp\n\n"); - - list::iterator itblock; - list::iterator itinst; - VuBaseBlock::LISTBLOCKS::iterator itchild; - - FORIT(itblock, blocks) { - eff.Printf("block:%c %x-%x; children: ", ((*itblock)->type&BLOCKTYPE_HASEOP)?'*':' ', - (*itblock)->startpc, (*itblock)->endpc-8); - FORIT(itchild, (*itblock)->blocks) { - eff.Printf("%x ", (*itchild)->startpc); - } - eff.Printf("; vuxyz = %x, vuxy = %x\n", (*itblock)->vuxyz&(*itblock)->insts.front().usedvars[1], - (*itblock)->vuxy&(*itblock)->insts.front().usedvars[1]); - - itinst = (*itblock)->insts.begin(); - i = (*itblock)->startpc; - while(itinst != (*itblock)->insts.end() ) { - assert( i <= (*itblock)->endpc ); - if( itinst->type & INST_DUMMY ) { - if( itinst->nParentPc >= 0 && !(itinst->type&INST_DUMMY_)) { - // search for the parent - eff.Printf("writeback 0x%x (%x)\n", itinst->type, itinst->nParentPc); - } - } - else { - mem = (u32*)&VU->Micro[i]; - char* pstr = disVU1MicroUF( mem[1], i+4 ); - eff.Printf("%.4x: %-40s", i, pstr); - if( mem[1] & 0x80000000 ) eff.Printf(" I=%f(%.8x)\n", *(float*)mem, mem[0]); - else eff.Printf("%s\n", disVU1MicroLF( mem[0], i )); - i += 8; - } - - ++itinst; - } - - eff.Printf("\n"); - - _x86regs* pregs; - if( (*itblock)->nStartx86 >= 0 || (*itblock)->nEndx86 >= 0 ) { - eff.Printf("X86: AX CX DX BX SP BP SI DI\n"); - } - - if( (*itblock)->nStartx86 >= 0 ) { - pregs = &s_vecRegArray[(*itblock)->nStartx86]; - eff.Printf("STR: "); - for(i = 0; i < iREGCNT_GPR; ++i) { - if( pregs[i].inuse ) eff.Printf("%.2d ", pregs[i].reg); - else eff.Printf("-1 "); - } - eff.Printf("\n"); - } - - if( (*itblock)->nEndx86 >= 0 ) { - eff.Printf("END: "); - pregs = &s_vecRegArray[(*itblock)->nEndx86]; - for(i = 0; i < iREGCNT_GPR; ++i) { - if( pregs[i].inuse ) eff.Printf("%.2d ", pregs[i].reg); - else eff.Printf("-1 "); - } - eff.Printf("\n"); - } - - itinst = (*itblock)->insts.begin(); - for ( i = (*itblock)->startpc; i < (*itblock)->endpc; ++itinst ) { - - if( itinst->type & INST_DUMMY ) { - } - else { - char str[256]; - sprintf(str, "%.4x:%x f:%.8x_%.8x", i, itinst->type, itinst->livevars[1], itinst->usedvars[1]); - eff.Printf("%-46s i:%.8x_%.8x c:%d pq:%d\n", str, - itinst->livevars[0], itinst->usedvars[0], (int)itinst->info.cycle, (int)itinst->pqcycles ); - - sprintf(str, "XMM r0:%d r1:%d w:%d a:%d t:%x;", - itinst->vfread0[1], itinst->vfread1[1], itinst->vfwrite[1], itinst->vfacc[1], itinst->vffree[1]); - eff.Printf("%-46s r0:%d r1:%d w:%d a:%d t:%x\n", str, - itinst->vfread0[0], itinst->vfread1[0], itinst->vfwrite[0], itinst->vfacc[0], itinst->vffree[0]); - i += 8; - } - } - -#ifdef __LINUX__ - // dump the asm - /* if( (*itblock)->pcode != NULL ) { - char command[255]; - FILE* fasm = fopen( "mydump1", "wb" ); - //Console::WriteLn("writing: %x, %x", params (*itblock)->startpc, (uptr)(*itblock)->pendcode - (uptr)(*itblock)->pcode); - fwrite( (*itblock)->pcode, 1, (uptr)(*itblock)->pendcode - (uptr)(*itblock)->pcode, fasm ); - fclose( fasm ); - sprintf( command, "objdump -D --target=binary --architecture=i386 -M intel mydump1 > tempdump"); - system( command ); - fasm = fopen("tempdump", "r"); - // read all of it and write it to f - fseek(fasm, 0, SEEK_END); - vector vbuffer(ftell(fasm)); - fseek(fasm, 0, SEEK_SET); - fread(&vbuffer[0], vbuffer.size(), 1, fasm); - - fprintf(f, "\n\n"); - fwrite(&vbuffer[0], vbuffer.size(), 1, f); - fclose(fasm); - }*/ -#endif - - eff.Printf("\n---------------\n"); - } -} - -// uncomment to count svu exec time -//#define SUPERVU_COUNT - -// Private methods -void* SuperVUGetProgram(u32 startpc, int vuindex) -{ - assert( startpc < s_MemSize[vuindex] ); - assert( (startpc%8) == 0 ); - assert( recVUHeaders[vuindex] != NULL ); - VuFunctionHeader** pheader = &recVUHeaders[vuindex][startpc/8]; - - if( *pheader == NULL ) { -#ifdef _DEBUG -// if( vuindex ) VU1.VI[REG_TPC].UL = startpc; -// else VU0.VI[REG_TPC].UL = startpc; -// __Log("VU: %x\n", startpc); -// iDumpVU1Registers(); -// vudump |= 2; -#endif - - // measure run time - //QueryPerformanceCounter(&svubase); - -#ifdef SUPERVU_CACHING - void* pmem = (vuindex&1) ? VU1.Micro : VU0.Micro; - // check if program exists in cache - list::iterator it; - FORIT(it, s_plistCachedHeaders[vuindex][startpc/8]) { - if( (*it)->IsSame(pmem) ) { - // found, transfer to regular lists - void* pfn = (*it)->pprogfunc; - recVUHeaders[vuindex][startpc/8] = *it; - s_listVUHeaders[vuindex].push_back(*it); - s_plistCachedHeaders[vuindex][startpc/8].erase(it); - return pfn; - } - } -#endif - - *pheader = SuperVURecompileProgram(startpc, vuindex); - - if( *pheader == NULL ) { - assert( s_TotalVUCycles > 0 ); - if( vuindex ) VU1.VI[REG_TPC].UL = startpc; - else VU0.VI[REG_TPC].UL = startpc; - return (void*)SuperVUEndProgram; - } - - //QueryPerformanceCounter(&svufinal); - //svutime += (u32)(svufinal.QuadPart-svubase.QuadPart); - - assert( (*pheader)->pprogfunc != NULL ); - } - //else assert( (*pheader)->IsSame((vuindex&1) ? VU1.Micro : VU0.Micro) ); - - assert( (*pheader)->startpc == startpc ); - - return (*pheader)->pprogfunc; -} - -bool VuFunctionHeader::IsSame(void* pmem) -{ -#ifdef SUPERVU_CACHING - vector::iterator it; - FORIT(it, ranges) - { - if( memcmp_mmx((u8*)pmem+it->start, it->pmem, it->size) ) - return false; - } -#endif - return true; -} - -list::iterator VuBaseBlock::GetInstIterAtPc(int instpc) -{ - assert( instpc >= 0 ); - - u32 curpc = startpc; - list::iterator it; - for(it = insts.begin(); it != insts.end(); ++it) { - if( it->type & INST_DUMMY ) - continue; - - if( curpc == instpc ) - break; - curpc += 8; - } - - if( it != insts.end() ) - return it; - - assert( 0 ); - return insts.begin(); -} - -void VuBaseBlock::GetInstsAtPc(int instpc, list& listinsts) -{ - assert( instpc >= 0 ); - - listinsts.clear(); - - u32 curpc = startpc; - list::iterator it; - for(it = insts.begin(); it != insts.end(); ++it) { - if( it->type & INST_DUMMY ) - continue; - - if( curpc == instpc ) - break; - curpc += 8; - } - - if( it != insts.end() ) { - listinsts.push_back(&(*it)); - return; - } - - // look for the pc in other blocks - for(list::iterator itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); ++itblock) { - if( *itblock == this ) - continue; - - if( instpc >= (*itblock)->startpc && instpc < (*itblock)->endpc ) { - listinsts.push_back(&(*(*itblock)->GetInstIterAtPc(instpc))); - } - } - - assert(listinsts.size()>0); -} - -static VuFunctionHeader* SuperVURecompileProgram(u32 startpc, int vuindex) -{ - assert( vuindex < 2 ); - assert( s_recVUPtr != NULL ); - //Console::WriteLn("svu%c rec: %x", params '0'+vuindex, startpc); - - // if recPtr reached the mem limit reset whole mem - if ( ( (uptr)s_recVUPtr - (uptr)s_recVUMem ) >= VU_EXESIZE-0x40000 ) { - //Console::WriteLn("SuperVU reset mem"); - SuperVUReset(0); - SuperVUReset(1); - SuperVUReset(-1); - if( s_TotalVUCycles > 0 ) { - // already executing, so return NULL - return NULL; - } - } - - list::iterator itblock; - - s_vu = vuindex; - VU = s_vu ? &VU1 : &VU0; - s_pFnHeader = new VuFunctionHeader(); - s_listVUHeaders[vuindex].push_back(s_pFnHeader); - s_pFnHeader->startpc = startpc; - - memset( recVUBlocks[s_vu], 0, sizeof(VuBlockHeader) * (s_MemSize[s_vu]/8) ); - - // analyze the global graph - s_listBlocks.clear(); - VUPIPELINES pipes; - memzero_obj(pipes.fmac); - memzero_obj(pipes.fdiv); - memzero_obj(pipes.efu); - memzero_obj(pipes.ialu); - SuperVUBuildBlocks(NULL, startpc, pipes); - - // fill parents - VuBaseBlock::LISTBLOCKS::iterator itchild; - FORIT(itblock, s_listBlocks) { - FORIT(itchild, (*itblock)->blocks) - (*itchild)->parents.push_back(*itblock); - - //(*itblock)->type &= ~(BLOCKTYPE_IGNORE|BLOCKTYPE_ANALYZED); - } - - assert( s_listBlocks.front()->startpc == startpc ); - s_listBlocks.front()->type |= BLOCKTYPE_FUNCTION; - - FORIT(itblock, s_listBlocks) { - SuperVUInitLiveness(*itblock); - } - - SuperVULivenessAnalysis(); - SuperVUEliminateDeadCode(); - SuperVUAssignRegs(); - -#ifdef _DEBUG - if( (s_vu && (vudump&1)) || (!s_vu && (vudump&16)) ) - SuperVUDumpBlock(s_listBlocks, s_vu); -#endif - - // code generation - x86SetPtr(s_recVUPtr); - branch = 0; - - SuperVURecompile(); - - s_recVUPtr = x86Ptr; - - // set the function's range - VuFunctionHeader::RANGE r; - s_pFnHeader->ranges.reserve(s_listBlocks.size()); - - FORIT(itblock, s_listBlocks) { - r.start = (*itblock)->startpc; - r.size = (*itblock)->endpc-(*itblock)->startpc; -#ifdef SUPERVU_CACHING - //memxor_mmx(r.checksum, &VU->Micro[r.start], r.size); - r.pmem = malloc(r.size); - memcpy_fast(r.pmem, &VU->Micro[r.start], r.size); -#endif - s_pFnHeader->ranges.push_back(r); - } - -#if defined(_DEBUG) && defined(__LINUX__) - // dump at the end to capture the actual code - if( (s_vu && (vudump&1)) || (!s_vu && (vudump&16)) ) - SuperVUDumpBlock(s_listBlocks, s_vu); -#endif - - // destroy - for(list::iterator itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); ++itblock) { - delete *itblock; - } - s_listBlocks.clear(); - - assert( s_recVUPtr < s_recVUMem+VU_EXESIZE ); - - return s_pFnHeader; -} - -static int _recbranchAddr(u32 vucode) { - s32 bpc = pc + (_Imm11_ << 3); -/* - if ( bpc < 0 ) { - Console::WriteLn("zerorec branch warning: bpc < 0 ( %x ); Using unsigned imm11", params bpc); - bpc = pc + (_UImm11_ << 3); - }*/ - bpc &= (s_MemSize[s_vu]-1); - - return bpc; -} - -// return inst that flushes everything -static VuInstruction SuperVUFlushInst() -{ - VuInstruction inst; - // don't need to raed q/p - inst.type = INST_DUMMY_;//|INST_Q_READ|INST_P_READ; - return inst; -} - -void SuperVUAddWritebacks(VuBaseBlock* pblock, const list& listWritebacks) -{ -#ifdef SUPERVU_WRITEBACKS - // regardless of repetition, add the pipes (for selfloops) - list::const_iterator itwriteback = listWritebacks.begin(); - list::iterator itinst = pblock->insts.begin(), itinst2; - - while(itwriteback != listWritebacks.end()) { - if( itinst != pblock->insts.end() && (itinst->info.cycle < itwriteback->cycle || (itinst->type&INST_DUMMY) ) ) { - ++itinst; - continue; - } - - itinst2 = pblock->insts.insert(itinst, VuInstruction()); - itwriteback->InitInst(&(*itinst2), vucycle); - ++itwriteback; - } -#endif -} - -#ifdef SUPERVU_VIBRANCHDELAY -static VuInstruction* getDelayInst(VuInstruction* pInst) -{ - // check for the N cycle branch delay - // example of 2 cycles delay (monster house) : - // sqi vi05 - // sqi vi05 - // ibeq vi05, vi03 - // The ibeq should read the vi05 before the first sqi - - //more info: - - // iaddiu vi01, 0, 1 - // ibeq vi01, 0 <- reads vi01 before the iaddiu - - // iaddiu vi01, 0, 1 - // iaddiu vi01, vi01, 1 - // iaddiu vi01, vi01, 1 - // ibeq vi01, 0 <- reads vi01 before the last two iaddiu's (so the value read is 1) - - // ilw vi02, addr - // iaddiu vi01, 0, 1 - // ibeq vi01, vi02 <- reads current values of both vi01 and vi02 because the branch instruction stalls - - int delay = 1; - VuInstruction* pDelayInst = NULL; - VuInstruction* pTargetInst = pInst->pPrevInst; - while( 1 ) { - if( pTargetInst != NULL - && pTargetInst->info.cycle+delay==pInst->info.cycle - && (pTargetInst->regs[0].pipe == VUPIPE_IALU||pTargetInst->regs[0].pipe == VUPIPE_FMAC) - && ((pTargetInst->regs[0].VIwrite & pInst->regs[0].VIread) & 0xffff) - && (delay == 1 || ((pTargetInst->regs[0].VIwrite & pInst->regs[0].VIread) & 0xffff) == ((pTargetInst->regs[0].VIwrite & pInst->pPrevInst->regs[0].VIread) & 0xffff)) - && !(pTargetInst->regs[0].VIread&((1<pPrevInst; - delay++; - if (delay == 5) //maximum delay is 4 (length of the pipeline) - { - DevCon::WriteLn("supervu: cycle branch delay maximum (4) is reached"); - break; - } - } - else break; - } - if( delay > 1 ) DevCon::WriteLn("supervu: %d cycle branch delay detected: %x %x", params delay-1, pc, s_pFnHeader->startpc); - return pDelayInst; -} -#endif - -static VuBaseBlock* SuperVUBuildBlocks(VuBaseBlock* parent, u32 startpc, const VUPIPELINES& pipes) -{ - // check if block already exists - //Console::WriteLn("startpc %x", params startpc); - startpc &= (s_vu ? 0x3fff : 0xfff); - VuBlockHeader* pbh = &recVUBlocks[s_vu][startpc/8]; - - if ( pbh->pblock != NULL ) { - - VuBaseBlock* pblock = pbh->pblock; - list::iterator itinst; - - if( pblock->startpc == startpc ) { - SuperVUAddWritebacks(pblock, pipes.listWritebacks); - return pblock; - } - - // have to divide the blocks, pnewblock is first block - assert( startpc > pblock->startpc ); - assert( startpc < pblock->endpc ); - - u32 dummyinst = (startpc-pblock->startpc)>>3; - - // count inst non-dummy insts - itinst = pblock->insts.begin(); - int cycleoff = 0; - - while(dummyinst > 0) { - if( itinst->type & INST_DUMMY ) - ++itinst; - else { - cycleoff = itinst->info.cycle; - ++itinst; - --dummyinst; - } - } - - // NOTE: still leaves insts with their writebacks in different blocks - while( itinst->type & INST_DUMMY ) - ++itinst; - - // the difference in cycles between dummy insts (naruto utlimate ninja) - int cyclediff = 0; - if( parent == pblock ) - cyclediff = itinst->info.cycle-cycleoff; - cycleoff = itinst->info.cycle; - - // new block - VuBaseBlock* pnewblock = new VuBaseBlock(); - s_listBlocks.push_back(pnewblock); - - pnewblock->startpc = startpc; - pnewblock->endpc = pblock->endpc; - pnewblock->cycles = pblock->cycles-cycleoff+cyclediff; - - pnewblock->blocks.splice(pnewblock->blocks.end(), pblock->blocks); - pnewblock->insts.splice(pnewblock->insts.end(), pblock->insts, itinst, pblock->insts.end()); - pnewblock->type = pblock->type; - - // any writebacks in the next 3 cycles also belong to original block -// for(itinst = pnewblock->insts.begin(); itinst != pnewblock->insts.end(); ) { -// if( (itinst->type & INST_DUMMY) && itinst->nParentPc >= 0 && itinst->nParentPc < (int)startpc ) { -// -// if( !(itinst->type & INST_Q_WRITE) ) -// pblock->insts.push_back(*itinst); -// itinst = pnewblock->insts.erase(itinst); -// continue; -// } -// -// ++itinst; -// } - - pbh = &recVUBlocks[s_vu][startpc/8]; - for(u32 inst = startpc; inst < pblock->endpc; inst += 8) { - if( pbh->pblock == pblock ) - pbh->pblock = pnewblock; - ++pbh; - } - - FORIT(itinst, pnewblock->insts) - itinst->info.cycle -= cycleoff; - - SuperVUAddWritebacks(pnewblock, pipes.listWritebacks); - - // old block - pblock->blocks.push_back(pnewblock); - pblock->endpc = startpc; - pblock->cycles = cycleoff; - pblock->type &= BLOCKTYPE_MACFLAGS; - //pblock->insts.push_back(SuperVUFlushInst()); //don't need - - return pnewblock; - } - - VuBaseBlock* pblock = new VuBaseBlock(); - s_listBlocks.push_back(pblock); - - int i = 0; - branch = 0; - pc = startpc; - pblock->startpc = startpc; - - // clear stalls (might be a prob) - memcpy(VU->fmac, pipes.fmac, sizeof(pipes.fmac)); - memcpy(&VU->fdiv, &pipes.fdiv, sizeof(pipes.fdiv)); - memcpy(&VU->efu, &pipes.efu, sizeof(pipes.efu)); - memcpy(VU->ialu, pipes.ialu, sizeof(pipes.ialu)); -// memset(VU->fmac, 0, sizeof(VU->fmac)); -// memset(&VU->fdiv, 0, sizeof(VU->fdiv)); -// memset(&VU->efu, 0, sizeof(VU->efu)); - - vucycle = 0; - - u8 macflags = 0; - - list< WRITEBACK > listWritebacks; - list< WRITEBACK >::iterator itwriteback; - list::iterator itinst; - u32 hasSecondBranch = 0; - u32 needFullStatusFlag = 0; - -#ifdef SUPERVU_WRITEBACKS - listWritebacks = pipes.listWritebacks; -#endif - - // first analysis pass for status flags - while(1) { - u32* ptr = (u32*)&VU->Micro[pc]; - pc += 8; - int prevbranch = branch; - - if( ptr[1] & 0x40000000 ) - branch = 1; - - if( !(ptr[1] & 0x80000000) ) { // not I - switch( ptr[0]>>25 ) { - case 0x24: // jr - case 0x25: // jalr - case 0x20: // B - case 0x21: // BAL - case 0x28: // IBEQ - case 0x2f: // IBGEZ - case 0x2d: // IBGTZ - case 0x2e: // IBLEZ - case 0x2c: // IBLTZ - case 0x29: // IBNE - branch = 1; - break; - - case 0x14: // fseq - case 0x17: // fsor - //needFullStatusFlag = 2; - break; - - case 0x16: // fsand - if( (ptr[0]&0xc0) ) { - // sometimes full sticky bits are needed (simple series 2000 - oane chapara) - //Console::WriteLn("needSticky: %x-%x", params s_pFnHeader->startpc, startpc); - needFullStatusFlag = 2; - } - break; - } - } - - if( prevbranch ) - break; - - if( pc >= s_MemSize[s_vu] ) { - Console::Error( "inf vu0 prog %x",params startpc); - break; - } - } - - // second full pass - pc = startpc; - branch = 0; - VuInstruction* pprevinst=NULL, *pinst = NULL; - - while(1) { - - if( pc == s_MemSize[s_vu] ) { - branch |= 8; - break; - } - - if( !branch && pbh->pblock != NULL ) { - pblock->blocks.push_back(pbh->pblock); - break; - } - - int prevbranch = branch; - - if( !prevbranch ) { - pbh->pblock = pblock; - } - else assert( prevbranch || pbh->pblock == NULL); - - pblock->insts.push_back(VuInstruction()); - - pprevinst = pinst; - pinst = &pblock->insts.back(); - pinst->pPrevInst = pprevinst; - SuperVUAnalyzeOp(VU, &pinst->info, pinst->regs); - -#ifdef SUPERVU_VIBRANCHDELAY - if( pinst->regs[0].pipe == VUPIPE_BRANCH && pblock->insts.size() > 1 ) { - - VuInstruction* pdelayinst = getDelayInst(pinst); - if( pdelayinst ) { - pdelayinst->type |= INST_CACHE_VI; - - // find the correct register - u32 mask = pdelayinst->regs[0].VIwrite & pinst->regs[0].VIread; - for(int i = 0; i < 16; ++i) { - if( mask & (1<vicached = i; - break; - } - } - - pinst->vicached = pdelayinst->vicached; - } - } -#endif - - if( prevbranch ) { - if( pinst->regs[0].pipe == VUPIPE_BRANCH ) - hasSecondBranch = 1; - pinst->type |= INST_BRANCH_DELAY; - } - - // check write back - for(itwriteback = listWritebacks.begin(); itwriteback != listWritebacks.end(); ) { - if( pinst->info.cycle >= itwriteback->cycle ) { - itinst = pblock->insts.insert(--pblock->insts.end(), VuInstruction()); - itwriteback->InitInst(&(*itinst), pinst->info.cycle); - itwriteback = listWritebacks.erase(itwriteback); - } - else ++itwriteback; - } - - // add new writebacks - WRITEBACK w; - const u32 allflags = (1<regs[j].VIwrite & allflags; - - if( pinst->info.macflag & VUOP_WRITE ) w.viwrite[1] |= (1<info.statusflag & VUOP_WRITE ) w.viwrite[1] |= (1<info.macflag|pinst->info.statusflag) & VUOP_READ ) - macflags = 1; - if( pinst->regs[0].VIread & ((1<regs[1].pipe == VUPIPE_FMAC && (pinst->regs[1].VFwrite==0&&!(pinst->regs[1].VIwrite&(1<regs[0].VIread |= (1<VIwrite |= lregs->VIwrite & (1<info.statusflag&VUOP_WRITE)&&!(pinst->regs[0].VIwrite&(1<regs[j].VIread & allflags; - - if( (pinst->regs[j].VIread&(1<regs[j].VIwrite&(1<regs[j].VIread &= ~(1<regs[j].VIread&(1<regs[j].VIwrite&(1<regs[j].VIread &= ~(1<regs[j].VIwrite &= ~allflags; - } - - if( pinst->info.macflag & VUOP_READ) w.viread[1] |= 1<info.statusflag & VUOP_READ) w.viread[1] |= 1<info.cycle+4; - listWritebacks.push_back(w); - } - - if( pinst->info.q&VUOP_READ ) pinst->type |= INST_Q_READ; - if( pinst->info.p&VUOP_READ ) pinst->type |= INST_P_READ; - - if( pinst->info.q&VUOP_WRITE ) { - pinst->pqcycles = QWaitTimes[pinst->info.pqinst]+1; - - memset(&w, 0, sizeof(w)); - w.nParentPc = pc-8; - w.cycle = pinst->info.cycle+pinst->pqcycles; - w.viwrite[0] = 1<info.p&VUOP_WRITE ) - pinst->pqcycles = PWaitTimes[pinst->info.pqinst]+1; - - if( prevbranch ) { - break; - } - - // make sure there is always a branch - // sensible soccer overflows on vu0, so increase the limit... - if( (s_vu==1 && i >= 0x799) || (s_vu==0 && i >= 0x201) ) { - Console::Error("VuRec base block doesn't terminate!"); - assert(0); - break; - } - - i++; - pbh++; - } - - if( macflags ) - pblock->type |= BLOCKTYPE_MACFLAGS; - - pblock->endpc = pc; - u32 lastpc = pc; - - pblock->cycles = vucycle; - -#ifdef SUPERVU_WRITEBACKS - if( !branch || (branch&8) ) -#endif - { - // flush writebacks - if( listWritebacks.size() > 0 ) { - listWritebacks.sort(WRITEBACK::SortWritebacks); - for(itwriteback = listWritebacks.begin(); itwriteback != listWritebacks.end(); ++itwriteback) { - if( itwriteback->viwrite[0] & (1<insts.push_back(VuInstruction()); - itwriteback->InitInst(&pblock->insts.back(), vucycle); - } - - listWritebacks.clear(); - } - } - - if( !branch ) - return pblock; - - if( branch & 8 ) { - // what if also a jump? - pblock->type |= BLOCKTYPE_EOP|BLOCKTYPE_HASEOP; - - // add an instruction to flush p and q (if written) - pblock->insts.push_back(SuperVUFlushInst()); - return pblock; - } - - // it is a (cond) branch or a jump - u32 vucode = *(u32*)(VU->Micro+lastpc-16); - int bpc = _recbranchAddr(vucode)-8; - - VUPIPELINES newpipes; - memcpy(newpipes.fmac, VU->fmac, sizeof(newpipes.fmac)); - memcpy(&newpipes.fdiv, &VU->fdiv, sizeof(newpipes.fdiv)); - memcpy(&newpipes.efu, &VU->efu, sizeof(newpipes.efu)); - memcpy(newpipes.ialu, VU->ialu, sizeof(newpipes.ialu)); - - for(i = 0; i < 8; ++i) newpipes.fmac[i].sCycle -= vucycle; - newpipes.fdiv.sCycle -= vucycle; - newpipes.efu.sCycle -= vucycle; - for(i = 0; i < 8; ++i) newpipes.ialu[i].sCycle -= vucycle; - - if( listWritebacks.size() > 0 ) { - // flush all when jumping, send down the pipe when in branching - bool bFlushWritebacks = (vucode>>25)==0x24||(vucode>>25)==0x25;//||(vucode>>25)==0x20||(vucode>>25)==0x21; - - listWritebacks.sort(WRITEBACK::SortWritebacks); - for(itwriteback = listWritebacks.begin(); itwriteback != listWritebacks.end(); ++itwriteback) { - if( itwriteback->viwrite[0] & (1<cycle < vucycle || bFlushWritebacks ) { - pblock->insts.push_back(VuInstruction()); - itwriteback->InitInst(&pblock->insts.back(), vucycle); - } - else { - newpipes.listWritebacks.push_back(*itwriteback); - newpipes.listWritebacks.back().cycle -= vucycle; - } - } - } - - if( newpipes.listWritebacks.size() > 0 ) // other blocks might read the mac flags - pblock->type |= BLOCKTYPE_MACFLAGS; - - u32 firstbranch = vucode>>25; - switch(firstbranch) { - case 0x24: // jr - pblock->type |= BLOCKTYPE_EOP; // jump out of procedure, since not returning, set EOP - pblock->insts.push_back(SuperVUFlushInst()); - firstbranch = 0xff; //Non-Conditional Jump - break; - - case 0x25: // jalr - { - // linking, so will return to procedure - pblock->insts.push_back(SuperVUFlushInst()); - - VuBaseBlock* pjumpblock = SuperVUBuildBlocks(pblock, lastpc, newpipes); - - // update pblock since could have changed - pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; - assert( pblock != NULL ); - - pblock->blocks.push_back(pjumpblock); - firstbranch = 0xff; //Non-Conditional Jump - break; - } - case 0x20: // B - { - VuBaseBlock* pbranchblock = SuperVUBuildBlocks(pblock, bpc, newpipes); - - // update pblock since could have changed - pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; - assert( pblock != NULL ); - - pblock->blocks.push_back(pbranchblock); - firstbranch = 0xff; //Non-Conditional Jump - break; - } - case 0x21: // BAL - { - VuBaseBlock* pbranchblock = SuperVUBuildBlocks(pblock, bpc, newpipes); - - // update pblock since could have changed - pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; - assert( pblock != NULL ); - pblock->blocks.push_back(pbranchblock); - firstbranch = 0xff; //Non-Conditional Jump - break; - } - case 0x28: // IBEQ - case 0x2f: // IBGEZ - case 0x2d: // IBGTZ - case 0x2e: // IBLEZ - case 0x2c: // IBLTZ - case 0x29: // IBNE - { - VuBaseBlock* pbranchblock = SuperVUBuildBlocks(pblock, bpc, newpipes); - - // update pblock since could have changed - pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; - assert( pblock != NULL ); - pblock->blocks.push_back(pbranchblock); - - // if has a second branch that is B or BAL, skip this - u32 secondbranch = (*(u32*)(VU->Micro+lastpc-8))>>25; - if( !hasSecondBranch || (secondbranch != 0x21 && secondbranch != 0x20) ) { - pbranchblock = SuperVUBuildBlocks(pblock, lastpc, newpipes); - - pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; - pblock->blocks.push_back(pbranchblock); - } - - break; - } - default: - assert(pblock->blocks.size() == 1); - break; - } - - pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; - -#ifdef SUPERVU_VIBRANCHDELAY -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -///// NOTE! This could still be a hack for KH2/GoW, but until we know how it properly works, this will do for now./// -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - if( hasSecondBranch && firstbranch != 0xff ) { //check the previous jump was conditional and there is a second branch -#else - if( hasSecondBranch) { -#endif - - u32 vucode = *(u32*)(VU->Micro+lastpc-8); - pc = lastpc; - int bpc = _recbranchAddr(vucode); - - switch(vucode>>25) { - case 0x24: // jr - Console::Error("svurec bad jr jump!"); - assert(0); - break; - - case 0x25: // jalr - { - Console::Error("svurec bad jalr jump!"); - assert(0); - break; - } - case 0x20: // B - { - VuBaseBlock* pbranchblock = SuperVUBuildBlocks(pblock, bpc, newpipes); - - // update pblock since could have changed - pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; - - pblock->blocks.push_back(pbranchblock); - break; - } - case 0x21: // BAL - { - VuBaseBlock* pbranchblock = SuperVUBuildBlocks(pblock, bpc, newpipes); - - // replace instead of pushing a new block - pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; - pblock->blocks.push_back(pbranchblock); - break; - } - case 0x28: // IBEQ - case 0x2f: // IBGEZ - case 0x2d: // IBGTZ - case 0x2e: // IBLEZ - case 0x2c: // IBLTZ - case 0x29: // IBNE - { - VuBaseBlock* pbranchblock = SuperVUBuildBlocks(pblock, bpc, newpipes); - - // update pblock since could have changed - pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; - pblock->blocks.push_back(pbranchblock); - - // only add the block if the previous branch doesn't include the next instruction (ie, if a direct jump) - if( firstbranch == 0x24 || firstbranch == 0x25 || firstbranch == 0x20 || firstbranch == 0x21 ) { - pbranchblock = SuperVUBuildBlocks(pblock, lastpc, newpipes); - - pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; - pblock->blocks.push_back(pbranchblock); - } - - break; - } - - jNO_DEFAULT; - } - } - - return recVUBlocks[s_vu][startpc/8].pblock; -} - -static void SuperVUInitLiveness(VuBaseBlock* pblock) -{ - list::iterator itinst, itnext; - - assert( pblock->insts.size() > 0 ); - - for(itinst = pblock->insts.begin(); itinst != pblock->insts.end(); ++itinst) { - - if( itinst->type & INST_DUMMY_ ) { - itinst->addvars[0] = itinst->addvars[1] = 0xffffffff; - itinst->livevars[0] = itinst->livevars[1] = 0xffffffff; - itinst->keepvars[0] = itinst->keepvars[1] = 0xffffffff; - itinst->usedvars[0] = itinst->usedvars[1] = 0; - } - else { - itinst->addvars[0] = itinst->regs[0].VIread | itinst->regs[1].VIread; - itinst->addvars[1] = (itinst->regs[0].VFread0 ? (1 << itinst->regs[0].VFread0) : 0) | - (itinst->regs[0].VFread1 ? (1 << itinst->regs[0].VFread1) : 0) | - (itinst->regs[1].VFread0 ? (1 << itinst->regs[1].VFread0) : 0) | - (itinst->regs[1].VFread1 ? (1 << itinst->regs[1].VFread1) : 0); - - // vf0 is not handled by VFread - if( !itinst->regs[0].VFread0 && (itinst->regs[0].VIread & (1<addvars[1] |= 1; - if( !itinst->regs[1].VFread0 && (itinst->regs[1].VIread & (1<addvars[1] |= 1; - if( !itinst->regs[0].VFread1 && (itinst->regs[0].VIread & (1<regs[0].VFr1xyzw != 0xff ) itinst->addvars[1] |= 1; - if( !itinst->regs[1].VFread1 && (itinst->regs[1].VIread & (1<regs[1].VFr1xyzw != 0xff ) itinst->addvars[1] |= 1; - - - u32 vfwrite = 0; - if( itinst->regs[0].VFwrite != 0 ) { - if( itinst->regs[0].VFwxyzw != 0xf ) itinst->addvars[1] |= 1<regs[0].VFwrite; - else vfwrite |= 1<regs[0].VFwrite; - } - if( itinst->regs[1].VFwrite != 0 ) { - if( itinst->regs[1].VFwxyzw != 0xf ) itinst->addvars[1] |= 1<regs[1].VFwrite; - else vfwrite |= 1<regs[1].VFwrite; - } - if( (itinst->regs[1].VIwrite & (1<regs[1].VFwxyzw != 0xf ) - itinst->addvars[1] |= 1<regs[0].VIwrite|itinst->regs[1].VIwrite); - - itinst->usedvars[0] = itinst->addvars[0]|viwrite; - itinst->usedvars[1] = itinst->addvars[1]|vfwrite; - -// itinst->addvars[0] &= ~viwrite; -// itinst->addvars[1] &= ~vfwrite; - itinst->keepvars[0] = ~viwrite; - itinst->keepvars[1] = ~vfwrite; - } - } - - itinst = --pblock->insts.end(); - while( itinst != pblock->insts.begin() ) { - itnext = itinst; --itnext; - - itnext->usedvars[0] |= itinst->usedvars[0]; - itnext->usedvars[1] |= itinst->usedvars[1]; - - itinst = itnext; - } -} - -u32 COMPUTE_LIVE(u32 R, u32 K, u32 L) -{ - u32 live = R | ((L)&(K)); - // special process mac and status flags - // only propagate liveness if doesn't write to the flag - if( !(L&(1<::reverse_iterator itblock; - list::iterator itinst, itnext; - VuBaseBlock::LISTBLOCKS::iterator itchild; - - u32 livevars[2]; - - do { - changed = FALSE; - for(itblock = s_listBlocks.rbegin(); itblock != s_listBlocks.rend(); ++itblock) { - - u32 newlive; - VuBaseBlock* pb = *itblock; - - // the last inst relies on the neighbor's insts - itinst = --pb->insts.end(); - - if( pb->blocks.size() > 0 ) { - livevars[0] = 0; livevars[1] = 0; - for( itchild = pb->blocks.begin(); itchild != pb->blocks.end(); ++itchild) { - VuInstruction& front = (*itchild)->insts.front(); - livevars[0] |= front.livevars[0]; - livevars[1] |= front.livevars[1]; - } - - newlive = COMPUTE_LIVE(itinst->addvars[0], itinst->keepvars[0], livevars[0]); - - // should propagate status flags whose parent insts are not in this block -// if( itinst->nParentPc >= 0 && (itinst->type & (INST_STATUS_WRITE|INST_MAC_WRITE)) ) -// newlive |= livevars[0]&((1<livevars[0] != newlive ) { - changed = TRUE; - itinst->livevars[0] = newlive; - } - - newlive = COMPUTE_LIVE(itinst->addvars[1], itinst->keepvars[1], livevars[1]); - if( itinst->livevars[1] != newlive ) { - changed = TRUE; - itinst->livevars[1] = newlive; - } - } - - while( itinst != pb->insts.begin() ) { - - itnext = itinst; --itnext; - - newlive = COMPUTE_LIVE(itnext->addvars[0], itnext->keepvars[0], itinst->livevars[0]); - - // should propagate status flags whose parent insts are not in this block -// if( itnext->nParentPc >= 0 && (itnext->type & (INST_STATUS_WRITE|INST_MAC_WRITE)) && !(itinst->type & (INST_STATUS_WRITE|INST_MAC_WRITE)) ) -// newlive |= itinst->livevars[0]&((1<livevars[0] != newlive ) { - changed = TRUE; - itnext->livevars[0] = newlive; - itnext->livevars[1] = COMPUTE_LIVE(itnext->addvars[1], itnext->keepvars[1], itinst->livevars[1]); - } - else { - newlive = COMPUTE_LIVE(itnext->addvars[1], itnext->keepvars[1], itinst->livevars[1]); - if( itnext->livevars[1] != newlive ) { - changed = TRUE; - itnext->livevars[1] = newlive; - } - } - - itinst = itnext; - } - -// if( (livevars[0] | itinst->livevars[0]) != itinst->livevars[0] ) { -// changed = TRUE; -// itinst->livevars[0] |= livevars[0]; -// } -// if( (livevars[1] | itinst->livevars[1]) != itinst->livevars[1] ) { -// changed = TRUE; -// itinst->livevars[1] |= livevars[1]; -// } -// -// while( itinst != pb->insts.begin() ) { -// -// itnext = itinst; --itnext; -// if( (itnext->livevars[0] | (itinst->livevars[0] & itnext->keepvars[0])) != itnext->livevars[0] ) { -// changed = TRUE; -// itnext->livevars[0] |= itinst->livevars[0] & itnext->keepvars[0]; -// itnext->livevars[1] |= itinst->livevars[1] & itnext->keepvars[1]; -// } -// else if( (itnext->livevars[1] | (itinst->livevars[1] & itnext->keepvars[1])) != itnext->livevars[1] ) { -// changed = TRUE; -// itnext->livevars[1] |= itinst->livevars[1] & itnext->keepvars[1]; -// } -// -// itinst = itnext; -// } - } - - } while(changed); -} - -static void SuperVUEliminateDeadCode() -{ - list::iterator itblock; - VuBaseBlock::LISTBLOCKS::iterator itchild; - list::iterator itinst, itnext; - list listParents; - list::iterator itparent; - - FORIT(itblock, s_listBlocks) { - -#ifdef _DEBUG - u32 startpc = (*itblock)->startpc; - u32 curpc = startpc; -#endif - - itnext = (*itblock)->insts.begin(); - itinst = itnext++; - while(itnext != (*itblock)->insts.end() ) { - if( itinst->type & (INST_CLIP_WRITE|INST_MAC_WRITE|INST_STATUS_WRITE) ) { - u32 live0 = itnext->livevars[0]; - if( itinst->nParentPc >= 0 && itnext->nParentPc >= 0 && itinst->nParentPc != itnext->nParentPc ) { // superman returns - // take the live vars from the next next inst - list::iterator itnextnext = itnext; ++itnextnext; - if( itnextnext != (*itblock)->insts.end() ) { - live0 = itnextnext->livevars[0]; - } - } - - itinst->regs[0].VIwrite &= live0; - itinst->regs[1].VIwrite &= live0; - - u32 viwrite = itinst->regs[0].VIwrite|itinst->regs[1].VIwrite; - - (*itblock)->GetInstsAtPc(itinst->nParentPc, listParents); - int removetype = 0; - - FORIT(itparent, listParents) { - VuInstruction* parent = *itparent; - - if( viwrite & (1<regs[0].VIwrite |= (itinst->regs[0].VIwrite&(1<regs[1].VIwrite |= (itinst->regs[1].VIwrite&(1<info.macflag && (itinst->type & INST_MAC_WRITE) ) { - if( !(viwrite&(1<info.macflag = 0; - // parent->regs[0].VIwrite &= ~(1<regs[1].VIwrite &= ~(1<regs[0].VIwrite & (1<regs[1].VIwrite & (1<regs[1].pipe == VUPIPE_FMAC && (parent->regs[1].VFwrite == 0&&!(parent->regs[1].VIwrite&(1<regs[0].VIwrite |= ((1<regs[1].VIwrite |= ((1<regs[0].VIwrite |= (itinst->regs[0].VIwrite&(1<regs[1].VIwrite |= (itinst->regs[1].VIwrite&(1<info.statusflag && (itinst->type & INST_STATUS_WRITE)) { - if( !(viwrite&(1<info.statusflag = 0; - // parent->regs[0].VIwrite &= ~(1<regs[1].VIwrite &= ~(1<regs[0].VIwrite & (1<regs[1].VIwrite & (1<regs[1].pipe == VUPIPE_FMAC && (parent->regs[1].VFwrite == 0&&!(parent->regs[1].VIwrite&(1<regs[0].VIwrite |= ((1<regs[1].VIwrite |= ((1<regs[0].VIwrite |= (itinst->regs[0].VIwrite&(1<regs[1].VIwrite |= (itinst->regs[1].VIwrite&(1<type &= ~removetype; - if( itinst->type == 0 ) { - itnext = (*itblock)->insts.erase(itinst); - itinst = itnext++; - continue; - } - } -#ifdef _DEBUG - else curpc += 8; -#endif - itinst = itnext; - ++itnext; - } - - if( itinst->type & INST_DUMMY ) { - // last inst with the children - u32 mask = 0; - for(itchild = (*itblock)->blocks.begin(); itchild != (*itblock)->blocks.end(); ++itchild) { - mask |= (*itchild)->insts.front().livevars[0]; - } - itinst->regs[0].VIwrite &= mask; - itinst->regs[1].VIwrite &= mask; - u32 viwrite = itinst->regs[0].VIwrite|itinst->regs[1].VIwrite; - - if( itinst->nParentPc >= 0 ) { - - (*itblock)->GetInstsAtPc(itinst->nParentPc, listParents); - int removetype = 0; - - FORIT(itparent, listParents) { - VuInstruction* parent = *itparent; - - if( viwrite & (1<regs[0].VIwrite |= (itinst->regs[0].VIwrite&(1<regs[1].VIwrite |= (itinst->regs[1].VIwrite&(1<info.macflag && (itinst->type & INST_MAC_WRITE) ) { - if( !(viwrite&(1<info.macflag = 0; -#ifndef SUPERVU_WRITEBACKS - assert( !(parent->regs[0].VIwrite & (1<regs[1].VIwrite & (1<regs[0].VIwrite |= (itinst->regs[0].VIwrite&(1<regs[1].VIwrite |= (itinst->regs[1].VIwrite&(1<info.statusflag && (itinst->type & INST_STATUS_WRITE)) { - if( !(viwrite&(1<info.statusflag = 0; -#ifndef SUPERVU_WRITEBACKS - assert( !(parent->regs[0].VIwrite & (1<regs[1].VIwrite & (1<regs[0].VIwrite |= (itinst->regs[0].VIwrite&(1<regs[1].VIwrite |= (itinst->regs[1].VIwrite&(1<type &= ~removetype; - if( itinst->type == 0 ) { - (*itblock)->insts.erase(itinst); - } - } - } - } -} - -void VuBaseBlock::AssignVFRegs() -{ - int i; - VuBaseBlock::LISTBLOCKS::iterator itchild; - list::iterator itblock; - list::iterator itinst, itnext, itinst2; - - // init the start regs - if( type & BLOCKTYPE_ANALYZED ) return; // nothing changed - memcpy(xmmregs, startregs, sizeof(xmmregs)); - - if( type & BLOCKTYPE_ANALYZED ) { - // check if changed - for(i = 0; i < iREGCNT_XMM; ++i) { - if( xmmregs[i].inuse != startregs[i].inuse ) - break; - if( xmmregs[i].inuse && (xmmregs[i].reg != startregs[i].reg || xmmregs[i].type != startregs[i].type) ) - break; - } - - if( i == iREGCNT_XMM ) return; // nothing changed - } - - u8* oldX86 = x86Ptr; - - FORIT(itinst, insts) { - - if( itinst->type & INST_DUMMY ) - continue; - - // reserve, go from upper to lower - int lastwrite = -1; - - for(i = 1; i >= 0; --i) { - _VURegsNum* regs = itinst->regs+i; - - - // redo the counters so that the proper regs are released - for(int j = 0; j < iREGCNT_XMM; ++j) { - if( xmmregs[j].inuse ) { - if( xmmregs[j].type == XMMTYPE_VFREG ) { - int count = 0; - itinst2 = itinst; - - if( i ) { - if( itinst2->regs[0].VFread0 == xmmregs[j].reg || itinst2->regs[0].VFread1 == xmmregs[j].reg || itinst2->regs[0].VFwrite == xmmregs[j].reg ) { - itinst2 = insts.end(); - break; - } - else { - ++count; - ++itinst2; - } - } - - while(itinst2 != insts.end() ) { - if( itinst2->regs[0].VFread0 == xmmregs[j].reg || itinst2->regs[0].VFread1 == xmmregs[j].reg || itinst2->regs[0].VFwrite == xmmregs[j].reg || - itinst2->regs[1].VFread0 == xmmregs[j].reg || itinst2->regs[1].VFread1 == xmmregs[j].reg || itinst2->regs[1].VFwrite == xmmregs[j].reg) - break; - - ++count; - ++itinst2; - } - xmmregs[j].counter = 1000-count; - } - else { - assert( xmmregs[j].type == XMMTYPE_ACC ); - - int count = 0; - itinst2 = itinst; - - if( i ) ++itinst2; // acc isn't used in lower insts - - while(itinst2 != insts.end() ) { - assert( !((itinst2->regs[0].VIread|itinst2->regs[0].VIwrite) & (1<regs[1].VIread|itinst2->regs[1].VIwrite) & (1<VFread0 ) _addNeededVFtoXMMreg(regs->VFread0); - if( regs->VFread1 ) _addNeededVFtoXMMreg(regs->VFread1); - if( regs->VFwrite ) _addNeededVFtoXMMreg(regs->VFwrite); - if( regs->VIread & (1<VIread & (1<vfread0[i] = itinst->vfread1[i] = itinst->vfwrite[i] = itinst->vfacc[i] = -1; - itinst->vfflush[i] = -1; - - if( regs->VFread0 ) itinst->vfread0[i] = _allocVFtoXMMreg(VU, -1, regs->VFread0, 0); - else if( regs->VIread & (1<vfread0[i] = _allocVFtoXMMreg(VU, -1, 0, 0); - if( regs->VFread1 ) itinst->vfread1[i] = _allocVFtoXMMreg(VU, -1, regs->VFread1, 0); - else if( (regs->VIread & (1<VFr1xyzw != 0xff ) itinst->vfread1[i] = _allocVFtoXMMreg(VU, -1, 0, 0); - if( regs->VIread & (1<vfacc[i] = _allocACCtoXMMreg(VU, -1, 0); - - int reusereg = -1; // 0 - VFwrite, 1 - VFAcc - - if( regs->VFwrite ) { - assert( !(regs->VIwrite&(1<VFwxyzw == 0xf ) { - itinst->vfwrite[i] = _checkXMMreg(XMMTYPE_VFREG, regs->VFwrite, 0); - if( itinst->vfwrite[i] < 0 ) reusereg = 0; - } - else { - itinst->vfwrite[i] = _allocVFtoXMMreg(VU, -1, regs->VFwrite, 0); - } - } - else if( regs->VIwrite & (1<VFwxyzw == 0xf ) { - itinst->vfacc[i] = _checkXMMreg(XMMTYPE_ACC, 0, 0); - if( itinst->vfacc[i] < 0 ) reusereg = 1; - } - else { - itinst->vfacc[i] = _allocACCtoXMMreg(VU, -1, 0); - } - } - - if( reusereg >= 0 ) { - // reuse - itnext = itinst; itnext++; - - u8 type = reusereg ? XMMTYPE_ACC : XMMTYPE_VFREG; - u8 reg = reusereg ? 0 : regs->VFwrite; - - if( itinst->vfacc[i] >= 0 && lastwrite != itinst->vfacc[i] && - (itnext == insts.end() || ((regs->VIread&(1<usedvars[0]&(1<livevars[0]&(1<livevars[0]&(1<vfacc[i]); - xmmregs[itinst->vfacc[i]].inuse = 1; - xmmregs[itinst->vfacc[i]].reg = reg; - xmmregs[itinst->vfacc[i]].type = type; - xmmregs[itinst->vfacc[i]].mode = 0; - itinst->vfwrite[i] = itinst->vfacc[i]; - } - else if( itinst->vfread0[i] >= 0 && lastwrite != itinst->vfread0[i] && - (itnext == insts.end() || (regs->VFread0 > 0 && (!(itnext->usedvars[1]&(1<VFread0)) || !(itnext->livevars[1]&(1<VFread0))))) ) { - - if(itnext == insts.end() || (itnext->livevars[1]®s->VFread0)) _freeXMMreg(itinst->vfread0[i]); - xmmregs[itinst->vfread0[i]].inuse = 1; - xmmregs[itinst->vfread0[i]].reg = reg; - xmmregs[itinst->vfread0[i]].type = type; - xmmregs[itinst->vfread0[i]].mode = 0; - if( reusereg ) itinst->vfacc[i] = itinst->vfread0[i]; - else itinst->vfwrite[i] = itinst->vfread0[i]; - } - else if( itinst->vfread1[i] >= 0 && lastwrite != itinst->vfread1[i] && - (itnext == insts.end() || (regs->VFread1 > 0 && (!(itnext->usedvars[1]&(1<VFread1)) || !(itnext->livevars[1]&(1<VFread1))))) ) { - - if(itnext == insts.end() || (itnext->livevars[1]®s->VFread1)) _freeXMMreg(itinst->vfread1[i]); - xmmregs[itinst->vfread1[i]].inuse = 1; - xmmregs[itinst->vfread1[i]].reg = reg; - xmmregs[itinst->vfread1[i]].type = type; - xmmregs[itinst->vfread1[i]].mode = 0; - if( reusereg ) itinst->vfacc[i] = itinst->vfread1[i]; - else itinst->vfwrite[i] = itinst->vfread1[i]; - } - else { - if( reusereg ) itinst->vfacc[i] = _allocACCtoXMMreg(VU, -1, 0); - else itinst->vfwrite[i] = _allocVFtoXMMreg(VU, -1, regs->VFwrite, 0); - } - } - - if( itinst->vfwrite[i] >= 0 ) lastwrite = itinst->vfwrite[i]; - else if( itinst->vfacc[i] >= 0 ) lastwrite = itinst->vfacc[i]; - - // always alloc at least 1 temp reg - int free0 = (i||regs->VFwrite||regs->VFread0||regs->VFread1||(regs->VIwrite&(1<VIread&(1<vfwrite[1] >= 0 && (itinst->vfread0[0]==itinst->vfwrite[1]||itinst->vfread1[0]==itinst->vfwrite[1]) ) { - itinst->vfflush[i] = _allocTempXMMreg(XMMT_FPS, -1); - } - - if( i == 1 && (regs->VIwrite & (1<VIwrite & (1<vfflush[i] >= 0 ) _freeXMMreg(itinst->vfflush[i]); - if( free0 >= 0 ) _freeXMMreg(free0); - - itinst->vffree[i] = (free0&0xf)|(free1<<8)|(free2<<16); - if( free0 == -1 ) itinst->vffree[i] |= VFFREE_INVALID0; - - _clearNeededXMMregs(); - } - } - - assert( x86Ptr == oldX86 ); - u32 analyzechildren = !(type&BLOCKTYPE_ANALYZED); - type |= BLOCKTYPE_ANALYZED; - - //memset(endregs, 0, sizeof(endregs)); - - if( analyzechildren ) { - FORIT(itchild, blocks) (*itchild)->AssignVFRegs(); - } -} - -struct MARKOVBLANKET -{ - list parents; - list children; -}; - -static MARKOVBLANKET s_markov; - -void VuBaseBlock::AssignVIRegs(int parent) -{ - const int maxregs = 6; - - if( parent ) { - if( (type&BLOCKTYPE_ANALYZEDPARENT) ) - return; - - type |= BLOCKTYPE_ANALYZEDPARENT; - s_markov.parents.push_back(this); - for(LISTBLOCKS::iterator it = blocks.begin(); it != blocks.end(); ++it) { - (*it)->AssignVIRegs(0); - } - return; - } - - if( (type&BLOCKTYPE_ANALYZED) ) - return; - - // child - assert( allocX86Regs == -1 ); - allocX86Regs = s_vecRegArray.size(); - s_vecRegArray.resize(allocX86Regs+iREGCNT_GPR); - - _x86regs* pregs = &s_vecRegArray[allocX86Regs]; - memset(pregs, 0, sizeof(_x86regs)*iREGCNT_GPR); - - assert( parents.size() > 0 ); - - list::iterator itparent; - u32 usedvars = insts.front().usedvars[0]; - u32 livevars = insts.front().livevars[0]; - - if( parents.size() > 0 ) { - u32 usedvars2 = 0xffffffff; - FORIT(itparent, parents) usedvars2 &= (*itparent)->insts.front().usedvars[0]; - usedvars |= usedvars2; - } - - usedvars &= livevars; - - // currently order doesn't matter - int num = 0; - - if( usedvars ) { - for(int i = 1; i < 16; ++i) { - if( usedvars & (1<= maxregs ) break; - } - } - } - - if( num < maxregs) { - livevars &= ~usedvars; - livevars &= insts.back().usedvars[0]; - - if( livevars ) { - for(int i = 1; i < 16; ++i) { - if( livevars & (1<= maxregs) break; - } - } - } - } - - s_markov.children.push_back(this); - type |= BLOCKTYPE_ANALYZED; - FORIT(itparent, parents) { - (*itparent)->AssignVIRegs(1); - } -} - -static void SuperVUAssignRegs() -{ - list::iterator itblock, itblock2; - - FORIT(itblock, s_listBlocks) (*itblock)->type &= ~BLOCKTYPE_ANALYZED; - s_listBlocks.front()->AssignVFRegs(); - - // VI assignments, find markov blanket for each node in the graph - // then allocate regs based on the commonly used ones -#ifdef SUPERVU_X86CACHING - FORIT(itblock, s_listBlocks) (*itblock)->type &= ~(BLOCKTYPE_ANALYZED|BLOCKTYPE_ANALYZEDPARENT); - s_vecRegArray.resize(0); - u8 usedregs[16]; - - // note: first block always has to start with no alloc regs - bool bfirst = true; - - FORIT(itblock, s_listBlocks) { - - if( !((*itblock)->type & BLOCKTYPE_ANALYZED) ) { - - if( (*itblock)->parents.size() == 0 ) { - (*itblock)->type |= BLOCKTYPE_ANALYZED; - bfirst = false; - continue; - } - - s_markov.children.clear(); - s_markov.parents.clear(); - (*itblock)->AssignVIRegs(0); - - // assign the regs - int regid = s_vecRegArray.size(); - s_vecRegArray.resize(regid+iREGCNT_GPR); - - _x86regs* mergedx86 = &s_vecRegArray[regid]; - memset(mergedx86, 0, sizeof(_x86regs)*iREGCNT_GPR); - - if( !bfirst ) { - *(u32*)usedregs = *((u32*)usedregs+1) = *((u32*)usedregs+2) = *((u32*)usedregs+3) = 0; - - FORIT(itblock2, s_markov.children) { - assert( (*itblock2)->allocX86Regs >= 0 ); - _x86regs* pregs = &s_vecRegArray[(*itblock2)->allocX86Regs]; - for(int i = 0; i < iREGCNT_GPR; ++i) { - if( pregs[i].inuse && pregs[i].reg < 16) { - //assert( pregs[i].reg < 16); - usedregs[pregs[i].reg]++; - } - } - } - - int num = 1; - for(int i = 0; i < 16; ++i) { - if( usedregs[i] == s_markov.children.size() ) { - // use - mergedx86[num].inuse = 1; - mergedx86[num].reg = i; - mergedx86[num].type = (s_vu?X86TYPE_VU1:0)|X86TYPE_VI; - mergedx86[num].mode = MODE_READ; - if( ++num >= iREGCNT_GPR ) - break; - if( num == ESP ) - ++num; - } - } - - FORIT(itblock2, s_markov.children) { - assert( (*itblock2)->nStartx86 == -1 ); - (*itblock2)->nStartx86 = regid; - } - - FORIT(itblock2, s_markov.parents) { - assert( (*itblock2)->nEndx86 == -1 ); - (*itblock2)->nEndx86 = regid; - } - } - - bfirst = false; - } - } -#endif -} - -////////////////// -// Recompilation -////////////////// - -// cycles in which the last Q,P regs were finished (written to VU->VI[]) -// the write occurs before the instruction is executed at that cycle -// compare with s_TotalVUCycles -// if less than 0, already flushed -int s_writeQ, s_writeP; - -// declare the saved registers -uptr s_vu1esp, s_callstack;//, s_vu1esp -uptr s_vu1ebp, s_vuebx, s_vuedi, s_vu1esi; - -static int s_recWriteQ, s_recWriteP; // wait times during recompilation -static int s_needFlush; // first bit - Q, second bit - P, third bit - Q has been written, fourth bit - P has been written - -static int s_JumpX86; -static int s_ScheduleXGKICK = 0, s_XGKICKReg = -1; - -void recVUMI_XGKICK_( VURegs *VU ); - -void SuperVUCleanupProgram(u32 startpc, int vuindex) -{ -#ifdef SUPERVU_COUNT - QueryPerformanceCounter(&svufinal); - svutime += (u32)(svufinal.QuadPart-svubase.QuadPart); -#endif - - assert( s_vu1esp == 0 ); - - VU = vuindex ? &VU1 : &VU0; - VU->cycle += s_TotalVUCycles; - - //VU cycle stealing hack, 3000 cycle maximum so it doesn't get out of hand - if (s_TotalVUCycles < 3000) - cpuRegs.cycle += s_TotalVUCycles * Config.Hacks.VUCycleSteal; - else - cpuRegs.cycle += 3000 * Config.Hacks.VUCycleSteal; - - if( (int)s_writeQ > 0 ) VU->VI[REG_Q] = VU->q; - if( (int)s_writeP > 0 ) { - assert(VU == &VU1); - VU1.VI[REG_P] = VU1.p; // only VU1 - } - - //memset(recVUStack, 0, SUPERVU_STACKSIZE * 4); - - // Could clear allocation info to prevent possibly bad data being used in other parts of pcsx2; - // not doing this because it's slow and not needed (rama) - // _initXMMregs(); - // _initMMXregs(); - // _initX86regs(); -} - -#if defined(_MSC_VER) - -// entry point of all vu programs from emulator calls -__declspec(naked) void SuperVUExecuteProgram(u32 startpc, int vuindex) -{ - __asm { - mov eax, dword ptr [esp] - mov s_TotalVUCycles, 0 // necessary to be here! - add esp, 4 - mov s_callstack, eax - call SuperVUGetProgram - - // save cpu state - mov s_vu1ebp, ebp - mov s_vu1esi, esi // have to save even in Release - mov s_vuedi, edi // have to save even in Release - mov s_vuebx, ebx - } -#ifdef _DEBUG - __asm { - mov s_vu1esp, esp - } -#endif - - __asm { - //stmxcsr s_ssecsr - ldmxcsr g_sseVUMXCSR - - // init vars - mov s_writeQ, 0xffffffff - mov s_writeP, 0xffffffff - - jmp eax - } -} - -// exit point of all vu programs -__declspec(naked) static void SuperVUEndProgram() -{ - __asm { - // restore cpu state - ldmxcsr g_sseMXCSR - - mov ebp, s_vu1ebp - mov esi, s_vu1esi - mov edi, s_vuedi - mov ebx, s_vuebx - } - -#ifdef _DEBUG - __asm { - sub s_vu1esp, esp - } -#endif - - __asm { - call SuperVUCleanupProgram - jmp s_callstack // so returns correctly - } -} - -#endif - -// Flushes P/Q regs -void SuperVUFlush(int p, int wait) -{ - u8* pjmp[3]; - if( !(s_needFlush&(1<info.cycle < recwait ) return; - - if( recwait == 0 ) { - // write didn't happen this block - MOV32MtoR(EAX, p ? (uptr)&s_writeP : (uptr)&s_writeQ); - OR32RtoR(EAX, EAX); - pjmp[0] = JS8(0); - - if( s_pCurInst->info.cycle ) SUB32ItoR(EAX, s_pCurInst->info.cycle); - - // if writeQ <= total+offset - if( !wait ) { // only write back if time is up - CMP32MtoR(EAX, (uptr)&s_TotalVUCycles); - pjmp[1] = JG8(0); - } - else { - // add (writeQ-total-offset) to s_TotalVUCycles - // necessary? - CMP32MtoR(EAX, (uptr)&s_TotalVUCycles); - pjmp[2] = JLE8(0); - MOV32RtoM((uptr)&s_TotalVUCycles, EAX); - x86SetJ8(pjmp[2]); - } - } - else if( wait && s_pCurInst->info.cycle < recwait ) { - ADD32ItoM((uptr)&s_TotalVUCycles, recwait); - } - - MOV32MtoR(EAX, SuperVUGetVIAddr(p?REG_P:REG_Q, 0)); - MOV32ItoM(p ? (uptr)&s_writeP : (uptr)&s_writeQ, 0x80000000); - MOV32RtoM(SuperVUGetVIAddr(p?REG_P:REG_Q, 1), EAX); - - if( recwait == 0 ) { - if( !wait ) x86SetJ8(pjmp[1]); - x86SetJ8(pjmp[0]); - } - - if( wait || (!p && recwait == 0 && s_pCurInst->info.cycle >= 12) || (!p && recwait > 0 && s_pCurInst->info.cycle >= recwait ) ) - s_needFlush &= ~(1<::iterator itblock; - - FORIT(itblock, s_listBlocks) (*itblock)->type &= ~BLOCKTYPE_ANALYZED; - s_listBlocks.front()->Recompile(); - // make sure everything compiled - FORIT(itblock, s_listBlocks) assert( ((*itblock)->type & BLOCKTYPE_ANALYZED) && (*itblock)->pcode != NULL ); - - // link all blocks - FORIT(itblock, s_listBlocks) { - VuBaseBlock::LISTBLOCKS::iterator itchild; - - assert( (*itblock)->blocks.size() <= ArraySize((*itblock)->pChildJumps) ); - - int i = 0; - FORIT(itchild, (*itblock)->blocks) { - - if( (u32)(uptr)(*itblock)->pChildJumps[i] == 0xffffffff ) - continue; - - if( (*itblock)->pChildJumps[i] == NULL ) { - VuBaseBlock* pchild = *itchild; - - if( pchild->type & BLOCKTYPE_HASEOP) { - assert( pchild->blocks.size() == 0); - - AND32ItoM( (uptr)&VU0.VI[ REG_VPU_STAT ].UL, s_vu?~0x100:~0x001 ); // E flag - AND32ItoM( (uptr)&VU->vifRegs->stat, ~0x4 ); - - MOV32ItoM((uptr)&VU->VI[REG_TPC], pchild->endpc); - JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr + 5 )); - } - // only other case is when there are two branches - else assert( (*itblock)->insts.back().regs[0].pipe == VUPIPE_BRANCH ); - - continue; - } - - if( (u32)(uptr)(*itblock)->pChildJumps[i] & 0x80000000 ) { - // relative - assert( (uptr)(*itblock)->pChildJumps[i] <= 0xffffffff); - (*itblock)->pChildJumps[i] = (u32*)((uptr)(*itblock)->pChildJumps[i] & 0x7fffffff); - *(*itblock)->pChildJumps[i] = (uptr)(*itchild)->pcode - ((uptr)(*itblock)->pChildJumps[i] + 4); - } - else *(*itblock)->pChildJumps[i] = (uptr)(*itchild)->pcode; - - ++i; - } - } - - s_pFnHeader->pprogfunc = s_listBlocks.front()->pcode; -} - -// debug - - -u32 s_saveecx, s_saveedx, s_saveebx, s_saveesi, s_saveedi, s_saveebp; -u32 g_curdebugvu; - -//float vuDouble(u32 f); - -#if defined(_MSC_VER) -__declspec(naked) static void svudispfn() -{ - __asm { - mov g_curdebugvu, eax - mov s_saveecx, ecx - mov s_saveedx, edx - mov s_saveebx, ebx - mov s_saveesi, esi - mov s_saveedi, edi - mov s_saveebp, ebp - } -#else - -void svudispfntemp() -{ -#endif - -#ifdef _DEBUG - static u32 i; - - if( ((vudump&8) && g_curdebugvu) || ((vudump&0x80) && !g_curdebugvu) ) { //&& g_vu1lastrec != g_vu1last ) { - - if( skipparent != g_vu1lastrec ) { - for(i = 0; i < ArraySize(badaddrs); ++i) { - if( s_svulast == badaddrs[i][1] && g_vu1lastrec == badaddrs[i][0] ) - break; - } - - if( i == ArraySize(badaddrs) ) - { - //static int curesp; - //__asm mov curesp, esp - //Console::WriteLn("tVU: %x %x %x", s_svulast, s_vucount, s_vufnheader); - if( g_curdebugvu ) iDumpVU1Registers(); - else iDumpVU0Registers(); - s_vucount++; - } - } - - g_vu1lastrec = s_svulast; - } -#endif - -#if defined(_MSC_VER) - __asm { - mov ecx, s_saveecx - mov edx, s_saveedx - mov ebx, s_saveebx - mov esi, s_saveesi - mov edi, s_saveedi - mov ebp, s_saveebp - ret - } -#endif -} - -// frees all regs taking into account the livevars -void SuperVUFreeXMMregs(u32* livevars) -{ - for(int i = 0; i < iREGCNT_XMM; ++i) { - if( xmmregs[i].inuse ) { - // same reg - if( (xmmregs[i].mode & MODE_WRITE) ) { - -#ifdef SUPERVU_INTERCACHING - if( xmmregs[i].type == XMMTYPE_VFREG ) { - if( !(livevars[1] & (1<VF[xmmregs[i].reg] : (uptr)&VU->ACC; - - if( xmmregs[i].mode & MODE_VUZ ) { - SSE_MOVHPS_XMM_to_M64(addr, (x86SSERegType)i); - SSE_SHUFPS_M128_to_XMM((x86SSERegType)i, addr, 0xc4); - } - else SSE_MOVHPS_M64_to_XMM((x86SSERegType)i, addr+8); - - xmmregs[i].mode &= ~MODE_VUXYZ; - } - - _freeXMMreg(i); - } - } - } - - //_freeXMMregs(); -} - -void SuperVUTestVU0Condition(u32 incstack) -{ - if( s_vu && !SUPERVU_CHECKCONDITION ) return; // vu0 only - - CMP32ItoM((uptr)&s_TotalVUCycles, 512); // sometimes games spin on vu0, so be careful with this value - // woody hangs if too high - - if( incstack ) { - u8* ptr = JB8(0); - - ADD32ItoR(ESP, incstack); - //CALLFunc((u32)timeout); - JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr + 5 )); - - x86SetJ8(ptr); - } - else JAE32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr + 6 ) ); -} - -void VuBaseBlock::Recompile() -{ - if( type & BLOCKTYPE_ANALYZED ) return; - - x86Align(16); - pcode = x86Ptr; - -#ifdef _DEBUG - MOV32ItoM((uptr)&s_vufnheader, s_pFnHeader->startpc); - MOV32ItoM((uptr)&VU->VI[REG_TPC], startpc); - MOV32ItoM((uptr)&s_svulast, startpc); - list::iterator itparent; - for(itparent = parents.begin(); itparent != parents.end(); ++itparent) { - if( (*itparent)->blocks.size()==1 && (*itparent)->blocks.front()->startpc == startpc && - ((*itparent)->insts.size() < 2 || (----(*itparent)->insts.end())->regs[0].pipe != VUPIPE_BRANCH) ) { - MOV32ItoM((uptr)&skipparent, (*itparent)->startpc); - break; - } - } - - if( itparent == parents.end() ) MOV32ItoM((uptr)&skipparent, -1); - - MOV32ItoR(EAX, s_vu); - CALLFunc((uptr)svudispfn); -#endif - - s_pCurBlock = this; - s_needFlush = 3; - pc = startpc; - branch = 0; - s_recWriteQ = s_recWriteP = 0; - s_XGKICKReg = -1; - s_ScheduleXGKICK = 0; - - s_ClipRead = s_PrevClipWrite = (uptr)&VU->VI[REG_CLIP_FLAG]; - s_StatusRead = s_PrevStatusWrite = (uptr)&VU->VI[REG_STATUS_FLAG]; - s_MACRead = s_PrevMACWrite = (uptr)&VU->VI[REG_MAC_FLAG]; - s_PrevIWrite = (uptr)&VU->VI[REG_I]; - s_JumpX86 = 0; - s_UnconditionalDelay = 0; - - memcpy(xmmregs, startregs, sizeof(xmmregs)); -#ifdef SUPERVU_X86CACHING - if( nStartx86 >= 0 ) - memcpy(x86regs, &s_vecRegArray[nStartx86], sizeof(x86regs)); - else _initX86regs(); -#else - _initX86regs(); -#endif - - list::iterator itinst; - FORIT(itinst, insts) { - s_pCurInst = &(*itinst); - if( s_JumpX86 > 0 ) { - if( !x86regs[s_JumpX86].inuse ) { - // load - s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_READ); - } - x86regs[s_JumpX86].needed = 1; - } - - if( s_ScheduleXGKICK && s_XGKICKReg > 0 ) { - assert( x86regs[s_XGKICKReg].inuse ); - x86regs[s_XGKICKReg].needed = 1; - } - itinst->Recompile(itinst, vuxyz); - - if( s_ScheduleXGKICK > 0 ) { - if( s_ScheduleXGKICK-- == 1 ) { - recVUMI_XGKICK_(VU); - } - } - } - assert( pc == endpc ); - assert( s_ScheduleXGKICK == 0 ); - - // flush flags - if( s_PrevClipWrite != (uptr)&VU->VI[REG_CLIP_FLAG] ) { - MOV32MtoR(EAX, s_PrevClipWrite); - MOV32RtoM((uptr)&VU->VI[REG_CLIP_FLAG], EAX); - } - if( s_PrevStatusWrite != (uptr)&VU->VI[REG_STATUS_FLAG] ) { - MOV32MtoR(EAX, s_PrevStatusWrite); - MOV32RtoM((uptr)&VU->VI[REG_STATUS_FLAG], EAX); - } - if( s_PrevMACWrite != (uptr)&VU->VI[REG_MAC_FLAG] ) { - MOV32MtoR(EAX, s_PrevMACWrite); - MOV32RtoM((uptr)&VU->VI[REG_MAC_FLAG], EAX); - } -// if( s_StatusRead != (uptr)&VU->VI[REG_STATUS_FLAG] ) { -// // only lower 8 bits valid! -// MOVZX32M8toR(EAX, s_StatusRead); -// MOV32RtoM((uptr)&VU->VI[REG_STATUS_FLAG], EAX); -// } -// if( s_MACRead != (uptr)&VU->VI[REG_MAC_FLAG] ) { -// // only lower 8 bits valid! -// MOVZX32M8toR(EAX, s_MACRead); -// MOV32RtoM((uptr)&VU->VI[REG_MAC_FLAG], EAX); -// } - if( s_PrevIWrite != (uptr)&VU->VI[REG_I] ) { - MOV32ItoM((uptr)&VU->VI[REG_I], *(u32*)s_PrevIWrite); // never changes - } - - ADD32ItoM((uptr)&s_TotalVUCycles, cycles); - - // compute branches, jumps, eop - if( type & BLOCKTYPE_HASEOP ) { - // end - _freeXMMregs(); - _freeX86regs(); - AND32ItoM( (uptr)&VU0.VI[ REG_VPU_STAT ].UL, s_vu?~0x100:~0x001 ); // E flag - AND32ItoM( (uptr)&VU->vifRegs->stat, ~0x4 ); - if( !branch ) MOV32ItoM((uptr)&VU->VI[REG_TPC], endpc); - JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr + 5 )); - } - else { - - u32 livevars[2] = {0}; - - list::iterator lastinst = GetInstIterAtPc(endpc-8); - lastinst++; - - if( lastinst != insts.end() ) { - livevars[0] = lastinst->livevars[0]; - livevars[1] = lastinst->livevars[1]; - } - else { - // take from children - if( blocks.size() > 0 ) { - LISTBLOCKS::iterator itchild; - FORIT(itchild, blocks) { - livevars[0] |= (*itchild)->insts.front().livevars[0]; - livevars[1] |= (*itchild)->insts.front().livevars[1]; - } - } - else { - livevars[0] = ~0; - livevars[1] = ~0; - } - } - - SuperVUFreeXMMregs(livevars); - - // get rid of any writes, otherwise _freeX86regs will write - x86regs[s_JumpX86].mode &= ~MODE_WRITE; - - if( branch == 1 ) { - if( !x86regs[s_JumpX86].inuse ) { - assert( x86regs[s_JumpX86].type == X86TYPE_VUJUMP ); - s_JumpX86 = 0xffffffff; // notify to jump from g_recWriteback - } - } - - // align VI regs -#ifdef SUPERVU_X86CACHING - if( nEndx86 >= 0 ) { - _x86regs* endx86 = &s_vecRegArray[nEndx86]; - for(int i = 0; i < iREGCNT_GPR; ++i) { - if( endx86[i].inuse ) { - - if( s_JumpX86 == i && x86regs[s_JumpX86].inuse ) { - x86regs[s_JumpX86].inuse = 0; - x86regs[EAX].inuse = 1; - MOV32RtoR(EAX, s_JumpX86); - s_JumpX86 = EAX; - } - - if( x86regs[i].inuse ) { - if( x86regs[i].type == endx86[i].type && x86regs[i].reg == endx86[i].reg ) { - _freeX86reg(i); - // will continue to use it - continue; - } - - if( x86regs[i].type == (X86TYPE_VI|(s_vu?X86TYPE_VU1:0)) ) { -#ifdef SUPERVU_INTERCACHING - if( livevars[0] & (1<startpc); - - switch(branch) { - case 1: // branch, esi has new prog - - SuperVUTestVU0Condition(0); - - if( s_JumpX86 == 0xffffffff ) - JMP32M((uptr)&g_recWriteback); - else - JMPR(s_JumpX86); - - break; - case 4: // jalr - pChildJumps[0] = (u32*)0xffffffff; - // fall through - - case 0x10: // jump, esi has new vupc - { - _freeXMMregs(); - _freeX86regs(); - - SuperVUTestVU0Condition(8); - - // already onto stack - CALLFunc((uptr)SuperVUGetProgram); - ADD32ItoR(ESP, 8); - JMPR(EAX); - break; - } - - case 0x13: // jr with uncon branch, uncond branch takes precendence (dropship) - { -// s32 delta = (s32)(VU->code & 0x400 ? 0xfffffc00 | (VU->code & 0x3ff) : VU->code & 0x3ff) << 3; -// ADD32ItoRmOffset(ESP, delta, 0); - - ADD32ItoR(ESP, 8); // restore - pChildJumps[0] = (u32*)((uptr)JMP32(0)|0x80000000); - break; - } - case 0: - case 3: // unconditional branch - pChildJumps[s_UnconditionalDelay] = (u32*)((uptr)JMP32(0)|0x80000000); - break; - - default: - DevCon::Error("Bad branch %x\n", params branch); - assert(0); - break; - } - } - - pendcode = x86Ptr; - type |= BLOCKTYPE_ANALYZED; - - LISTBLOCKS::iterator itchild; - FORIT(itchild, blocks) { - (*itchild)->Recompile(); - } -} - -#define GET_VUXYZMODE(reg) 0//((vuxyz&(1<<(reg)))?MODE_VUXYZ:0) - -int VuInstruction::SetCachedRegs(int upper, u32 vuxyz) -{ - if( vfread0[upper] >= 0 ) { - SuperVUFreeXMMreg(vfread0[upper], XMMTYPE_VFREG, regs[upper].VFread0); - _allocVFtoXMMreg(VU, vfread0[upper], regs[upper].VFread0, MODE_READ|GET_VUXYZMODE(regs[upper].VFread0)); - } - if( vfread1[upper] >= 0 ) { - SuperVUFreeXMMreg(vfread1[upper], XMMTYPE_VFREG, regs[upper].VFread1); - _allocVFtoXMMreg(VU, vfread1[upper], regs[upper].VFread1, MODE_READ|GET_VUXYZMODE(regs[upper].VFread1)); - } - if( vfacc[upper] >= 0 && (regs[upper].VIread&(1<= 0 ) { - assert( regs[upper].VFwrite > 0); - SuperVUFreeXMMreg(vfwrite[upper], XMMTYPE_VFREG, regs[upper].VFwrite); - _allocVFtoXMMreg(VU, vfwrite[upper], regs[upper].VFwrite, - MODE_WRITE|(regs[upper].VFwxyzw != 0xf?MODE_READ:0)|GET_VUXYZMODE(regs[upper].VFwrite)); - } - if( vfacc[upper] >= 0 && (regs[upper].VIwrite&(1<= 0 ) info |= PROCESS_EE_SET_S(vfread0[upper]); - if( vfread1[upper] >= 0 ) info |= PROCESS_EE_SET_T(vfread1[upper]); - if( vfacc[upper] >= 0 ) info |= PROCESS_VU_SET_ACC(vfacc[upper]); - if( vfwrite[upper] >= 0 ) { - if( regs[upper].VFwrite == _Ft_ && vfread1[upper] < 0 ) { - info |= PROCESS_EE_SET_T(vfwrite[upper]); - } - else { - assert( regs[upper].VFwrite == _Fd_ ); - info |= PROCESS_EE_SET_D(vfwrite[upper]); - } - } - - if( !(vffree[upper]&VFFREE_INVALID0) ) { - SuperVUFreeXMMreg(vffree[upper]&0xf, XMMTYPE_TEMP, 0); - _allocTempXMMreg(XMMT_FPS, vffree[upper]&0xf); - } - info |= PROCESS_VU_SET_TEMP(vffree[upper]&0xf); - - if( vfflush[upper] >= 0 ) { - SuperVUFreeXMMreg(vfflush[upper], XMMTYPE_TEMP, 0); - _allocTempXMMreg(XMMT_FPS, vfflush[upper]); - } - - if( upper && (regs[upper].VIwrite & (1 << REG_CLIP_FLAG)) ) { - // CLIP inst, need two extra temp registers, put it EEREC_D and EEREC_ACC - assert( vfwrite[upper] == -1 ); - SuperVUFreeXMMreg((vffree[upper]>>8)&0xf, XMMTYPE_TEMP, 0); - _allocTempXMMreg(XMMT_FPS, (vffree[upper]>>8)&0xf); - info |= PROCESS_EE_SET_D((vffree[upper]>>8)&0xf); - - SuperVUFreeXMMreg((vffree[upper]>>16)&0xf, XMMTYPE_TEMP, 0); - _allocTempXMMreg(XMMT_FPS, (vffree[upper]>>16)&0xf); - info |= PROCESS_EE_SET_ACC((vffree[upper]>>16)&0xf); - - _freeXMMreg((vffree[upper]>>8)&0xf); // don't need anymore - _freeXMMreg((vffree[upper]>>16)&0xf); // don't need anymore - } - else if( regs[upper].VIwrite & (1<>8)&0xf, XMMTYPE_TEMP, 0); - _allocTempXMMreg(XMMT_FPS, (vffree[upper]>>8)&0xf); - info |= PROCESS_EE_SET_D((vffree[upper]>>8)&0xf); - _freeXMMreg((vffree[upper]>>8)&0xf); // don't need anymore - } - - if( vfflush[upper] >= 0 ) _freeXMMreg(vfflush[upper]); - if( !(vffree[upper]&VFFREE_INVALID0) ) - _freeXMMreg(vffree[upper]&0xf); // don't need anymore - - if( (regs[0].VIwrite|regs[1].VIwrite) & ((1<::iterator& itinst, u32 vuxyz) -{ - //static PCSX2_ALIGNED16(VECTOR _VF); - //static PCSX2_ALIGNED16(VECTOR _VFc); - u32 *ptr; - u8* pjmp; - int vfregstore=0; - - assert( s_pCurInst == this); - s_WriteToReadQ = 0; - - ptr = (u32*)&VU->Micro[ pc ]; - - if( type & INST_Q_READ ) - SuperVUFlush(0, (ptr[0] == 0x800003bf)||!!(regs[0].VIwrite & (1<startpc || nParentPc >= (int)pc) ) { - -// if( !s_vu ) { -// for(int j = 0; j < ARRAYSIZE(badaddrs); ++j) { -// if( badaddrs[j] == nParentPc ) -// goto NoParent; -// } -// } - - list::iterator itblock; - FORIT(itblock, s_listBlocks) { - if( nParentPc >= (*itblock)->startpc && nParentPc < (*itblock)->endpc ) { - pparentinst = &(*(*itblock)->GetInstIterAtPc(nParentPc)); - //if( !s_vu ) SysPrintf("%x ", nParentPc); - if( find(s_pCurBlock->parents.begin(), s_pCurBlock->parents.end(), *itblock) != s_pCurBlock->parents.end() ) - nParentCheckForExecution = (*itblock)->startpc; - break; - } - } - - assert( pparentinst != NULL ); - } -#endif - - if( type & INST_CLIP_WRITE ) { - if( nParentPc < s_pCurBlock->startpc || nParentPc >= (int)pc ) { - - if( !CHECK_VUCLIPFLAGHACK && pparentinst != NULL ) { - - if( nParentCheckForExecution >= 0 ) { - if( pparentinst->pClipWrite == 0 ) - pparentinst->pClipWrite = (uptr)SuperVUStaticAlloc(4); - - if( s_ClipRead == 0 ) - s_ClipRead = (uptr)&VU->VI[REG_CLIP_FLAG]; - - CMP32ItoM((uptr)&g_nLastBlockExecuted, nParentCheckForExecution); - u8* jptr = JNE8(0); - CMP32ItoM((uptr)&s_ClipRead, (uptr)&VU->VI[REG_CLIP_FLAG]); - u8* jptr2 = JE8(0); - MOV32MtoR(EAX, pparentinst->pClipWrite); - MOV32RtoM(s_ClipRead, EAX); - x86SetJ8(jptr); - x86SetJ8(jptr2); - } - } - else s_ClipRead = (uptr)&VU->VI[REG_CLIP_FLAG]; - } - else { - s_ClipRead = s_pCurBlock->GetInstIterAtPc(nParentPc)->pClipWrite; - if (s_ClipRead == 0) Console::WriteLn("super ClipRead allocation error!"); - } - } - - // before modifying, check if they will ever be read - if( s_pCurBlock->type & BLOCKTYPE_MACFLAGS ) { - - u8 outofblock=0; - if( type & INST_STATUS_WRITE ) { - - if( nParentPc < s_pCurBlock->startpc || nParentPc >= (int)pc ) { - - // reading from out of this block, so already flushed to mem - if( pparentinst != NULL ) { //&& pparentinst->pStatusWrite != NULL ) { - - // might not have processed it yet, so reserve a mem loc - if( pparentinst->pStatusWrite == 0 ) { - pparentinst->pStatusWrite = (uptr)SuperVUStaticAlloc(4); - //MOV32ItoM(pparentinst->pStatusWrite, 0); - } - -// if( s_pCurBlock->prevFlagsOutOfBlock && s_StatusRead != NULL ) { -// // or instead since don't now which parent we came from -// MOV32MtoR(EAX, pparentinst->pStatusWrite); -// OR32RtoM(s_StatusRead, EAX); -// MOV32ItoM(pparentinst->pStatusWrite, 0); -// } - - if( nParentCheckForExecution >= 0 ) { - - // don't now which parent we came from, so have to check -// uptr tempstatus = (uptr)SuperVUStaticAlloc(4); -// if( s_StatusRead != NULL ) -// MOV32MtoR(EAX, s_StatusRead); -// else -// MOV32MtoR(EAX, (uptr)&VU->VI[REG_STATUS_FLAG]); -// s_StatusRead = tempstatus; - if( s_StatusRead == 0 ) - s_StatusRead = (uptr)&VU->VI[REG_STATUS_FLAG]; - - CMP32ItoM((uptr)&g_nLastBlockExecuted, nParentCheckForExecution); - u8* jptr = JNE8(0); - MOV32MtoR(EAX, pparentinst->pStatusWrite); - MOV32ItoM(pparentinst->pStatusWrite, 0); - MOV32RtoM(s_StatusRead, EAX); - x86SetJ8(jptr); - } - else { - uptr tempstatus = (uptr)SuperVUStaticAlloc(4); - MOV32MtoR(EAX, pparentinst->pStatusWrite); - MOV32RtoM(tempstatus, EAX); - MOV32ItoM(pparentinst->pStatusWrite, 0); - s_StatusRead = tempstatus; - } - - outofblock = 2; - } - else - s_StatusRead = (uptr)&VU->VI[REG_STATUS_FLAG]; - } - else { - s_StatusRead = s_pCurBlock->GetInstIterAtPc(nParentPc)->pStatusWrite; - if (s_StatusRead == 0) Console::WriteLn("super StatusRead allocation error!"); -// if( pc >= (u32)s_pCurBlock->endpc-8 ) { -// // towards the end, so variable might be leaded to another block (silent hill 4) -// uptr tempstatus = (uptr)SuperVUStaticAlloc(4); -// MOV32MtoR(EAX, s_StatusRead); -// MOV32RtoM(tempstatus, EAX); -// MOV32ItoM(s_StatusRead, 0); -// s_StatusRead = tempstatus; -// } - } - } - if( type & INST_MAC_WRITE ) { - - if( nParentPc < s_pCurBlock->startpc || nParentPc >= (int)pc ) { - // reading from out of this block, so already flushed to mem - - if( pparentinst != NULL ) {//&& pparentinst->pMACWrite != NULL ) { - // necessary for (katamari) - // towards the end, so variable might be leaked to another block (silent hill 4) - - // might not have processed it yet, so reserve a mem loc - if( pparentinst->pMACWrite == 0 ) { - pparentinst->pMACWrite = (uptr)SuperVUStaticAlloc(4); - //MOV32ItoM(pparentinst->pMACWrite, 0); - } - -// if( s_pCurBlock->prevFlagsOutOfBlock && s_MACRead != NULL ) { -// // or instead since don't now which parent we came from -// MOV32MtoR(EAX, pparentinst->pMACWrite); -// OR32RtoM(s_MACRead, EAX); -// MOV32ItoM(pparentinst->pMACWrite, 0); -// } - if( nParentCheckForExecution >= 0 ) { - - // don't now which parent we came from, so have to check -// uptr tempmac = (uptr)SuperVUStaticAlloc(4); -// if( s_MACRead != NULL ) -// MOV32MtoR(EAX, s_MACRead); -// else -// MOV32MtoR(EAX, (uptr)&VU->VI[REG_MAC_FLAG]); -// s_MACRead = tempmac; - - if( s_MACRead == 0 ) - s_MACRead = (uptr)&VU->VI[REG_MAC_FLAG]; - - CMP32ItoM((uptr)&g_nLastBlockExecuted, nParentCheckForExecution); - u8* jptr = JNE8(0); - MOV32MtoR(EAX, pparentinst->pMACWrite); - MOV32ItoM(pparentinst->pMACWrite, 0); - MOV32RtoM(s_MACRead, EAX); - x86SetJ8(jptr); - } - else { - uptr tempMAC = (uptr)SuperVUStaticAlloc(4); - MOV32MtoR(EAX, pparentinst->pMACWrite); - MOV32RtoM(tempMAC, EAX); - MOV32ItoM(pparentinst->pMACWrite, 0); - s_MACRead = tempMAC; - } - - outofblock = 2; - } - else - s_MACRead = (uptr)&VU->VI[REG_MAC_FLAG]; - -// if( pc >= (u32)s_pCurBlock->endpc-8 ) { -// // towards the end, so variable might be leaked to another block (silent hill 4) -// uptr tempMAC = (uptr)SuperVUStaticAlloc(4); -// MOV32MtoR(EAX, s_MACRead); -// MOV32RtoM(tempMAC, EAX); -// MOV32ItoM(s_MACRead, 0); -// s_MACRead = tempMAC; -// } - } - else { - s_MACRead = s_pCurBlock->GetInstIterAtPc(nParentPc)->pMACWrite; - } - } - - s_pCurBlock->prevFlagsOutOfBlock = outofblock; - } - else if( pparentinst != NULL) { - // make sure to reset the mac and status flags! (katamari) - if( pparentinst->pStatusWrite) - MOV32ItoM(pparentinst->pStatusWrite, 0); - if( pparentinst->pMACWrite) - MOV32ItoM(pparentinst->pMACWrite, 0); - } - - assert( s_ClipRead != 0 ); - assert( s_MACRead != 0 ); - assert( s_StatusRead != 0 ); - - return; - } - - s_pCurBlock->prevFlagsOutOfBlock = 0; - -#ifdef _DEBUG - MOV32ItoR(EAX, pc); -#endif - - assert( !(type & (INST_CLIP_WRITE|INST_STATUS_WRITE|INST_MAC_WRITE)) ); - pc += 8; - - list::const_iterator itinst2; - - if( (regs[0].VIwrite|regs[1].VIwrite) & ((1<type & BLOCKTYPE_MACFLAGS ) { - if( pMACWrite == 0 ) { - pMACWrite = (uptr)SuperVUStaticAlloc(4); - //MOV32ItoM(pMACWrite, 0); - } - if( pStatusWrite == 0 ) { - pStatusWrite = (uptr)SuperVUStaticAlloc(4); - //MOV32ItoM(pStatusWrite, 0); - } - } - else { - assert( s_StatusRead == (uptr)&VU->VI[REG_STATUS_FLAG] ); - assert( s_MACRead == (uptr)&VU->VI[REG_MAC_FLAG] ); - pMACWrite = s_MACRead; - pStatusWrite = s_StatusRead; - } - } - - if( (pClipWrite == 0) && ((regs[0].VIwrite|regs[1].VIwrite) & (1<insts.end() ) { - if( (itinst2->regs[0].VIread|itinst2->regs[0].VIwrite|itinst2->regs[1].VIread|itinst2->regs[1].VIwrite) && (1<flags, VUFLAG_MFLAGSET); - } - if (ptr[1] & 0x10000000) { // D flag - TEST32ItoM((uptr)&VU0.VI[REG_FBRST].UL, s_vu?0x400:0x004); - u8* ptr = JZ8(0); - OR32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, s_vu?0x200:0x002); - _callFunctionArg1((uptr)hwIntcIrq, MEM_CONSTTAG, s_vu?INTC_VU1:INTC_VU0); - x86SetJ8(ptr); - } - if (ptr[1] & 0x08000000) { // T flag - TEST32ItoM((uptr)&VU0.VI[REG_FBRST].UL, s_vu?0x800:0x008); - u8* ptr = JZ8(0); - OR32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, s_vu?0x400:0x004); - _callFunctionArg1((uptr)hwIntcIrq, MEM_CONSTTAG, s_vu?INTC_VU1:INTC_VU0); - x86SetJ8(ptr); - } - - // check upper flags - if (ptr[1] & 0x80000000) { // I flag - - assert( !(regs[0].VIwrite & ((1<code = ptr[1]; - s_vuInfo = SetCachedRegs(1, vuxyz); - if( s_JumpX86 > 0 ) x86regs[s_JumpX86].needed = 1; - if( s_ScheduleXGKICK && s_XGKICKReg > 0 ) x86regs[s_XGKICKReg].needed = 1; - - recVU_UPPER_OPCODE[ VU->code & 0x3f ]( VU, s_vuInfo ); - - s_PrevIWrite = (uptr)ptr; - _clearNeededXMMregs(); - _clearNeededX86regs(); - } - else { - if( regs[0].VIwrite & (1<insts.end()); - u32* codeptr2 = ptr+2; - - while(itinst2 != s_pCurBlock->insts.end() ) { - if( !(itinst2->type & INST_DUMMY) && ((itinst2->regs[0].VIwrite&(1<type & INST_Q_WRITE) && itinst2->nParentPc == pc-8 ) { - break; - } - if( itinst2->type & INST_Q_READ ) { - cacheq = 1; - break; - } - if( itinst2->type & INST_DUMMY ) { - ++itinst2; - continue; - } - codeptr2 += 2; - ++itinst2; - } - - if( itinst2 == s_pCurBlock->insts.end() ) - cacheq = 1; - - int x86temp = -1; - if( cacheq ) - x86temp = _allocX86reg(-1, X86TYPE_TEMP, 0, 0); - - // new is written so flush old - // if type & INST_Q_READ, already flushed - if( !(type & INST_Q_READ) && s_recWriteQ == 0 ) MOV32MtoR(EAX, (uptr)&s_writeQ); - - if( cacheq ) - MOV32MtoR(x86temp, (uptr)&s_TotalVUCycles); - - if( !(type & INST_Q_READ) ) { - if( s_recWriteQ == 0 ) { - OR32RtoR(EAX, EAX); - pjmp = JS8(0); - MOV32MtoR(EAX, SuperVUGetVIAddr(REG_Q, 0)); - MOV32RtoM(SuperVUGetVIAddr(REG_Q, 1), EAX); - x86SetJ8(pjmp); - } - else if( s_needFlush & 1 ) { - MOV32MtoR(EAX, SuperVUGetVIAddr(REG_Q, 0)); - MOV32RtoM(SuperVUGetVIAddr(REG_Q, 1), EAX); - s_needFlush &= ~1; - } - } - - // write new Q - if( cacheq ) { - assert(s_pCurInst->pqcycles>1); - ADD32ItoR(x86temp, s_pCurInst->info.cycle+s_pCurInst->pqcycles); - MOV32RtoM((uptr)&s_writeQ, x86temp); - s_needFlush |= 1; - } - else { - // won't be writing back - s_WriteToReadQ = 1; - s_needFlush &= ~1; - MOV32ItoM((uptr)&s_writeQ, 0x80000001); - } - - s_recWriteQ = s_pCurInst->info.cycle+s_pCurInst->pqcycles; - - if( x86temp >= 0 ) - _freeX86reg(x86temp); - } - - if( regs[0].VIwrite & (1<pqcycles>1); - ADD32ItoR(x86temp, s_pCurInst->info.cycle+s_pCurInst->pqcycles); - MOV32RtoM((uptr)&s_writeP, x86temp); - s_needFlush |= 2; - - s_recWriteP = s_pCurInst->info.cycle+s_pCurInst->pqcycles; - - _freeX86reg(x86temp); - } - - if( ptr[0] == 0x800003bf ) // waitq - SuperVUFlush(0, 1); - - if( ptr[0] == 0x800007bf ) // waitp - SuperVUFlush(1, 1); - -#ifdef PCSX2_DEVBUILD - if ( regs[1].VIread & regs[0].VIwrite & ~((1<startpc); - } -#endif - - u32 modewrite = 0; - if( vfwrite[1] >= 0 && xmmregs[vfwrite[1]].inuse && xmmregs[vfwrite[1]].type == XMMTYPE_VFREG && xmmregs[vfwrite[1]].reg == regs[1].VFwrite ) - modewrite = xmmregs[vfwrite[1]].mode & MODE_WRITE; - - VU->code = ptr[1]; - s_vuInfo = SetCachedRegs(1, vuxyz); - - if (vfwrite[1] >= 0) { - assert( regs[1].VFwrite > 0 ); - - if (vfwrite[0] == vfwrite[1]) { - //Console::WriteLn("*PCSX2*: Warning, VF write to the same reg in both lower/upper cycle %x", params s_pCurBlock->startpc); - } - - if (vfread0[0] == vfwrite[1] || vfread1[0] == vfwrite[1] ) { - assert( regs[0].VFread0 == regs[1].VFwrite || regs[0].VFread1 == regs[1].VFwrite ); - assert( vfflush[0] >= 0 ); - if( modewrite ) { - SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[regs[1].VFwrite], (x86SSERegType)vfwrite[1]); - } - vfregstore = 1; - } - } - - if( s_JumpX86 > 0 ) x86regs[s_JumpX86].needed = 1; - if( s_ScheduleXGKICK && s_XGKICKReg > 0 ) x86regs[s_XGKICKReg].needed = 1; - - recVU_UPPER_OPCODE[ VU->code & 0x3f ]( VU, s_vuInfo ); - _clearNeededXMMregs(); - _clearNeededX86regs(); - - // necessary because status can be set by both upper and lower - if( regs[1].VIwrite & (1<code = ptr[0]; - s_vuInfo = SetCachedRegs(0, vuxyz); - - if( vfregstore ) { - // load - SSE_MOVAPS_M128_to_XMM(vfflush[0], (uptr)&VU->VF[regs[1].VFwrite]); - - assert( xmmregs[vfwrite[1]].mode & MODE_WRITE ); - - // replace with vfflush - if( _Fs_ == regs[1].VFwrite ) { - s_vuInfo &= ~PROCESS_EE_SET_S(0xf); - s_vuInfo |= PROCESS_EE_SET_S(vfflush[0]); - } - if( _Ft_ == regs[1].VFwrite ) { - s_vuInfo &= ~PROCESS_EE_SET_T(0xf); - s_vuInfo |= PROCESS_EE_SET_T(vfflush[0]); - } - - xmmregs[vfflush[0]].mode |= MODE_NOFLUSH|MODE_WRITE; // so that lower inst doesn't flush - } - - // notify vuinsts that upper inst is a fmac - if( regs[1].pipe == VUPIPE_FMAC ) - s_vuInfo |= PROCESS_VU_SET_FMAC(); - - if( s_JumpX86 > 0 ) x86regs[s_JumpX86].needed = 1; - if( s_ScheduleXGKICK && s_XGKICKReg > 0 ) x86regs[s_XGKICKReg].needed = 1; - -#ifdef SUPERVU_VIBRANCHDELAY - if ( type & INST_CACHE_VI ) { - assert( vicached >= 0 ); - int cachedreg = _allocX86reg(-1, X86TYPE_VI|(s_vu?X86TYPE_VU1:0), vicached, MODE_READ); - MOV32RtoM((uptr)&s_VIBranchDelay, cachedreg); - } -#endif - - // check if inst before branch and the write is the same as the read in the branch (wipeout) -// int oldreg=0; -// if( pc == s_pCurBlock->endpc-16 ) { -// itinst2 = itinst; ++itinst2; -// if( itinst2->regs[0].pipe == VUPIPE_BRANCH && (itinst->regs[0].VIwrite&itinst2->regs[0].VIread) ) { -// -// CALLFunc((u32)branchfn); -// assert( itinst->regs[0].VIwrite & 0xffff ); -// Console::WriteLn("vi write before branch"); -// for(s_CacheVIReg = 0; s_CacheVIReg < 16; ++s_CacheVIReg) { -// if( itinst->regs[0].VIwrite & (1<endpc-8 && s_CacheVIReg >= 0 ) { -// assert( s_CacheVIX86 > 0 && x86regs[s_CacheVIX86].inuse && x86regs[s_CacheVIX86].reg == s_CacheVIReg && x86regs[s_CacheVIX86].type == X86TYPE_VITEMP ); -// -// oldreg = _allocX86reg(-1, X86TYPE_VI|(s_vu?X86TYPE_VU1:0), s_CacheVIReg, MODE_READ); -// x86regs[s_CacheVIX86].needed = 1; -// assert( x86regs[oldreg].mode & MODE_WRITE ); -// -// x86regs[s_CacheVIX86].type = X86TYPE_VI|(s_vu?X86TYPE_VU1:0); -// x86regs[oldreg].type = X86TYPE_VITEMP; -// } - - recVU_LOWER_OPCODE[ VU->code >> 25 ]( VU, s_vuInfo ); - -// if( pc == s_pCurBlock->endpc-8 && s_CacheVIReg >= 0 ) { -// // revert -// x86regs[s_CacheVIX86].inuse = 0; -// x86regs[oldreg].type = X86TYPE_VI|(s_vu?X86TYPE_VU1:0); -// } - - _clearNeededXMMregs(); - _clearNeededX86regs(); - } - - // clip is always written so ok - if( (regs[0].VIwrite|regs[1].VIwrite) & (1<code); - int curjump = 0; - - if( s_pCurInst->type & INST_BRANCH_DELAY ) { - assert( (branch&0x17)!=0x10 && (branch&0x17)!=4 ); // no jump handlig for now - - if( (branch & 0x7) == 3 ) { - // previous was a direct jump - curjump = 1; - } - else if( branch & 1 ) curjump = 2; - } - - assert( s_JumpX86 > 0 ); - - if( (s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION) - MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), bpc); - MOV32ItoR(s_JumpX86, 1); // use 1 to disable optimization to XOR - s_pCurBlock->pChildJumps[curjump] = (u32*)x86Ptr-1; - - if( !(s_pCurInst->type & INST_BRANCH_DELAY) ) { - j8Ptr[1] = JMP8(0); - x86SetJ8( j8Ptr[ 0 ] ); - - if( (s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION ) - MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), pc+8); - MOV32ItoR(s_JumpX86, 1); // use 1 to disable optimization to XOR - s_pCurBlock->pChildJumps[curjump+1] = (u32*)x86Ptr-1; - - x86SetJ8( j8Ptr[ 1 ] ); - } - else - x86SetJ8( j8Ptr[ 0 ] ); - - branch |= 1; -} - -// supervu specific insts -void recVUMI_IBQ_prep() -{ - int fsreg, ftreg; - - if( _Fs_ == 0 ) { -#ifdef SUPERVU_VIBRANCHDELAY - if( s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Ft_ ) { - ftreg = -1; - } - else -#endif - { - ftreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Ft_, MODE_READ); - } - - s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); - - if( ftreg >= 0 ) { - CMP16ItoR( ftreg, 0 ); - } - else CMP16ItoM(SuperVUGetVIAddr(_Ft_, 1), 0); - } - else if( _Ft_ == 0 ) { -#ifdef SUPERVU_VIBRANCHDELAY - if( s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Fs_ ) { - fsreg = -1; - } - else -#endif - { - fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_READ); - } - - s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); - - if( fsreg >= 0 ) { - CMP16ItoR( fsreg, 0 ); - } - else CMP16ItoM(SuperVUGetVIAddr(_Fs_, 1), 0); - - } - else { - _addNeededX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Ft_); - -#ifdef SUPERVU_VIBRANCHDELAY - if( s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Fs_ ) { - fsreg = -1; - } - else -#endif - { - fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_READ); - } - -#ifdef SUPERVU_VIBRANCHDELAY - if( s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Ft_ ) { - ftreg = -1; - - if( fsreg <= 0 ) { - // allocate fsreg - if( s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Fs_ ) { - fsreg = _allocX86reg(-1, X86TYPE_TEMP, 0, MODE_READ|MODE_WRITE); - MOV32MtoR(fsreg, SuperVUGetVIAddr(_Fs_, 1)); - } - else - fsreg = _allocX86reg(-1, X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_READ); - } - } - else -#endif - { - ftreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Ft_, MODE_READ); - } - - s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); - - if( fsreg >= 0 ) { - if( ftreg >= 0 ) { - CMP16RtoR( fsreg, ftreg ); - } - else CMP16MtoR(fsreg, SuperVUGetVIAddr(_Ft_, 1)); - } - else if( ftreg >= 0 ) { - CMP16MtoR(ftreg, SuperVUGetVIAddr(_Fs_, 1)); - } - else { - fsreg = _allocX86reg(-1, X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_READ); - CMP16MtoR(fsreg, SuperVUGetVIAddr(_Ft_, 1)); - } - } -} - -void recVUMI_IBEQ( VURegs* vuu, s32 info ) -{ - recVUMI_IBQ_prep(); - j8Ptr[ 0 ] = JNE8( 0 ); - recVUMI_BranchHandle(); -} - -void recVUMI_IBGEZ( VURegs* vuu, s32 info ) -{ - int fsreg; - s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); - -#ifdef SUPERVU_VIBRANCHDELAY - if( s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Fs_ ) { - fsreg = -1; - } - else -#endif - { - fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_READ); - } - - if( fsreg >= 0 ) { - OR16RtoR(fsreg, fsreg); - j8Ptr[ 0 ] = JS8( 0 ); - } - else { - CMP16ItoM( SuperVUGetVIAddr(_Fs_, 1), 0x0 ); - j8Ptr[ 0 ] = JL8( 0 ); - } - - recVUMI_BranchHandle(); -} - -void recVUMI_IBGTZ( VURegs* vuu, s32 info ) -{ - int fsreg; - s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); - -#ifdef SUPERVU_VIBRANCHDELAY - if( s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Fs_ ) { - fsreg = -1; - } - else -#endif - { - fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_READ); - } - - if( fsreg >= 0 ) { - CMP16ItoR(fsreg, 0); - j8Ptr[ 0 ] = JLE8( 0 ); - } - else { - CMP16ItoM( SuperVUGetVIAddr(_Fs_, 1), 0x0 ); - j8Ptr[ 0 ] = JLE8( 0 ); - } - recVUMI_BranchHandle(); -} - -void recVUMI_IBLEZ( VURegs* vuu, s32 info ) -{ - int fsreg; - s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); - -#ifdef SUPERVU_VIBRANCHDELAY - if( s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Fs_ ) { - fsreg = -1; - } - else -#endif - { - fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_READ); - } - - if( fsreg >= 0 ) { - CMP16ItoR(fsreg, 0); - j8Ptr[ 0 ] = JG8( 0 ); - } - else { - CMP16ItoM( SuperVUGetVIAddr(_Fs_, 1), 0x0 ); - j8Ptr[ 0 ] = JG8( 0 ); - } - recVUMI_BranchHandle(); -} - -void recVUMI_IBLTZ( VURegs* vuu, s32 info ) -{ - int fsreg; - s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); - -#ifdef SUPERVU_VIBRANCHDELAY - if( s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Fs_ ) { - fsreg = -1; - } - else -#endif - { - fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_READ); - } - - if( fsreg >= 0 ) { - OR16RtoR(fsreg, fsreg); - j8Ptr[ 0 ] = JNS8( 0 ); - } - else { - CMP16ItoM( SuperVUGetVIAddr(_Fs_, 1), 0x0 ); - j8Ptr[ 0 ] = JGE8( 0 ); - } - recVUMI_BranchHandle(); -} - -void recVUMI_IBNE( VURegs* vuu, s32 info ) -{ - recVUMI_IBQ_prep(); - j8Ptr[ 0 ] = JE8( 0 ); - recVUMI_BranchHandle(); -} - -void recVUMI_B( VURegs* vuu, s32 info ) -{ - // supervu will take care of the rest - int bpc = _recbranchAddr(VU->code); - if( (s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION) - MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), bpc); - - // loops to self, so check condition - if( bpc == s_pCurBlock->startpc && (s_vu == 0 || SUPERVU_CHECKCONDITION) ) { - SuperVUTestVU0Condition(0); - } - - if( s_pCurBlock->blocks.size() > 1 ) { - s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); - MOV32ItoR(s_JumpX86, 1); - s_pCurBlock->pChildJumps[(s_pCurInst->type & INST_BRANCH_DELAY)?1:0] = (u32*)x86Ptr-1; - s_UnconditionalDelay = 1; - } - - branch |= 3; -} - -void recVUMI_BAL( VURegs* vuu, s32 info ) -{ - int bpc = _recbranchAddr(VU->code); - if( (s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION ) - MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), bpc); - - // loops to self, so check condition - if( bpc == s_pCurBlock->startpc && (s_vu == 0 || SUPERVU_CHECKCONDITION) ) { - SuperVUTestVU0Condition(0); - } - - if ( _Ft_ ) { - _deleteX86reg(X86TYPE_VI|(s_vu?X86TYPE_VU1:0), _Ft_, 2); - MOV16ItoM( SuperVUGetVIAddr(_Ft_, 0), (pc+8)>>3 ); - } - - if( s_pCurBlock->blocks.size() > 1 ) { - s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); - MOV32ItoR(s_JumpX86, 1); - s_pCurBlock->pChildJumps[(s_pCurInst->type & INST_BRANCH_DELAY)?1:0] = (u32*)x86Ptr-1; - s_UnconditionalDelay = 1; - } - - branch |= 3; -} - -void recVUMI_JR( VURegs* vuu, s32 info ) -{ - int fsreg = _allocX86reg(-1, X86TYPE_VI|(s_vu?X86TYPE_VU1:0), _Fs_, MODE_READ); - LEA32RStoR(EAX, fsreg, 3); - - //Mask the address to something valid - if(vuu == &VU0) - AND32ItoR(EAX, 0xfff); - else - AND32ItoR(EAX, 0x3fff); - - if( (s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 ) MOV32RtoM(SuperVUGetVIAddr(REG_TPC, 0), EAX); - - if( !(s_pCurBlock->type & BLOCKTYPE_HASEOP) ) { - PUSH32I(s_vu); - PUSH32R(EAX); - } - branch |= 0x10; // 0x08 is reserved -} - -void recVUMI_JALR( VURegs* vuu, s32 info ) -{ - _addNeededX86reg(X86TYPE_VI|(s_vu?X86TYPE_VU1:0), _Ft_); - - int fsreg = _allocX86reg(-1, X86TYPE_VI|(s_vu?X86TYPE_VU1:0), _Fs_, MODE_READ); - LEA32RStoR(EAX, fsreg, 3); - - //Mask the address to something valid - if(vuu == &VU0) - AND32ItoR(EAX, 0xfff); - else - AND32ItoR(EAX, 0x3fff); - - if ( _Ft_ ) { - _deleteX86reg(X86TYPE_VI|(s_vu?X86TYPE_VU1:0), _Ft_, 2); - MOV16ItoM( SuperVUGetVIAddr(_Ft_, 0), (pc+8)>>3 ); - } - - if( (s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 ) MOV32RtoM(SuperVUGetVIAddr(REG_TPC, 0), EAX); - - if( !(s_pCurBlock->type & BLOCKTYPE_HASEOP) ) { - PUSH32I(s_vu); - PUSH32R(EAX); - } - - branch |= 4; -} - -#ifdef PCSX2_DEVBUILD -void vu1xgkick(u32* pMem, u32 addr) -{ - assert( addr < 0x4000 ); -#ifdef SUPERVU_COUNT - StopSVUCounter(); -#endif - - GSGIFTRANSFER1(pMem, addr); - -#ifdef SUPERVU_COUNT - StartSVUCounter(); -#endif -} -#endif - -void recVUMI_XGKICK_( VURegs *VU ) -{ - assert( s_XGKICKReg > 0 && x86regs[s_XGKICKReg].inuse && x86regs[s_XGKICKReg].type == X86TYPE_VITEMP); - - x86regs[s_XGKICKReg].inuse = 0; // so free doesn't flush - _freeX86regs(); - _freeXMMregs(); - - PUSH32R(s_XGKICKReg); - PUSH32I((uptr)VU->Mem); - - //CALLFunc((u32)countfn); - - if( mtgsThread != NULL ) { - CALLFunc((uptr)VU1XGKICK_MTGSTransfer); - ADD32ItoR(ESP, 8); - } - else { -#ifdef PCSX2_DEVBUILD - CALLFunc((uptr)vu1xgkick); - ADD32ItoR(ESP, 8); -#else - CALLFunc((uptr)GSgifTransfer1); -#endif - } - - s_ScheduleXGKICK = 0; -} - -void recVUMI_XGKICK( VURegs *VU, int info ) -{ - if( s_ScheduleXGKICK ) { - // second xgkick, so launch the first - recVUMI_XGKICK_(VU); - } - - int fsreg = _allocX86reg(X86ARG2, X86TYPE_VI|(s_vu?X86TYPE_VU1:0), _Fs_, MODE_READ); - _freeX86reg(fsreg); // flush - x86regs[fsreg].inuse = 1; - x86regs[fsreg].type = X86TYPE_VITEMP; - x86regs[fsreg].needed = 1; - x86regs[fsreg].mode = MODE_WRITE|MODE_READ; - SHL32ItoR(fsreg, 4); - AND32ItoR(fsreg, 0x3fff); - s_XGKICKReg = fsreg; - - if( !SUPERVU_XGKICKDELAY || pc == s_pCurBlock->endpc ) { - recVUMI_XGKICK_(VU); - } - else { - if( g_VUGameFixes & VUFIX_XGKICKDELAY2 ) - s_ScheduleXGKICK = min((u32)4, (s_pCurBlock->endpc-pc)/8); - else - s_ScheduleXGKICK = 2; - } -} - -void recVU_UPPER_FD_00( VURegs* VU, s32 info ); -void recVU_UPPER_FD_01( VURegs* VU, s32 info ); -void recVU_UPPER_FD_10( VURegs* VU, s32 info ); -void recVU_UPPER_FD_11( VURegs* VU, s32 info ); -void recVULowerOP( VURegs* VU, s32 info ); -void recVULowerOP_T3_00( VURegs* VU, s32 info ); -void recVULowerOP_T3_01( VURegs* VU, s32 info ); -void recVULowerOP_T3_10( VURegs* VU, s32 info ); -void recVULowerOP_T3_11( VURegs* VU, s32 info ); -void recVUunknown( VURegs* VU, s32 info ); - -void (*recVU_LOWER_OPCODE[128])( VURegs* VU, s32 info ) = { - recVUMI_LQ , recVUMI_SQ , recVUunknown , recVUunknown, - recVUMI_ILW , recVUMI_ISW , recVUunknown , recVUunknown, - recVUMI_IADDIU, recVUMI_ISUBIU, recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUMI_FCEQ , recVUMI_FCSET , recVUMI_FCAND, recVUMI_FCOR, /* 0x10 */ - recVUMI_FSEQ , recVUMI_FSSET , recVUMI_FSAND, recVUMI_FSOR, - recVUMI_FMEQ , recVUunknown , recVUMI_FMAND, recVUMI_FMOR, - recVUMI_FCGET , recVUunknown , recVUunknown , recVUunknown, - recVUMI_B , recVUMI_BAL , recVUunknown , recVUunknown, /* 0x20 */ - recVUMI_JR , recVUMI_JALR , recVUunknown , recVUunknown, - recVUMI_IBEQ , recVUMI_IBNE , recVUunknown , recVUunknown, - recVUMI_IBLTZ , recVUMI_IBGTZ , recVUMI_IBLEZ, recVUMI_IBGEZ, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x30 */ - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVULowerOP , recVUunknown , recVUunknown , recVUunknown, /* 0x40*/ - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x50 */ - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x60 */ - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x70 */ - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, -}; - -void (*recVULowerOP_T3_00_OPCODE[32])(VURegs* VU, s32 info) = { - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUMI_MOVE , recVUMI_LQI , recVUMI_DIV , recVUMI_MTIR, - recVUMI_RNEXT , recVUunknown , recVUunknown , recVUunknown, /* 0x10 */ - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUMI_MFP , recVUMI_XTOP , recVUMI_XGKICK, - recVUMI_ESADD , recVUMI_EATANxy, recVUMI_ESQRT, recVUMI_ESIN, -}; - -void (*recVULowerOP_T3_01_OPCODE[32])(VURegs* VU, s32 info) = { - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUMI_MR32 , recVUMI_SQI , recVUMI_SQRT , recVUMI_MFIR, - recVUMI_RGET , recVUunknown , recVUunknown , recVUunknown, /* 0x10 */ - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUMI_XITOP, recVUunknown, - recVUMI_ERSADD, recVUMI_EATANxz, recVUMI_ERSQRT, recVUMI_EATAN, -}; - -void (*recVULowerOP_T3_10_OPCODE[32])(VURegs* VU, s32 info) = { - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUMI_LQD , recVUMI_RSQRT, recVUMI_ILWR, - recVUMI_RINIT , recVUunknown , recVUunknown , recVUunknown, /* 0x10 */ - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUMI_ELENG , recVUMI_ESUM , recVUMI_ERCPR, recVUMI_EEXP, -}; - -void (*recVULowerOP_T3_11_OPCODE[32])(VURegs* VU, s32 info) = { - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUMI_SQD , recVUMI_WAITQ, recVUMI_ISWR, - recVUMI_RXOR , recVUunknown , recVUunknown , recVUunknown, /* 0x10 */ - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUMI_ERLENG, recVUunknown , recVUMI_WAITP, recVUunknown, -}; - -void (*recVULowerOP_OPCODE[64])(VURegs* VU, s32 info) = { - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x10 */ - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x20 */ - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUMI_IADD , recVUMI_ISUB , recVUMI_IADDI, recVUunknown, /* 0x30 */ - recVUMI_IAND , recVUMI_IOR , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVULowerOP_T3_00, recVULowerOP_T3_01, recVULowerOP_T3_10, recVULowerOP_T3_11, -}; - -void (*recVU_UPPER_OPCODE[64])(VURegs* VU, s32 info) = { - recVUMI_ADDx , recVUMI_ADDy , recVUMI_ADDz , recVUMI_ADDw, - recVUMI_SUBx , recVUMI_SUBy , recVUMI_SUBz , recVUMI_SUBw, - recVUMI_MADDx , recVUMI_MADDy , recVUMI_MADDz , recVUMI_MADDw, - recVUMI_MSUBx , recVUMI_MSUBy , recVUMI_MSUBz , recVUMI_MSUBw, - recVUMI_MAXx , recVUMI_MAXy , recVUMI_MAXz , recVUMI_MAXw, /* 0x10 */ - recVUMI_MINIx , recVUMI_MINIy , recVUMI_MINIz , recVUMI_MINIw, - recVUMI_MULx , recVUMI_MULy , recVUMI_MULz , recVUMI_MULw, - recVUMI_MULq , recVUMI_MAXi , recVUMI_MULi , recVUMI_MINIi, - recVUMI_ADDq , recVUMI_MADDq , recVUMI_ADDi , recVUMI_MADDi, /* 0x20 */ - recVUMI_SUBq , recVUMI_MSUBq , recVUMI_SUBi , recVUMI_MSUBi, - recVUMI_ADD , recVUMI_MADD , recVUMI_MUL , recVUMI_MAX, - recVUMI_SUB , recVUMI_MSUB , recVUMI_OPMSUB, recVUMI_MINI, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x30 */ - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVUunknown , recVUunknown , recVUunknown , recVUunknown, - recVU_UPPER_FD_00, recVU_UPPER_FD_01, recVU_UPPER_FD_10, recVU_UPPER_FD_11, -}; - -void (*recVU_UPPER_FD_00_TABLE[32])(VURegs* VU, s32 info) = { - recVUMI_ADDAx, recVUMI_SUBAx , recVUMI_MADDAx, recVUMI_MSUBAx, - recVUMI_ITOF0, recVUMI_FTOI0, recVUMI_MULAx , recVUMI_MULAq , - recVUMI_ADDAq, recVUMI_SUBAq, recVUMI_ADDA , recVUMI_SUBA , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , -}; - -void (*recVU_UPPER_FD_01_TABLE[32])(VURegs* VU, s32 info) = { - recVUMI_ADDAy , recVUMI_SUBAy , recVUMI_MADDAy, recVUMI_MSUBAy, - recVUMI_ITOF4 , recVUMI_FTOI4 , recVUMI_MULAy , recVUMI_ABS , - recVUMI_MADDAq, recVUMI_MSUBAq, recVUMI_MADDA , recVUMI_MSUBA , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , -}; - -void (*recVU_UPPER_FD_10_TABLE[32])(VURegs* VU, s32 info) = { - recVUMI_ADDAz , recVUMI_SUBAz , recVUMI_MADDAz, recVUMI_MSUBAz, - recVUMI_ITOF12, recVUMI_FTOI12, recVUMI_MULAz , recVUMI_MULAi , - recVUMI_ADDAi, recVUMI_SUBAi , recVUMI_MULA , recVUMI_OPMULA, - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , -}; - -void (*recVU_UPPER_FD_11_TABLE[32])(VURegs* VU, s32 info) = { - recVUMI_ADDAw , recVUMI_SUBAw , recVUMI_MADDAw, recVUMI_MSUBAw, - recVUMI_ITOF15, recVUMI_FTOI15, recVUMI_MULAw , recVUMI_CLIP , - recVUMI_MADDAi, recVUMI_MSUBAi, recVUunknown , recVUMI_NOP , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , - recVUunknown , recVUunknown , recVUunknown , recVUunknown , -}; - -void recVU_UPPER_FD_00( VURegs* VU, s32 info ) -{ - recVU_UPPER_FD_00_TABLE[ ( VU->code >> 6 ) & 0x1f ]( VU, info ); -} - -void recVU_UPPER_FD_01( VURegs* VU, s32 info ) -{ - recVU_UPPER_FD_01_TABLE[ ( VU->code >> 6 ) & 0x1f ]( VU, info ); -} - -void recVU_UPPER_FD_10( VURegs* VU, s32 info ) -{ - recVU_UPPER_FD_10_TABLE[ ( VU->code >> 6 ) & 0x1f ]( VU, info ); -} - -void recVU_UPPER_FD_11( VURegs* VU, s32 info ) -{ - recVU_UPPER_FD_11_TABLE[ ( VU->code >> 6 ) & 0x1f ]( VU, info ); -} - -void recVULowerOP( VURegs* VU, s32 info ) -{ - recVULowerOP_OPCODE[ VU->code & 0x3f ]( VU, info ); -} - -void recVULowerOP_T3_00( VURegs* VU, s32 info ) -{ - recVULowerOP_T3_00_OPCODE[ ( VU->code >> 6 ) & 0x1f ]( VU, info ); -} - -void recVULowerOP_T3_01( VURegs* VU, s32 info ) -{ - recVULowerOP_T3_01_OPCODE[ ( VU->code >> 6 ) & 0x1f ]( VU, info ); -} - -void recVULowerOP_T3_10( VURegs* VU, s32 info ) -{ - recVULowerOP_T3_10_OPCODE[ ( VU->code >> 6 ) & 0x1f ]( VU, info ); -} - -void recVULowerOP_T3_11( VURegs* VU, s32 info ) -{ - recVULowerOP_T3_11_OPCODE[ ( VU->code >> 6 ) & 0x1f ]( VU, info ); -} - -void recVUunknown( VURegs* VU, s32 info ) -{ - Console::Notice("Unknown SVU micromode opcode called"); -} diff --git a/pcsx2/x86/iVif.cpp b/pcsx2/x86/iVif.cpp index 64d63a99f9..a55fea26c4 100644 --- a/pcsx2/x86/iVif.cpp +++ b/pcsx2/x86/iVif.cpp @@ -31,31 +31,35 @@ extern u32 g_vif1HasMask3[4], g_vif0HasMask3[4]; // arranged in writearr, rowarr, colarr, updatearr static PCSX2_ALIGNED16(u32 s_maskarr[16][4]) = { - 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, - 0xffff0000, 0x0000ffff, 0x00000000, 0xffffffff, - 0xffff0000, 0x00000000, 0x0000ffff, 0xffffffff, - 0xffff0000, 0x00000000, 0x00000000, 0xffff0000, - 0x0000ffff, 0xffff0000, 0x00000000, 0xffffffff, - 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, - 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff, - 0x00000000, 0xffff0000, 0x00000000, 0xffff0000, - 0x0000ffff, 0x00000000, 0xffff0000, 0xffffffff, - 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff, - 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, - 0x00000000, 0x00000000, 0xffff0000, 0xffff0000, - 0x0000ffff, 0x00000000, 0x00000000, 0x0000ffff, - 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, - 0x00000000, 0x00000000, 0x0000ffff, 0x0000ffff, - 0x00000000, 0x00000000, 0x00000000, 0x00000000 + {0xffffffff, 0x00000000, 0x00000000, 0xffffffff}, + {0xffff0000, 0x0000ffff, 0x00000000, 0xffffffff}, + {0xffff0000, 0x00000000, 0x0000ffff, 0xffffffff}, + {0xffff0000, 0x00000000, 0x00000000, 0xffff0000}, + {0x0000ffff, 0xffff0000, 0x00000000, 0xffffffff}, + {0x00000000, 0xffffffff, 0x00000000, 0xffffffff}, + {0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff}, + {0x00000000, 0xffff0000, 0x00000000, 0xffff0000}, + {0x0000ffff, 0x00000000, 0xffff0000, 0xffffffff}, + {0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff}, + {0x00000000, 0x00000000, 0xffffffff, 0xffffffff}, + {0x00000000, 0x00000000, 0xffff0000, 0xffff0000}, + {0x0000ffff, 0x00000000, 0x00000000, 0x0000ffff}, + {0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff}, + {0x00000000, 0x00000000, 0x0000ffff, 0x0000ffff}, + {0x00000000, 0x00000000, 0x00000000, 0x00000000} }; extern u8 s_maskwrite[256]; extern "C" PCSX2_ALIGNED16(u32 s_TempDecompress[4]) = {0}; +#ifdef __LINUX__ +static void __forceinline UseOldMaskCode(u32* &vif1masks, u32 &mask); +#endif + void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask) { - u32 i; + u32 i; u32 prev = 0; FreezeXMMRegs(1); for(i = 0; i < 4; ++i, mask >>= 8, oldmask >>= 8, vif1masks += 16) { @@ -63,7 +67,13 @@ void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask) prev |= s_maskwrite[mask&0xff]; hasmask[i] = prev; - if( (mask&0xff) != (oldmask&0xff) ) { + if ((mask&0xff) != (oldmask&0xff)) +#ifdef __LINUX__ + if (mask == 0) // Temporary workaround for a bug causing a segfault. + UseOldMaskCode(vif1masks, mask); + else +#endif + { __m128i r0, r1, r2, r3; r0 = _mm_load_si128((__m128i*)&s_maskarr[mask&15][0]); r2 = _mm_unpackhi_epi16(r0, r0); @@ -86,3 +96,30 @@ void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask) } FreezeXMMRegs(0); } + +#ifdef __LINUX__ +static void __forceinline UseOldMaskCode(u32* &vif1masks, u32 &mask) +{ + u8* p0 = (u8*)&s_maskarr[mask&15][0]; + u8* p1 = (u8*)&s_maskarr[(mask>>4)&15][0]; + + __asm__(".intel_syntax noprefix\n" + "movaps xmm0, [%0]\n" + "movaps xmm1, [%1]\n" + "movaps xmm2, xmm0\n" + "punpcklwd xmm0, xmm0\n" + "punpckhwd xmm2, xmm2\n" + "movaps xmm3, xmm1\n" + "punpcklwd xmm1, xmm1\n" + "punpckhwd xmm3, xmm3\n" + "movq [%2], xmm0\n" + "movq [%2+8], xmm1\n" + "movhps [%2+16], xmm0\n" + "movhps [%2+24], xmm1\n" + "movq [%2+32], xmm2\n" + "movq [%2+40], xmm3\n" + "movhps [%2+48], xmm2\n" + "movhps [%2+56], xmm3\n" + ".att_syntax\n" : : "r"(p0), "r"(p1), "r"(vif1masks) ); +} +#endif diff --git a/pcsx2/x86/ix86-32/iCore-32.cpp b/pcsx2/x86/ix86-32/iCore-32.cpp index e90e051a22..35c1cfd919 100644 --- a/pcsx2/x86/ix86-32/iCore-32.cpp +++ b/pcsx2/x86/ix86-32/iCore-32.cpp @@ -21,7 +21,7 @@ #include "iR5900.h" #include "Vif.h" #include "VU.h" -#include "ix86/ix86.h" +#include "x86emitter/x86emitter.h" #include "R3000A.h" #include @@ -139,10 +139,10 @@ void _flushConstReg(int reg) void _flushConstRegs() { - int i, j; - int zero_cnt = 0, minusone_cnt = 0; - int eaxval = 1; // 0, -1 - unsigned long done[4] = {0, 0, 0, 0}; + s32 i, j; + s32 zero_cnt = 0, minusone_cnt = 0; + s32 eaxval = 1; // 0, -1 + u32 done[4] = {0, 0, 0, 0}; u8* rewindPtr; // flush constants diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index 30c2df0a97..e7bb45986a 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -36,11 +36,11 @@ #include "iMMI.h" #include "iFPU.h" #include "iCOP0.h" -#include "iVUmicro.h" +#include "sVU_Micro.h" #include "VU.h" #include "VUmicro.h" -#include "iVUzerorec.h" +#include "sVU_zerorec.h" #include "vtlb.h" #include "SamplProf.h" @@ -74,8 +74,7 @@ u32 g_cpuHasConstReg = 0, g_cpuFlushedConstReg = 0; // Static Private Variables - R5900 Dynarec #define X86 -static const int RECSTACK_SIZE = 0x00010000; -static const int EE_NUMBLOCKS = (1<<15); +static const int RECSTACK_SIZE = 0x00020000; static u8 *recMem = NULL; // the recompiled blocks will be here static u8* recStack = NULL; // stack mem @@ -84,7 +83,7 @@ static BASEBLOCK *recROM = NULL; // and here static BASEBLOCK *recROM1 = NULL; // also here static u32 *recRAMCopy = NULL; void JITCompile(); -static BaseBlocks recBlocks(EE_NUMBLOCKS, (uptr)JITCompile); +static BaseBlocks recBlocks((uptr)JITCompile); static u8* recPtr = NULL, *recStackPtr = NULL; EEINST* s_pInstCache = NULL; static u32 s_nInstCacheSize = 0; @@ -103,7 +102,7 @@ static EEINST* s_psaveInstInfo = NULL; static u32 s_savenBlockCycles = 0; -#ifdef _DEBUG +#ifdef PCSX2_DEBUG static u32 dumplog = 0; #else #define dumplog 0 @@ -111,6 +110,7 @@ static u32 dumplog = 0; static void iBranchTest(u32 newpc = 0xffffffff, bool noDispatch=false); static void ClearRecLUT(BASEBLOCK* base, int count); +static u32 eeScaleBlockCycles(); #ifdef PCSX2_VM_COISSUE static u8 _eeLoadWritesRs(u32 tempcode) @@ -340,14 +340,23 @@ int _flushUnusedConstReg() return 0; } +// ------------------------------------------------------------------------ +// recAllocStackMem -- an optimization trick to write data to a location so that +// recompiled code can reference it later on during execution. +// +// Intended use is for setting up 64/128 bit SSE immediates, primarily. +// u32* recAllocStackMem(int size, int align) { - // write to a temp loc, trick - if( (u32)recStackPtr % align ) recStackPtr += align - ((u32)recStackPtr%align); + jASSUME( align == 4 || align == 8 || align == 16 ); + + recStackPtr = (u8*) ( (((uptr)recStackPtr) + (align-1)) & ~(align-1) ); recStackPtr += size; return (u32*)(recStackPtr-size); } +////////////////////////////////////////////////////////////////////////////////////////// +// static const int REC_CACHEMEM = 0x01000000; static void __fastcall dyna_block_discard(u32 start,u32 sz); @@ -477,15 +486,6 @@ void recResetEE( void ) recLUT_SetPage(recLUT, hwLUT, recROM1, 0xa000, i, i - 0x1e00); } - // drk||Raziel says this is useful but I'm not sure why. Something to do with forward jumps. - // Anyways, it causes random crashing for some reasom, possibly because of memory - // corrupition elsewhere in the recs. I can't reproduce the problem here though, - // so a fix will have to wait until later. -_- (air) - - //x86SetPtr(recMem+REC_CACHEMEM); - //dyna_block_discard_recmem=(u8*)x86Ptr; - //JMP32( (uptr)&dyna_block_discard - ( (u32)x86Ptr + 5 )); - x86SetPtr(recMem); recPtr = recMem; @@ -718,7 +718,7 @@ void recBREAK( void ) { } } } // end namespace R5900::Dynarec::OpcodeImpl // Clears the recLUT table so that all blocks are mapped to the JIT recompiler by default. -static void ClearRecLUT(BASEBLOCK* base, int count) +static __releaseinline void ClearRecLUT(BASEBLOCK* base, int count) { for (int i = 0; i < count; i++) base[i].SetFnptr((uptr)JITCompile); @@ -960,7 +960,7 @@ void iFlushCall(int flushtype) //} -u32 eeScaleBlockCycles() +static u32 scaleBlockCycles_helper() { // Note: s_nBlockCycles is 3 bit fixed point. Divide by 8 when done! @@ -992,12 +992,6 @@ u32 eeScaleBlockCycles() scalarHigh = 7; break; - case 3: // Sync hack x3 - scalarLow = 10; - scalarMid = 19; - scalarHigh = 10; - break; - jNO_DEFAULT } @@ -1009,19 +1003,14 @@ u32 eeScaleBlockCycles() return temp >> (3+2); } -static void iBranch(u32 newpc, int type) +static u32 eeScaleBlockCycles() { - u32* ptr; - - MOV32ItoM((uptr)&cpuRegs.pc, newpc); - if (type == 0) - ptr = JMP32(0); - else if (type == 1) - ptr = JS32(0); - - recBlocks.Link(HWADDR(newpc), (uptr)ptr); + // Ensures block cycles count is never less than 1: + u32 retval = scaleBlockCycles_helper(); + return (retval < 1) ? 1 : retval; } + // Generates dynarec code for Event tests followed by a block dispatch (branch). // Parameters: // newpc - address to jump to at the end of the block. If newpc == 0xffffffff then @@ -1034,10 +1023,6 @@ static void iBranch(u32 newpc, int type) // setting "branch = 2"; static void iBranchTest(u32 newpc, bool noDispatch) { -#ifdef _DEBUG - //CALLFunc((uptr)testfpu); -#endif - if( bExecBIOS ) CheckForBIOSEnd(); // Check the Event scheduler if our "cycle target" has been reached. @@ -1051,20 +1036,23 @@ static void iBranchTest(u32 newpc, bool noDispatch) xCMP(eax, ptr32[&cpuRegs.cycle]); xCMOVL(eax, ptr32[&cpuRegs.cycle]); xMOV(ptr32[&cpuRegs.cycle], eax); - RET(); } else { - MOV32MtoR(EAX, (uptr)&cpuRegs.cycle); - ADD32ItoR(EAX, eeScaleBlockCycles()); - MOV32RtoM((uptr)&cpuRegs.cycle, EAX); // update cycles - SUB32MtoR(EAX, (uptr)&g_nextBranchCycle); - if (!noDispatch) { + xMOV(eax, &cpuRegs.cycle); + xADD(eax, eeScaleBlockCycles()); + xMOV(&cpuRegs.cycle, eax); // update cycles + xSUB(eax, &g_nextBranchCycle); + if (!noDispatch) + { if (newpc == 0xffffffff) - JS32((uptr)DispatcherReg - ( (uptr)x86Ptr + 6 )); + xJS( DispatcherReg ); else - iBranch(newpc, 1); + { + xMOV( ptr32[&cpuRegs.pc], newpc ); + recBlocks.Link( HWADDR(newpc), xJcc32( Jcc_Signed ) ); + } } - RET(); } + xRET(); } static void checkcodefn() @@ -1096,7 +1084,7 @@ void recompileNextInstruction(int delayslot) pc += 4; #if 0 -#ifdef _DEBUG +#ifdef PCSX2_DEBUG CMP32ItoM((u32)s_pCode, cpuRegs.code); j8Ptr[0] = JE8(0); MOV32ItoR(EAX, pc); @@ -1163,7 +1151,7 @@ void recompileNextInstruction(int delayslot) return; } } - //If thh COP0 DIE bit is disabled, double the cycles. Happens rarely. + //If the COP0 DIE bit is disabled, double the cycles. Happens rarely. s_nBlockCycles += opcode.cycles * (2 - ((cpuRegs.CP0.n.Config >> 18) & 0x1)); opcode.recompile(); @@ -1195,8 +1183,6 @@ void recompileNextInstruction(int delayslot) s_nEndBlock = pc; } -extern u32 psxdump; - static void printfn() { static int lastrec = 0; @@ -1225,19 +1211,20 @@ void badespfn() { assert(0); } +// Called when a block under manual protection fails it's pre-execution integrity check. void __fastcall dyna_block_discard(u32 start,u32 sz) { - DevCon::WriteLn("dyna_block_discard .. start: %08X count=%d", params start,sz); - Cpu->Clear(start, sz); + DevCon::WriteLn("dyna_block_discard .. start=0x%08X size=%d", params start, sz*4); + recClear(start, sz); } - +// called when a block under manual protection has been run enough times to be a +// candidate for being reset under the faster vtlb write protection. void __fastcall dyna_page_reset(u32 start,u32 sz) { - DevCon::WriteLn("dyna_page_reset .. start=%08X size=%d", params start,sz*4); - Cpu->Clear(start & ~0xfffUL, 0x400); + recClear(start & ~0xfffUL, 0x400); manual_counter[start >> 12]++; - mmap_MarkCountedRamPage(PSM(start), start & ~0xfffUL); + mmap_MarkCountedRamPage( start ); } void recRecompile( const u32 startpc ) @@ -1247,7 +1234,7 @@ void recRecompile( const u32 startpc ) u32 willbranch3 = 0; u32 usecop2; -#ifdef _DEBUG +#ifdef PCSX2_DEBUG //dumplog |= 4; if( dumplog & 4 ) iDumpRegisters(startpc, 0); @@ -1282,13 +1269,6 @@ void recRecompile( const u32 startpc ) s_pCurBlockEx = recBlocks.New(HWADDR(startpc), (uptr)recPtr); - if( s_pCurBlockEx == NULL ) { - //Console::WriteLn("ee reset (blocks)"); - recResetEE(); - x86SetPtr( recPtr ); - s_pCurBlockEx = recBlocks.New(HWADDR(startpc), (uptr)recPtr); - } - assert(s_pCurBlockEx); branch = 0; @@ -1306,7 +1286,7 @@ void recRecompile( const u32 startpc ) _initXMMregs(); _initMMXregs(); -#ifdef _DEBUG +#ifdef PCSX2_DEBUG // for debugging purposes MOV32ItoM((uptr)&g_lastpc, pc); CALLFunc((uptr)printfn); @@ -1491,7 +1471,7 @@ StartRecomp: } } -#ifdef _DEBUG +#ifdef PCSX2_DEBUG // dump code for(i = 0; i < ArraySize(s_recblocks); ++i) { if( startpc == s_recblocks[i] ) { @@ -1509,15 +1489,14 @@ StartRecomp: // note: blocks are guaranteed to reside within the confines of a single page. - const int PageType = mmap_GetRamPageInfo((u32*)PSM(inpage_ptr)); - const u32 inpage_offs = inpage_ptr & 0xFFF; + const int PageType = mmap_GetRamPageInfo( inpage_ptr ); //const u32 pgsz = std::min(0x1000 - inpage_offs, inpage_sz); const u32 pgsz = inpage_sz; if(PageType!=-1) { if (PageType==0) { - mmap_MarkCountedRamPage(PSM(inpage_ptr),inpage_ptr&~0xFFF); + mmap_MarkCountedRamPage( inpage_ptr ); manual_page[inpage_ptr >> 12] = 0; } else @@ -1567,13 +1546,13 @@ StartRecomp: xJC( dyna_page_reset ); // note: clearcnt is measured per-page, not per-block! - DbgCon::WriteLn( "Manual block @ %08X : size=%3d page/offs=%05X/%03X inpgsz=%d clearcnt=%d", - params startpc, sz, inpage_ptr>>12, inpage_offs, inpage_sz, manual_counter[inpage_ptr >> 12] ); + //DbgCon::WriteLn( "Manual block @ %08X : size=%3d page/offs=%05X/%03X inpgsz=%d clearcnt=%d", + // params startpc, sz, inpage_ptr>>12, inpage_ptr&0xfff, inpage_sz, manual_counter[inpage_ptr >> 12] ); } else { DbgCon::Notice( "Uncounted Manual block @ %08X : size=%3d page/offs=%05X/%03X inpgsz=%d", - params startpc, sz, inpage_ptr>>12, inpage_offs, pgsz, inpage_sz ); + params startpc, sz, inpage_ptr>>12, inpage_ptr&0xfff, pgsz, inpage_sz ); } } @@ -1585,7 +1564,7 @@ StartRecomp: recompileNextInstruction(0); // For the love of recursion, batman! } -#ifdef _DEBUG +#ifdef PCSX2_DEBUG if( (dumplog & 1) ) iDumpBlock(startpc, recPtr); #endif @@ -1640,11 +1619,8 @@ StartRecomp: } else { - assert( branch != 3 ); if( branch ) assert( !willbranch3 ); - else - ADD32ItoM((int)&cpuRegs.cycle, eeScaleBlockCycles() ); if( willbranch3 || !branch) { @@ -1657,10 +1633,14 @@ StartRecomp: // performance reasons. int numinsts = (pc - startpc) / 4; - if( numinsts > 12 ) + if( numinsts > 6 ) iBranchTest(pc); else - iBranch(pc,0); // unconditional static link + { + xMOV( ptr32[&cpuRegs.pc], pc ); + xADD( ptr32[&cpuRegs.cycle], eeScaleBlockCycles() ); + recBlocks.Link( HWADDR(pc), xJcc32() ); + } } } diff --git a/pcsx2/x86/ix86-32/iR5900LoadStore.cpp b/pcsx2/x86/ix86-32/iR5900LoadStore.cpp index aaf93d1d47..6416de45da 100644 --- a/pcsx2/x86/ix86-32/iR5900LoadStore.cpp +++ b/pcsx2/x86/ix86-32/iR5900LoadStore.cpp @@ -67,9 +67,6 @@ REC_FUNC(SQC2); #else PCSX2_ALIGNED16(u64 retValues[2]); -static u32 s_bCachingMem = 0; -static u32 s_nAddMemOffset = 0; -static u32 s_tempaddr = 0; void _eeOnLoadWrite(int reg) { @@ -94,6 +91,10 @@ void _eeOnLoadWrite(int reg) #ifdef PCSX2_VIRTUAL_MEM +static u32 s_bCachingMem = 0; +static u32 s_nAddMemOffset = 0; +static u32 s_tempaddr = 0; + //////////////////////////////////////////////////// //#define REC_SLOWREAD //#define REC_SLOWWRITE @@ -129,7 +130,7 @@ void recTransferX86ToReg(int x86reg, int gprreg, int sign) } } -#ifdef _DEBUG +#ifdef PCSX2_DEBUG void testaddrs() { register int tempaddr; @@ -230,7 +231,7 @@ int recSetMemLocation(int regs, int imm, int mmreg, int msize, int j32) if ( imm != 0 ) ADD32ItoR( ECX, imm ); -#ifdef _DEBUG +#ifdef PCSX2_DEBUG //CALLFunc((uptr)testaddrs); #endif @@ -255,7 +256,7 @@ int recSetMemLocation(int regs, int imm, int mmreg, int msize, int j32) x86SetJ8(ptr); if( msize == 1 ) AND8ItoR(ECX, 0xf8); else if( msize == 2 ) AND8ItoR(ECX, 0xf0); -#ifdef _DEBUG +#ifdef PCSX2_DEBUG MOV32RtoR(EAX, ECX); SHR32ItoR(EAX, 28); CMP32ItoR(EAX, 1); diff --git a/pcsx2/x86/ix86-32/iR5900Templates.cpp b/pcsx2/x86/ix86-32/iR5900Templates.cpp index 2149848dfc..b2633bcd6d 100644 --- a/pcsx2/x86/ix86-32/iR5900Templates.cpp +++ b/pcsx2/x86/ix86-32/iR5900Templates.cpp @@ -26,11 +26,11 @@ #include "iMMI.h" #include "iFPU.h" #include "iCOP0.h" -#include "iVUmicro.h" +#include "sVU_Micro.h" #include "VU.h" #include "VUmicro.h" -#include "iVUzerorec.h" +#include "sVU_zerorec.h" #include "vtlb.h" diff --git a/pcsx2/x86/ix86-32/recVTLB.cpp b/pcsx2/x86/ix86-32/recVTLB.cpp index b4ff537b44..16f76b193d 100644 --- a/pcsx2/x86/ix86-32/recVTLB.cpp +++ b/pcsx2/x86/ix86-32/recVTLB.cpp @@ -155,89 +155,178 @@ void iMOV64_Smart( const ModSibBase& destRm, const ModSibBase& srcRm ) cont: ........ - */ +*/ + +namespace vtlb_private +{ + // ------------------------------------------------------------------------ + // Prepares eax, ecx, and, ebx for Direct or Indirect operations. + // Returns the writeback pointer for ebx (return address from indirect handling) + // + static uptr* DynGen_PrepRegs() + { + xMOV( eax, ecx ); + xSHR( eax, VTLB_PAGE_BITS ); + xMOV( eax, ptr[(eax*4) + vtlbdata.vmap] ); + xMOV( ebx, 0xcdcdcdcd ); + uptr* writeback = ((uptr*)xGetPtr()) - 1; + xADD( ecx, eax ); + + return writeback; + } + + // ------------------------------------------------------------------------ + static void DynGen_DirectRead( u32 bits, bool sign ) + { + switch( bits ) + { + case 8: + if( sign ) + xMOVSX( eax, ptr8[ecx] ); + else + xMOVZX( eax, ptr8[ecx] ); + break; + + case 16: + if( sign ) + xMOVSX( eax, ptr16[ecx] ); + else + xMOVZX( eax, ptr16[ecx] ); + break; + + case 32: + xMOV( eax, ptr[ecx] ); + break; + + case 64: + iMOV64_Smart( ptr[edx], ptr[ecx] ); + break; + + case 128: + iMOV128_SSE( ptr[edx], ptr[ecx] ); + break; + + jNO_DEFAULT + } + } + + // ------------------------------------------------------------------------ + static void DynGen_DirectWrite( u32 bits ) + { + switch(bits) + { + //8 , 16, 32 : data on EDX + case 8: + xMOV( ptr[ecx], dl ); + break; + + case 16: + xMOV( ptr[ecx], dx ); + break; + + case 32: + xMOV( ptr[ecx], edx ); + break; + + case 64: + iMOV64_Smart( ptr[ecx], ptr[edx] ); + break; + + case 128: + iMOV128_SSE( ptr[ecx], ptr[edx] ); + break; + } + } +} + +// ------------------------------------------------------------------------ +// allocate one page for our naked indirect dispatcher function. +// this *must* be a full page, since we'll give it execution permission later. +// If it were smaller than a page we'd end up allowing execution rights on some +// other vars additionally (bad!). +// +PCSX2_ALIGNED( 0x1000, static u8 m_IndirectDispatchers[0x1000] ); + +// ------------------------------------------------------------------------ +// mode - 0 for read, 1 for write! +// operandsize - 0 thru 4 represents 8, 16, 32, 64, and 128 bits. +// +static u8* GetIndirectDispatcherPtr( int mode, int operandsize ) +{ + // Each dispatcher is aligned to 64 bytes. The actual dispatchers are only like + // 20-some bytes each, but 64 byte alignment on functions that are called + // more frequently than a hot sex hotline at 1:15am is probably a good thing. + + // 5*64? Because 5 operand types per each mode :D + + return &m_IndirectDispatchers[(mode*(5*64)) + (operandsize*64)]; +} + +// ------------------------------------------------------------------------ +// Generates a JS instruction that targets the appropriate templated instance of +// the vtlb Indirect Dispatcher. +// +static void DynGen_IndirectDispatch( int mode, int bits ) +{ + int szidx; + switch( bits ) + { + case 8: szidx=0; break; + case 16: szidx=1; break; + case 32: szidx=2; break; + case 64: szidx=3; break; + case 128: szidx=4; break; + jNO_DEFAULT; + } + xJS( GetIndirectDispatcherPtr( mode, szidx ) ); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// One-time initialization procedure. Calling it multiple times shouldn't +// hurt anything tho. +// +void vtlb_dynarec_init() +{ + // In case init gets called multiple times: + HostSys::MemProtect( m_IndirectDispatchers, 0x1000, Protect_ReadWrite, false ); + + // clear the buffer to 0xcc (easier debugging). + memset_8<0xcc,0x1000>( m_IndirectDispatchers ); + + //u8* baseptr = m_IndirectDispatchers; + + for( int mode=0; mode<2; ++mode ) + { + for( int bits=0; bits<5; ++bits ) + { + xSetPtr( GetIndirectDispatcherPtr( mode, bits ) ); + + xMOVZX( eax, al ); + xSUB( ecx, 0x80000000 ); + xSUB( ecx, eax ); + + // jump to the indirect handler, which is a __fastcall C++ function. + // [ecx is address, edx is data] + xCALL( ptr32[(eax*4) + vtlbdata.RWFT[bits][mode]] ); + xJMP( ebx ); + } + } + + HostSys::MemProtect( m_IndirectDispatchers, 0x1000, Protect_ReadOnly, true ); +} ////////////////////////////////////////////////////////////////////////////////////////// // Dynarec Load Implementations - -static void _vtlb_DynGen_DirectRead( u32 bits, bool sign ) -{ - switch( bits ) - { - case 8: - if( sign ) - MOVSX32Rm8toR(EAX,ECX); - else - MOVZX32Rm8toR(EAX,ECX); - break; - - case 16: - if( sign ) - MOVSX32Rm16toR(EAX,ECX); - else - MOVZX32Rm16toR(EAX,ECX); - break; - - case 32: - MOV32RmtoR(EAX,ECX); - break; - - case 64: - iMOV64_Smart(ptr[edx],ptr[ecx]); - break; - - case 128: - iMOV128_SSE(ptr[edx],ptr[ecx]); - break; - - jNO_DEFAULT - } -} - -// ------------------------------------------------------------------------ -static void _vtlb_DynGen_IndirectRead( u32 bits ) -{ - int szidx; - - switch( bits ) - { - case 8: szidx=0; break; - case 16: szidx=1; break; - case 32: szidx=2; break; - case 64: szidx=3; break; - case 128: szidx=4; break; - jNO_DEFAULT - } - - MOVZX32R8toR(EAX,EAX); - SUB32RtoR(ECX,EAX); - //eax=[funct+eax] - MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.RWFT[szidx][0],2); - SUB32ItoR(ECX,0x80000000); - CALL32R(EAX); -} - -// ------------------------------------------------------------------------ -// Recompiled input registers: -// ecx = source addr to read from -// edx = ptr to dest to write to void vtlb_DynGenRead64(u32 bits) { jASSUME( bits == 64 || bits == 128 ); - MOV32RtoR(EAX,ECX); - SHR32ItoR(EAX,VTLB_PAGE_BITS); - MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.vmap,2); - ADD32RtoR(ECX,EAX); - xForwardJS8 _fullread; + uptr* writeback = DynGen_PrepRegs(); - _vtlb_DynGen_DirectRead( bits, false ); - xForwardJump8 cont; - - _fullread.SetTarget(); + DynGen_IndirectDispatch( 0, bits ); + DynGen_DirectRead( bits, false ); - _vtlb_DynGen_IndirectRead( bits ); - cont.SetTarget(); + *writeback = (uptr)xGetPtr(); // return target for indirect's call/ret } // ------------------------------------------------------------------------ @@ -248,35 +337,29 @@ void vtlb_DynGenRead32(u32 bits, bool sign) { jASSUME( bits <= 32 ); - MOV32RtoR(EAX,ECX); - SHR32ItoR(EAX,VTLB_PAGE_BITS); - MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.vmap,2); - ADD32RtoR(ECX,EAX); - xForwardJS8 _fullread; + uptr* writeback = DynGen_PrepRegs(); - _vtlb_DynGen_DirectRead( bits, sign ); - xForwardJump8 cont; + DynGen_IndirectDispatch( 0, bits ); + DynGen_DirectRead( bits, sign ); - _fullread.SetTarget(); - _vtlb_DynGen_IndirectRead( bits ); + *writeback = (uptr)xGetPtr(); // perform sign extension on the result: - if( bits==8 ) + if( bits == 8 ) { if( sign ) - MOVSX32R8toR(EAX,EAX); + xMOVSX( eax, al ); else - MOVZX32R8toR(EAX,EAX); + xMOVZX( eax, al ); } - else if( bits==16 ) + else if( bits == 16 ) { if( sign ) - MOVSX32R16toR(EAX,EAX); + xMOVSX( eax, ax ); else - MOVZX32R16toR(EAX,EAX); + xMOVZX( eax, ax ); } - cont.SetTarget(); } // ------------------------------------------------------------------------ @@ -291,11 +374,11 @@ void vtlb_DynGenRead64_Const( u32 bits, u32 addr_const ) switch( bits ) { case 64: - iMOV64_Smart(ptr[edx],ptr[ppf]); + iMOV64_Smart( ptr[edx], ptr[ppf] ); break; case 128: - iMOV128_SSE(ptr[edx],ptr[ppf]); + iMOV128_SSE( ptr[edx], ptr[ppf] ); break; jNO_DEFAULT @@ -314,8 +397,8 @@ void vtlb_DynGenRead64_Const( u32 bits, u32 addr_const ) case 128: szidx=4; break; } - MOV32ItoR( ECX, paddr ); - CALLFunc( (int)vtlbdata.RWFT[szidx][0][handler] ); + xMOV( ecx, paddr ); + xCALL( vtlbdata.RWFT[szidx][0][handler] ); } } @@ -326,6 +409,7 @@ void vtlb_DynGenRead64_Const( u32 bits, u32 addr_const ) // // TLB lookup is performed in const, with the assumption that the COP0/TLB will clear the // recompiler if the TLB is changed. +// void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const ) { u32 vmv_ptr = vtlbdata.vmap[addr_const>>VTLB_PAGE_BITS]; @@ -336,20 +420,20 @@ void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const ) { case 8: if( sign ) - MOVSX32M8toR(EAX,ppf); + xMOVSX( eax, ptr8[ppf] ); else - MOVZX32M8toR(EAX,ppf); + xMOVZX( eax, ptr8[ppf] ); break; case 16: if( sign ) - MOVSX32M16toR(EAX,ppf); + xMOVSX( eax, ptr16[ppf] ); else - MOVZX32M16toR(EAX,ppf); + xMOVZX( eax, ptr16[ppf] ); break; case 32: - MOV32MtoR(EAX,ppf); + xMOV( eax, ptr[ppf] ); break; } } @@ -370,28 +454,28 @@ void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const ) // Shortcut for the INTC_STAT register, which many games like to spin on heavily. if( (bits == 32) && !Config.Hacks.INTCSTATSlow && (paddr == INTC_STAT) ) { - MOV32MtoR( EAX, (uptr)&psHu32( INTC_STAT ) ); + xMOV( eax, &psHu32( INTC_STAT ) ); } else { - MOV32ItoR( ECX, paddr ); - CALLFunc( (int)vtlbdata.RWFT[szidx][0][handler] ); + xMOV( ecx, paddr ); + xCALL( vtlbdata.RWFT[szidx][0][handler] ); // perform sign extension on the result: if( bits==8 ) { if( sign ) - MOVSX32R8toR(EAX,EAX); + xMOVSX( eax, al ); else - MOVZX32R8toR(EAX,EAX); + xMOVZX( eax, al ); } else if( bits==16 ) { if( sign ) - MOVSX32R16toR(EAX,EAX); + xMOVSX( eax, ax ); else - MOVZX32R16toR(EAX,EAX); + xMOVZX( eax, ax ); } } } @@ -400,67 +484,14 @@ void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const ) ////////////////////////////////////////////////////////////////////////////////////////// // Dynarec Store Implementations -static void _vtlb_DynGen_DirectWrite( u32 bits ) -{ - switch(bits) - { - //8 , 16, 32 : data on EDX - case 8: - MOV8RtoRm(ECX,EDX); - break; - case 16: - MOV16RtoRm(ECX,EDX); - break; - case 32: - MOV32RtoRm(ECX,EDX); - break; - - case 64: - iMOV64_Smart(ptr[ecx],ptr[edx]); - break; - - case 128: - iMOV128_SSE(ptr[ecx],ptr[edx]); - break; - } -} - -// ------------------------------------------------------------------------ -static void _vtlb_DynGen_IndirectWrite( u32 bits ) -{ - int szidx=0; - switch( bits ) - { - case 8: szidx=0; break; - case 16: szidx=1; break; - case 32: szidx=2; break; - case 64: szidx=3; break; - case 128: szidx=4; break; - } - MOVZX32R8toR(EAX,EAX); - SUB32RtoR(ECX,EAX); - //eax=[funct+eax] - MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.RWFT[szidx][1],2); - SUB32ItoR(ECX,0x80000000); - CALL32R(EAX); -} - -// ------------------------------------------------------------------------ void vtlb_DynGenWrite(u32 sz) { - MOV32RtoR(EAX,ECX); - SHR32ItoR(EAX,VTLB_PAGE_BITS); - MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.vmap,2); - ADD32RtoR(ECX,EAX); - xForwardJS8 _full; + uptr* writeback = DynGen_PrepRegs(); - _vtlb_DynGen_DirectWrite( sz ); - xForwardJump8 cont; + DynGen_IndirectDispatch( 1, sz ); + DynGen_DirectWrite( sz ); - _full.SetTarget(); - _vtlb_DynGen_IndirectWrite( sz ); - - cont.SetTarget(); + *writeback = (uptr)xGetPtr(); } @@ -478,13 +509,15 @@ void vtlb_DynGenWrite_Const( u32 bits, u32 addr_const ) { //8 , 16, 32 : data on EDX case 8: - MOV8RtoM(ppf,EDX); + xMOV( ptr[ppf], dl ); break; + case 16: - MOV16RtoM(ppf,EDX); + xMOV( ptr[ppf], dx ); break; + case 32: - MOV32RtoM(ppf,EDX); + xMOV( ptr[ppf], edx ); break; case 64: @@ -513,8 +546,8 @@ void vtlb_DynGenWrite_Const( u32 bits, u32 addr_const ) case 128: szidx=4; break; } - MOV32ItoR( ECX, paddr ); - CALLFunc( (int)vtlbdata.RWFT[szidx][1][handler] ); + xMOV( ecx, paddr ); + xCALL( vtlbdata.RWFT[szidx][1][handler] ); } } diff --git a/pcsx2/x86/ix86/Makefile.am b/pcsx2/x86/ix86/Makefile.am deleted file mode 100644 index 46d18b2017..0000000000 --- a/pcsx2/x86/ix86/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -INCLUDES = -I@srcdir@/.. -I@srcdir@/../../ -I@srcdir@/../../../common/include -I@srcdir@/../../../3rdparty -I/implement -I/implement/xmm $(shell wx-config --cppflags) -noinst_LIBRARIES = libix86.a - -libix86_a_SOURCES = \ -ix86.cpp ix86_cpudetect.cpp ix86_fpu.cpp ix86_jmp.cpp ix86_tools.cpp ix86_3dnow.cpp \ -ix86_legacy.cpp ix86_legacy_sse.cpp ix86_simd.cpp \ -ix86_internal.h ix86_legacy_instructions.h ix86_macros.h ix86_sse_helpers.h ix86.h ix86_legacy_internal.h \ -ix86_instructions.h ix86_legacy_types.h ix86_types.h \ -bittest.h dwshift.h group1.h group2.h group3.h incdec.h jmpcall.h movs.h test.h \ -movqss.h arithmetic.h shufflepack.h basehelpers.h comparisons.h moremovs.h xchg.h \ No newline at end of file diff --git a/pcsx2/x86/ix86/implement/movs.h b/pcsx2/x86/ix86/implement/movs.h deleted file mode 100644 index b8b5323db1..0000000000 --- a/pcsx2/x86/ix86/implement/movs.h +++ /dev/null @@ -1,308 +0,0 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#pragma once - -// Header: ix86_impl_movs.h -- covers mov, cmov, movsx/movzx, and SETcc (which shares -// with cmov many similarities). - -// Note: This header is meant to be included from within the x86Emitter::Internal namespace. - -////////////////////////////////////////////////////////////////////////////////////////// -// MOV instruction Implementation - -template< typename ImmType > -class MovImpl -{ -protected: - static const uint OperandSize = sizeof(ImmType); - static bool Is8BitOperand() { return OperandSize == 1; } - static void prefix16() { if( OperandSize == 2 ) xWrite8( 0x66 ); } - -public: - MovImpl() {} - - // ------------------------------------------------------------------------ - static __emitinline void Emit( const xRegister& to, const xRegister& from ) - { - if( to == from ) return; // ignore redundant MOVs. - - prefix16(); - xWrite8( Is8BitOperand() ? 0x88 : 0x89 ); - EmitSibMagic( from, to ); - } - - // ------------------------------------------------------------------------ - static __emitinline void Emit( const ModSibBase& dest, const xRegister& from ) - { - prefix16(); - - // mov eax has a special from when writing directly to a DISP32 address - // (sans any register index/base registers). - - if( from.IsAccumulator() && dest.Index.IsEmpty() && dest.Base.IsEmpty() ) - { - xWrite8( Is8BitOperand() ? 0xa2 : 0xa3 ); - xWrite32( dest.Displacement ); - } - else - { - xWrite8( Is8BitOperand() ? 0x88 : 0x89 ); - EmitSibMagic( from.Id, dest ); - } - } - - // ------------------------------------------------------------------------ - static __emitinline void Emit( const xRegister& to, const ModSibBase& src ) - { - prefix16(); - - // mov eax has a special from when reading directly from a DISP32 address - // (sans any register index/base registers). - - if( to.IsAccumulator() && src.Index.IsEmpty() && src.Base.IsEmpty() ) - { - xWrite8( Is8BitOperand() ? 0xa0 : 0xa1 ); - xWrite32( src.Displacement ); - } - else - { - xWrite8( Is8BitOperand() ? 0x8a : 0x8b ); - EmitSibMagic( to, src ); - } - } - - // ------------------------------------------------------------------------ - static __emitinline void Emit( void* dest, const xRegister& from ) - { - prefix16(); - - // mov eax has a special from when writing directly to a DISP32 address - - if( from.IsAccumulator() ) - { - xWrite8( Is8BitOperand() ? 0xa2 : 0xa3 ); - xWrite( (s32)dest ); - } - else - { - xWrite8( Is8BitOperand() ? 0x88 : 0x89 ); - EmitSibMagic( from, dest ); - } - } - - // ------------------------------------------------------------------------ - static __emitinline void Emit( const xRegister& to, const void* src ) - { - prefix16(); - - // mov eax has a special from when reading directly from a DISP32 address - - if( to.IsAccumulator() ) - { - xWrite8( Is8BitOperand() ? 0xa0 : 0xa1 ); - xWrite( (s32)src ); - } - else - { - xWrite8( Is8BitOperand() ? 0x8a : 0x8b ); - EmitSibMagic( to, src ); - } - } - - // ------------------------------------------------------------------------ - static __emitinline void Emit( const xRegister& to, ImmType imm ) - { - // Note: MOV does not have (reg16/32,imm8) forms. - - prefix16(); - xWrite8( (Is8BitOperand() ? 0xb0 : 0xb8) | to.Id ); - xWrite( imm ); - } - - // ------------------------------------------------------------------------ - static __emitinline void Emit( ModSibStrict dest, ImmType imm ) - { - prefix16(); - xWrite8( Is8BitOperand() ? 0xc6 : 0xc7 ); - EmitSibMagic( 0, dest ); - xWrite( imm ); - } -}; - -// ------------------------------------------------------------------------ -class MovImplAll -{ -public: - template< typename T > - __forceinline void operator()( const xRegister& to, const xRegister& from ) const { MovImpl::Emit( to, from ); } - template< typename T > - __forceinline void operator()( const xRegister& to, const void* src ) const { MovImpl::Emit( to, src ); } - template< typename T > - __forceinline void operator()( void* dest, const xRegister& from ) const { MovImpl::Emit( dest, from ); } - template< typename T > - __noinline void operator()( const ModSibBase& sibdest, const xRegister& from ) const { MovImpl::Emit( sibdest, from ); } - template< typename T > - __noinline void operator()( const xRegister& to, const ModSibBase& sibsrc ) const { MovImpl::Emit( to, sibsrc ); } - - template< typename T > - __noinline void operator()( const ModSibStrict& sibdest, int imm ) const { MovImpl::Emit( sibdest, imm ); } - - // preserve_flags - set to true to disable optimizations which could alter the state of - // the flags (namely replacing mov reg,0 with xor). - - template< typename T > - __emitinline void operator()( const xRegister& to, int imm, bool preserve_flags=false ) const - { - if( !preserve_flags && (imm == 0) ) - xXOR( to, to ); - else - MovImpl::Emit( to, imm ); - } - - MovImplAll() {} // Satisfy GCC's whims. -}; - -#define ccSane() jASSUME( ccType >= 0 && ccType <= 0x0f ) - -////////////////////////////////////////////////////////////////////////////////////////// -// CMOV !! [in all of it's disappointing lack-of glory] .. and .. -// SETcc!! [more glory, less lack!] -// -// CMOV Disclaimer: Caution! This instruction can look exciting and cool, until you -// realize that it cannot load immediate values into registers. -_- -// -// I use explicit method declarations here instead of templates, in order to provide -// *only* 32 and 16 bit register operand forms (8 bit registers are not valid in CMOV). -// -class CMovImplGeneric -{ -public: - __forceinline void operator()( JccComparisonType ccType, const xRegister32& to, const xRegister32& from ) const { ccSane(); xOpWrite0F( 0x40 | ccType, to, from ); } - __forceinline void operator()( JccComparisonType ccType, const xRegister32& to, const void* src ) const { ccSane(); xOpWrite0F( 0x40 | ccType, to, src ); } - __forceinline void operator()( JccComparisonType ccType, const xRegister32& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( 0x40 | ccType, to, sibsrc ); } - - __forceinline void operator()( JccComparisonType ccType, const xRegister16& to, const xRegister16& from ) const { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, from ); } - __forceinline void operator()( JccComparisonType ccType, const xRegister16& to, const void* src ) const { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, src ); } - __forceinline void operator()( JccComparisonType ccType, const xRegister16& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, sibsrc ); } - - CMovImplGeneric() {} // don't ask. -}; - -// ------------------------------------------------------------------------ -template< JccComparisonType ccType > -class CMovImplAll -{ - static const u16 Opcode = 0x40 | ccType; - -public: - __forceinline void operator()( const xRegister32& to, const xRegister32& from ) const { ccSane(); xOpWrite0F( Opcode, to, from ); } - __forceinline void operator()( const xRegister32& to, const void* src ) const { ccSane(); xOpWrite0F( Opcode, to, src ); } - __forceinline void operator()( const xRegister32& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( Opcode, to, sibsrc ); } - - __forceinline void operator()( const xRegister16& to, const xRegister16& from ) const { ccSane(); xOpWrite0F( 0x66, Opcode, to, from ); } - __forceinline void operator()( const xRegister16& to, const void* src ) const { ccSane(); xOpWrite0F( 0x66, Opcode, to, src ); } - __forceinline void operator()( const xRegister16& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( 0x66, Opcode, to, sibsrc ); } - - CMovImplAll() {} // don't ask. -}; - -// ------------------------------------------------------------------------ -class SetImplGeneric -{ - // note: SETcc are 0x90, with 0 in the Reg field of ModRM. -public: - __forceinline void operator()( JccComparisonType ccType, const xRegister8& to ) const { ccSane(); xOpWrite0F( 0x90 | ccType, 0, to ); } - __forceinline void operator()( JccComparisonType ccType, void* dest ) const { ccSane(); xOpWrite0F( 0x90 | ccType, 0, dest ); } - __noinline void operator()( JccComparisonType ccType, const ModSibStrict& dest ) const { ccSane(); xOpWrite0F( 0x90 | ccType, 0, dest ); } - - SetImplGeneric() {} // if you do, ask GCC. -}; - -// ------------------------------------------------------------------------ -template< JccComparisonType ccType > -class SetImplAll -{ - static const u16 Opcode = 0x90 | ccType; // SETcc are 0x90 base opcode, with 0 in the Reg field of ModRM. - -public: - __forceinline void operator()( const xRegister8& to ) const { ccSane(); xOpWrite0F( Opcode, 0, to ); } - __forceinline void operator()( void* dest ) const { ccSane(); xOpWrite0F( Opcode, 0, dest ); } - __noinline void operator()( const ModSibStrict& dest ) const { ccSane(); xOpWrite0F( Opcode, 0, dest ); } - - SetImplAll() {} // if you do, ask GCC. -}; - - -////////////////////////////////////////////////////////////////////////////////////////// -// Mov with sign/zero extension implementations (movsx / movzx) -// -template< typename DestImmType, typename SrcImmType > -class MovExtendImpl -{ -protected: - static const uint DestOperandSize = sizeof( DestImmType ); - static const uint SrcOperandSize = sizeof( SrcImmType ); - - static bool Is8BitOperand() { return SrcOperandSize == 1; } - static void prefix16() { if( DestOperandSize == 2 ) xWrite8( 0x66 ); } - static __forceinline void emit_base( bool SignExtend ) - { - prefix16(); - xWrite8( 0x0f ); - xWrite8( 0xb6 | (Is8BitOperand() ? 0 : 1) | (SignExtend ? 8 : 0 ) ); - } - -public: - MovExtendImpl() {} // For the love of GCC. - - static __emitinline void Emit( const xRegister& to, const xRegister& from, bool SignExtend ) - { - emit_base( SignExtend ); - EmitSibMagic( to, from ); - } - - static __emitinline void Emit( const xRegister& to, const ModSibStrict& sibsrc, bool SignExtend ) - { - emit_base( SignExtend ); - EmitSibMagic( to, sibsrc ); - } -}; - -// ------------------------------------------------------------------------ -template< bool SignExtend > -class MovExtendImplAll -{ -protected: - typedef MovExtendImpl m_16to32; - typedef MovExtendImpl m_8to32; - typedef MovExtendImpl m_8to16; - -public: - __forceinline void operator()( const xRegister32& to, const xRegister16& from ) const { m_16to32::Emit( to, from, SignExtend ); } - __noinline void operator()( const xRegister32& to, const ModSibStrict& sibsrc ) const { m_16to32::Emit( to, sibsrc, SignExtend ); } - - __forceinline void operator()( const xRegister32& to, const xRegister8& from ) const { m_8to32::Emit( to, from, SignExtend ); } - __noinline void operator()( const xRegister32& to, const ModSibStrict& sibsrc ) const { m_8to32::Emit( to, sibsrc, SignExtend ); } - - __forceinline void operator()( const xRegister16& to, const xRegister8& from ) const { m_8to16::Emit( to, from, SignExtend ); } - __noinline void operator()( const xRegister16& to, const ModSibStrict& sibsrc ) const { m_8to16::Emit( to, sibsrc, SignExtend ); } - - MovExtendImplAll() {} // don't ask. -}; - diff --git a/pcsx2/x86/microVU.cpp b/pcsx2/x86/microVU.cpp index 72e8aa9cf1..7cf5f92994 100644 --- a/pcsx2/x86/microVU.cpp +++ b/pcsx2/x86/microVU.cpp @@ -1,26 +1,25 @@ /* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2009 Pcsx2-Playground Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ + * Copyright (C) 2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ // Micro VU recompiler! - author: cottonvibes(@gmail.com) #include "PrecompiledHeader.h" #include "microVU.h" -#ifdef PCSX2_MICROVU //------------------------------------------------------------------ // Micro VU - Global Variables @@ -30,97 +29,99 @@ PCSX2_ALIGNED16(microVU microVU0); PCSX2_ALIGNED16(microVU microVU1); declareAllVariables // Declares All Global Variables :D + //------------------------------------------------------------------ // Micro VU - Main Functions //------------------------------------------------------------------ // Only run this once per VU! ;) -microVUt(void) mVUinit(VURegs* vuRegsPtr) { - - microVU* mVU = mVUx; - mVU->regs = vuRegsPtr; - mVU->index = vuIndex; - mVU->microSize = (vuIndex ? 0x4000 : 0x1000); - mVU->progSize = (vuIndex ? 0x4000 : 0x1000) / 4; - mVU->cache = NULL; - memset(&mVU->prog, 0, sizeof(mVU->prog)); - mVUprint((vuIndex) ? "microVU1: init" : "microVU0: init"); - - mVUreset(); -} - -// Will Optimize later -microVUt(void) mVUreset() { +microVUt(void) mVUinit(VURegs* vuRegsPtr, int vuIndex) { microVU* mVU = mVUx; - mVUclose(); // Close + memset(&mVU->prog, 0, sizeof(mVU->prog)); - mVUprint((vuIndex) ? "microVU1: reset" : "microVU0: reset"); + mVU->regs = vuRegsPtr; + mVU->index = vuIndex; + mVU->vuMemSize = (vuIndex ? 0x4000 : 0x1000); + mVU->microMemSize = (vuIndex ? 0x4000 : 0x1000); + mVU->progSize = (vuIndex ? 0x4000 : 0x1000) / 4; + mVU->cache = NULL; + mVU->cacheSize = mVUcacheSize; + mVU->prog.max = mMaxProg - 1; + mVUprint((vuIndex) ? "microVU1: init" : "microVU0: init"); + + mVU->cache = SysMmapEx((vuIndex ? 0x5f240000 : 0x5e240000), mVU->cacheSize + 0x1000, 0, (vuIndex ? "Micro VU1" : "Micro VU0")); + if (!mVU->cache) throw Exception::OutOfMemory(L"microVU Error: Failed to allocate recompiler memory!"); + + mVUemitSearch(); + mVUreset(mVU); +} + +// Resets Rec Data +microVUt(void) mVUreset(mV) { + + mVUprint((mVU->index) ? "microVU1: reset" : "microVU0: reset"); + mVUclose(mVU, 1); // Dynarec Cache - mVU->cache = SysMmapEx((vuIndex ? 0x1e840000 : 0x0e840000), mVU->cacheSize, 0, (vuIndex ? "Micro VU1" : "Micro VU0")); - if ( mVU->cache == NULL ) throw Exception::OutOfMemory(fmt_string( "microVU Error: Failed to allocate recompiler memory! (addr: 0x%x)", params (u32)mVU->cache)); - memset(mVU->cache, 0xcc, mVU->cacheSize); + memset(mVU->cache, 0xcc, mVU->cacheSize + 0x1000); // Setup Entrance/Exit Points x86SetPtr(mVU->cache); - mVUdispatcherA(); - mVUdispatcherB(); + mVUdispatcherA(mVU); + mVUdispatcherB(mVU); // Clear All Program Data memset(&mVU->prog, 0, sizeof(mVU->prog)); - - // Create Block Managers - for (int i = 0; i <= mVU->prog.max; i++) { - for (u32 j = 0; j < (mVU->progSize / 2); j++) { - mVU->prog.prog[i].block[j] = new microBlockManager(); - } - } + memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState)); // Program Variables - mVU->prog.finished = 1; - mVU->prog.cleared = 1; - mVU->prog.cur = -1; - mVU->prog.total = -1; - memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState)); - //mVU->prog.lpState = &mVU->prog.prog[15].allocInfo.block.pState; // Blank Pipeline State (ToDo: finish implementation) + mVU->prog.cleared = 1; + mVU->prog.isSame = -1; + mVU->prog.cur = -1; + mVU->prog.total = -1; + mVU->prog.max = mMaxProg - 1; + mVU->prog.prog = (microProgram*)_aligned_malloc(sizeof(microProgram)*(mVU->prog.max+1), 64); // Setup Dynarec Cache Limits for Each Program - u8* z = (mVU->cache + 512); // Dispatcher Code is in first 512 bytes + u8* z = (mVU->cache + 0x1000); // Dispatcher Code is in first page of cache for (int i = 0; i <= mVU->prog.max; i++) { mVU->prog.prog[i].x86start = z; mVU->prog.prog[i].x86ptr = z; z += (mVU->cacheSize / (mVU->prog.max + 1)); mVU->prog.prog[i].x86end = z; - } -} - -// Free Allocated Resources -microVUt(void) mVUclose() { - - microVU* mVU = mVUx; - mVUprint((vuIndex) ? "microVU1: close" : "microVU0: close"); - - if ( mVU->cache ) { HostSys::Munmap( mVU->cache, mVU->cacheSize ); mVU->cache = NULL; } - - // Delete Block Managers - for (int i = 0; i <= mVU->prog.max; i++) { - for (u32 j = 0; j < (mVU->progSize / 2); j++) { - if (mVU->prog.prog[i].block[j]) delete mVU->prog.prog[i].block[j]; + for (int j = 0; j <= mVU->prog.prog[i].ranges.max; j++) { + mVU->prog.prog[i].ranges.range[j][0] = -1; // Set range to + mVU->prog.prog[i].ranges.range[j][1] = -1; // indeterminable status + mVU->prog.prog[i].ranges.total = -1; } } } -// Clears Block Data in specified range -microVUt(void) mVUclear(u32 addr, u32 size) { +// Free Allocated Resources +microVUt(void) mVUclose(mV, bool isReset) { - microVU* mVU = mVUx; - memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState)); - mVU->prog.cleared = 1; // Next execution searches/creates a new microprogram - // Note: It might be better to copy old recompiled blocks to the new microprogram rec data - // however, if games primarily do big writes, its probably not worth it. - // The cost of invalidating bad blocks is also kind of expensive, which is another reason - // that its probably not worth it... + mVUprint((mVU->index) ? "microVU1: close" : "microVU0: close"); + + if (!isReset && mVU->cache) { HostSys::Munmap(mVU->cache, mVU->cacheSize); mVU->cache = NULL; } + + // Delete Programs and Block Managers + if (mVU->prog.prog) { + for (int i = 0; i <= mVU->prog.max; i++) { + for (u32 j = 0; j < (mVU->progSize / 2); j++) { + microBlockManager::Delete(mVU->prog.prog[i].block[j]); + } + } + if (!isReset) { _aligned_free(mVU->prog.prog); } + } +} + +// Clears Block Data in specified range +microVUt(void) mVUclear(mV, u32 addr, u32 size) { + //if (!mVU->prog.cleared) { + //memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState)); + mVU->prog.cleared = 1; // Next execution searches/creates a new microprogram + //} } //------------------------------------------------------------------ @@ -128,114 +129,147 @@ microVUt(void) mVUclear(u32 addr, u32 size) { //------------------------------------------------------------------ // Clears program data (Sets used to 1 because calling this function implies the program will be used at least once) -microVUt(void) mVUclearProg(int progIndex) { +microVUf(void) mVUclearProg(int progIndex) { microVU* mVU = mVUx; - mVU->prog.prog[progIndex].used = 1; - mVU->prog.prog[progIndex].x86ptr = mVU->prog.prog[progIndex].x86start; + mVUprogI.used = 1; + mVUprogI.last_used = 3; + mVUprogI.x86ptr = mVUprogI.x86start; + for (int j = 0; j <= mVUprogI.ranges.max; j++) { + mVUprogI.ranges.range[j][0] = -1; // Set range to + mVUprogI.ranges.range[j][1] = -1; // indeterminable status + mVUprogI.ranges.total = -1; + } for (u32 i = 0; i < (mVU->progSize / 2); i++) { - mVU->prog.prog[progIndex].block[i]->reset(); + if (mVUprogI.block[i]) mVUprogI.block[i]->reset(); } } // Caches Micro Program -microVUt(void) mVUcacheProg(int progIndex) { +microVUf(void) mVUcacheProg(int progIndex) { microVU* mVU = mVUx; - memcpy_fast(mVU->prog.prog[progIndex].data, mVU->regs->Micro, mVU->microSize); + memcpy_fast(mVU->prog.prog[progIndex].data, mVU->regs->Micro, mVU->microMemSize); mVUdumpProg(progIndex); } // Finds the least used program, (if program list full clears and returns an old program; if not-full, returns free program) -microVUt(int) mVUfindLeastUsedProg() { +microVUf(int) mVUfindLeastUsedProg() { microVU* mVU = mVUx; if (mVU->prog.total < mVU->prog.max) { mVU->prog.total++; mVUcacheProg(mVU->prog.total); // Cache Micro Program + mVU->prog.prog[mVU->prog.total].used = 1; + mVU->prog.prog[mVU->prog.total].last_used = 3; Console::Notice("microVU%d: Cached MicroPrograms = %d", params vuIndex, mVU->prog.total+1); return mVU->prog.total; } else { - int j = (mVU->prog.cur + 1) & mVU->prog.max; - /*u32 smallest = mVU->prog.prog[j].used; - for (int i = ((j+1)&mVU->prog.max), z = 0; z < mVU->prog.max; i = (i+1)&mVU->prog.max, z++) { - if (smallest > mVU->prog.prog[i].used) { - smallest = mVU->prog.prog[i].used; - j = i; + + const int pMax = mVU->prog.max; + int smallidx = (mVU->prog.cur+1)&pMax; + u64 smallval = mVU->prog.prog[smallidx].used; + + for (int i = 1, j = (smallidx+1)&pMax; i <= pMax; i++, j=(j+1)&pMax) { + if (smallval > mVU->prog.prog[j].used) { + smallval = mVU->prog.prog[j].used; + smallidx = j; } - }*/ - mVUclearProg(j); // Clear old data if overwriting old program - mVUcacheProg(j); // Cache Micro Program - Console::Notice("microVU%d: MicroProgram Cache Full!", params vuIndex); - return j; + } + + mVUclearProg(smallidx); // Clear old data if overwriting old program + mVUcacheProg(smallidx); // Cache Micro Program + //Console::Notice("microVU%d: Overwriting existing program in slot %d [%d times used]", params vuIndex, smallidx, smallval); + return smallidx; } } +// mVUvsyncUpdate --> +// This should be run at 30fps intervals from Counters.cpp (or 60fps works too, but 30fps is +// probably all we need for accurate results) +// +// To fix the program cache to more efficiently dispose of "obsolete" programs, we need to use a +// frame-based decrementing system in combination with a program-execution-based incrementing +// system. In English: if last_used >= 2 it means the program has been used for the current +// or prev frame. if it's 0, the program hasn't been used for a while. +microVUt(void) mVUvsyncUpdate(mV) { + + if (mVU->prog.total < mVU->prog.max) return; + + for (int i = 0; i <= mVU->prog.max; i++) { + if (mVU->prog.prog[i].last_used != 0) { + if (mVU->prog.prog[i].last_used >= 3) { + mVU->prog.prog[i].used += 0x200; // give 'weighted' bonus + } + mVU->prog.prog[i].last_used--; + } + else mVU->prog.prog[i].used /= 2; // penalize unused programs. + } +} + +microVUf(bool) mVUcmpPartial(int progIndex) { + microVU* mVU = mVUx; + for (int i = 0; i <= mVUprogI.ranges.total; i++) { + if (memcmp_mmx(cmpOffset(mVUprogI.data), cmpOffset(mVU->regs->Micro), ((mVUprogI.ranges.range[i][1] + 8) - mVUprogI.ranges.range[i][0]))) { + return 0; + } + } + return 1; +} + +// Compare Cached microProgram to mVU->regs->Micro +microVUf(bool) mVUcmpProg(int progIndex, bool progUsed, const bool cmpWholeProg) { + microVU* mVU = mVUx; + if (progUsed) { + if ((cmpWholeProg && !memcmp_mmx((u8*)mVUprogI.data, mVU->regs->Micro, mVU->microMemSize)) + || (!cmpWholeProg && mVUcmpPartial(progIndex))) { + mVU->prog.cur = progIndex; + mVU->prog.cleared = 0; + mVU->prog.isSame = cmpWholeProg ? 1 : -1; + mVU->prog.prog[progIndex].last_used = 3; + mVU->prog.prog[progIndex].used++; // increment 'used' + return 1; + } + } + return 0; +} + // Searches for Cached Micro Program and sets prog.cur to it (returns 1 if program found, else returns 0) -microVUt(int) mVUsearchProg() { +microVUf(int) mVUsearchProg() { microVU* mVU = mVUx; + if (mVU->prog.cleared) { // If cleared, we need to search for new program for (int i = 0; i <= mVU->prog.total; i++) { - if (!memcmp_mmx(mVU->prog.prog[i].data, mVU->regs->Micro, mVU->microSize)) { - mVU->prog.cur = i; - mVU->prog.cleared = 0; - mVU->prog.prog[i].used++; - return 1; - } + if (mVUcmpProg(i, !!mVU->prog.prog[i].used, 0)) + return 1; // Check Recently Used Programs + } + for (int i = 0; i <= mVU->prog.total; i++) { + if (mVUcmpProg(i, !mVU->prog.prog[i].used, 0)) + return 1; // Check Older Programs } mVU->prog.cur = mVUfindLeastUsedProg(); // If cleared and program not found, make a new program instance mVU->prog.cleared = 0; + mVU->prog.isSame = 1; return 0; } mVU->prog.prog[mVU->prog.cur].used++; + mVU->prog.prog[mVU->prog.cur].last_used = 3; return 1; // If !cleared, then we're still on the same program as last-time ;) } -/* -// Block Invalidation -__forceinline void mVUinvalidateBlock(microVU* mVU, u32 addr, u32 size) { - int i = addr/8; - int end = i+((size+(8-(size&7)))/8); // ToDo: Can be simplified to addr+size if Size is always a multiple of 8 - - if (!mVU->prog.cleared) { - for ( ; i < end; i++) { - if ( mVU->prog.prog[mVU->prog.cur].block[i]->clear() ) { - mVU->prog.cleared = 1; - i++; - break; - } - } - } - for ( ; i < end; i++) { - mVU->prog.prog[mVU->prog.cur].block[i]->clearFast(); - } -} -*/ //------------------------------------------------------------------ // Wrapper Functions - Called by other parts of the Emu //------------------------------------------------------------------ -void initVUrec(VURegs* vuRegs, const int vuIndex) { - if (!vuIndex) mVUinit<0>(vuRegs); - else mVUinit<1>(vuRegs); +void initVUrec (VURegs* vuRegs, const int vuIndex) { mVUinit(vuRegs, vuIndex); } +void closeVUrec(const int vuIndex) { mVUclose(mVUx, 0); } +void resetVUrec(const int vuIndex) { mVUreset(mVUx); } +void vsyncVUrec(const int vuIndex) { mVUvsyncUpdate(mVUx); } + +void __fastcall clearVUrec(u32 addr, u32 size, const int vuIndex) { + mVUclear(mVUx, addr, size); } -void closeVUrec(const int vuIndex) { - if (!vuIndex) mVUclose<0>(); - else mVUclose<1>(); +void __fastcall runVUrec(u32 startPC, u32 cycles, const int vuIndex) { + if (!vuIndex) ((mVUrecCall)microVU0.startFunct)(startPC, cycles); + else ((mVUrecCall)microVU1.startFunct)(startPC, cycles); } -void resetVUrec(const int vuIndex) { - if (!vuIndex) mVUreset<0>(); - else mVUreset<1>(); -} - -void clearVUrec(u32 addr, u32 size, const int vuIndex) { - if (!vuIndex) mVUclear<0>(addr, size); - else mVUclear<1>(addr, size); -} - -void runVUrec(u32 startPC, u32 cycles, const int vuIndex) { - if (!vuIndex) startVU0(startPC, cycles); - else startVU1(startPC, cycles); -} - -#endif // PCSX2_MICROVU diff --git a/pcsx2/x86/microVU.h b/pcsx2/x86/microVU.h index 9c829d53d6..cb23137b94 100644 --- a/pcsx2/x86/microVU.h +++ b/pcsx2/x86/microVU.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2009 Pcsx2-Playground Team + * Copyright (C) 2009 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,127 +17,168 @@ */ #pragma once -#define mVUdebug // Prints Extra Info to Console -#define mVUlogProg // Dumps MicroPrograms into microVU0.txt/microVU1.txt +//#define mVUdebug // Prints Extra Info to Console +//#define mVUlogProg // Dumps MicroPrograms to \logs\*.html + #include "Common.h" #include "VU.h" #include "GS.h" -#include "ix86/ix86.h" -#include "microVU_Alloc.h" +#include "x86emitter/x86emitter.h" +#include "microVU_IR.h" #include "microVU_Misc.h" + #define mMaxBlocks 32 // Max Blocks With Different Pipeline States (For n = 1, 2, 4, 8, 16, etc...) class microBlockManager { private: static const int MaxBlocks = mMaxBlocks - 1; + microBlock blockList[mMaxBlocks]; // Should always be first in the class to ensure 16-byte alignment int listSize; // Total Items - 1 - microBlock blockList[mMaxBlocks]; + int listI; // Index to Add new block public: + // Aligned replacement for 'new' + static microBlockManager* AlignedNew() { + microBlockManager* alloc = (microBlockManager*)_aligned_malloc(sizeof(microBlockManager), 16); + new (alloc) microBlockManager(); + return alloc; + } + // Use instead of normal 'delete' + static void Delete(microBlockManager* dead) { + if (dead == NULL) return; + dead->~microBlockManager(); + _aligned_free(dead); + } + microBlockManager() { reset(); } ~microBlockManager() {} - void reset() { listSize = -1; }; + void reset() { listSize = -1; listI = -1; }; microBlock* add(microBlock* pBlock) { microBlock* thisBlock = search(&pBlock->pState); if (!thisBlock) { - listSize++; - if (listSize > MaxBlocks) { Console::Error("microVU Warning: Block List Overflow"); listSize &= MaxBlocks; } - memcpy_fast(&blockList[listSize], pBlock, sizeof(microBlock)); - thisBlock = &blockList[listSize]; + listI++; + if (listSize < MaxBlocks) { listSize++; } + if (listI > MaxBlocks) { Console::Error("microVU Warning: Block List Overflow"); listI = 0; } + memcpy_fast(&blockList[listI], pBlock, sizeof(microBlock)); + thisBlock = &blockList[listI]; } return thisBlock; } - microBlock* search(microRegInfo* pState) { + __forceinline microBlock* search(microRegInfo* pState) { if (listSize < 0) return NULL; - //if (blockList[0].pState.needExactMatch) { // Needs Detailed Search (Exact Match of Pipeline State) + if (pState->needExactMatch) { // Needs Detailed Search (Exact Match of Pipeline State) for (int i = 0; i <= listSize; i++) { - if (!memcmp(pState, &blockList[i].pState, sizeof(microRegInfo) - 1)) return &blockList[i]; + if (mVUquickSearch((void*)pState, (void*)&blockList[i].pState, sizeof(microRegInfo))) return &blockList[i]; } - /*} + } else { // Can do Simple Search (Only Matches the Important Pipeline Stuff) for (int i = 0; i <= listSize; i++) { - if ((blockList[i].pState.q == pState->q) && (blockList[i].pState.p == pState->p)) { return &blockList[i]; } + if ((blockList[i].pState.q == pState->q) + && (blockList[i].pState.p == pState->p) + && (blockList[i].pState.xgkick == pState->xgkick) + && (blockList[i].pState.flags == pState->flags) + && !(blockList[i].pState.needExactMatch & 0xf0f)) { return &blockList[i]; } } - }*/ + } return NULL; } }; -template +#define mMaxRanges 128 +struct microRange { + static const int max = mMaxRanges - 1; + int total; + s32 range[mMaxRanges][2]; +}; + +#define mProgSize 0x4000/4 struct microProgram { - u32 data[progSize/4]; - u32 used; // Number of times its been used + u32 data [mProgSize]; // Holds a copy of the VU microProgram + microBlockManager* block[mProgSize/2]; // Array of Block Managers + microIR allocInfo; // IR information + microRange ranges; // The ranges of the microProgram that have already been recompiled + u64 used; // Number of times its been used + u32 last_used; // Counters # of frames since last use (starts at 3 and counts backwards to 0 for each 30fps vSync) u8* x86ptr; // Pointer to program's recompilation code u8* x86start; // Start of program's rec-cache u8* x86end; // Limit of program's rec-cache - microBlockManager* block[progSize/8]; - microAllocInfo allocInfo; }; -#define mMaxProg 16 // The amount of Micro Programs Recs will 'remember' (For n = 1, 2, 4, 8, 16, etc...) -template +#define mMaxProg ((mVU->index)?64:8) // The amount of Micro Programs Recs will 'remember' (For n = 1, 2, 4, 8, 16, etc...) struct microProgManager { - microProgram prog[mMaxProg]; // Store MicroPrograms in memory - static const int max = mMaxProg - 1; - int cur; // Index to Current MicroProgram thats running (-1 = uncached) - int total; // Total Number of valid MicroPrograms minus 1 - int cleared; // Micro Program is Indeterminate so must be searched for (and if no matches are found then recompile a new one) - int finished; // Completed MicroProgram by E-bit Termination - microRegInfo lpState; // Pipeline state from where program left off (useful for continuing execution) + microProgram* prog; // Store MicroPrograms in memory + int max; // Max Number of MicroPrograms minus 1 + int total; // Total Number of valid MicroPrograms minus 1 + int cur; // Index to Current MicroProgram thats running (-1 = uncached) + int isSame; // Current cached microProgram is Exact Same program as mVU->regs->Micro (-1 = unknown, 0 = No, 1 = Yes) + int cleared; // Micro Program is Indeterminate so must be searched for (and if no matches are found then recompile a new one) + microRegInfo lpState; // Pipeline state from where program left off (useful for continuing execution) }; +#define mVUcacheSize (mMaxProg * 0xCCCCC) // 0.8mb per program struct microVU { - u32 index; // VU Index (VU0 or VU1) - u32 microSize; // VU Micro Memory Size - u32 progSize; // VU Micro Program Size (microSize/4) - static const u32 cacheSize = 0x800000; // VU Cache Size - microProgManager<0x4000> prog; // Micro Program Data + PCSX2_ALIGNED16(u32 macFlag[4]); // 4 instances of mac flag (used in execution) + PCSX2_ALIGNED16(u32 clipFlag[4]); // 4 instances of clip flag (used in execution) + PCSX2_ALIGNED16(u32 xmmPQb[4]); // Backup for xmmPQ + PCSX2_ALIGNED16(u32 xmmVFb[4]); // Backup for VF regs + + u32 index; // VU Index (VU0 or VU1) + u32 vuMemSize; // VU Main Memory Size (in bytes) + u32 microMemSize; // VU Micro Memory Size (in bytes) + u32 progSize; // VU Micro Memory Size (in u32's) + u32 cacheSize; // VU Cache Size + + microProgManager prog; // Micro Program Data FILE* logFile; // Log File Pointer VURegs* regs; // VU Regs Struct u8* cache; // Dynarec Cache Start (where we will start writing the recompiled code to) u8* startFunct; // Ptr Function to the Start code for recompiled programs - u8* exitFunct; // Ptr Function to the Exit code for recompiled programs + u8* exitFunct; // Ptr Function to the Exit code for recompiled programs u32 code; // Contains the current Instruction - u32 iReg; // iReg (only used in recompilation, not execution) - u32 clipFlag[4]; // 4 instances of clip flag (used in execution) u32 divFlag; // 1 instance of I/D flags - u32 VIbackup[2]; // Holds a backup of a VI reg if modified before a branch + u32 VIbackup; // Holds a backup of a VI reg if modified before a branch + u32 VIxgkick; // Holds a backup of a VI reg used for xgkick-delays u32 branch; // Holds branch compare result (IBxx) OR Holds address to Jump to (JALR/JR) u32 p; // Holds current P instance index u32 q; // Holds current Q instance index - u32 espBackup; // Temp Backup for ESP - u32 totalCycles; - u32 cycles; - - PCSX2_ALIGNED16(u32 xmmPQb[4]); // Backup for xmmPQ + u32 totalCycles; // Total Cycles that mVU is expected to run for + u32 cycles; // Cycles Counter }; // microVU rec structs extern PCSX2_ALIGNED16(microVU microVU0); extern PCSX2_ALIGNED16(microVU microVU1); -// Opcode Tables -extern void (*mVU_UPPER_OPCODE[64])( VURegs* VU, s32 info ); -extern void (*mVU_LOWER_OPCODE[128])( VURegs* VU, s32 info ); +// Debug Helper +extern int mVUdebugNow; // Main Functions -microVUt(void) mVUinit(VURegs*); -microVUt(void) mVUreset(); -microVUt(void) mVUclose(); -microVUt(void) mVUclear(u32, u32); +microVUt(void) mVUinit(VURegs*, int); +microVUt(void) mVUreset(mV); +microVUt(void) mVUclose(mV, bool isReset); +microVUt(void) mVUclear(mV, u32, u32); +microVUt(void*) mVUblockFetch(microVU* mVU, u32 startPC, uptr pState); +microVUx(void*) __fastcall mVUcompileJIT(u32 startPC, uptr pState); + +// Prototypes for Linux +void __fastcall mVUcleanUpVU0(); +void __fastcall mVUcleanUpVU1(); +mVUop(mVUopU); +mVUop(mVUopL); // Private Functions -microVUt(void) mVUclearProg(microVU* mVU, int progIndex); -microVUt(int) mVUfindLeastUsedProg(microVU* mVU); -microVUt(int) mVUsearchProg(microVU* mVU); -microVUt(void) mVUcacheProg(microVU* mVU, int progIndex); +microVUf(int) mVUfindLeastUsedProg(microVU* mVU); +microVUf(int) mVUsearchProg(); +microVUf(void) mVUcacheProg(int progIndex); void* __fastcall mVUexecuteVU0(u32 startPC, u32 cycles); void* __fastcall mVUexecuteVU1(u32 startPC, u32 cycles); +// recCall Function Pointer typedef void (__fastcall *mVUrecCall)(u32, u32); + // Include all the *.inl files (Needed because C++ sucks with templates and *.cpp files) #include "microVU_Misc.inl" #include "microVU_Log.inl" @@ -146,5 +187,6 @@ typedef void (__fastcall *mVUrecCall)(u32, u32); #include "microVU_Upper.inl" #include "microVU_Lower.inl" #include "microVU_Tables.inl" +#include "microVU_Flags.inl" #include "microVU_Compile.inl" #include "microVU_Execute.inl" diff --git a/pcsx2/x86/microVU_Alloc.h b/pcsx2/x86/microVU_Alloc.h deleted file mode 100644 index a16c3f4396..0000000000 --- a/pcsx2/x86/microVU_Alloc.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2009 Pcsx2-Playground Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ - -#pragma once - - -union regInfo { - u32 reg; - struct { - u8 x; - u8 y; - u8 z; - u8 w; - }; -}; - -struct microRegInfo { - regInfo VF[32]; - u8 VI[32]; - u8 q; - u8 p; - u8 r; - u8 xgkick; - u8 clip; - u8 needExactMatch; // If set, block needs an exact match of pipeline state (needs to be last byte in struct) -}; - -struct microTempRegInfo { - regInfo VF[2]; // Holds cycle info for Fd, VF[0] = Upper Instruction, VF[1] = Lower Instruction - u8 VFreg[2]; // Index of the VF reg - u8 VI; // Holds cycle info for Id - u8 VIreg; // Index of the VI reg - u8 q; // Holds cycle info for Q reg - u8 p; // Holds cycle info for P reg - u8 r; // Holds cycle info for R reg (Will never cause stalls, but useful to know if R is modified) - u8 xgkick; // Holds the cycle info for XGkick -}; - -struct microBlock { - microRegInfo pState; // Detailed State of Pipeline - microRegInfo pStateEnd; // Detailed State of Pipeline at End of Block (needed by JR/JALR opcodes) - u8* x86ptrStart; // Start of code -}; - -template -struct microAllocInfo { - microBlock block; // Block/Pipeline info - microTempRegInfo regsTemp; // Temp Pipeline info (used so that new pipeline info isn't conflicting between upper and lower instructions in the same cycle) - u8 branch; // 0 = No Branch, 1 = B. 2 = BAL, 3~8 = Conditional Branches, 9 = JALR, 10 = JR - u32 cycles; // Cycles for current block - u32 count; // Number of VU 64bit instructions ran (starts at 0 for each block) - u32 curPC; // Current PC - u32 startPC; // Start PC for Cur Block - u32 info[pSize/8]; // Info for Instructions in current block - u8 stall[pSize/8]; // Info on how much each instruction stalled (stores the max amount of cycles to stall for the current opcodes) -}; diff --git a/pcsx2/x86/microVU_Alloc.inl b/pcsx2/x86/microVU_Alloc.inl index 1d972814ee..61fd7c593a 100644 --- a/pcsx2/x86/microVU_Alloc.inl +++ b/pcsx2/x86/microVU_Alloc.inl @@ -1,49 +1,47 @@ /* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2009 Pcsx2-Playground Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ + * Copyright (C) 2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #pragma once -#ifdef PCSX2_MICROVU //------------------------------------------------------------------ -// Micro VU - recPass 1 Functions +// Micro VU - Pass 2 Functions //------------------------------------------------------------------ //------------------------------------------------------------------ // FMAC1 - Normal FMAC Opcodes //------------------------------------------------------------------ -#define getReg(reg, _reg_) { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], _X_Y_Z_W); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, _X_Y_Z_W); \ +#define getReg(reg, _reg_) { \ + mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], _X_Y_Z_W); \ + if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, _X_Y_Z_W); \ } -#define getZero(reg) { \ - if (_W) { mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], _X_Y_Z_W); } \ - else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ +#define getZero(reg) { \ + if (_W) { mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], _X_Y_Z_W); } \ + else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ } -#define getReg6(reg, _reg_) { \ - if (!_reg_) { getZero(reg); } \ - else { getReg(reg, _reg_); } \ +#define getReg6(reg, _reg_) { \ + if (!_reg_) { getZero(reg); } \ + else { getReg(reg, _reg_); } \ } -microVUt(void) mVUallocFMAC1a(int& Fd, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC1a(mV, int& Fd, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmFs; @@ -52,61 +50,57 @@ microVUt(void) mVUallocFMAC1a(int& Fd, int& Fs, int& Ft) { else { getReg6(Ft, _Ft_); } } -microVUt(void) mVUallocFMAC1b(int& Fd) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC1b(mV, int& Fd) { if (!_Fd_) return; - if (CHECK_VU_OVERFLOW) mVUclamp1(Fd, xmmT1, _X_Y_Z_W); - mVUsaveReg(Fd, (uptr)&mVU->regs->VF[_Fd_].UL[0], _X_Y_Z_W, 1); + if (CHECK_VU_OVERFLOW) mVUclamp1(Fd, xmmT1, _X_Y_Z_W); + mVUsaveReg(Fd, (uptr)&mVU->regs->VF[_Fd_].UL[0], _X_Y_Z_W, 1); } //------------------------------------------------------------------ // FMAC2 - ABS/FTOI/ITOF Opcodes //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC2a(int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC2a(mV, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFs; getReg6(Fs, _Fs_); } -microVUt(void) mVUallocFMAC2b(int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC2b(mV, int& Ft) { if (!_Ft_) return; //if (CHECK_VU_OVERFLOW) mVUclamp1(Ft, xmmT1, _X_Y_Z_W); - mVUsaveReg(Ft, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); + mVUsaveReg(Ft, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); } //------------------------------------------------------------------ // FMAC3 - BC(xyzw) FMAC Opcodes //------------------------------------------------------------------ -#define getReg3SS(reg, _reg_) { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], (1 << (3 - _bc_))); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, (1 << (3 - _bc_))); \ +#define getReg3SS(reg, _reg_) { \ + mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], (1 << (3 - _bc_))); \ + if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, (1 << (3 - _bc_))); \ } -#define getReg3(reg, _reg_) { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], (1 << (3 - _bc_))); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, (1 << (3 - _bc_))); \ - mVUunpack_xyzw(reg, reg, 0); \ +#define getReg3(reg, _reg_) { \ + mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], (1 << (3 - _bc_))); \ + if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, (1 << (3 - _bc_))); \ + mVUunpack_xyzw(reg, reg, 0); \ } -#define getZero3SS(reg) { \ - if (_bc_w) { mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], 1); } \ - else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ +#define getZero3SS(reg) { \ + if (_bc_w) { mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], 1); } \ + else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ } -#define getZero3(reg) { \ - if (_bc_w) { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], 1); \ - mVUunpack_xyzw(reg, reg, 0); \ - } \ - else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ +#define getZero3(reg) { \ + if (_bc_w) { \ + mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], 1); \ + mVUunpack_xyzw(reg, reg, 0); \ + } \ + else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ } -microVUt(void) mVUallocFMAC3a(int& Fd, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC3a(mV, int& Fd, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmFs; @@ -125,26 +119,25 @@ microVUt(void) mVUallocFMAC3a(int& Fd, int& Fs, int& Ft) { } } -microVUt(void) mVUallocFMAC3b(int& Fd) { - mVUallocFMAC1b(Fd); +microVUt(void) mVUallocFMAC3b(mV, int& Fd) { + mVUallocFMAC1b(mVU, Fd); } //------------------------------------------------------------------ // FMAC4 - FMAC Opcodes Storing Result to ACC //------------------------------------------------------------------ -#define getReg4(reg, _reg_) { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], _xyzw_ACC); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, _xyzw_ACC); \ +#define getReg4(reg, _reg_) { \ + mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], _xyzw_ACC); \ + if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, _xyzw_ACC); \ } -#define getZero4(reg) { \ - if (_W) { mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], _xyzw_ACC); } \ - else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ +#define getZero4(reg) { \ + if (_W) { mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], _xyzw_ACC); } \ + else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ } -microVUt(void) mVUallocFMAC4a(int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC4a(mV, int& ACC, int& Fs, int& Ft) { ACC = xmmACC; Fs = (_X_Y_Z_W == 15) ? xmmACC : xmmFs; Ft = xmmFt; @@ -163,18 +156,16 @@ microVUt(void) mVUallocFMAC4a(int& ACC, int& Fs, int& Ft) { } } -microVUt(void) mVUallocFMAC4b(int& ACC, int& Fs) { - microVU* mVU = mVUx; - if (CHECK_VU_OVERFLOW) mVUclamp1(Fs, xmmT1, _xyzw_ACC); - mVUmergeRegs(ACC, Fs, _X_Y_Z_W); +microVUt(void) mVUallocFMAC4b(mV, int& ACC, int& Fs) { + if (CHECK_VU_OVERFLOW) mVUclamp1(Fs, xmmT1, _xyzw_ACC); + mVUmergeRegs(ACC, Fs, _X_Y_Z_W); } //------------------------------------------------------------------ // FMAC5 - FMAC BC(xyzw) Opcodes Storing Result to ACC //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC5a(int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC5a(mV, int& ACC, int& Fs, int& Ft) { ACC = xmmACC; Fs = (_X_Y_Z_W == 15) ? xmmACC : xmmFs; Ft = xmmFt; @@ -193,23 +184,22 @@ microVUt(void) mVUallocFMAC5a(int& ACC, int& Fs, int& Ft) { } } -microVUt(void) mVUallocFMAC5b(int& ACC, int& Fs) { - mVUallocFMAC4b(ACC, Fs); +microVUt(void) mVUallocFMAC5b(mV, int& ACC, int& Fs) { + mVUallocFMAC4b(mVU, ACC, Fs); } //------------------------------------------------------------------ // FMAC6 - Normal FMAC Opcodes (I Reg) //------------------------------------------------------------------ -#define getIreg(reg, modXYZW) { \ - MOV32MtoR(gprT1, (uptr)&mVU->regs->VI[REG_I].UL); \ - SSE2_MOVD_R_to_XMM(reg, gprT1); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, 8); \ - if (!((_XYZW_SS && modXYZW) || (_X_Y_Z_W == 8))) { mVUunpack_xyzw(reg, reg, 0); } \ +#define getIreg(reg, modXYZW) { \ + MOV32MtoR(gprT1, (uptr)&mVU->regs->VI[REG_I].UL); \ + SSE2_MOVD_R_to_XMM(reg, gprT1); \ + if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, 8); \ + if (!((_XYZW_SS && modXYZW) || (_X_Y_Z_W == 8))) { mVUunpack_xyzw(reg, reg, 0); } \ } -microVUt(void) mVUallocFMAC6a(int& Fd, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC6a(mV, int& Fd, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmFs; @@ -217,16 +207,15 @@ microVUt(void) mVUallocFMAC6a(int& Fd, int& Fs, int& Ft) { getReg6(Fs, _Fs_); } -microVUt(void) mVUallocFMAC6b(int& Fd) { - mVUallocFMAC1b(Fd); +microVUt(void) mVUallocFMAC6b(mV, int& Fd) { + mVUallocFMAC1b(mVU, Fd); } //------------------------------------------------------------------ // FMAC7 - FMAC Opcodes Storing Result to ACC (I Reg) //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC7a(int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC7a(mV, int& ACC, int& Fs, int& Ft) { ACC = xmmACC; Fs = (_X_Y_Z_W == 15) ? xmmACC : xmmFs; Ft = xmmFt; @@ -236,16 +225,15 @@ microVUt(void) mVUallocFMAC7a(int& ACC, int& Fs, int& Ft) { else { getReg4(Fs, _Fs_); } } -microVUt(void) mVUallocFMAC7b(int& ACC, int& Fs) { - mVUallocFMAC4b(ACC, Fs); +microVUt(void) mVUallocFMAC7b(mV, int& ACC, int& Fs) { + mVUallocFMAC4b(mVU, ACC, Fs); } //------------------------------------------------------------------ // FMAC8 - MADD FMAC Opcode Storing Result to Fd //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC8a(int& Fd, int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC8a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmFs; @@ -265,19 +253,17 @@ microVUt(void) mVUallocFMAC8a(int& Fd, int& ACC, int& Fs, int& Ft) { } } -microVUt(void) mVUallocFMAC8b(int& Fd) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC8b(mV, int& Fd) { if (!_Fd_) return; - if (CHECK_VU_OVERFLOW) mVUclamp1(Fd, xmmT1, _xyzw_ACC); - mVUsaveReg(Fd, (uptr)&mVU->regs->VF[_Fd_].UL[0], _X_Y_Z_W, 0); + if (CHECK_VU_OVERFLOW) mVUclamp1(Fd, xmmT1, _xyzw_ACC); + mVUsaveReg(Fd, (uptr)&mVU->regs->VF[_Fd_].UL[0], _X_Y_Z_W, 0); } //------------------------------------------------------------------ // FMAC9 - MSUB FMAC Opcode Storing Result to Fd //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC9a(int& Fd, int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC9a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmT1; @@ -298,19 +284,17 @@ microVUt(void) mVUallocFMAC9a(int& Fd, int& ACC, int& Fs, int& Ft) { SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC); } -microVUt(void) mVUallocFMAC9b(int& Fd) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC9b(mV, int& Fd) { if (!_Fd_) return; - if (CHECK_VU_OVERFLOW) mVUclamp1(Fd, xmmFt, _xyzw_ACC); - mVUsaveReg(Fd, (uptr)&mVU->regs->VF[_Fd_].UL[0], _X_Y_Z_W, 0); + if (CHECK_VU_OVERFLOW) mVUclamp1(Fd, xmmFt, _xyzw_ACC); + mVUsaveReg(Fd, (uptr)&mVU->regs->VF[_Fd_].UL[0], _X_Y_Z_W, 0); } //------------------------------------------------------------------ // FMAC10 - MADD FMAC BC(xyzw) Opcode Storing Result to Fd //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC10a(int& Fd, int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC10a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmFs; @@ -330,16 +314,15 @@ microVUt(void) mVUallocFMAC10a(int& Fd, int& ACC, int& Fs, int& Ft) { } } -microVUt(void) mVUallocFMAC10b(int& Fd) { - mVUallocFMAC8b(Fd); +microVUt(void) mVUallocFMAC10b(mV, int& Fd) { + mVUallocFMAC8b(mVU, Fd); } //------------------------------------------------------------------ // FMAC11 - MSUB FMAC BC(xyzw) Opcode Storing Result to Fd //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC11a(int& Fd, int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC11a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmT1; @@ -360,16 +343,15 @@ microVUt(void) mVUallocFMAC11a(int& Fd, int& ACC, int& Fs, int& Ft) { SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC); } -microVUt(void) mVUallocFMAC11b(int& Fd) { - mVUallocFMAC9b(Fd); +microVUt(void) mVUallocFMAC11b(mV, int& Fd) { + mVUallocFMAC9b(mVU, Fd); } //------------------------------------------------------------------ // FMAC12 - MADD FMAC Opcode Storing Result to Fd (I Reg) //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC12a(int& Fd, int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC12a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmFs; @@ -380,16 +362,15 @@ microVUt(void) mVUallocFMAC12a(int& Fd, int& ACC, int& Fs, int& Ft) { else { getReg4(Fs, _Fs_); } } -microVUt(void) mVUallocFMAC12b(int& Fd) { - mVUallocFMAC8b(Fd); +microVUt(void) mVUallocFMAC12b(mV, int& Fd) { + mVUallocFMAC8b(mVU, Fd); } //------------------------------------------------------------------ // FMAC13 - MSUB FMAC Opcode Storing Result to Fd (I Reg) //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC13a(int& Fd, int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC13a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmT1; @@ -401,16 +382,15 @@ microVUt(void) mVUallocFMAC13a(int& Fd, int& ACC, int& Fs, int& Ft) { SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC); } -microVUt(void) mVUallocFMAC13b(int& Fd) { - mVUallocFMAC9b(Fd); +microVUt(void) mVUallocFMAC13b(mV, int& Fd) { + mVUallocFMAC9b(mVU, Fd); } //------------------------------------------------------------------ // FMAC14 - MADDA/MSUBA FMAC Opcodes //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC14a(int& ACCw, int& ACCr, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC14a(mV, int& ACCw, int& ACCr, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; ACCw = xmmACC; @@ -432,18 +412,16 @@ microVUt(void) mVUallocFMAC14a(int& ACCw, int& ACCr, int& Fs, int& Ft) { SSE_MOVAPS_XMM_to_XMM(ACCr, xmmACC); } -microVUt(void) mVUallocFMAC14b(int& ACCw, int& ACCr) { - microVU* mVU = mVUx; - if (CHECK_VU_OVERFLOW) mVUclamp1(ACCr, xmmFt, _xyzw_ACC); - mVUmergeRegs(ACCw, ACCr, _X_Y_Z_W); +microVUt(void) mVUallocFMAC14b(mV, int& ACCw, int& ACCr) { + if (CHECK_VU_OVERFLOW) mVUclamp1(ACCr, xmmFt, _xyzw_ACC); + mVUmergeRegs(ACCw, ACCr, _X_Y_Z_W); } //------------------------------------------------------------------ // FMAC15 - MADDA/MSUBA BC(xyzw) FMAC Opcode //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC15a(int& ACCw, int& ACCr, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC15a(mV, int& ACCw, int& ACCr, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; ACCw = xmmACC; @@ -465,16 +443,15 @@ microVUt(void) mVUallocFMAC15a(int& ACCw, int& ACCr, int& Fs, int& Ft) { SSE_MOVAPS_XMM_to_XMM(ACCr, xmmACC); } -microVUt(void) mVUallocFMAC15b(int& ACCw, int& ACCr) { - mVUallocFMAC14b(ACCw, ACCr); +microVUt(void) mVUallocFMAC15b(mV, int& ACCw, int& ACCr) { + mVUallocFMAC14b(mVU, ACCw, ACCr); } //------------------------------------------------------------------ // FMAC16 - MADDA/MSUBA FMAC Opcode (I Reg) //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC16a(int& ACCw, int& ACCr, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC16a(mV, int& ACCw, int& ACCr, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; ACCw = xmmACC; @@ -486,22 +463,21 @@ microVUt(void) mVUallocFMAC16a(int& ACCw, int& ACCr, int& Fs, int& Ft) { SSE_MOVAPS_XMM_to_XMM(ACCr, xmmACC); } -microVUt(void) mVUallocFMAC16b(int& ACCw, int& ACCr) { - mVUallocFMAC14b(ACCw, ACCr); +microVUt(void) mVUallocFMAC16b(mV, int& ACCw, int& ACCr) { + mVUallocFMAC14b(mVU, ACCw, ACCr); } //------------------------------------------------------------------ // FMAC17 - CLIP FMAC Opcode //------------------------------------------------------------------ -#define getReg9(reg, _reg_) { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], 1); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, 1); \ - mVUunpack_xyzw(reg, reg, 0); \ +#define getReg9(reg, _reg_) { \ + mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], 1); \ + if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, 1); \ + mVUunpack_xyzw(reg, reg, 0); \ } -microVUt(void) mVUallocFMAC17a(int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC17a(mV, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; getReg6(Fs, _Fs_); @@ -512,8 +488,7 @@ microVUt(void) mVUallocFMAC17a(int& Fs, int& Ft) { // FMAC18 - OPMULA FMAC Opcode //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC18a(int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC18a(mV, int& ACC, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; ACC = xmmACC; @@ -528,16 +503,15 @@ microVUt(void) mVUallocFMAC18a(int& ACC, int& Fs, int& Ft) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ } -microVUt(void) mVUallocFMAC18b(int& ACC, int& Fs) { - mVUallocFMAC4b(ACC, Fs); +microVUt(void) mVUallocFMAC18b(mV, int& ACC, int& Fs) { + mVUallocFMAC4b(mVU, ACC, Fs); } //------------------------------------------------------------------ // FMAC19 - OPMSUB FMAC Opcode //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC19a(int& Fd, int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC19a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmT1; @@ -554,21 +528,20 @@ microVUt(void) mVUallocFMAC19a(int& Fd, int& ACC, int& Fs, int& Ft) { SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC); } -microVUt(void) mVUallocFMAC19b(int& Fd) { - mVUallocFMAC9b(Fd); +microVUt(void) mVUallocFMAC19b(mV, int& Fd) { + mVUallocFMAC9b(mVU, Fd); } //------------------------------------------------------------------ // FMAC22 - Normal FMAC Opcodes (Q Reg) //------------------------------------------------------------------ -#define getQreg(reg) { \ - mVUunpack_xyzw(reg, xmmPQ, readQ); \ - /*if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, 15);*/ \ +#define getQreg(reg) { \ + mVUunpack_xyzw(reg, xmmPQ, mVUinfo.readQ); \ + /*if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, 15);*/ \ } -microVUt(void) mVUallocFMAC22a(int& Fd, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC22a(mV, int& Fd, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmFs; @@ -576,16 +549,15 @@ microVUt(void) mVUallocFMAC22a(int& Fd, int& Fs, int& Ft) { getReg6(Fs, _Fs_); } -microVUt(void) mVUallocFMAC22b(int& Fd) { - mVUallocFMAC1b(Fd); +microVUt(void) mVUallocFMAC22b(mV, int& Fd) { + mVUallocFMAC1b(mVU, Fd); } //------------------------------------------------------------------ // FMAC23 - FMAC Opcodes Storing Result to ACC (Q Reg) //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC23a(int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC23a(mV, int& ACC, int& Fs, int& Ft) { ACC = xmmACC; Fs = (_X_Y_Z_W == 15) ? xmmACC : xmmFs; Ft = xmmFt; @@ -595,16 +567,15 @@ microVUt(void) mVUallocFMAC23a(int& ACC, int& Fs, int& Ft) { else { getReg4(Fs, _Fs_); } } -microVUt(void) mVUallocFMAC23b(int& ACC, int& Fs) { - mVUallocFMAC4b(ACC, Fs); +microVUt(void) mVUallocFMAC23b(mV, int& ACC, int& Fs) { + mVUallocFMAC4b(mVU, ACC, Fs); } //------------------------------------------------------------------ // FMAC24 - MADD FMAC Opcode Storing Result to Fd (Q Reg) //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC24a(int& Fd, int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC24a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmFs; @@ -615,16 +586,15 @@ microVUt(void) mVUallocFMAC24a(int& Fd, int& ACC, int& Fs, int& Ft) { else { getReg4(Fs, _Fs_); } } -microVUt(void) mVUallocFMAC24b(int& Fd) { - mVUallocFMAC8b(Fd); +microVUt(void) mVUallocFMAC24b(mV, int& Fd) { + mVUallocFMAC8b(mVU, Fd); } //------------------------------------------------------------------ // FMAC25 - MSUB FMAC Opcode Storing Result to Fd (Q Reg) //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC25a(int& Fd, int& ACC, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC25a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; Fd = xmmT1; @@ -636,16 +606,15 @@ microVUt(void) mVUallocFMAC25a(int& Fd, int& ACC, int& Fs, int& Ft) { SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC); } -microVUt(void) mVUallocFMAC25b(int& Fd) { - mVUallocFMAC9b(Fd); +microVUt(void) mVUallocFMAC25b(mV, int& Fd) { + mVUallocFMAC9b(mVU, Fd); } //------------------------------------------------------------------ // FMAC26 - MADDA/MSUBA FMAC Opcode (Q Reg) //------------------------------------------------------------------ -microVUt(void) mVUallocFMAC26a(int& ACCw, int& ACCr, int& Fs, int& Ft) { - microVU* mVU = mVUx; +microVUt(void) mVUallocFMAC26a(mV, int& ACCw, int& ACCr, int& Fs, int& Ft) { Fs = xmmFs; Ft = xmmFt; ACCw = xmmACC; @@ -657,54 +626,79 @@ microVUt(void) mVUallocFMAC26a(int& ACCw, int& ACCr, int& Fs, int& Ft) { SSE_MOVAPS_XMM_to_XMM(ACCr, xmmACC); } -microVUt(void) mVUallocFMAC26b(int& ACCw, int& ACCr) { - mVUallocFMAC14b(ACCw, ACCr); +microVUt(void) mVUallocFMAC26b(mV, int& ACCw, int& ACCr) { + mVUallocFMAC14b(mVU, ACCw, ACCr); } //------------------------------------------------------------------ // Flag Allocators //------------------------------------------------------------------ -#define getFlagReg(regX, fInst) { \ - switch (fInst) { \ - case 0: regX = gprF0; break; \ - case 1: regX = gprF1; break; \ - case 2: regX = gprF2; break; \ - case 3: regX = gprF3; break; \ - } \ +#define getFlagReg(regX, fInst) { \ + switch (fInst) { \ + case 0: regX = gprF0; break; \ + case 1: regX = gprF1; break; \ + case 2: regX = gprF2; break; \ + case 3: regX = gprF3; break; \ + default: \ + Console::Error("microVU: Flag Instance Error (fInst = %d)", params fInst); \ + regX = gprF0; \ + break; \ + } \ +} + +#define setBitSFLAG(bitTest, bitSet) { \ + TEST32ItoR(regT, bitTest); \ + pjmp = JZ8(0); \ + OR32ItoR(reg, bitSet); \ + x86SetJ8(pjmp); \ +} + +#define setBitFSEQ(bitX) { \ + TEST32ItoR(gprT1, bitX); \ + pjmp = JZ8(0); \ + OR32ItoR(gprT1, bitX); \ + x86SetJ8(pjmp); \ } microVUt(void) mVUallocSFLAGa(int reg, int fInstance) { - microVU* mVU = mVUx; getFlagReg(fInstance, fInstance); - MOVZX32R16toR(reg, fInstance); + MOV32RtoR(reg, fInstance); } microVUt(void) mVUallocSFLAGb(int reg, int fInstance) { getFlagReg(fInstance, fInstance); - MOV16RtoR(fInstance, reg); + MOV32RtoR(fInstance, reg); } -microVUt(void) mVUallocMFLAGa(int reg, int fInstance) { - getFlagReg(fInstance, fInstance); - MOV32RtoR(reg, fInstance); - SHR32ItoR(reg, 16); +// Normalize Status Flag +microVUt(void) mVUallocSFLAGc(int reg, int regT, int fInstance) { + u8 *pjmp; + XOR32RtoR(reg, reg); + mVUallocSFLAGa(regT, fInstance); + setBitSFLAG(0x0f00, 0x0001); // Z Bit + setBitSFLAG(0xf000, 0x0002); // S Bit + setBitSFLAG(0x000f, 0x0040); // ZS Bit + setBitSFLAG(0x00f0, 0x0080); // SS Bit + AND32ItoR(regT, 0xffff0000); // DS/DI/OS/US/D/I/O/U Bits + SHR32ItoR(regT, 14); + OR32RtoR(reg, regT); } -microVUt(void) mVUallocMFLAGb(int reg, int fInstance) { - getFlagReg(fInstance, fInstance); - AND32ItoR(fInstance, 0xffff); - SHL32ItoR(reg, 16); - OR32RtoR(fInstance, reg); +microVUt(void) mVUallocMFLAGa(mV, int reg, int fInstance) { + MOVZX32M16toR(reg, (uptr)&mVU->macFlag[fInstance]); } -microVUt(void) mVUallocCFLAGa(int reg, int fInstance) { - microVU* mVU = mVUx; +microVUt(void) mVUallocMFLAGb(mV, int reg, int fInstance) { + //AND32ItoR(reg, 0xffff); + MOV32RtoM((uptr)&mVU->macFlag[fInstance], reg); +} + +microVUt(void) mVUallocCFLAGa(mV, int reg, int fInstance) { MOV32MtoR(reg, (uptr)&mVU->clipFlag[fInstance]); } -microVUt(void) mVUallocCFLAGb(int reg, int fInstance) { - microVU* mVU = mVUx; +microVUt(void) mVUallocCFLAGb(mV, int reg, int fInstance) { MOV32RtoM((uptr)&mVU->clipFlag[fInstance], reg); } @@ -712,60 +706,55 @@ microVUt(void) mVUallocCFLAGb(int reg, int fInstance) { // VI Reg Allocators //------------------------------------------------------------------ -microVUt(void) mVUallocVIa(int GPRreg, int _reg_) { - microVU* mVU = mVUx; - if (!_reg_ || _reg_>15) { XOR32RtoR(GPRreg, GPRreg); } +microVUt(void) mVUallocVIa(mV, int GPRreg, int _reg_) { + if (!_reg_) { XOR32RtoR(GPRreg, GPRreg); } else if (isMMX(_reg_)) { MOVD32MMXtoR(GPRreg, mmVI(_reg_)); } - else { MOVZX32M16toR(GPRreg, (uptr)&mVU->regs->VI[_reg_].UL); } + else { MOVZX32Rm16toR(GPRreg, gprR, (_reg_ - 9) * 16); } } -microVUt(void) mVUallocVIb(int GPRreg, int _reg_) { - microVU* mVU = mVUx; - if (backupVI) { // Backs up reg to memory (used when VI is modified b4 a branch) - MOV32RtoM((uptr)&mVU->VIbackup[1], GPRreg); - mVUallocVIa(GPRreg, _reg_); - MOV32RtoM((uptr)&mVU->VIbackup[0], GPRreg); - MOV32MtoR(GPRreg, (uptr)&mVU->VIbackup[1]); +microVUt(void) mVUallocVIb(mV, int GPRreg, int _reg_) { + if (mVUlow.backupVI) { // Backs up reg to memory (used when VI is modified b4 a branch) + MOVZX32M16toR(gprR, (uptr)&mVU->regs->VI[_reg_].UL); + MOV32RtoM((uptr)&mVU->VIbackup, gprR); + MOV32ItoR(gprR, Roffset); } if (_reg_ == 0) { return; } else if (isMMX(_reg_)) { MOVD32RtoMMX(mmVI(_reg_), GPRreg); } - else if (_reg_ < 16) { MOV16RtoM((uptr)&mVU->regs->VI[_reg_].UL, GPRreg); } + else if (_reg_ < 16) { MOV16RtoRm(gprR, GPRreg, (_reg_ - 9) * 16); } } //------------------------------------------------------------------ // P Reg Allocator //------------------------------------------------------------------ -#define getPreg(reg) { \ - mVUunpack_xyzw(reg, xmmPQ, (2 + readP)); \ - /*if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, 15);*/ \ +#define getPreg(reg) { \ + mVUunpack_xyzw(reg, xmmPQ, (2 + mVUinfo.readP)); \ + /*if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, 15);*/ \ } //------------------------------------------------------------------ // Lower Instruction Allocator Helpers //------------------------------------------------------------------ -#define getReg5(reg, _reg_, _fxf_) { \ - if (!_reg_) { \ - if (_fxf_ < 3) { SSE_XORPS_XMM_to_XMM(reg, reg); } \ - else { mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], 1); } \ - } \ - else { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], (1 << (3 - _fxf_))); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, (1 << (3 - _fxf_))); \ - } \ +#define getReg5(reg, _reg_, _fxf_) { \ + if (!_reg_) { \ + if (_fxf_ < 3) { SSE_XORPS_XMM_to_XMM(reg, reg); } \ + else { mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], 1); } \ + } \ + else { \ + mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], (1 << (3 - _fxf_))); \ + if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, (1 << (3 - _fxf_))); \ + } \ } // Doesn't Clamp -#define getReg7(reg, _reg_) { \ - if (!_reg_) { getZero(reg); } \ - else { mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], _X_Y_Z_W); } \ +#define getReg7(reg, _reg_) { \ + if (!_reg_) { getZero(reg); } \ + else { mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], _X_Y_Z_W); } \ } // VF to GPR -#define getReg8(GPRreg, _reg_, _fxf_) { \ - if (!_reg_ && (_fxf_ < 3)) { XOR32RtoR(GPRreg, GPRreg); } \ - else { MOV32MtoR(GPRreg, (uptr)&mVU->regs->VF[_reg_].UL[0]); } \ +#define getReg8(GPRreg, _reg_, _fxf_) { \ + if (!_reg_ && (_fxf_ < 3)) { XOR32RtoR(GPRreg, GPRreg); } \ + else { MOV32MtoR(GPRreg, (uptr)&mVU->regs->VF[_reg_].UL[0]); } \ } - -#endif //PCSX2_MICROVU diff --git a/pcsx2/x86/microVU_Analyze.inl b/pcsx2/x86/microVU_Analyze.inl index 81512ba1f9..cd9d47b659 100644 --- a/pcsx2/x86/microVU_Analyze.inl +++ b/pcsx2/x86/microVU_Analyze.inl @@ -1,179 +1,196 @@ /* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2009 Pcsx2-Playground Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ + * Copyright (C) 2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #pragma once -#ifdef PCSX2_MICROVU //------------------------------------------------------------------ -// Micro VU - recPass 0 Functions +// Micro VU - Pass 1 Functions //------------------------------------------------------------------ +//------------------------------------------------------------------ +// Helper Macros +//------------------------------------------------------------------ + +#define aReg(x) mVUregs.VF[x] +#define bReg(x, y) mVUregsTemp.VFreg[y] = x; mVUregsTemp.VF[y] +#define aMax(x, y) ((x > y) ? x : y) +#define aMin(x, y) ((x < y) ? x : y) + +// Read a VF reg +#define analyzeReg1(xReg, vfRead) { \ + if (xReg) { \ + if (_X) { mVUstall = aMax(mVUstall, aReg(xReg).x); vfRead.reg = xReg; vfRead.x = 1; } \ + if (_Y) { mVUstall = aMax(mVUstall, aReg(xReg).y); vfRead.reg = xReg; vfRead.y = 1; } \ + if (_Z) { mVUstall = aMax(mVUstall, aReg(xReg).z); vfRead.reg = xReg; vfRead.z = 1; } \ + if (_W) { mVUstall = aMax(mVUstall, aReg(xReg).w); vfRead.reg = xReg; vfRead.w = 1; } \ + } \ +} + +// Write to a VF reg +#define analyzeReg2(xReg, vfWrite, isLowOp) { \ + if (xReg) { \ + if (_X) { bReg(xReg, isLowOp).x = 4; vfWrite.reg = xReg; vfWrite.x = 4; } \ + if (_Y) { bReg(xReg, isLowOp).y = 4; vfWrite.reg = xReg; vfWrite.y = 4; } \ + if (_Z) { bReg(xReg, isLowOp).z = 4; vfWrite.reg = xReg; vfWrite.z = 4; } \ + if (_W) { bReg(xReg, isLowOp).w = 4; vfWrite.reg = xReg; vfWrite.w = 4; } \ + } \ +} + +// Read a VF reg (BC opcodes) +#define analyzeReg3(xReg, vfRead) { \ + if (xReg) { \ + if (_bc_x) { mVUstall = aMax(mVUstall, aReg(xReg).x); vfRead.reg = xReg; vfRead.x = 1; } \ + else if (_bc_y) { mVUstall = aMax(mVUstall, aReg(xReg).y); vfRead.reg = xReg; vfRead.y = 1; } \ + else if (_bc_z) { mVUstall = aMax(mVUstall, aReg(xReg).z); vfRead.reg = xReg; vfRead.z = 1; } \ + else { mVUstall = aMax(mVUstall, aReg(xReg).w); vfRead.reg = xReg; vfRead.w = 1; } \ + } \ +} + +// For Clip Opcode +#define analyzeReg4(xReg, vfRead) { \ + if (xReg) { \ + mVUstall = aMax(mVUstall, aReg(xReg).w); \ + vfRead.reg = xReg; vfRead.w = 1; \ + } \ +} + +// Read VF reg (FsF/FtF) +#define analyzeReg5(xReg, fxf, vfRead) { \ + if (xReg) { \ + switch (fxf) { \ + case 0: mVUstall = aMax(mVUstall, aReg(xReg).x); vfRead.reg = xReg; vfRead.x = 1; break; \ + case 1: mVUstall = aMax(mVUstall, aReg(xReg).y); vfRead.reg = xReg; vfRead.y = 1; break; \ + case 2: mVUstall = aMax(mVUstall, aReg(xReg).z); vfRead.reg = xReg; vfRead.z = 1; break; \ + case 3: mVUstall = aMax(mVUstall, aReg(xReg).w); vfRead.reg = xReg; vfRead.w = 1; break; \ + } \ + } \ +} + +// Flips xyzw stalls to yzwx (MR32 Opcode) +#define analyzeReg6(xReg, vfRead) { \ + if (xReg) { \ + if (_X) { mVUstall = aMax(mVUstall, aReg(xReg).y); vfRead.reg = xReg; vfRead.y = 1; } \ + if (_Y) { mVUstall = aMax(mVUstall, aReg(xReg).z); vfRead.reg = xReg; vfRead.z = 1; } \ + if (_Z) { mVUstall = aMax(mVUstall, aReg(xReg).w); vfRead.reg = xReg; vfRead.w = 1; } \ + if (_W) { mVUstall = aMax(mVUstall, aReg(xReg).x); vfRead.reg = xReg; vfRead.x = 1; } \ + } \ +} + +// Reading a VI reg +#define analyzeVIreg1(xReg, viRead) { \ + if (xReg) { \ + mVUstall = aMax(mVUstall, mVUregs.VI[xReg]); \ + viRead.reg = xReg; viRead.used = 1; \ + } \ +} + +// Writing to a VI reg +#define analyzeVIreg2(xReg, viWrite, aCycles) { \ + if (xReg) { \ + mVUregsTemp.VIreg = xReg; \ + mVUregsTemp.VI = aCycles; \ + viWrite.reg = xReg; \ + viWrite.used = aCycles; \ + } \ +} + +#define analyzeQreg(x) { mVUregsTemp.q = x; mVUstall = aMax(mVUstall, mVUregs.q); } +#define analyzePreg(x) { mVUregsTemp.p = x; mVUstall = aMax(mVUstall, ((mVUregs.p) ? (mVUregs.p - 1) : 0)); } +#define analyzeRreg() { mVUregsTemp.r = 1; } +#define analyzeXGkick1() { mVUstall = aMax(mVUstall, mVUregs.xgkick); } +#define analyzeXGkick2(x) { mVUregsTemp.xgkick = x; } + //------------------------------------------------------------------ // FMAC1 - Normal FMAC Opcodes //------------------------------------------------------------------ -#define aReg(x) mVUregs.VF[x] -#define bReg(x) mVUregsTemp.VFreg[0] = x; mVUregsTemp.VF[0] -#define aMax(x, y) ((x > y) ? x : y) - -#define analyzeReg1(reg) { \ - if (reg) { \ - if (_X) { mVUstall = aMax(mVUstall, aReg(reg).x); } \ - if (_Y) { mVUstall = aMax(mVUstall, aReg(reg).y); } \ - if (_Z) { mVUstall = aMax(mVUstall, aReg(reg).z); } \ - if (_W) { mVUstall = aMax(mVUstall, aReg(reg).w); } \ - } \ -} - -#define analyzeReg2(reg) { \ - if (reg) { \ - if (_X) { bReg(reg).x = 4; } \ - if (_Y) { bReg(reg).y = 4; } \ - if (_Z) { bReg(reg).z = 4; } \ - if (_W) { bReg(reg).w = 4; } \ - } \ -} - -microVUt(void) mVUanalyzeFMAC1(int Fd, int Fs, int Ft) { - microVU* mVU = mVUx; - //mVUprint("microVU: FMAC1 Opcode"); - mVUinfo |= _doStatus; - analyzeReg1(Fs); - analyzeReg1(Ft); - analyzeReg2(Fd); +microVUt(void) mVUanalyzeFMAC1(mV, int Fd, int Fs, int Ft) { + sFLAG.doFlag = 1; + analyzeReg1(Fs, mVUup.VF_read[0]); + analyzeReg1(Ft, mVUup.VF_read[1]); + analyzeReg2(Fd, mVUup.VF_write, 0); } //------------------------------------------------------------------ // FMAC2 - ABS/FTOI/ITOF Opcodes //------------------------------------------------------------------ -microVUt(void) mVUanalyzeFMAC2(int Fs, int Ft) { - microVU* mVU = mVUx; - //mVUprint("microVU: FMAC2 Opcode"); - analyzeReg1(Fs); - analyzeReg2(Ft); +microVUt(void) mVUanalyzeFMAC2(mV, int Fs, int Ft) { + analyzeReg1(Fs, mVUup.VF_read[0]); + analyzeReg2(Ft, mVUup.VF_write, 0); } //------------------------------------------------------------------ // FMAC3 - BC(xyzw) FMAC Opcodes //------------------------------------------------------------------ -#define analyzeReg3(reg) { \ - if (reg) { \ - if (_bc_x) { mVUstall = aMax(mVUstall, aReg(reg).x); } \ - else if (_bc_y) { mVUstall = aMax(mVUstall, aReg(reg).y); } \ - else if (_bc_z) { mVUstall = aMax(mVUstall, aReg(reg).z); } \ - else { mVUstall = aMax(mVUstall, aReg(reg).w); } \ - } \ -} - -microVUt(void) mVUanalyzeFMAC3(int Fd, int Fs, int Ft) { - microVU* mVU = mVUx; - //mVUprint("microVU: FMAC3 Opcode"); - mVUinfo |= _doStatus; - analyzeReg1(Fs); - analyzeReg3(Ft); - analyzeReg2(Fd); +microVUt(void) mVUanalyzeFMAC3(mV, int Fd, int Fs, int Ft) { + sFLAG.doFlag = 1; + analyzeReg1(Fs, mVUup.VF_read[0]); + analyzeReg3(Ft, mVUup.VF_read[1]); + analyzeReg2(Fd, mVUup.VF_write, 0); } //------------------------------------------------------------------ // FMAC4 - Clip FMAC Opcode //------------------------------------------------------------------ -#define analyzeReg4(reg) { \ - if (reg) { mVUstall = aMax(mVUstall, aReg(reg).w); } \ -} - -microVUt(void) mVUanalyzeFMAC4(int Fs, int Ft) { - microVU* mVU = mVUx; - mVUinfo |= doClip; - analyzeReg1(Fs); - analyzeReg4(Ft); +microVUt(void) mVUanalyzeFMAC4(mV, int Fs, int Ft) { + cFLAG.doFlag = 1; + analyzeReg1(Fs, mVUup.VF_read[0]); + analyzeReg4(Ft, mVUup.VF_read[1]); } //------------------------------------------------------------------ // IALU - IALU Opcodes //------------------------------------------------------------------ -#define analyzeVIreg1(reg) { if (reg) { mVUstall = aMax(mVUstall, mVUregs.VI[reg]); } } -#define analyzeVIreg2(reg, aCycles) { if (reg) { mVUregsTemp.VIreg = reg; mVUregsTemp.VI = aCycles; mVUinfo |= _writesVI; mVU->VIbackup[0] = reg; } } - -microVUt(void) mVUanalyzeIALU1(int Id, int Is, int It) { - microVU* mVU = mVUx; - //mVUprint("microVU: IALU1 Opcode"); - if (!Id) { mVUinfo |= _isNOP; } - analyzeVIreg1(Is); - analyzeVIreg1(It); - analyzeVIreg2(Id, 1); +microVUt(void) mVUanalyzeIALU1(mV, int Id, int Is, int It) { + if (!Id) { mVUlow.isNOP = 1; } + analyzeVIreg1(Is, mVUlow.VI_read[0]); + analyzeVIreg1(It, mVUlow.VI_read[1]); + analyzeVIreg2(Id, mVUlow.VI_write, 1); } -microVUt(void) mVUanalyzeIALU2(int Is, int It) { - microVU* mVU = mVUx; - //mVUprint("microVU: IALU2 Opcode"); - if (!It) { mVUinfo |= _isNOP; } - analyzeVIreg1(Is); - analyzeVIreg2(It, 1); +microVUt(void) mVUanalyzeIALU2(mV, int Is, int It) { + if (!It) { mVUlow.isNOP = 1; } + analyzeVIreg1(Is, mVUlow.VI_read[0]); + analyzeVIreg2(It, mVUlow.VI_write, 1); } //------------------------------------------------------------------ // MR32 - MR32 Opcode //------------------------------------------------------------------ -// Flips xyzw stalls to yzwx -#define analyzeReg6(reg) { \ - if (reg) { \ - if (_X) { mVUstall = aMax(mVUstall, aReg(reg).y); } \ - if (_Y) { mVUstall = aMax(mVUstall, aReg(reg).z); } \ - if (_Z) { mVUstall = aMax(mVUstall, aReg(reg).w); } \ - if (_W) { mVUstall = aMax(mVUstall, aReg(reg).x); } \ - } \ -} - -microVUt(void) mVUanalyzeMR32(int Fs, int Ft) { - microVU* mVU = mVUx; - if (!Ft) { mVUinfo |= _isNOP; } - analyzeReg6(Fs); - analyzeReg2(Ft); +microVUt(void) mVUanalyzeMR32(mV, int Fs, int Ft) { + if (!Ft) { mVUlow.isNOP = 1; } + analyzeReg6(Fs, mVUlow.VF_read[0]); + analyzeReg2(Ft, mVUlow.VF_write, 1); } //------------------------------------------------------------------ // FDIV - DIV/SQRT/RSQRT Opcodes //------------------------------------------------------------------ -#define analyzeReg5(reg, fxf) { \ - if (reg) { \ - switch (fxf) { \ - case 0: mVUstall = aMax(mVUstall, aReg(reg).x); break; \ - case 1: mVUstall = aMax(mVUstall, aReg(reg).y); break; \ - case 2: mVUstall = aMax(mVUstall, aReg(reg).z); break; \ - case 3: mVUstall = aMax(mVUstall, aReg(reg).w); break; \ - } \ - } \ -} - -#define analyzeQreg(x) { mVUregsTemp.q = x; mVUstall = aMax(mVUstall, mVUregs.q); } -#define analyzePreg(x) { mVUregsTemp.p = x; mVUstall = aMax(mVUstall, ((mVUregs.p) ? (mVUregs.p - 1) : 0)); } - -microVUt(void) mVUanalyzeFDIV(int Fs, int Fsf, int Ft, int Ftf, u8 xCycles) { - microVU* mVU = mVUx; +microVUt(void) mVUanalyzeFDIV(mV, int Fs, int Fsf, int Ft, int Ftf, u8 xCycles) { mVUprint("microVU: DIV Opcode"); - analyzeReg5(Fs, Fsf); - analyzeReg5(Ft, Ftf); + analyzeReg5(Fs, Fsf, mVUlow.VF_read[0]); + analyzeReg5(Ft, Ftf, mVUlow.VF_read[1]); analyzeQreg(xCycles); } @@ -181,17 +198,15 @@ microVUt(void) mVUanalyzeFDIV(int Fs, int Fsf, int Ft, int Ftf, u8 xCycles) { // EFU - EFU Opcodes //------------------------------------------------------------------ -microVUt(void) mVUanalyzeEFU1(int Fs, int Fsf, u8 xCycles) { - microVU* mVU = mVUx; +microVUt(void) mVUanalyzeEFU1(mV, int Fs, int Fsf, u8 xCycles) { mVUprint("microVU: EFU Opcode"); - analyzeReg5(Fs, Fsf); + analyzeReg5(Fs, Fsf, mVUlow.VF_read[0]); analyzePreg(xCycles); } -microVUt(void) mVUanalyzeEFU2(int Fs, u8 xCycles) { - microVU* mVU = mVUx; +microVUt(void) mVUanalyzeEFU2(mV, int Fs, u8 xCycles) { mVUprint("microVU: EFU Opcode"); - analyzeReg1(Fs); + analyzeReg1(Fs, mVUlow.VF_read[0]); analyzePreg(xCycles); } @@ -199,144 +214,175 @@ microVUt(void) mVUanalyzeEFU2(int Fs, u8 xCycles) { // MFP - MFP Opcode //------------------------------------------------------------------ -microVUt(void) mVUanalyzeMFP(int Ft) { - microVU* mVU = mVUx; - if (!Ft) { mVUinfo |= _isNOP; } - analyzeReg2(Ft); +microVUt(void) mVUanalyzeMFP(mV, int Ft) { + if (!Ft) { mVUlow.isNOP = 1; } + analyzeReg2(Ft, mVUlow.VF_write, 1); +} + +//------------------------------------------------------------------ +// MOVE - MOVE Opcode +//------------------------------------------------------------------ + +microVUt(void) mVUanalyzeMOVE(mV, int Fs, int Ft) { + if (!Ft || (Ft == Fs)) { mVUlow.isNOP = 1; } + analyzeReg1(Fs, mVUlow.VF_read[0]); + analyzeReg2(Ft, mVUlow.VF_write, 1); } //------------------------------------------------------------------ // LQx - LQ/LQD/LQI Opcodes //------------------------------------------------------------------ -microVUt(void) mVUanalyzeLQ(int Ft, int Is, bool writeIs) { - microVU* mVU = mVUx; - //mVUprint("microVU: LQ Opcode"); - analyzeVIreg1(Is); - analyzeReg2(Ft); - if (!Ft) { mVUinfo |= (writeIs && Is) ? _noWriteVF : _isNOP; } - if (writeIs) { analyzeVIreg2(Is, 1); } +microVUt(void) mVUanalyzeLQ(mV, int Ft, int Is, bool writeIs) { + analyzeVIreg1(Is, mVUlow.VI_read[0]); + analyzeReg2 (Ft, mVUlow.VF_write, 1); + if (!Ft) { if (writeIs && Is) { mVUlow.noWriteVF = 1; } else { mVUlow.isNOP = 1; } } + if (writeIs) { analyzeVIreg2(Is, mVUlow.VI_write, 1); } } //------------------------------------------------------------------ // SQx - SQ/SQD/SQI Opcodes //------------------------------------------------------------------ -microVUt(void) mVUanalyzeSQ(int Fs, int It, bool writeIt) { - microVU* mVU = mVUx; - analyzeReg1(Fs); - analyzeVIreg1(It); - if (writeIt) { analyzeVIreg2(It, 1); } +microVUt(void) mVUanalyzeSQ(mV, int Fs, int It, bool writeIt) { + analyzeReg1 (Fs, mVUlow.VF_read[0]); + analyzeVIreg1(It, mVUlow.VI_read[0]); + if (writeIt) { analyzeVIreg2(It, mVUlow.VI_write, 1); } } //------------------------------------------------------------------ // R*** - R Reg Opcodes //------------------------------------------------------------------ -#define analyzeRreg() { mVUregsTemp.r = 1; } - -microVUt(void) mVUanalyzeR1(int Fs, int Fsf) { - microVU* mVU = mVUx; - analyzeReg5(Fs, Fsf); +microVUt(void) mVUanalyzeR1(mV, int Fs, int Fsf) { + analyzeReg5(Fs, Fsf, mVUlow.VF_read[0]); analyzeRreg(); } -microVUt(void) mVUanalyzeR2(int Ft, bool canBeNOP) { - microVU* mVU = mVUx; - if (!Ft) { mVUinfo |= ((canBeNOP) ? _isNOP : _noWriteVF); } - analyzeReg2(Ft); +microVUt(void) mVUanalyzeR2(mV, int Ft, bool canBeNOP) { + if (!Ft) { if (canBeNOP) { mVUlow.isNOP = 1; } else { mVUlow.noWriteVF = 1; } } + analyzeReg2(Ft, mVUlow.VF_write, 1); analyzeRreg(); } //------------------------------------------------------------------ // Sflag - Status Flag Opcodes //------------------------------------------------------------------ +#define flagSet(xFLAG) { \ + int curPC = iPC; \ + for (int i = mVUcount, j = 0; i > 0; i--, j++) { \ + incPC2(-2); \ + if (sFLAG.doFlag) { xFLAG = 1; if (j >= 3) { break; } } \ + } \ + iPC = curPC; \ +} -microVUt(void) mVUanalyzeSflag(int It) { - microVU* mVU = mVUx; - if (!It) { mVUinfo |= _isNOP; } - else { // Sets _isSflag at instruction that FSxxx opcode reads it's status flag from - mVUinfo |= _swapOps; - if (mVUcount < 4) { mVUregs.needExactMatch = 1; } - if (mVUcount >= 1) { incPC2(-2); mVUinfo |= _isSflag; incPC2(2); } - // Note: _isSflag is used for status flag optimizations. +microVUt(void) mVUanalyzeSflag(mV, int It) { + mVUlow.readFlags = 1; + analyzeVIreg2(It, mVUlow.VI_write, 1); + if (!It) { mVUlow.isNOP = 1; } + else { + mVUinfo.swapOps = 1; + mVUsFlagHack = 0; // Don't Optimize Out Status Flags for this block + flagSet(sFLAG.doNonSticky); + if (mVUcount < 4) { mVUpBlock->pState.needExactMatch |= 0xf; } + if (mVUcount >= 1) { incPC2(-2); mVUlow.useSflag = 1; incPC2(2); } + // Note: useSflag is used for status flag optimizations when a FSSET instruction is called. // Do to stalls, it can only be set one instruction prior to the status flag read instruction // if we were guaranteed no-stalls were to happen, it could be set 4 instruction prior. } - analyzeVIreg2(It, 1); } -microVUt(void) mVUanalyzeFSSET() { - microVU* mVU = mVUx; - mVUinfo |= _isFSSET; - // mVUinfo &= ~_doStatus; - // Note: I'm not entirely sure if the non-sticky flags - // should be taken from the current upper instruction - // or if they should be taken from the previous instruction - // Uncomment the above line if the latter-case is true +microVUt(void) mVUanalyzeFSSET(mV) { + mVUlow.isFSSET = 1; + mVUlow.readFlags = 1; } //------------------------------------------------------------------ // Mflag - Mac Flag Opcodes //------------------------------------------------------------------ -microVUt(void) mVUanalyzeMflag(int Is, int It) { - microVU* mVU = mVUx; - if (!It) { mVUinfo |= _isNOP; } +microVUt(void) mVUanalyzeMflag(mV, int Is, int It) { + mVUlow.readFlags = 1; + analyzeVIreg1(Is, mVUlow.VI_read[0]); + analyzeVIreg2(It, mVUlow.VI_write, 1); + if (!It) { mVUlow.isNOP = 1; } else { // Need set _doMac for 4 previous Ops (need to do all 4 because stalls could change the result needed) - mVUinfo |= _swapOps; - if (mVUcount < 4) { mVUregs.needExactMatch = 1; } - int curPC = iPC; - for (int i = mVUcount, j = 0; i > 1; i--, j++) { - incPC2(-2); - if (doStatus) { mVUinfo |= _doMac; if (j >= 3) { break; } } - } - iPC = curPC; + mVUinfo.swapOps = 1; + if (mVUcount < 4) { mVUpBlock->pState.needExactMatch |= 0xf << 4; } + flagSet(mFLAG.doFlag); } - analyzeVIreg1(Is); - analyzeVIreg2(It, 1); +} + +//------------------------------------------------------------------ +// Cflag - Clip Flag Opcodes +//------------------------------------------------------------------ + +microVUt(void) mVUanalyzeCflag(mV, int It) { + mVUinfo.swapOps = 1; + mVUlow.readFlags = 1; + if (mVUcount < 4) { mVUpBlock->pState.needExactMatch |= 0xf << 8; } + analyzeVIreg2(It, mVUlow.VI_write, 1); } //------------------------------------------------------------------ // XGkick //------------------------------------------------------------------ -#define analyzeXGkick1() { mVUstall = aMax(mVUstall, mVUregs.xgkick); } -#define analyzeXGkick2(x) { mVUregsTemp.xgkick = x; } - -microVUt(void) mVUanalyzeXGkick(int Fs, int xCycles) { - microVU* mVU = mVUx; - analyzeVIreg1(Fs); +microVUt(void) mVUanalyzeXGkick(mV, int Fs, int xCycles) { + analyzeVIreg1(Fs, mVUlow.VI_read[0]); analyzeXGkick1(); analyzeXGkick2(xCycles); + // Note: Technically XGKICK should stall on the next instruction, + // this code stalls on the same instruction. The only case where this + // will be a problem with, is if you have very-specifically placed + // FMxxx or FSxxx opcodes checking flags near this instruction AND + // the XGKICK instruction stalls. No-game should be effected by + // this minor difference. } //------------------------------------------------------------------ // Branches - Branch Opcodes //------------------------------------------------------------------ -#define analyzeBranchVI(reg, infoVal) { \ - if (reg && (mVUcount > 0)) { /* Ensures branch is not first opcode in block */ \ - incPC2(-2); \ - if (writesVI && (reg == mVU->VIbackup[0])) { /* If prev Op modified VI reg */ \ - mVUinfo |= _backupVI; \ - incPC2(2); \ - mVUinfo |= infoVal; \ - } \ - else { incPC2(2); } \ - } \ +microVUt(void) analyzeBranchVI(mV, int xReg, bool &infoVar) { + if (!xReg) return; + int i; + int iEnd = aMin(5, mVUcount); + int bPC = iPC; + incPC2(-2); + for (i = 0; i < iEnd; i++) { + if ((mVUlow.VI_write.reg == xReg) && mVUlow.VI_write.used) { + if (mVUlow.readFlags || i == 5) break; + if (i == 0) { incPC2(-2); continue; } + if (((mVUlow.VI_read[0].reg == xReg) && (mVUlow.VI_read[0].used)) + || ((mVUlow.VI_read[1].reg == xReg) && (mVUlow.VI_read[1].used))) + { incPC2(-2); continue; } + } + break; + } + if (i) { + incPC2(2); + mVUlow.backupVI = 1; + iPC = bPC; + infoVar = 1; + DevCon::Status("microVU%d: Branch VI-Delay (%d) [%04x]", params getIndex, i, xPC); + } + iPC = bPC; } -microVUt(void) mVUanalyzeBranch1(int Is) { - microVU* mVU = mVUx; - if (mVUregs.VI[Is] || mVUstall) { analyzeVIreg1(Is); } - else { analyzeBranchVI(Is, _memReadIs); } +microVUt(void) mVUanalyzeBranch1(mV, int Is) { + analyzeVIreg1(Is, mVUlow.VI_read[0]); + if (!mVUstall) { + analyzeBranchVI(mVU, Is, mVUlow.memReadIs); + } } -microVUt(void) mVUanalyzeBranch2(int Is, int It) { - microVU* mVU = mVUx; - if (mVUregs.VI[Is] || mVUregs.VI[It] || mVUstall) { analyzeVIreg1(Is); analyzeVIreg1(It); } - else { analyzeBranchVI(Is, _memReadIs); analyzeBranchVI(It, _memReadIt);} +microVUt(void) mVUanalyzeBranch2(mV, int Is, int It) { + analyzeVIreg1(Is, mVUlow.VI_read[0]); + analyzeVIreg1(It, mVUlow.VI_read[1]); + if (!mVUstall) { + analyzeBranchVI(mVU, Is, mVUlow.memReadIs); + analyzeBranchVI(mVU, It, mVUlow.memReadIt); + } } - -#endif //PCSX2_MICROVU diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index b0cddab4ca..4a01c6a31b 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -1,190 +1,161 @@ /* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2009 Pcsx2-Playground Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ + * Copyright (C) 2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #pragma once -#ifdef PCSX2_MICROVU //------------------------------------------------------------------ // Helper Macros //------------------------------------------------------------------ -#define branchCase(JMPcc, nJMPcc) \ - mVUsetupBranch(bStatus, bMac); \ - mVUprint("mVUcompile branchCase"); \ - CMP16ItoM((uptr)&mVU->branch, 0); \ - incPC2(1); \ - bBlock = mVUblocks[iPC/2]->search((microRegInfo*)&mVUregs); \ - incPC2(-1); \ - if (bBlock) { nJMPcc((uptr)pBlock->x86ptrStart - ((uptr)x86Ptr + 6)); } \ - else { ajmp = JMPcc((uptr)0); } \ - break +#define branchCase(JMPcond) branchCaseFunct(mVU, bBlock, xStatus, xMac, xClip, xCycles, ajmp, JMPcond); break -// ToDo: Fix this properly. -#define flagSetMacro(xFlag, pFlag, xF, yF, zF) { \ - yF += (mVUstall > 3) ? 3 : mVUstall; \ - if (yF > zF) { \ - pFlag += (yF-zF); \ - if (pFlag >= xFlag) pFlag = (xFlag-1); \ - zF++; \ - xF = (yF-zF); \ - zF = yF; \ - yF -= xF; \ - } \ - yF++; \ +#define branchWarning() { \ + if (mVUbranch) { \ + Console::Error("microVU%d Warning: Branch in E-bit/Branch delay slot! [%04x]", params mVU->index, xPC); \ + mVUlow.isNOP = 1; \ + } \ +} + +#define doBackupVF1() { \ + if (mVUinfo.backupVF && !mVUlow.noWriteVF) { \ + DevCon::Status("microVU%d: Backing Up VF Reg [%04x]", params getIndex, xPC); \ + SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&mVU->regs->VF[mVUlow.VF_write.reg].UL[0]); \ + SSE_MOVAPS_XMM_to_M128((uptr)mVU->xmmVFb, xmmT1); \ + } \ +} + +#define doBackupVF2() { \ + if (mVUinfo.backupVF && !mVUlow.noWriteVF) { \ + SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)mVU->xmmVFb); \ + SSE_MOVAPS_M128_to_XMM(xmmT2, (uptr)&mVU->regs->VF[mVUlow.VF_write.reg].UL[0]); \ + SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->VF[mVUlow.VF_write.reg].UL[0], xmmT1); \ + SSE_MOVAPS_XMM_to_M128((uptr)mVU->xmmVFb, xmmT2); \ + } \ +} + +#define doBackupVF3() { \ + if (mVUinfo.backupVF && !mVUlow.noWriteVF) { \ + SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)mVU->xmmVFb); \ + SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->VF[mVUlow.VF_write.reg].UL[0], xmmT1); \ + } \ +} + +#define startLoop() { \ + mVUdebug1(); \ + memset(&mVUinfo, 0, sizeof(mVUinfo)); \ + memset(&mVUregsTemp, 0, sizeof(mVUregsTemp)); \ } -#define startLoop() { mVUdebug1(); mVUstall = 0; memset(&mVUregsTemp, 0, sizeof(mVUregsTemp)); } #define calcCycles(reg, x) { reg = ((reg > x) ? (reg - x) : 0); } #define tCycles(dest, src) { dest = aMax(dest, src); } #define incP() { mVU->p = (mVU->p+1) & 1; } #define incQ() { mVU->q = (mVU->q+1) & 1; } -#define doUpperOp() { mVUopU(); mVUdivSet(); } +#define doUpperOp() { mVUopU(mVU, 1); mVUdivSet(mVU); } +#define doLowerOp() { incPC(-1); mVUopL(mVU, 1); incPC(1); } +#define doSwapOp() { doBackupVF1(); mVUopL(mVU, 1); doBackupVF2(); incPC(1); doUpperOp(); doBackupVF3(); } +#define doIbit() { if (mVUup.iBit) { incPC(-1); MOV32ItoM((uptr)&mVU->regs->VI[REG_I].UL, curI); incPC(1); } } +#define blockCreate(addr) { if (!mVUblocks[addr]) mVUblocks[addr] = microBlockManager::AlignedNew(); } //------------------------------------------------------------------ // Helper Functions //------------------------------------------------------------------ -// Optimizes out unneeded status flag updates -microVUt(void) mVUstatusFlagOp() { - microVU* mVU = mVUx; - int curPC = iPC; - int i = mVUcount; - bool runLoop = 1; - if (doStatus) { mVUinfo |= _isSflag; } +// Used by mVUsetupRange +microVUt(void) mVUcheckIsSame(mV) { + + if (mVU->prog.isSame == -1) { + mVU->prog.isSame = !memcmp_mmx((u8*)mVUcurProg.data, mVU->regs->Micro, mVU->microMemSize); + } + if (mVU->prog.isSame == 0) { + if (!isVU1) mVUcacheProg<0>(mVU->prog.cur); + else mVUcacheProg<1>(mVU->prog.cur); + mVU->prog.isSame = 1; + } +} + +// Sets up microProgram PC ranges based on whats been recompiled +microVUt(void) mVUsetupRange(mV, s32 pc, bool isStartPC) { + + for (int i = 0; i <= mVUcurProg.ranges.total; i++) { + if ((pc >= mVUcurProg.ranges.range[i][0]) + && (pc <= mVUcurProg.ranges.range[i][1])) { return; } + } + + mVUcheckIsSame(mVU); + + if (isStartPC) { + if (mVUcurProg.ranges.total < mVUcurProg.ranges.max) { + mVUcurProg.ranges.total++; + mVUrange[0] = pc; + } + else { + mVUcurProg.ranges.total = 0; + mVUrange[0] = 0; + mVUrange[1] = mVU->microMemSize - 8; + DevCon::Status("microVU%d: Prog Range List Full", params mVU->index); + } + } else { - for (; i > 0; i--) { - incPC2(-2); - if (isSflag) { runLoop = 0; break; } - if (doStatus) { mVUinfo |= _isSflag; break; } + if (mVUrange[0] <= pc) { + mVUrange[1] = pc; + for (int i = 0; i <= (mVUcurProg.ranges.total-1); i++) { + int rStart = (mVUrange[0] < 8) ? 0 : (mVUrange[0] - 8); + int rEnd = pc; + if((mVUcurProg.ranges.range[i][1] >= rStart) + && (mVUcurProg.ranges.range[i][1] <= rEnd)){ + mVUcurProg.ranges.range[i][1] = pc; + mVUrange[0] = -1; + mVUrange[1] = -1; + mVUcurProg.ranges.total--; + //DevCon::Status("microVU%d: Prog Range Merging", params mVU->index); + } + } } - } - if (runLoop) { - for (; i > 0; i--) { - incPC2(-2); - if (isSflag) break; - mVUinfo &= ~_doStatus; + else { + DevCon::Status("microVU%d: Prog Range Wrap [%04x] [%d]", params mVU->index, mVUrange[0], mVUrange[1]); + mVUrange[1] = mVU->microMemSize - 8; + if (mVUcurProg.ranges.total < mVUcurProg.ranges.max) { + mVUcurProg.ranges.total++; + mVUrange[0] = 0; + mVUrange[1] = pc; + } + else { + mVUcurProg.ranges.total = 0; + mVUrange[0] = 0; + mVUrange[1] = mVU->microMemSize - 8; + DevCon::Status("microVU%d: Prog Range List Full", params mVU->index); + } } } - iPC = curPC; -} - -// Note: Flag handling is 'very' complex, it requires full knowledge of how microVU recs work, so don't touch! -microVUt(void) mVUsetFlags(int* bStatus, int* bMac) { - microVU* mVU = mVUx; - - // Ensure last ~4+ instructions update mac flags - int endPC = iPC; - u32 aCount = 1; // Amount of instructions needed to get 4 valid status/mac flag instances - for (int i = mVUcount, iX = 0; i > 0; i--, aCount++) { - if (doStatus) { mVUinfo |= _doMac; iX++; if ((iX >= 4) || (aCount > 4)) { break; } } - incPC2(-2); - } - - // Status/Mac Flags Setup Code - int xStatus = 8, xMac = 8; // Flag Instances start at #0 on every block ((8&3) == 0) - int pStatus = 3, pMac = 3; - int xClip = mVUregs.clip + 8, pClip = mVUregs.clip + 7; // Clip Instance starts from where it left off - int xS = 0, yS = 1, zS = 0; - int xM = 0, yM = 1, zM = 0; - int xC = 0, yC = 1, zC = 0; - u32 xCount = mVUcount; // Backup count - iPC = mVUstartPC; - for (mVUcount = 0; mVUcount < xCount; mVUcount++) { - if (((xCount - mVUcount) > aCount) && isFSSET) mVUstatusFlagOp(); // Don't Optimize out on the last ~4+ instructions - - flagSetMacro(xStatus, pStatus, xS, yS, zS); // Handles _fvsinstances - flagSetMacro(xMac, pMac, xM, yM, zM); // Handles _fvminstances - flagSetMacro(xClip, pClip, xC, yC, zC); // Handles _fvcinstances - - mVUinfo |= (xStatus&3) << 12; // _fsInstance - mVUinfo |= (xMac&3) << 10; // _fmInstance - mVUinfo |= (xClip&3) << 14; // _fcInstance - - mVUinfo |= (pStatus&3) << 18; // _fvsInstance - mVUinfo |= (pMac&3) << 16; // _fvmInstance - mVUinfo |= (pClip&3) << 20; // _fvcInstance - - if (doStatus||isFSSET||doDivFlag) { xStatus = (xStatus+1); } - if (doMac) { xMac = (xMac+1); } - if (doClip) { xClip = (xClip+1); } - incPC2(2); - } - mVUcount = xCount; // Restore count - mVUregs.clip = xClip&3; // Note: Clip timing isn't cycle-accurate between block linking; but hopefully doesn't matter - - // Setup Last 4 instances of Status/Mac flags (needed for accurate block linking) - iPC = endPC; - for (int i = 3, j = 3, ii = 1, jj = 1; aCount > 0; ii++, jj++, aCount--) { - if ((doStatus||isFSSET||doDivFlag) && (i >= 0)) { - for (; (ii > 0 && i >= 0); i--, ii--) { xStatus = (xStatus-1) & 3; bStatus[i] = xStatus; } - } - if (doMac && (j >= 0)) { - for (; (jj > 0 && j >= 0); j--, jj--) { xMac = (xMac-1) & 3; bMac[j] = xMac; } - } - incPC2(-2); - } } -#define getFlagReg1(x) ((x == 3) ? gprF3 : ((x == 2) ? gprF2 : ((x == 1) ? gprF1 : gprF0))) -#define getFlagReg2(x) ((x == bStatus[3]) ? gprESP : ((x == bStatus[2]) ? gprR : ((x == bStatus[1]) ? gprT2 : gprT1))) - // Recompiles Code for Proper Flags and Q/P regs on Block Linkings -microVUt(void) mVUsetupBranch(int* bStatus, int* bMac) { - microVU* mVU = mVUx; +microVUt(void) mVUsetupBranch(mV, int* xStatus, int* xMac, int* xClip, int xCycles) { mVUprint("mVUsetupBranch"); - PUSH32R(gprR); // Backup gprR - MOV32RtoM((uptr)&mVU->espBackup, gprESP); - - MOV32RtoR(gprT1, getFlagReg1(bStatus[0])); - MOV32RtoR(gprT2, getFlagReg1(bStatus[1])); - MOV32RtoR(gprR, getFlagReg1(bStatus[2])); - MOV32RtoR(gprESP, getFlagReg1(bStatus[3])); - - MOV32RtoR(gprF0, gprT1); - MOV32RtoR(gprF1, gprT2); - MOV32RtoR(gprF2, gprR); - MOV32RtoR(gprF3, gprESP); - - AND32ItoR(gprT1, 0xffff0000); - AND32ItoR(gprT2, 0xffff0000); - AND32ItoR(gprR, 0xffff0000); - AND32ItoR(gprESP, 0xffff0000); - - AND32ItoR(gprF0, 0x0000ffff); - AND32ItoR(gprF1, 0x0000ffff); - AND32ItoR(gprF2, 0x0000ffff); - AND32ItoR(gprF3, 0x0000ffff); - - OR32RtoR(gprF0, getFlagReg2(bMac[0])); - OR32RtoR(gprF1, getFlagReg2(bMac[1])); - OR32RtoR(gprF2, getFlagReg2(bMac[2])); - OR32RtoR(gprF3, getFlagReg2(bMac[3])); - - MOV32MtoR(gprESP, (uptr)&mVU->espBackup); - POP32R(gprR); // Restore gprR + // Shuffle Flag Instances + mVUsetupFlags(mVU, xStatus, xMac, xClip, xCycles); // Shuffle P/Q regs since every block starts at instance #0 if (mVU->p || mVU->q) { SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, shufflePQ); } } -microVUt(void) mVUincCycles(int x) { - microVU* mVU = mVUx; +microVUt(void) mVUincCycles(mV, int x) { mVUcycles += x; for (int z = 31; z > 0; z--) { calcCycles(mVUregs.VF[z].x, x); @@ -196,28 +167,49 @@ microVUt(void) mVUincCycles(int x) { calcCycles(mVUregs.VI[z], x); } if (mVUregs.q) { - if (mVUregs.q > 4) { calcCycles(mVUregs.q, x); if (mVUregs.q <= 4) { mVUinfo |= _doDivFlag; } } + if (mVUregs.q > 4) { calcCycles(mVUregs.q, x); if (mVUregs.q <= 4) { mVUinfo.doDivFlag = 1; } } else { calcCycles(mVUregs.q, x); } if (!mVUregs.q) { incQ(); } } if (mVUregs.p) { calcCycles(mVUregs.p, x); - if (!mVUregs.p) { incP(); } + if (!mVUregs.p || (mVUregs.p && mVUregsTemp.p)) { incP(); } + } + if (mVUregs.xgkick) { + calcCycles(mVUregs.xgkick, x); + if (!mVUregs.xgkick) { mVUinfo.doXGKICK = 1; } } calcCycles(mVUregs.r, x); - calcCycles(mVUregs.xgkick, x); } -microVUt(void) mVUsetCycles() { - microVU* mVU = mVUx; - incCycles(mVUstall); - if (mVUregsTemp.VFreg[0] == mVUregsTemp.VFreg[1] && mVUregsTemp.VFreg[0]) { // If upper Op && lower Op write to same VF reg - mVUinfo |= (mVUregsTemp.r || mVUregsTemp.VI) ? _noWriteVF : _isNOP; // If lower Op doesn't modify anything else, then make it a NOP - tCycles(mVUregsTemp.VF[1].x, mVUregsTemp.VF[0].x) // Use max cycles from each vector - tCycles(mVUregsTemp.VF[1].y, mVUregsTemp.VF[0].y) - tCycles(mVUregsTemp.VF[1].z, mVUregsTemp.VF[0].z) - tCycles(mVUregsTemp.VF[1].w, mVUregsTemp.VF[0].w) +#define cmpVFregs(VFreg1, VFreg2, xVar) { \ + if (VFreg1.reg == VFreg2.reg) { \ + if ((VFreg1.x && VFreg2.x) \ + || (VFreg1.y && VFreg2.y) \ + || (VFreg1.z && VFreg2.z) \ + || (VFreg1.w && VFreg2.w)) \ + { xVar = 1; } \ + } \ +} + +microVUt(void) mVUsetCycles(mV) { + mVUincCycles(mVU, mVUstall); + // If upper Op && lower Op write to same VF reg: + if ((mVUregsTemp.VFreg[0] == mVUregsTemp.VFreg[1]) && mVUregsTemp.VFreg[0]) { + if (mVUregsTemp.r || mVUregsTemp.VI) mVUlow.noWriteVF = 1; + else mVUlow.isNOP = 1; // If lower Op doesn't modify anything else, then make it a NOP } + // If lower op reads a VF reg that upper Op writes to: + if ((mVUlow.VF_read[0].reg || mVUlow.VF_read[1].reg) && mVUup.VF_write.reg) { + cmpVFregs(mVUup.VF_write, mVUlow.VF_read[0], mVUinfo.swapOps); + cmpVFregs(mVUup.VF_write, mVUlow.VF_read[1], mVUinfo.swapOps); + } + // If above case is true, and upper op reads a VF reg that lower Op Writes to: + if (mVUinfo.swapOps && ((mVUup.VF_read[0].reg || mVUup.VF_read[1].reg) && mVUlow.VF_write.reg)) { + cmpVFregs(mVUlow.VF_write, mVUup.VF_read[0], mVUinfo.backupVF); + cmpVFregs(mVUlow.VF_write, mVUup.VF_read[1], mVUinfo.backupVF); + } + tCycles(mVUregs.VF[mVUregsTemp.VFreg[0]].x, mVUregsTemp.VF[0].x); tCycles(mVUregs.VF[mVUregsTemp.VFreg[0]].y, mVUregsTemp.VF[0].y); tCycles(mVUregs.VF[mVUregsTemp.VFreg[0]].z, mVUregsTemp.VF[0].z); @@ -235,60 +227,117 @@ microVUt(void) mVUsetCycles() { tCycles(mVUregs.xgkick, mVUregsTemp.xgkick); } -microVUt(void) mVUdivSet() { - microVU* mVU = mVUx; - int flagReg1, flagReg2; - if (doDivFlag) { - getFlagReg(flagReg1, fsInstance); - if (!doStatus) { getFlagReg(flagReg2, fpsInstance); MOV16RtoR(flagReg1, flagReg2); } - MOV32RtoR(gprT1, flagReg1); - AND32ItoR(gprT1, 0xffff0fcf); - OR32MtoR (gprT1, (uptr)&mVU->divFlag); - MOV32RtoR(flagReg1, gprT1); +#define sI ((mVUpBlock->pState.needExactMatch & 0x000f) ? 0 : ((mVUpBlock->pState.flags >> 0) & 3)) +#define cI ((mVUpBlock->pState.needExactMatch & 0x0f00) ? 0 : ((mVUpBlock->pState.flags >> 2) & 3)) + +microVUt(void) mVUendProgram(mV, int isEbit, int* xStatus, int* xMac, int* xClip) { + + int fStatus = (isEbit) ? findFlagInst(xStatus, 0x7fffffff) : sI; + int fMac = (isEbit) ? findFlagInst(xMac, 0x7fffffff) : 0; + int fClip = (isEbit) ? findFlagInst(xClip, 0x7fffffff) : cI; + int qInst = 0; + int pInst = 0; + + if (isEbit) { + mVUprint("mVUcompile ebit"); + memset(&mVUinfo, 0, sizeof(mVUinfo)); + mVUincCycles(mVU, 100); // Ensures Valid P/Q instances (And sets all cycle data to 0) + mVUcycles -= 100; + qInst = mVU->q; + pInst = mVU->p; + if (mVUinfo.doDivFlag) { + sFLAG.doFlag = 1; + sFLAG.write = fStatus; + mVUdivSet(mVU); + } + if (mVUinfo.doXGKICK) { mVU_XGKICK_DELAY(mVU, 1); } + } + + // Save P/Q Regs + if (qInst) { SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, 0xe5); } + SSE_MOVSS_XMM_to_M32((uptr)&mVU->regs->VI[REG_Q].UL, xmmPQ); + if (isVU1) { + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, pInst ? 3 : 2); + SSE_MOVSS_XMM_to_M32((uptr)&mVU->regs->VI[REG_P].UL, xmmPQ); + } + + // Save Flag Instances + mVUallocSFLAGc(gprT1, gprT2, fStatus); + MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, gprT1); + mVUallocMFLAGa(mVU, gprT1, fMac); + mVUallocCFLAGa(mVU, gprT2, fClip); + MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, gprT1); + MOV32RtoM((uptr)&mVU->regs->VI[REG_CLIP_FLAG].UL, gprT2); + + if (isEbit || isVU1) { // Clear 'is busy' Flags + AND32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, (isVU1 ? ~0x100 : ~0x001)); // VBS0/VBS1 flag + AND32ItoM((uptr)&mVU->regs->vifRegs->stat, ~0x4); // Clear VU 'is busy' signal for vif + } + + if (isEbit != 2) { // Save PC, and Jump to Exit Point + MOV32ItoM((uptr)&mVU->regs->VI[REG_TPC].UL, xPC); + JMP32((uptr)mVU->exitFunct - ((uptr)x86Ptr + 5)); } } -microVUt(void) mVUendProgram() { - microVU* mVU = mVUx; - incCycles(100); // Ensures Valid P/Q instances (And sets all cycle data to 0) - mVUcycles -= 100; - if (mVU->q) { SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, 0xe5); } - SSE_MOVSS_XMM_to_M32((uptr)&mVU->regs->VI[REG_Q].UL, xmmPQ); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVU->p ? 3 : 2); - SSE_MOVSS_XMM_to_M32((uptr)&mVU->regs->VI[REG_P].UL, xmmPQ); - - //memcpy_fast(&pBlock->pStateEnd, &mVUregs, sizeof(microRegInfo)); - //MOV32ItoM((uptr)&mVU->prog.lpState, (int)&mVUblock.pState); // Save pipeline state (clipflag instance) - AND32ItoM((uptr)µVU0.regs->VI[REG_VPU_STAT].UL, (vuIndex ? ~0x100 : ~0x001)); // VBS0/VBS1 flag - AND32ItoM((uptr)&mVU->regs->vifRegs->stat, ~0x4); // Clear VU 'is busy' signal for vif - MOV32ItoM((uptr)&mVU->regs->VI[REG_TPC].UL, xPC); - JMP32((uptr)mVU->exitFunct - ((uptr)x86Ptr + 5)); +void branchCaseFunct(mV, microBlock* &bBlock, int* xStatus, int* xMac, int* xClip, int &xCycles, s32* &ajmp, int JMPcc) { + using namespace x86Emitter; + mVUsetupBranch(mVU, xStatus, xMac, xClip, xCycles); + xCMP(ptr16[&mVU->branch], 0); + if (mVUup.eBit) { // Conditional Branch With E-Bit Set + mVUendProgram(mVU, 2, xStatus, xMac, xClip); + xForwardJump8 eJMP((JccComparisonType)JMPcc); + incPC(1); // Set PC to First instruction of Non-Taken Side + xMOV(ptr32[&mVU->regs->VI[REG_TPC].UL], xPC); + xJMP(mVU->exitFunct); + eJMP.SetTarget(); + incPC(-4); // Go Back to Branch Opcode to get branchAddr + iPC = branchAddr/4; + xMOV(ptr32[&mVU->regs->VI[REG_TPC].UL], xPC); + xJMP(mVU->exitFunct); + } + else { // Normal Conditional Branch + incPC2(1); // Check if Branch Non-Taken Side has already been recompiled + blockCreate(iPC/2); + bBlock = mVUblocks[iPC/2]->search((microRegInfo*)&mVUregs); + incPC2(-1); + if (bBlock) { xJcc( xInvertCond((JccComparisonType)JMPcc), bBlock->x86ptrStart ); } + else { ajmp = xJcc32((JccComparisonType)JMPcc); } + } } -microVUt(void) mVUtestCycles() { - microVU* mVU = mVUx; +void __fastcall mVUwarning0(u32 PC) { Console::Error("microVU0 Warning: Exiting from Possible Infinite Loop [%04x]", params PC); } +void __fastcall mVUwarning1(u32 PC) { Console::Error("microVU1 Warning: Exiting from Possible Infinite Loop [%04x]", params PC); } +void __fastcall mVUprintPC1(u32 PC) { Console::Write("Block PC [%04x] ", params PC); } +void __fastcall mVUprintPC2(u32 PC) { Console::Write("[%04x]\n", params PC); } + +microVUt(void) mVUtestCycles(mV) { iPC = mVUstartPC; - CMP32ItoM((uptr)&mVU->cycles, 0); - u8* jmp8 = JG8(0); - mVUendProgram(); - x86SetJ8(jmp8); + mVUdebugNOW(0); SUB32ItoM((uptr)&mVU->cycles, mVUcycles); + u32* jmp32 = JG32(0); + MOV32ItoR(gprT2, xPC); + if (isVU1) CALLFunc((uptr)mVUwarning1); + //else CALLFunc((uptr)mVUwarning0); // VU0 is allowed early exit for COP2 Interlock Simulation + MOV32ItoR(gprR, Roffset); // Restore gprR + mVUendProgram(mVU, 0, NULL, NULL, NULL); + x86SetJ32(jmp32); } + //------------------------------------------------------------------ // Recompiler //------------------------------------------------------------------ -microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) { - microVU* mVU = mVUx; - u8* thisPtr = x86Ptr; +microVUr(void*) mVUcompile(microVU* mVU, u32 startPC, uptr pState) { - if (startPC > ((vuIndex) ? 0x3fff : 0xfff)) { mVUprint("microVU: invalid startPC"); } - startPC &= (vuIndex ? 0x3ff8 : 0xff8); + using namespace x86Emitter; + microBlock* pBlock = NULL; + u8* thisPtr = x86Ptr; + const u32 endCount = (mVU->microMemSize / 8) - 1; + + // Setup Program Bounds/Range + mVUsetupRange(mVU, startPC, 1); - // Searches for Existing Compiled Block (if found, then returns; else, compile) - microBlock* pBlock = mVUblocks[startPC/8]->search((microRegInfo*)pState); - if (pBlock) { return pBlock->x86ptrStart; } - // First Pass iPC = startPC / 4; setCode(); @@ -301,122 +350,155 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) { memcpy_fast(&mVUregs, (microRegInfo*)pState, sizeof(microRegInfo)); // Loads up Pipeline State Info mVUblock.x86ptrStart = thisPtr; pBlock = mVUblocks[startPC/8]->add(&mVUblock); // Add this block to block manager + mVUpBlock = pBlock; + mVUregs.flags = 0; + mVUflagInfo = 0; + mVUsFlagHack = CHECK_VU_FLAGHACK; - for (int branch = 0;; ) { + for (int branch = 0; mVUcount < endCount; mVUcount++) { incPC(1); - mVUinfo = 0; - incCycles(1); startLoop(); - mVUopU(); - if (curI & _Ebit_) { branch = 1; } - if (curI & _MDTbit_) { branch = 2; } - if (curI & _Ibit_) { mVUinfo |= _isNOP; } - else { incPC(-1); mVUopL(); incPC(1); } - mVUsetCycles(); - if (mVU->p) { mVUinfo |= _readP; } - if (mVU->q) { mVUinfo |= _readQ; } - else { mVUinfo |= _writeQ; } - if (branch >= 2) { mVUinfo |= _isEOB | ((branch == 3) ? _isBdelay : 0); if (mVUbranch) { Console::Error("microVU Warning: Branch in E-bit/Branch delay slot!"); mVUinfo |= _isNOP; } break; } + mVUincCycles(mVU, 1); + mVUopU(mVU, 0); + if (curI & _Ebit_) { branch = 1; mVUup.eBit = 1; } + if (curI & _DTbit_) { branch = 4; } + if (curI & _Mbit_) { mVUup.mBit = 1; } + if (curI & _Ibit_) { mVUlow.isNOP = 1; mVUup.iBit = 1; } + else { incPC(-1); mVUopL(mVU, 0); incPC(1); } + mVUsetCycles(mVU); + mVUinfo.readQ = mVU->q; + mVUinfo.writeQ = !mVU->q; + mVUinfo.readP = mVU->p; + mVUinfo.writeP = !mVU->p; + if (branch >= 2) { mVUinfo.isEOB = 1; if (branch == 3) { mVUinfo.isBdelay = 1; } mVUcount++; branchWarning(); break; } else if (branch == 1) { branch = 2; } - if (mVUbranch) { branch = 3; mVUbranch = 0; mVUinfo |= _isBranch; } + if (mVUbranch) { mVUsetFlagInfo(mVU); branch = 3; mVUbranch = 0; } incPC(1); - mVUcount++; } // Sets Up Flag instances - int bStatus[4]; int bMac[4]; - mVUsetFlags(bStatus, bMac); - mVUtestCycles(); + int xStatus[4], xMac[4], xClip[4]; + int xCycles = mVUsetFlags(mVU, xStatus, xMac, xClip); + mVUtestCycles(mVU); // Second Pass iPC = mVUstartPC; setCode(); mVUbranch = 0; - int x; - for (x = 0; x < (vuIndex ? (0x3fff/8) : (0xfff/8)); x++) { - if (isEOB) { x = 0xffff; } - if (isNOP) { incPC(1); doUpperOp(); if (curI & _Ibit_) { incPC(-1); MOV32ItoM((uptr)&mVU->regs->VI[REG_I].UL, curI); incPC(1); } } - else if (!swapOps) { incPC(1); doUpperOp(); incPC(-1); mVUopL(); incPC(1); } - else { mVUopL(); incPC(1); doUpperOp(); } + uint x; + for (x = 0; x < endCount; x++) { + if (mVUinfo.isEOB) { x = 0xffff; } + if (mVUup.mBit) { OR32ItoM((uptr)&mVU->regs->flags, VUFLAG_MFLAGSET); } + if (mVUlow.isNOP) { incPC(1); doUpperOp(); doIbit(); } + else if (!mVUinfo.swapOps) { incPC(1); doUpperOp(); doLowerOp(); } + else { doSwapOp(); } + if (mVUinfo.doXGKICK) { mVU_XGKICK_DELAY(mVU, 1); } - if (!isBdelay) { incPC(1); } + if (!mVUinfo.isBdelay) { incPC(1); } else { microBlock* bBlock = NULL; - u32* ajmp = 0; + s32* ajmp = 0; + mVUsetupRange(mVU, xPC, 0); + mVUdebugNOW(1); + switch (mVUbranch) { - case 3: branchCase(JZ32, JNZ32); // IBEQ - case 4: branchCase(JGE32, JNGE32); // IBGEZ - case 5: branchCase(JG32, JNG32); // IBGTZ - case 6: branchCase(JLE32, JNLE32); // IBLEQ - case 7: branchCase(JL32, JNL32); // IBLTZ - case 8: branchCase(JNZ32, JZ32); // IBNEQ + case 3: branchCase(Jcc_Equal); // IBEQ + case 4: branchCase(Jcc_GreaterOrEqual); // IBGEZ + case 5: branchCase(Jcc_Greater); // IBGTZ + case 6: branchCase(Jcc_LessOrEqual); // IBLEQ + case 7: branchCase(Jcc_Less); // IBLTZ + case 8: branchCase(Jcc_NotEqual); // IBNEQ case 1: case 2: // B/BAL mVUprint("mVUcompile B/BAL"); incPC(-3); // Go back to branch opcode (to get branch imm addr) - mVUsetupBranch(bStatus, bMac); + + if (mVUup.eBit) { iPC = branchAddr/4; mVUendProgram(mVU, 1, xStatus, xMac, xClip); } // E-bit Branch + mVUsetupBranch(mVU, xStatus, xMac, xClip, xCycles); // Check if branch-block has already been compiled + blockCreate(branchAddr/8); pBlock = mVUblocks[branchAddr/8]->search((microRegInfo*)&mVUregs); - if (pBlock) { JMP32((uptr)pBlock->x86ptrStart - ((uptr)x86Ptr + 5)); } - else if (!vuIndex) { mVUcompileVU0(branchAddr, (uptr)&mVUregs); } - else { mVUcompileVU1(branchAddr, (uptr)&mVUregs); } + if (pBlock) { xJMP(pBlock->x86ptrStart); } + else { mVUcompile(mVU, branchAddr, (uptr)&mVUregs); } return thisPtr; case 9: case 10: // JR/JALR mVUprint("mVUcompile JR/JALR"); + incPC(-3); // Go back to jump opcode + + if (mVUup.eBit) { // E-bit Jump + mVUendProgram(mVU, 2, xStatus, xMac, xClip); + MOV32MtoR(gprT1, (uptr)&mVU->branch); + MOV32RtoM((uptr)&mVU->regs->VI[REG_TPC].UL, gprT1); + xJMP(mVU->exitFunct); + return thisPtr; + } + memcpy_fast(&pBlock->pStateEnd, &mVUregs, sizeof(microRegInfo)); - mVUsetupBranch(bStatus, bMac); + mVUsetupBranch(mVU, xStatus, xMac, xClip, xCycles); - mVUbackupRegs(); - MOV32MtoR(gprT2, (uptr)&mVU->branch); // Get startPC (ECX first argument for __fastcall) - //AND32ItoR(gprT2, (vuIndex)?0x3ff8:0xff8); // Ensure valid jump address - MOV32ItoR(gprR, (u32)&pBlock->pStateEnd); // Get pState (EDX second argument for __fastcall) + mVUbackupRegs(mVU); + MOV32MtoR(gprT2, (uptr)&mVU->branch); // Get startPC (ECX first argument for __fastcall) + MOV32ItoR(gprR, (u32)&pBlock->pStateEnd); // Get pState (EDX second argument for __fastcall) - if (!vuIndex) CALLFunc((uptr)mVUcompileVU0); //(u32 startPC, uptr pState) - else CALLFunc((uptr)mVUcompileVU1); - mVUrestoreRegs(); + if (!mVU->index) xCALL(mVUcompileJIT<0>); //(u32 startPC, uptr pState) + else xCALL(mVUcompileJIT<1>); + mVUrestoreRegs(mVU); JMPR(gprT1); // Jump to rec-code address return thisPtr; } // Conditional Branches mVUprint("mVUcompile conditional branch"); - if (bBlock) { // Branch non-taken has already been compiled + if (mVUup.eBit) return thisPtr; // Handled in Branch Case + if (bBlock) { // Branch non-taken has already been compiled incPC(-3); // Go back to branch opcode (to get branch imm addr) + // Check if branch-block has already been compiled + blockCreate(branchAddr/8); pBlock = mVUblocks[branchAddr/8]->search((microRegInfo*)&mVUregs); - if (pBlock) { JMP32((uptr)pBlock->x86ptrStart - ((uptr)x86Ptr + 5)); } - else if (!vuIndex) { mVUcompileVU0(branchAddr, (uptr)&mVUregs); } - else { mVUcompileVU1(branchAddr, (uptr)&mVUregs); } + if (pBlock) { xJMP( pBlock->x86ptrStart ); } + else { mVUblockFetch(mVU, branchAddr, (uptr)&mVUregs); } } else { uptr jumpAddr; - u32 bPC = iPC; // mVUcompile can modify iPC and mVUregs, so back them up + u32 bPC = iPC; // mVUcompile can modify iPC and mVUregs so back them up memcpy_fast(&pBlock->pStateEnd, &mVUregs, sizeof(microRegInfo)); incPC2(1); // Get PC for branch not-taken - if (!vuIndex) mVUcompileVU0(xPC, (uptr)&mVUregs); - else mVUcompileVU1(xPC, (uptr)&mVUregs); + mVUcompile(mVU, xPC, (uptr)&mVUregs); iPC = bPC; incPC(-3); // Go back to branch opcode (to get branch imm addr) - if (!vuIndex) jumpAddr = (uptr)mVUcompileVU0(branchAddr, (uptr)&pBlock->pStateEnd); - else jumpAddr = (uptr)mVUcompileVU1(branchAddr, (uptr)&pBlock->pStateEnd); + jumpAddr = (uptr)mVUblockFetch(mVU, branchAddr, (uptr)&pBlock->pStateEnd); *ajmp = (jumpAddr - ((uptr)ajmp + 4)); } return thisPtr; } } - mVUprint("mVUcompile ebit"); - if (x == (vuIndex?(0x3fff/8):(0xfff/8))) { mVUprint("microVU: Possible infinite compiling loop!"); } + if (x == endCount) { Console::Error("microVU%d: Possible infinite compiling loop!", params mVU->index); } - // Do E-bit end stuff here - mVUendProgram(); - - return thisPtr; //ToDo: Save pipeline state? + // E-bit End + mVUsetupRange(mVU, xPC-8, 0); + mVUendProgram(mVU, 1, xStatus, xMac, xClip); + return thisPtr; } -void* __fastcall mVUcompileVU0(u32 startPC, uptr pState) { return mVUcompile<0>(startPC, pState); } -void* __fastcall mVUcompileVU1(u32 startPC, uptr pState) { return mVUcompile<1>(startPC, pState); } + // Search for Existing Compiled Block (if found, return x86ptr; else, compile and return x86ptr) +microVUt(void*) mVUblockFetch(microVU* mVU, u32 startPC, uptr pState) { + + using namespace x86Emitter; + if (startPC > mVU->microMemSize-8) { DevCon::Error("microVU%d: invalid startPC [%04x]", params mVU->index, startPC); } + startPC &= mVU->microMemSize-8; + + blockCreate(startPC/8); + microBlock* pBlock = mVUblocks[startPC/8]->search((microRegInfo*)pState); + if (pBlock) { return pBlock->x86ptrStart; } + else { return mVUcompile(mVU, startPC, pState); } +} + +// mVUcompileJIT() - Called By JR/JALR during execution +microVUx(void*) __fastcall mVUcompileJIT(u32 startPC, uptr pState) { + return mVUblockFetch(mVUx, startPC, pState); +} -#endif //PCSX2_MICROVU diff --git a/pcsx2/x86/microVU_Execute.inl b/pcsx2/x86/microVU_Execute.inl index a8765d4a8e..9a8e4b28b1 100644 --- a/pcsx2/x86/microVU_Execute.inl +++ b/pcsx2/x86/microVU_Execute.inl @@ -1,39 +1,34 @@ /* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2009 Pcsx2-Playground Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ + * Copyright (C) 2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #pragma once -#ifdef PCSX2_MICROVU //------------------------------------------------------------------ // Dispatcher Functions //------------------------------------------------------------------ -void testFunction() { mVUprint("microVU: Entered Execution Mode"); } - // Generates the code for entering recompiled blocks -microVUt(void) mVUdispatcherA() { - static u32 PCSX2_ALIGNED16(vuMXCSR); - microVU* mVU = mVUx; +void mVUdispatcherA(mV) { mVU->startFunct = x86Ptr; // __fastcall = The first two DWORD or smaller arguments are passed in ECX and EDX registers; all other arguments are passed right to left. - if (!vuIndex) { CALLFunc((uptr)mVUexecuteVU0); } - else { CALLFunc((uptr)mVUexecuteVU1); } + if (!isVU1) { CALLFunc((uptr)mVUexecuteVU0); } + else { CALLFunc((uptr)mVUexecuteVU1); } // Backup cpu state PUSH32R(EBX); @@ -42,23 +37,36 @@ microVUt(void) mVUdispatcherA() { PUSH32R(EDI); // Load VU's MXCSR state - vuMXCSR = g_sseVUMXCSR; - SSE_LDMXCSR((uptr)&vuMXCSR); + SSE_LDMXCSR((uptr)&g_sseVUMXCSR); // Load Regs - MOV32MtoR(gprR, (uptr)&mVU->regs->VI[REG_R].UL); + MOV32ItoR(gprR, Roffset); // Load VI Reg Offset MOV32MtoR(gprF0, (uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL); - MOV32MtoR(gprF1, (uptr)&mVU->regs->VI[REG_MAC_FLAG].UL); - SHL32ItoR(gprF0, 16); - AND32ItoR(gprF1, 0xffff); - OR32RtoR (gprF0, gprF1); + MOV32RtoR(gprF1, gprF0); - MOV32RtoR(gprF2, gprF0); - MOV32RtoR(gprF3, gprF0); + SHR32ItoR(gprF1, 3); + AND32ItoR(gprF1, 0x18); - for (int i = 1; i < 16; i++) { - if (isMMX(i)) { MOVQMtoR(mmVI(i), (uptr)&mVU->regs->VI[i].UL); } - } + MOV32RtoR(gprF2, gprF0); + SHL32ItoR(gprF2, 11); + AND32ItoR(gprF2, 0x1800); + OR32RtoR (gprF1, gprF2); + + SHL32ItoR(gprF0, 14); + AND32ItoR(gprF0, 0x3cf0000); + OR32RtoR (gprF1, gprF0); + + MOV32RtoR(gprF0, gprF1); + MOV32RtoR(gprF2, gprF1); + MOV32RtoR(gprF3, gprF1); + + SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&mVU->regs->VI[REG_MAC_FLAG].UL); + SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, 0); + SSE_MOVAPS_XMM_to_M128((uptr)mVU->macFlag, xmmT1); + + SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&mVU->regs->VI[REG_CLIP_FLAG].UL); + SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, 0); + SSE_MOVAPS_XMM_to_M128((uptr)mVU->clipFlag, xmmT1); SSE_MOVAPS_M128_to_XMM(xmmACC, (uptr)&mVU->regs->ACC.UL[0]); SSE_MOVAPS_M128_to_XMM(xmmMax, (uptr)mVU_maxvals); @@ -67,45 +75,31 @@ microVUt(void) mVUdispatcherA() { SSE_MOVAPS_M128_to_XMM(xmmPQ, (uptr)&mVU->regs->VI[REG_Q].UL); SSE_SHUFPS_XMM_to_XMM(xmmPQ, xmmT1, 0); // wzyx = PPQQ - //PUSH32R(EAX); - //CALLFunc((uptr)testFunction); - //POP32R(EAX); - //write8(0xcc); + for (int i = 1; i < 16; i++) { + if (isMMX(i)) { MOVQMtoR(mmVI(i), (uptr)&mVU->regs->VI[i].UL); } + } // Jump to Recompiled Code Block JMPR(EAX); } // Generates the code to exit from recompiled blocks -microVUt(void) mVUdispatcherB() { - static u32 PCSX2_ALIGNED16(eeMXCSR); - microVU* mVU = mVUx; +void mVUdispatcherB(mV) { mVU->exitFunct = x86Ptr; - // __fastcall = The first two DWORD or smaller arguments are passed in ECX and EDX registers; all other arguments are passed right to left. - if (!vuIndex) { CALLFunc((uptr)mVUcleanUpVU0); } - else { CALLFunc((uptr)mVUcleanUpVU1); } - // Load EE's MXCSR state - eeMXCSR = g_sseMXCSR; - SSE_LDMXCSR((uptr)&eeMXCSR); + SSE_LDMXCSR((uptr)&g_sseMXCSR); - // Save Regs - MOV32RtoR(gprT1, gprF0); // ToDo: Ensure Correct Flag instances - AND32ItoR(gprT1, 0xffff); - SHR32ItoR(gprF0, 16); - MOV32RtoM((uptr)&mVU->regs->VI[REG_R].UL, gprR); - MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, gprT1); - MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, gprF0); - - for (int i = 0; i < 8; i++) { - - } + // Save Regs (Other Regs Saved in mVUcompile) + SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->ACC.UL[0], xmmACC); + for (int i = 1; i < 16; i++) { if (isMMX(i)) { MOVDMMXtoM((uptr)&mVU->regs->VI[i].UL, mmVI(i)); } } - SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->ACC.UL[0], xmmACC); + // __fastcall = The first two DWORD or smaller arguments are passed in ECX and EDX registers; all other arguments are passed right to left. + if (!isVU1) { CALLFunc((uptr)mVUcleanUpVU0); } + else { CALLFunc((uptr)mVUcleanUpVU1); } // Restore cpu state POP32R(EDI); @@ -113,12 +107,10 @@ microVUt(void) mVUdispatcherB() { POP32R(EBP); POP32R(EBX); - //write8(0xcc); - if (isMMX(1)) EMMS(); RET(); - mVUcacheCheck(x86Ptr, mVU->cache, 512); + mVUcacheCheck(x86Ptr, mVU->cache, 0x1000); } //------------------------------------------------------------------ @@ -126,7 +118,7 @@ microVUt(void) mVUdispatcherB() { //------------------------------------------------------------------ // Executes for number of cycles -microVUt(void*) __fastcall mVUexecute(u32 startPC, u32 cycles) { +microVUx(void*) __fastcall mVUexecute(u32 startPC, u32 cycles) { microVU* mVU = mVUx; //mVUprint("microVU%x: startPC = 0x%x, cycles = 0x%x", params vuIndex, startPC, cycles); @@ -136,32 +128,31 @@ microVUt(void*) __fastcall mVUexecute(u32 startPC, u32 cycles) { mVU->totalCycles = cycles; x86SetPtr(mVUcurProg.x86ptr); // Set x86ptr to where program left off - if (!vuIndex) return mVUcompileVU0(startPC, (uptr)&mVU->prog.lpState); - else return mVUcompileVU1(startPC, (uptr)&mVU->prog.lpState); + return mVUblockFetch(mVU, startPC, (uptr)&mVU->prog.lpState); } //------------------------------------------------------------------ // Cleanup Functions //------------------------------------------------------------------ -microVUt(void) mVUcleanUp() { +microVUx(void) mVUcleanUp() { microVU* mVU = mVUx; //mVUprint("microVU: Program exited successfully!"); //mVUprint("microVU: VF0 = {%x,%x,%x,%x}", params mVU->regs->VF[0].UL[0], mVU->regs->VF[0].UL[1], mVU->regs->VF[0].UL[2], mVU->regs->VF[0].UL[3]); //mVUprint("microVU: VI0 = %x", params mVU->regs->VI[0].UL); mVUcurProg.x86ptr = x86Ptr; mVUcacheCheck(x86Ptr, mVUcurProg.x86start, (uptr)(mVUcurProg.x86end - mVUcurProg.x86start)); + mVU->cycles = mVU->totalCycles - mVU->cycles; + mVU->regs->cycle += mVU->cycles; + cpuRegs.cycle += ((mVU->cycles < 3000) ? mVU->cycles : 3000) * Config.Hacks.VUCycleSteal; } //------------------------------------------------------------------ // Caller Functions //------------------------------------------------------------------ -void __fastcall startVU0(u32 startPC, u32 cycles) { ((mVUrecCall)microVU0.startFunct)(startPC, cycles); } -void __fastcall startVU1(u32 startPC, u32 cycles) { ((mVUrecCall)microVU1.startFunct)(startPC, cycles); } void* __fastcall mVUexecuteVU0(u32 startPC, u32 cycles) { return mVUexecute<0>(startPC, cycles); } void* __fastcall mVUexecuteVU1(u32 startPC, u32 cycles) { return mVUexecute<1>(startPC, cycles); } void __fastcall mVUcleanUpVU0() { mVUcleanUp<0>(); } void __fastcall mVUcleanUpVU1() { mVUcleanUp<1>(); } -#endif //PCSX2_MICROVU diff --git a/pcsx2/x86/microVU_Flags.inl b/pcsx2/x86/microVU_Flags.inl new file mode 100644 index 0000000000..57f35cca54 --- /dev/null +++ b/pcsx2/x86/microVU_Flags.inl @@ -0,0 +1,280 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +// Sets FDIV Flags at the proper time +microVUt(void) mVUdivSet(mV) { + int flagReg1, flagReg2; + if (mVUinfo.doDivFlag) { + getFlagReg(flagReg1, sFLAG.write); + if (!sFLAG.doFlag) { getFlagReg(flagReg2, sFLAG.lastWrite); MOV32RtoR(flagReg1, flagReg2); } + AND32ItoR(flagReg1, 0xfff3ffff); + OR32MtoR (flagReg1, (uptr)&mVU->divFlag); + } +} + +// Optimizes out unneeded status flag updates +microVUt(void) mVUstatusFlagOp(mV) { + int curPC = iPC; + int i = mVUcount; + bool runLoop = 1; + if (sFLAG.doFlag) { mVUlow.useSflag = 1; } + else { + for (; i > 0; i--) { + incPC2(-2); + if (mVUlow.useSflag) { runLoop = 0; break; } + if (sFLAG.doFlag) { mVUlow.useSflag = 1; break; } + } + } + if (runLoop) { + for (; i > 0; i--) { + incPC2(-2); + if (mVUlow.useSflag) break; + sFLAG.doFlag = 0; + } + } + iPC = curPC; + DevCon::Status("microVU%d: FSSET Optimization", params getIndex); +} + +int findFlagInst(int* fFlag, int cycles) { + int j = 0, jValue = -1; + for (int i = 0; i < 4; i++) { + if ((fFlag[i] <= cycles) && (fFlag[i] > jValue)) { j = i; jValue = fFlag[i]; } + } + return j; +} + +// Setup Last 4 instances of Status/Mac/Clip flags (needed for accurate block linking) +int sortFlag(int* fFlag, int* bFlag, int cycles) { + int lFlag = -5; + int x = 0; + for (int i = 0; i < 4; i++) { + bFlag[i] = findFlagInst(fFlag, cycles); + if (lFlag != bFlag[i]) { x++; } + lFlag = bFlag[i]; + cycles++; + } + return x; // Returns the number of Valid Flag Instances +} + +#define sFlagCond ((sFLAG.doFlag && !mVUsFlagHack) || mVUlow.isFSSET || mVUinfo.doDivFlag) + +// Note: Flag handling is 'very' complex, it requires full knowledge of how microVU recs work, so don't touch! +microVUt(int) mVUsetFlags(mV, int* xStatus, int* xMac, int* xClip) { + + int endPC = iPC; + u32 aCount = 1; // Amount of instructions needed to get valid mac flag instances for block linking + + // Ensure last ~4+ instructions update mac/status flags (if next block's first 4 instructions will read them) + for (int i = mVUcount; i > 0; i--, aCount++) { + if (sFLAG.doFlag) { + if (__Mac) { mFLAG.doFlag = 1; } + if (__Status) { sFLAG.doNonSticky = 1; } + if (aCount >= 4) { break; } + } + incPC2(-2); + } + + // Status/Mac Flags Setup Code + int xS = 0, xM = 0, xC = 0; + for (int i = 0; i < 4; i++) { + xStatus[i] = i; + xMac [i] = i; + xClip [i] = i; + } + + if (!(mVUpBlock->pState.needExactMatch & 0x00f)) { + xS = (mVUpBlock->pState.flags >> 0) & 3; + xStatus[0] = -1; xStatus[1] = -1; + xStatus[2] = -1; xStatus[3] = -1; + xStatus[(xS-1)&3] = 0; + } + + if (!(mVUpBlock->pState.needExactMatch & 0xf00)) { + xC = (mVUpBlock->pState.flags >> 2) & 3; + xClip[0] = -1; xClip[1] = -1; + xClip[2] = -1; xClip[3] = -1; + xClip[(xC-1)&3] = 0; + } + + if (!(mVUpBlock->pState.needExactMatch & 0x0f0)) { + xMac[0] = -1; xMac[1] = -1; + xMac[2] = -1; xMac[3] = -1; + } + + int cycles = 0; + u32 xCount = mVUcount; // Backup count + iPC = mVUstartPC; + for (mVUcount = 0; mVUcount < xCount; mVUcount++) { + if (mVUlow.isFSSET) { + if (__Status) { // Don't Optimize out on the last ~4+ instructions + if ((xCount - mVUcount) > aCount) { mVUstatusFlagOp(mVU); } + } + else mVUstatusFlagOp(mVU); + } + cycles += mVUstall; + + sFLAG.read = findFlagInst(xStatus, cycles); + mFLAG.read = findFlagInst(xMac, cycles); + cFLAG.read = findFlagInst(xClip, cycles); + + sFLAG.write = xS; + mFLAG.write = xM; + cFLAG.write = xC; + + sFLAG.lastWrite = (xS-1) & 3; + mFLAG.lastWrite = (xM-1) & 3; + cFLAG.lastWrite = (xC-1) & 3; + + if (sFlagCond) { xStatus[xS] = cycles + 4; xS = (xS+1) & 3; } + if (mFLAG.doFlag) { xMac [xM] = cycles + 4; xM = (xM+1) & 3; } + if (cFLAG.doFlag) { xClip [xC] = cycles + 4; xC = (xC+1) & 3; } + + cycles++; + incPC2(2); + } + + mVUregs.flags = ((__Clip) ? 0 : (xC << 2)) | ((__Status) ? 0 : xS); + return cycles; +} + +#define getFlagReg1(x) ((x == 3) ? gprF3 : ((x == 2) ? gprF2 : ((x == 1) ? gprF1 : gprF0))) +#define getFlagReg2(x) ((bStatus[0] == x) ? getFlagReg1(x) : gprT1) +#define getFlagReg3(x) ((gFlag == x) ? gprT1 : getFlagReg1(x)) +#define getFlagReg4(x) ((gFlag == x) ? gprT1 : gprT2) +#define shuffleMac ((bMac [3]<<6)|(bMac [2]<<4)|(bMac [1]<<2)|bMac [0]) +#define shuffleClip ((bClip[3]<<6)|(bClip[2]<<4)|(bClip[1]<<2)|bClip[0]) + +// Recompiles Code for Proper Flags on Block Linkings +microVUt(void) mVUsetupFlags(mV, int* xStatus, int* xMac, int* xClip, int cycles) { + + if (__Status) { + int bStatus[4]; + int sortRegs = sortFlag(xStatus, bStatus, cycles); + // DevCon::Status("sortRegs = %d", params sortRegs); + // Note: Emitter will optimize out mov(reg1, reg1) cases... + // There 'is' still room for small optimizations but the + // sorting algorithm would be really complex and not really + // a noticeable improvement... (Most common cases are 1 & 2) + if (sortRegs == 1) { + MOV32RtoR(gprF0, getFlagReg1(bStatus[0])); + MOV32RtoR(gprF1, getFlagReg1(bStatus[1])); + MOV32RtoR(gprF2, getFlagReg1(bStatus[2])); + MOV32RtoR(gprF3, getFlagReg1(bStatus[3])); + } + else if (sortRegs == 2) { + MOV32RtoR(gprT1, getFlagReg1(bStatus[3])); + MOV32RtoR(gprF0, getFlagReg1(bStatus[0])); + MOV32RtoR(gprF1, getFlagReg2(bStatus[1])); + MOV32RtoR(gprF2, getFlagReg2(bStatus[2])); + MOV32RtoR(gprF3, gprT1); + } + else if (sortRegs == 3) { + int gFlag = (bStatus[0] == bStatus[1]) ? bStatus[2] : bStatus[1]; + MOV32RtoR(gprT1, getFlagReg1(gFlag)); + MOV32RtoR(gprT2, getFlagReg1(bStatus[3])); + MOV32RtoR(gprF0, getFlagReg1(bStatus[0])); + MOV32RtoR(gprF1, getFlagReg3(bStatus[1])); + MOV32RtoR(gprF2, getFlagReg4(bStatus[2])); + MOV32RtoR(gprF3, gprT2); + } + else { + MOV32RtoR(gprT1, getFlagReg1(bStatus[0])); + MOV32RtoR(gprT2, getFlagReg1(bStatus[1])); + MOV32RtoR(gprR, getFlagReg1(bStatus[2])); + MOV32RtoR(gprF3, getFlagReg1(bStatus[3])); + MOV32RtoR(gprF0, gprT1); + MOV32RtoR(gprF1, gprT2); + MOV32RtoR(gprF2, gprR); + MOV32ItoR(gprR, Roffset); // Restore gprR + } + } + + if (__Mac) { + int bMac[4]; + sortFlag(xMac, bMac, cycles); + SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)mVU->macFlag); + SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, shuffleMac); + SSE_MOVAPS_XMM_to_M128((uptr)mVU->macFlag, xmmT1); + } + + if (__Clip) { + int bClip[4]; + sortFlag(xClip, bClip, cycles); + SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)mVU->clipFlag); + SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, shuffleClip); + SSE_MOVAPS_XMM_to_M128((uptr)mVU->clipFlag, xmmT1); + } +} + +#define shortBranch() { \ + if (branch == 3) { \ + mVUflagPass(mVU, aBranchAddr, (xCount - (mVUcount+1))); \ + mVUcount = 4; \ + } \ +} + +// Scan through instructions and check if flags are read (FSxxx, FMxxx, FCxxx opcodes) +void mVUflagPass(mV, u32 startPC, u32 xCount) { + + int oldPC = iPC; + int oldCount = mVUcount; + int oldBranch = mVUbranch; + int aBranchAddr; + iPC = startPC / 4; + mVUcount = 0; + mVUbranch = 0; + for (int branch = 0; mVUcount < xCount; mVUcount++) { + incPC(1); + if ( curI & _Ebit_ ) { branch = 1; } + if ( curI & _DTbit_ ) { branch = 4; } + if (!(curI & _Ibit_) ) { incPC(-1); mVUopL(mVU, 3); incPC(1); } + if (branch >= 2) { shortBranch(); break; } + else if (branch == 1) { branch = 2; } + if (mVUbranch) { branch = (mVUbranch >= 9) ? 5 : 3; aBranchAddr = branchAddr; mVUbranch = 0; } + incPC(1); + } + if (mVUcount < 4) { mVUflagInfo |= 0xfff; } + iPC = oldPC; + mVUcount = oldCount; + mVUbranch = oldBranch; + setCode(); +} + +#define branchType1 if (mVUbranch <= 2) // B/BAL +#define branchType2 else if (mVUbranch >= 9) // JR/JALR +#define branchType3 else // Conditional Branch + +// Checks if the first 4 instructions of a block will read flags +microVUt(void) mVUsetFlagInfo(mV) { + branchType1 { incPC(-1); mVUflagPass(mVU, branchAddr, 4); incPC(1); } + branchType2 { mVUflagInfo |= 0xfff; } + branchType3 { + incPC(-1); + mVUflagPass(mVU, branchAddr, 4); + int backupFlagInfo = mVUflagInfo; + mVUflagInfo = 0; + incPC(4); // Branch Not Taken + mVUflagPass(mVU, xPC, 4); + incPC(-3); + mVUflagInfo |= backupFlagInfo; + } +} + diff --git a/pcsx2/x86/microVU_IR.h b/pcsx2/x86/microVU_IR.h new file mode 100644 index 0000000000..08a794100f --- /dev/null +++ b/pcsx2/x86/microVU_IR.h @@ -0,0 +1,150 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +union regInfo { + u32 reg; + struct { + u8 x; + u8 y; + u8 z; + u8 w; + }; +}; + +#if defined(_MSC_VER) +#pragma pack(1) +#pragma warning(disable:4996) +#endif + +__declspec(align(16)) struct microRegInfo { // Ordered for Faster Compares + u32 needExactMatch; // If set, block needs an exact match of pipeline state + u8 q; + u8 p; + u8 r; + u8 xgkick; + u8 VI[16]; + regInfo VF[32]; + u8 flags; // clip x2 :: status x2 + u8 padding[7]; // 160 bytes +#if defined(_MSC_VER) +}; +#else +} __attribute__((packed)); +#endif + +__declspec(align(16)) struct microBlock { + microRegInfo pState; // Detailed State of Pipeline + microRegInfo pStateEnd; // Detailed State of Pipeline at End of Block (needed by JR/JALR opcodes) + u8* x86ptrStart; // Start of code +#if defined(_MSC_VER) +}; +#pragma pack() +#else +} __attribute__((packed)); +#endif + +struct microTempRegInfo { + regInfo VF[2]; // Holds cycle info for Fd, VF[0] = Upper Instruction, VF[1] = Lower Instruction + u8 VFreg[2]; // Index of the VF reg + u8 VI; // Holds cycle info for Id + u8 VIreg; // Index of the VI reg + u8 q; // Holds cycle info for Q reg + u8 p; // Holds cycle info for P reg + u8 r; // Holds cycle info for R reg (Will never cause stalls, but useful to know if R is modified) + u8 xgkick; // Holds the cycle info for XGkick +}; + +struct microVFreg { + u8 reg; // Reg Index + u8 x; // X vector read/written to? + u8 y; // Y vector read/written to? + u8 z; // Z vector read/written to? + u8 w; // W vector read/written to? +}; + +struct microVIreg { + u8 reg; // Reg Index + u8 used; // Reg is Used? (Read/Written) +}; + +struct microUpperOp { + bool eBit; // Has E-bit set + bool iBit; // Has I-bit set + bool mBit; // Has M-bit set + microVFreg VF_write; // VF Vectors written to by this instruction + microVFreg VF_read[2]; // VF Vectors read by this instruction +}; + +struct microLowerOp { + microVFreg VF_write; // VF Vectors written to by this instruction + microVFreg VF_read[2]; // VF Vectors read by this instruction + microVIreg VI_write; // VI reg written to by this instruction + microVIreg VI_read[2]; // VI regs read by this instruction + u32 branch; // Branch Type (0 = Not a Branch, 1 = B. 2 = BAL, 3~8 = Conditional Branches, 9 = JALR, 10 = JR) + bool isNOP; // This instruction is a NOP + bool isFSSET; // This instruction is a FSSET + bool useSflag; // This instruction uses/reads Sflag + bool noWriteVF; // Don't write back the result of a lower op to VF reg if upper op writes to same reg (or if VF = 0) + bool backupVI; // Backup VI reg to memory if modified before branch (branch uses old VI value unless opcode is ILW or ILWR) + bool memReadIs; // Read Is (VI reg) from memory (used by branches) + bool memReadIt; // Read If (VI reg) from memory (used by branches) + bool readFlags; // Current Instruction reads Status, Mac, or Clip flags +}; + +struct microFlagInst { + bool doFlag; // Update Flag on this Instruction + bool doNonSticky; // Update O,U,S,Z (non-sticky) bits on this Instruction (status flag only) + u8 write; // Points to the instance that should be written to (s-stage write) + u8 lastWrite; // Points to the instance that was last written to (most up-to-date flag) + u8 read; // Points to the instance that should be read by a lower instruction (t-stage read) +}; + +struct microOp { + u8 stall; // Info on how much current instruction stalled + bool isEOB; // Cur Instruction is last instruction in block (End of Block) + bool isBdelay; // Cur Instruction in Branch Delay slot + bool swapOps; // Run Lower Instruction before Upper Instruction + bool backupVF; // Backup mVUlow.VF_write.reg, and restore it before the Upper Instruction is called + bool doXGKICK; // Do XGKICK transfer on this instruction + bool doDivFlag; // Transfer Div flag to Status Flag on this instruction + int readQ; // Q instance for reading + int writeQ; // Q instance for writing + int readP; // P instance for reading + int writeP; // P instance for writing + microFlagInst sFlag; // Status Flag Instance Info + microFlagInst mFlag; // Mac Flag Instance Info + microFlagInst cFlag; // Clip Flag Instance Info + microUpperOp uOp; // Upper Op Info + microLowerOp lOp; // Lower Op Info +}; + +template +struct microIR { + microBlock block; // Block/Pipeline info + microBlock* pBlock; // Pointer to a block in mVUblocks + microTempRegInfo regsTemp; // Temp Pipeline info (used so that new pipeline info isn't conflicting between upper and lower instructions in the same cycle) + microOp info[pSize/2]; // Info for Instructions in current block + u8 branch; + u32 cycles; // Cycles for current block + u32 count; // Number of VU 64bit instructions ran (starts at 0 for each block) + u32 curPC; // Current PC + u32 startPC; // Start PC for Cur Block + u32 sFlagHack; // Optimize out all Status flag updates if microProgram doesn't use Status flags +}; diff --git a/pcsx2/x86/microVU_Log.inl b/pcsx2/x86/microVU_Log.inl index 9c05a82317..4b84ab61cc 100644 --- a/pcsx2/x86/microVU_Log.inl +++ b/pcsx2/x86/microVU_Log.inl @@ -1,23 +1,22 @@ /* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2009 Pcsx2-Playground Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ + * Copyright (C) 2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #pragma once -#ifdef PCSX2_MICROVU // writes text directly to the microVU.txt, no newlines appended. microVUx(void) __mVULog(const char* fmt, ...) { @@ -39,12 +38,15 @@ microVUx(void) __mVULog(const char* fmt, ...) { #define commaIf() { if (bitX[6]) { mVUlog(","); bitX[6] = 0; } } -microVUt(void) __mVUdumpProgram(int progIndex) { +microVUx(void) __mVUdumpProgram(int progIndex) { microVU* mVU = mVUx; - bool bitX[9]; + bool bitX[7]; char str[30]; int delay = 0; - mVUbranch = 0; + int bBranch = mVUbranch; + int bCode = mVU->code; + int bPC = iPC; + mVUbranch = 0; sprintf(str, "%s\\microVU%d prog - %02d.html", LOGS_DIR, vuIndex, progIndex); mVU->logFile = fopen(str, "w"); @@ -73,10 +75,8 @@ microVUt(void) __mVUdumpProgram(int progIndex) { bitX[4] = 0; bitX[5] = 0; bitX[6] = 0; - bitX[7] = 0; - bitX[8] = 0; - if (mVU->code & _Ibit_) { bitX[0] = 1; bitX[5] = 1; bitX[7] = 1; } + if (mVU->code & _Ibit_) { bitX[0] = 1; bitX[5] = 1; } if (mVU->code & _Ebit_) { bitX[1] = 1; bitX[5] = 1; delay = 2; } if (mVU->code & _Mbit_) { bitX[2] = 1; bitX[5] = 1; } if (mVU->code & _Dbit_) { bitX[3] = 1; bitX[5] = 1; } @@ -88,7 +88,7 @@ microVUt(void) __mVUdumpProgram(int progIndex) { iPC = (i+1); mVUlog("", i*4); mVUlog("[%04x] (%08x) ", i*4, mVU->code); - mVUopU(); + mVUopU(mVU, 2); if (bitX[5]) { mVUlog(" ("); @@ -101,17 +101,25 @@ microVUt(void) __mVUdumpProgram(int progIndex) { } iPC = i; - if (bitX[7]) { mVUlog(""); } mVU->code = mVU->prog.prog[progIndex].data[i]; - mVUlog("
\n[%04x] (%08x) ", i*4, mVU->code); - mVUopL(); - mVUlog("\n\n

"); - if (bitX[7]) { mVUlog("
"); } + + if(bitX[0]) { + mVUlog("
\n"); + mVUlog("[%04x] (%08x) %f", i*4, mVU->code, *(float*)&mVU->code); + mVUlog("\n\n

"); + } + else { + mVUlog("
\n[%04x] (%08x) ", i*4, mVU->code); + mVUopL(mVU, 2); + mVUlog("\n\n

"); + } } mVUlog("\n"); mVUlog("\n"); mVUlog("\n"); fclose(mVU->logFile); + mVUbranch = bBranch; + mVU->code = bCode; + iPC = bPC; + setCode(); } - -#endif //PCSX2_MICROVU diff --git a/pcsx2/x86/microVU_Lower.inl b/pcsx2/x86/microVU_Lower.inl index dfe5fefb96..8c82889596 100644 --- a/pcsx2/x86/microVU_Lower.inl +++ b/pcsx2/x86/microVU_Lower.inl @@ -1,23 +1,22 @@ /* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2009 Pcsx2-Playground Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ + * Copyright (C) 2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #pragma once -#ifdef PCSX2_MICROVU //------------------------------------------------------------------ // Micro VU Micromode Lower instructions @@ -38,14 +37,13 @@ SSE_MOVMSKPS_XMM_to_R32(gprTemp, xmmReg); \ TEST32ItoR(gprTemp, 1); /* Check sign bit */ \ aJump = JZ8(0); /* Skip if positive */ \ - MOV32ItoM((uptr)&mVU->divFlag, 0x410); /* Set Invalid Flags */ \ + MOV32ItoM((uptr)&mVU->divFlag, divI); /* Set Invalid Flags */ \ SSE_ANDPS_M128_to_XMM(xmmReg, (uptr)mVU_absclip); /* Abs(xmmReg) */ \ x86SetJ8(aJump); \ } -microVUf(void) mVU_DIV() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeFDIV(_Fs_, _Fsf_, _Ft_, _Ftf_, 7); } +mVUop(mVU_DIV) { + pass1 { mVUanalyzeFDIV(mVU, _Fs_, _Fsf_, _Ft_, _Ftf_, 7); } pass2 { u8 *ajmp, *bjmp, *cjmp, *djmp; getReg5(xmmFs, _Fs_, _Fsf_); @@ -56,10 +54,10 @@ microVUf(void) mVU_DIV() { testZero(xmmFs, xmmT1, gprT1); // Test if Fs is zero ajmp = JZ8(0); - MOV32ItoM((uptr)&mVU->divFlag, 0x410); // Set invalid flag (0/0) + MOV32ItoM((uptr)&mVU->divFlag, divI); // Set invalid flag (0/0) bjmp = JMP8(0); x86SetJ8(ajmp); - MOV32ItoM((uptr)&mVU->divFlag, 0x820); // Zero divide (only when not 0/0) + MOV32ItoM((uptr)&mVU->divFlag, divD); // Zero divide (only when not 0/0) x86SetJ8(bjmp); SSE_XORPS_XMM_to_XMM(xmmFs, xmmFt); @@ -70,18 +68,18 @@ microVUf(void) mVU_DIV() { x86SetJ8(cjmp); MOV32ItoM((uptr)&mVU->divFlag, 0); // Clear I/D flags SSE_DIVSS_XMM_to_XMM(xmmFs, xmmFt); - mVUclamp1(xmmFs, xmmFt, 8); + if (CHECK_VU_OVERFLOW) mVUclamp1(xmmFs, xmmFt, 8); x86SetJ8(djmp); - mVUunpack_xyzw(xmmFs, xmmFs, 0); - mVUmergeRegs(xmmPQ, xmmFs, writeQ ? 4 : 8); + if (mVUinfo.writeQ) SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, 0xe1); + SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); + if (mVUinfo.writeQ) SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, 0xe1); } pass3 { mVUlog("DIV Q, vf%02d%s, vf%02d%s", _Fs_, _Fsf_String, _Ft_, _Ftf_String); } } -microVUf(void) mVU_SQRT() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeFDIV(0, 0, _Ft_, _Ftf_, 7); } +mVUop(mVU_SQRT) { + pass1 { mVUanalyzeFDIV(mVU, 0, 0, _Ft_, _Ftf_, 7); } pass2 { u8 *ajmp; getReg5(xmmFt, _Ft_, _Ftf_); @@ -91,15 +89,15 @@ microVUf(void) mVU_SQRT() { if (CHECK_VU_OVERFLOW) SSE_MINSS_XMM_to_XMM(xmmFt, xmmMax); // Clamp infinities (only need to do positive clamp since xmmFt is positive) SSE_SQRTSS_XMM_to_XMM(xmmFt, xmmFt); - mVUunpack_xyzw(xmmFt, xmmFt, 0); - mVUmergeRegs(xmmPQ, xmmFt, writeQ ? 4 : 8); + if (mVUinfo.writeQ) SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, 0xe1); + SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFt); + if (mVUinfo.writeQ) SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, 0xe1); } pass3 { mVUlog("SQRT Q, vf%02d%s", _Ft_, _Ftf_String); } } -microVUf(void) mVU_RSQRT() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeFDIV(_Fs_, _Fsf_, _Ft_, _Ftf_, 13); } +mVUop(mVU_RSQRT) { + pass1 { mVUanalyzeFDIV(mVU, _Fs_, _Fsf_, _Ft_, _Ftf_, 13); } pass2 { u8 *ajmp, *bjmp, *cjmp, *djmp; getReg5(xmmFs, _Fs_, _Fsf_); @@ -114,10 +112,10 @@ microVUf(void) mVU_RSQRT() { testZero(xmmFs, xmmT1, gprT1); // Test if Fs is zero bjmp = JZ8(0); // Skip if none are - MOV32ItoM((uptr)&mVU->divFlag, 0x410); // Set invalid flag (0/0) + MOV32ItoM((uptr)&mVU->divFlag, divI); // Set invalid flag (0/0) cjmp = JMP8(0); x86SetJ8(bjmp); - MOV32ItoM((uptr)&mVU->divFlag, 0x820); // Zero divide flag (only when not 0/0) + MOV32ItoM((uptr)&mVU->divFlag, divD); // Zero divide flag (only when not 0/0) x86SetJ8(cjmp); SSE_ANDPS_M128_to_XMM(xmmFs, (uptr)mVU_signbit); @@ -126,11 +124,12 @@ microVUf(void) mVU_RSQRT() { djmp = JMP8(0); x86SetJ8(ajmp); SSE_DIVSS_XMM_to_XMM(xmmFs, xmmFt); - mVUclamp1(xmmFs, xmmFt, 8); + if (CHECK_VU_OVERFLOW) mVUclamp1(xmmFs, xmmFt, 8); x86SetJ8(djmp); - mVUunpack_xyzw(xmmFs, xmmFs, 0); - mVUmergeRegs(xmmPQ, xmmFs, writeQ ? 4 : 8); + if (mVUinfo.writeQ) SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, 0xe1); + SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); + if (mVUinfo.writeQ) SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, 0xe1); } pass3 { mVUlog("RSQRT Q, vf%02d%s, vf%02d%s", _Fs_, _Fsf_String, _Ft_, _Ftf_String); } } @@ -147,8 +146,7 @@ microVUf(void) mVU_RSQRT() { SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFt); \ } -microVUt(void) mVU_EATAN_() { - microVU* mVU = mVUx; +microVUt(void) mVU_EATAN_(mV) { // ToDo: Can Be Optimized Further? (takes approximately (~115 cycles + mem access time) on a c2d) SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); @@ -164,58 +162,55 @@ microVUt(void) mVU_EATAN_() { EATANhelper(mVU_T8); SSE_ADDSS_M32_to_XMM(xmmPQ, (uptr)mVU_Pi4); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); } -microVUf(void) mVU_EATAN() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU1(_Fs_, _Fsf_, 54); } +mVUop(mVU_EATAN) { + pass1 { mVUanalyzeEFU1(mVU, _Fs_, _Fsf_, 54); } pass2 { getReg5(xmmFs, _Fs_, _Fsf_); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); SSE_SUBSS_M32_to_XMM(xmmFs, (uptr)mVU_one); SSE_ADDSS_M32_to_XMM(xmmPQ, (uptr)mVU_one); SSE_DIVSS_XMM_to_XMM(xmmFs, xmmPQ); - mVU_EATAN_(); + mVU_EATAN_(mVU); } pass3 { mVUlog("EATAN P"); } } -microVUf(void) mVU_EATANxy() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU2(_Fs_, 54); } +mVUop(mVU_EATANxy) { + pass1 { mVUanalyzeEFU2(mVU, _Fs_, 54); } pass2 { getReg6(xmmFt, _Fs_); SSE2_PSHUFD_XMM_to_XMM(xmmFs, xmmFt, 0x01); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); SSE_SUBSS_XMM_to_XMM(xmmFs, xmmFt); // y-x, not y-1? >< SSE_ADDSS_XMM_to_XMM(xmmFt, xmmPQ); SSE_DIVSS_XMM_to_XMM(xmmFs, xmmFt); - mVU_EATAN_(); + mVU_EATAN_(mVU); } pass3 { mVUlog("EATANxy P"); } } -microVUf(void) mVU_EATANxz() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU2(_Fs_, 54); } +mVUop(mVU_EATANxz) { + pass1 { mVUanalyzeEFU2(mVU, _Fs_, 54); } pass2 { getReg6(xmmFt, _Fs_); SSE2_PSHUFD_XMM_to_XMM(xmmFs, xmmFt, 0x02); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); SSE_SUBSS_XMM_to_XMM(xmmFs, xmmFt); SSE_ADDSS_XMM_to_XMM(xmmFt, xmmPQ); SSE_DIVSS_XMM_to_XMM(xmmFs, xmmFt); - mVU_EATAN_(); + mVU_EATAN_(mVU); } pass3 { mVUlog("EATANxz P"); } } @@ -227,12 +222,11 @@ microVUf(void) mVU_EATANxz() { SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFt); \ } -microVUf(void) mVU_EEXP() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU1(_Fs_, _Fsf_, 44); } +mVUop(mVU_EEXP) { + pass1 { mVUanalyzeEFU1(mVU, _Fs_, _Fsf_, 44); } pass2 { getReg5(xmmFs, _Fs_, _Fsf_); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); SSE_MULSS_M32_to_XMM(xmmPQ, (uptr)mVU_E1); SSE_ADDSS_M32_to_XMM(xmmPQ, (uptr)mVU_one); @@ -255,20 +249,20 @@ microVUf(void) mVU_EEXP() { SSE_MOVSS_M32_to_XMM(xmmT1, (uptr)mVU_one); SSE_DIVSS_XMM_to_XMM(xmmT1, xmmPQ); SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmT1); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip back } pass3 { mVUlog("EEXP P"); } } microVUt(void) mVU_sumXYZ() { - // regd.x = x ^ 2 + y ^ 2 + z ^ 2 + // xmmPQ.x = x ^ 2 + y ^ 2 + z ^ 2 if( cpucaps.hasStreamingSIMD4Extensions ) { SSE4_DPPS_XMM_to_XMM(xmmFs, xmmFs, 0x71); SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); } else { SSE_MULPS_XMM_to_XMM(xmmFs, xmmFs); // wzyx ^ 2 - SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); + SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); // x ^ 2 SSE2_PSHUFD_XMM_to_XMM(xmmFs, xmmFs, 0xe1); // wzyx -> wzxy SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFs); // x ^ 2 + y ^ 2 SSE2_PSHUFD_XMM_to_XMM(xmmFs, xmmFs, 0xD2); // wzxy -> wxyz @@ -276,89 +270,83 @@ microVUt(void) mVU_sumXYZ() { } } -microVUf(void) mVU_ELENG() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU2(_Fs_, 18); } +mVUop(mVU_ELENG) { + pass1 { mVUanalyzeEFU2(mVU, _Fs_, 18); } pass2 { getReg6(xmmFs, _Fs_); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance - mVU_sumXYZ(); + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + mVU_sumXYZ(); SSE_SQRTSS_XMM_to_XMM(xmmPQ, xmmPQ); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip back } pass3 { mVUlog("ELENG P"); } } -microVUf(void) mVU_ERCPR() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU1(_Fs_, _Fsf_, 12); } +mVUop(mVU_ERCPR) { + pass1 { mVUanalyzeEFU1(mVU, _Fs_, _Fsf_, 12); } pass2 { getReg5(xmmFs, _Fs_, _Fsf_); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); SSE_MOVSS_M32_to_XMM(xmmFs, (uptr)mVU_one); SSE_DIVSS_XMM_to_XMM(xmmFs, xmmPQ); SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip back } pass3 { mVUlog("ERCPR P"); } } -microVUf(void) mVU_ERLENG() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU2(_Fs_, 24); } +mVUop(mVU_ERLENG) { + pass1 { mVUanalyzeEFU2(mVU, _Fs_, 24); } pass2 { getReg6(xmmFs, _Fs_); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance - mVU_sumXYZ(); + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + mVU_sumXYZ(); SSE_SQRTSS_XMM_to_XMM(xmmPQ, xmmPQ); SSE_MOVSS_M32_to_XMM(xmmFs, (uptr)mVU_one); SSE_DIVSS_XMM_to_XMM(xmmFs, xmmPQ); SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip back } pass3 { mVUlog("ERLENG P"); } } -microVUf(void) mVU_ERSADD() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU2(_Fs_, 18); } +mVUop(mVU_ERSADD) { + pass1 { mVUanalyzeEFU2(mVU, _Fs_, 18); } pass2 { getReg6(xmmFs, _Fs_); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance - mVU_sumXYZ(); + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + mVU_sumXYZ(); //SSE_RCPSS_XMM_to_XMM(xmmPQ, xmmPQ); // Lower Precision is bad? SSE_MOVSS_M32_to_XMM(xmmFs, (uptr)mVU_one); SSE_DIVSS_XMM_to_XMM(xmmFs, xmmPQ); SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip back } pass3 { mVUlog("ERSADD P"); } } -microVUf(void) mVU_ERSQRT() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU1(_Fs_, _Fsf_, 18); } +mVUop(mVU_ERSQRT) { + pass1 { mVUanalyzeEFU1(mVU, _Fs_, _Fsf_, 18); } pass2 { getReg5(xmmFs, _Fs_, _Fsf_); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance SSE_SQRTSS_XMM_to_XMM(xmmPQ, xmmFs); SSE_MOVSS_M32_to_XMM(xmmFs, (uptr)mVU_one); SSE_DIVSS_XMM_to_XMM(xmmFs, xmmPQ); SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip back } pass3 { mVUlog("ERSQRT P"); } } -microVUf(void) mVU_ESADD() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU2(_Fs_, 11); } +mVUop(mVU_ESADD) { + pass1 { mVUanalyzeEFU2(mVU, _Fs_, 11); } pass2 { getReg6(xmmFs, _Fs_); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance - mVU_sumXYZ(); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + mVU_sumXYZ(); + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip back } pass3 { mVUlog("ESADD P"); } } @@ -370,12 +358,11 @@ microVUf(void) mVU_ESADD() { SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFs); \ } -microVUf(void) mVU_ESIN() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU2(_Fs_, 29); } +mVUop(mVU_ESIN) { + pass1 { mVUanalyzeEFU2(mVU, _Fs_, 29); } pass2 { getReg5(xmmFs, _Fs_, _Fsf_); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); //SSE_MULSS_M32_to_XMM(xmmPQ, (uptr)mVU_one); // Multiplying by 1 is redundant? SSE_MOVAPS_XMM_to_XMM(xmmFt, xmmFs); @@ -392,35 +379,33 @@ microVUf(void) mVU_ESIN() { SSE_MULSS_XMM_to_XMM(xmmT1, xmmFt); SSE_MULSS_M32_to_XMM(xmmT1, (uptr)mVU_S5); SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmT1); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip back } pass3 { mVUlog("ESIN P"); } } -microVUf(void) mVU_ESQRT() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU1(_Fs_, _Fsf_, 12); } +mVUop(mVU_ESQRT) { + pass1 { mVUanalyzeEFU1(mVU, _Fs_, _Fsf_, 12); } pass2 { getReg5(xmmFs, _Fs_, _Fsf_); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance SSE_SQRTSS_XMM_to_XMM(xmmPQ, xmmFs); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip back } pass3 { mVUlog("ESQRT P"); } } -microVUf(void) mVU_ESUM() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeEFU2(_Fs_, 12); } +mVUop(mVU_ESUM) { + pass1 { mVUanalyzeEFU2(mVU, _Fs_, 12); } pass2 { getReg6(xmmFs, _Fs_); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance SSE2_PSHUFD_XMM_to_XMM(xmmFt, xmmFs, 0x1b); SSE_ADDPS_XMM_to_XMM(xmmFs, xmmFt); SSE2_PSHUFD_XMM_to_XMM(xmmFt, xmmFs, 0x01); SSE_ADDSS_XMM_to_XMM(xmmFs, xmmFt); SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); - SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back + SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip back } pass3 { mVUlog("ESUM P"); } } @@ -429,58 +414,61 @@ microVUf(void) mVU_ESUM() { // FCAND/FCEQ/FCGET/FCOR/FCSET //------------------------------------------------------------------ -microVUf(void) mVU_FCAND() { - microVU* mVU = mVUx; +mVUop(mVU_FCAND) { + pass1 { mVUanalyzeCflag(mVU, 1); } pass2 { - mVUallocCFLAGa(gprT1, fvcInstance); + mVUallocCFLAGa(mVU, gprT1, cFLAG.read); AND32ItoR(gprT1, _Imm24_); ADD32ItoR(gprT1, 0xffffff); SHR32ItoR(gprT1, 24); - mVUallocVIb(gprT1, 1); + mVUallocVIb(mVU, gprT1, 1); } pass3 { mVUlog("FCAND vi01, $%x", _Imm24_); } + pass4 { mVUflagInfo |= 0xf << 8; } } -microVUf(void) mVU_FCEQ() { - microVU* mVU = mVUx; +mVUop(mVU_FCEQ) { + pass1 { mVUanalyzeCflag(mVU, 1); } pass2 { - mVUallocCFLAGa(gprT1, fvcInstance); + mVUallocCFLAGa(mVU, gprT1, cFLAG.read); XOR32ItoR(gprT1, _Imm24_); SUB32ItoR(gprT1, 1); SHR32ItoR(gprT1, 31); - mVUallocVIb(gprT1, 1); + mVUallocVIb(mVU, gprT1, 1); } pass3 { mVUlog("FCEQ vi01, $%x", _Imm24_); } + pass4 { mVUflagInfo |= 0xf << 8; } } -microVUf(void) mVU_FCGET() { - microVU* mVU = mVUx; +mVUop(mVU_FCGET) { + pass1 { mVUanalyzeCflag(mVU, _It_); } pass2 { - mVUallocCFLAGa(gprT1, fvcInstance); + mVUallocCFLAGa(mVU, gprT1, cFLAG.read); AND32ItoR(gprT1, 0xfff); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } - pass3 { mVUlog("FCGET vi%02d", _Ft_); } + pass3 { mVUlog("FCGET vi%02d", _Ft_); } + pass4 { mVUflagInfo |= 0xf << 8; } } -microVUf(void) mVU_FCOR() { - microVU* mVU = mVUx; +mVUop(mVU_FCOR) { + pass1 { mVUanalyzeCflag(mVU, 1); } pass2 { - mVUallocCFLAGa(gprT1, fvcInstance); + mVUallocCFLAGa(mVU, gprT1, cFLAG.read); OR32ItoR(gprT1, _Imm24_); ADD32ItoR(gprT1, 1); // If 24 1's will make 25th bit 1, else 0 SHR32ItoR(gprT1, 24); // Get the 25th bit (also clears the rest of the garbage in the reg) - mVUallocVIb(gprT1, 1); + mVUallocVIb(mVU, gprT1, 1); } pass3 { mVUlog("FCOR vi01, $%x", _Imm24_); } + pass4 { mVUflagInfo |= 0xf << 8; } } -microVUf(void) mVU_FCSET() { - microVU* mVU = mVUx; - pass1 { mVUinfo |= doClip; } +mVUop(mVU_FCSET) { + pass1 { cFLAG.doFlag = 1; } pass2 { MOV32ItoR(gprT1, _Imm24_); - mVUallocCFLAGb(gprT1, fcInstance); + mVUallocCFLAGb(mVU, gprT1, cFLAG.write); } pass3 { mVUlog("FCSET $%x", _Imm24_); } } @@ -489,92 +477,118 @@ microVUf(void) mVU_FCSET() { // FMAND/FMEQ/FMOR //------------------------------------------------------------------ -microVUf(void) mVU_FMAND() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeMflag(_Fs_, _Ft_); } +mVUop(mVU_FMAND) { + pass1 { mVUanalyzeMflag(mVU, _Is_, _It_); } pass2 { - mVUallocMFLAGa(gprT1, fvmInstance); - mVUallocVIa(gprT2, _Fs_); + mVUallocMFLAGa(mVU, gprT1, mFLAG.read); + mVUallocVIa(mVU, gprT2, _Is_); AND16RtoR(gprT1, gprT2); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("FMAND vi%02d, vi%02d", _Ft_, _Fs_); } + pass4 { mVUflagInfo |= 0xf << 4; } } -microVUf(void) mVU_FMEQ() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeMflag(_Fs_, _Ft_); } +mVUop(mVU_FMEQ) { + pass1 { mVUanalyzeMflag(mVU, _Is_, _It_); } pass2 { - mVUallocMFLAGa(gprT1, fvmInstance); - mVUallocVIa(gprT2, _Fs_); + mVUallocMFLAGa(mVU, gprT1, mFLAG.read); + mVUallocVIa(mVU, gprT2, _Is_); XOR32RtoR(gprT1, gprT2); SUB32ItoR(gprT1, 1); SHR32ItoR(gprT1, 31); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("FMEQ vi%02d, vi%02d", _Ft_, _Fs_); } + pass4 { mVUflagInfo |= 0xf << 4; } } -microVUf(void) mVU_FMOR() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeMflag(_Fs_, _Ft_); } +mVUop(mVU_FMOR) { + pass1 { mVUanalyzeMflag(mVU, _Is_, _It_); } pass2 { - mVUallocMFLAGa(gprT1, fvmInstance); - mVUallocVIa(gprT2, _Fs_); + mVUallocMFLAGa(mVU, gprT1, mFLAG.read); + mVUallocVIa(mVU, gprT2, _Is_); OR16RtoR(gprT1, gprT2); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("FMOR vi%02d, vi%02d", _Ft_, _Fs_); } + pass4 { mVUflagInfo |= 0xf << 4; } } //------------------------------------------------------------------ // FSAND/FSEQ/FSOR/FSSET //------------------------------------------------------------------ -microVUf(void) mVU_FSAND() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeSflag(_Ft_); } +mVUop(mVU_FSAND) { + pass1 { mVUanalyzeSflag(mVU, _It_); } pass2 { - mVUallocSFLAGa(gprT1, fvsInstance); - AND16ItoR(gprT1, _Imm12_); - mVUallocVIb(gprT1, _Ft_); + mVUallocSFLAGc(gprT1, gprT2, sFLAG.read); + AND32ItoR(gprT1, _Imm12_); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("FSAND vi%02d, $%x", _Ft_, _Imm12_); } + pass4 { mVUflagInfo |= 0xf; } } -microVUf(void) mVU_FSEQ() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeSflag(_Ft_); } +mVUop(mVU_FSOR) { + pass1 { mVUanalyzeSflag(mVU, _It_); } pass2 { - mVUallocSFLAGa(gprT1, fvsInstance); - XOR16ItoR(gprT1, _Imm12_); - SUB16ItoR(gprT1, 1); - SHR16ItoR(gprT1, 15); - mVUallocVIb(gprT1, _Ft_); - } - pass3 { mVUlog("FSEQ vi%02d, $%x", _Ft_, _Imm12_); } -} - -microVUf(void) mVU_FSOR() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeSflag(_Ft_); } - pass2 { - mVUallocSFLAGa(gprT1, fvsInstance); - OR16ItoR(gprT1, _Imm12_); - mVUallocVIb(gprT1, _Ft_); + mVUallocSFLAGc(gprT1, gprT2, sFLAG.read); + OR32ItoR(gprT1, _Imm12_); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("FSOR vi%02d, $%x", _Ft_, _Imm12_); } + pass4 { mVUflagInfo |= 0xf; } } -microVUf(void) mVU_FSSET() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeFSSET(); } +mVUop(mVU_FSEQ) { + pass1 { mVUanalyzeSflag(mVU, _It_); } pass2 { - int flagReg1, flagReg2; - getFlagReg(flagReg1, fsInstance); - if (!(doStatus||doDivFlag)) { getFlagReg(flagReg2, fpsInstance); MOV16RtoR(flagReg1, flagReg2); } // Get status result from last status setting instruction - AND16ItoR(flagReg1, 0x03f); // Remember not to modify upper 16 bits because of mac flag - OR16ItoR (flagReg1, (_Imm12_ & 0xfc0)); + u8 *pjmp; + int imm = 0; + if (_Imm12_ & 0x0001) imm |= 0x0000f00; // Z + if (_Imm12_ & 0x0002) imm |= 0x000f000; // S + if (_Imm12_ & 0x0004) imm |= 0x0010000; // U + if (_Imm12_ & 0x0008) imm |= 0x0020000; // O + if (_Imm12_ & 0x0010) imm |= 0x0040000; // I + if (_Imm12_ & 0x0020) imm |= 0x0080000; // D + if (_Imm12_ & 0x0040) imm |= 0x000000f; // ZS + if (_Imm12_ & 0x0080) imm |= 0x00000f0; // SS + if (_Imm12_ & 0x0100) imm |= 0x0400000; // US + if (_Imm12_ & 0x0200) imm |= 0x0800000; // OS + if (_Imm12_ & 0x0400) imm |= 0x1000000; // IS + if (_Imm12_ & 0x0800) imm |= 0x2000000; // DS + + mVUallocSFLAGa(gprT1, sFLAG.read); + setBitFSEQ(0x0f00); // Z bit + setBitFSEQ(0xf000); // S bit + setBitFSEQ(0x000f); // ZS bit + setBitFSEQ(0x00f0); // SS bit + XOR32ItoR(gprT1, imm); + SUB32ItoR(gprT1, 1); + SHR32ItoR(gprT1, 31); + mVUallocVIb(mVU, gprT1, _It_); + } + pass3 { mVUlog("FSEQ vi%02d, $%x", _Ft_, _Imm12_); } + pass4 { mVUflagInfo |= 0xf; } +} + +mVUop(mVU_FSSET) { + pass1 { mVUanalyzeFSSET(mVU); } + pass2 { + int sReg, imm = 0; + if (_Imm12_ & 0x0040) imm |= 0x000000f; // ZS + if (_Imm12_ & 0x0080) imm |= 0x00000f0; // SS + if (_Imm12_ & 0x0100) imm |= 0x0400000; // US + if (_Imm12_ & 0x0200) imm |= 0x0800000; // OS + if (_Imm12_ & 0x0400) imm |= 0x1000000; // IS + if (_Imm12_ & 0x0800) imm |= 0x2000000; // DS + getFlagReg(sReg, sFLAG.write); + if (!(sFLAG.doFlag || mVUinfo.doDivFlag)) { + mVUallocSFLAGa(sReg, sFLAG.lastWrite); // Get Prev Status Flag + } + AND32ItoR(sReg, 0xfff00); // Keep Non-Sticky Bits + if (imm) OR32ItoR(sReg, imm); } pass3 { mVUlog("FSSET $%x", _Imm12_); } } @@ -583,97 +597,90 @@ microVUf(void) mVU_FSSET() { // IADD/IADDI/IADDIU/IAND/IOR/ISUB/ISUBIU //------------------------------------------------------------------ -microVUf(void) mVU_IADD() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeIALU1(_Fd_, _Fs_, _Ft_); } +mVUop(mVU_IADD) { + pass1 { mVUanalyzeIALU1(mVU, _Id_, _Is_, _It_); } pass2 { - mVUallocVIa(gprT1, _Fs_); - if (_Ft_ != _Fs_) { - mVUallocVIa(gprT2, _Ft_); + mVUallocVIa(mVU, gprT1, _Is_); + if (_It_ != _Is_) { + mVUallocVIa(mVU, gprT2, _It_); ADD16RtoR(gprT1, gprT2); } else ADD16RtoR(gprT1, gprT1); - mVUallocVIb(gprT1, _Fd_); + mVUallocVIb(mVU, gprT1, _Id_); } pass3 { mVUlog("IADD vi%02d, vi%02d, vi%02d", _Fd_, _Fs_, _Ft_); } } -microVUf(void) mVU_IADDI() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeIALU2(_Fs_, _Ft_); } +mVUop(mVU_IADDI) { + pass1 { mVUanalyzeIALU2(mVU, _Is_, _It_); } pass2 { - mVUallocVIa(gprT1, _Fs_); + mVUallocVIa(mVU, gprT1, _Is_); ADD16ItoR(gprT1, _Imm5_); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("IADDI vi%02d, vi%02d, %d", _Ft_, _Fs_, _Imm5_); } } -microVUf(void) mVU_IADDIU() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeIALU2(_Fs_, _Ft_); } +mVUop(mVU_IADDIU) { + pass1 { mVUanalyzeIALU2(mVU, _Is_, _It_); } pass2 { - mVUallocVIa(gprT1, _Fs_); + mVUallocVIa(mVU, gprT1, _Is_); ADD16ItoR(gprT1, _Imm15_); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("IADDIU vi%02d, vi%02d, %d", _Ft_, _Fs_, _Imm15_); } } -microVUf(void) mVU_IAND() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeIALU1(_Fd_, _Fs_, _Ft_); } +mVUop(mVU_IAND) { + pass1 { mVUanalyzeIALU1(mVU, _Id_, _Is_, _It_); } pass2 { - mVUallocVIa(gprT1, _Fs_); - if (_Ft_ != _Fs_) { - mVUallocVIa(gprT2, _Ft_); + mVUallocVIa(mVU, gprT1, _Is_); + if (_It_ != _Is_) { + mVUallocVIa(mVU, gprT2, _It_); AND32RtoR(gprT1, gprT2); } - mVUallocVIb(gprT1, _Fd_); + mVUallocVIb(mVU, gprT1, _Id_); } pass3 { mVUlog("IAND vi%02d, vi%02d, vi%02d", _Fd_, _Fs_, _Ft_); } } -microVUf(void) mVU_IOR() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeIALU1(_Fd_, _Fs_, _Ft_); } +mVUop(mVU_IOR) { + pass1 { mVUanalyzeIALU1(mVU, _Id_, _Is_, _It_); } pass2 { - mVUallocVIa(gprT1, _Fs_); - if (_Ft_ != _Fs_) { - mVUallocVIa(gprT2, _Ft_); + mVUallocVIa(mVU, gprT1, _Is_); + if (_It_ != _Is_) { + mVUallocVIa(mVU, gprT2, _It_); OR32RtoR(gprT1, gprT2); } - mVUallocVIb(gprT1, _Fd_); + mVUallocVIb(mVU, gprT1, _Id_); } pass3 { mVUlog("IOR vi%02d, vi%02d, vi%02d", _Fd_, _Fs_, _Ft_); } } -microVUf(void) mVU_ISUB() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeIALU1(_Fd_, _Fs_, _Ft_); } +mVUop(mVU_ISUB) { + pass1 { mVUanalyzeIALU1(mVU, _Id_, _Is_, _It_); } pass2 { - if (_Ft_ != _Fs_) { - mVUallocVIa(gprT1, _Fs_); - mVUallocVIa(gprT2, _Ft_); + if (_It_ != _Is_) { + mVUallocVIa(mVU, gprT1, _Is_); + mVUallocVIa(mVU, gprT2, _It_); SUB16RtoR(gprT1, gprT2); - mVUallocVIb(gprT1, _Fd_); + mVUallocVIb(mVU, gprT1, _Id_); } - else if (!isMMX(_Fd_)) { + else if (!isMMX(_Id_)) { XOR32RtoR(gprT1, gprT1); - mVUallocVIb(gprT1, _Fd_); + mVUallocVIb(mVU, gprT1, _Id_); } - else { PXORRtoR(mmVI(_Fd_), mmVI(_Fd_)); } + else { PXORRtoR(mmVI(_Id_), mmVI(_Id_)); } } pass3 { mVUlog("ISUB vi%02d, vi%02d, vi%02d", _Fd_, _Fs_, _Ft_); } } -microVUf(void) mVU_ISUBIU() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeIALU2(_Fs_, _Ft_); } +mVUop(mVU_ISUBIU) { + pass1 { mVUanalyzeIALU2(mVU, _Is_, _It_); } pass2 { - mVUallocVIa(gprT1, _Fs_); + mVUallocVIa(mVU, gprT1, _Is_); SUB16ItoR(gprT1, _Imm15_); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("ISUBIU vi%02d, vi%02d, %d", _Ft_, _Fs_, _Imm15_); } } @@ -682,56 +689,51 @@ microVUf(void) mVU_ISUBIU() { // MFIR/MFP/MOVE/MR32/MTIR //------------------------------------------------------------------ -microVUf(void) mVU_MFIR() { - microVU* mVU = mVUx; - pass1 { if (!_Ft_) { mVUinfo |= _isNOP; } analyzeVIreg1(_Fs_); analyzeReg2(_Ft_); } +mVUop(mVU_MFIR) { + pass1 { if (!_Ft_) { mVUlow.isNOP = 1; } analyzeVIreg1(_Is_, mVUlow.VI_read[0]); analyzeReg2(_Ft_, mVUlow.VF_write, 1); } pass2 { - mVUallocVIa(gprT1, _Fs_); + mVUallocVIa(mVU, gprT1, _Is_); MOVSX32R16toR(gprT1, gprT1); SSE2_MOVD_R_to_XMM(xmmT1, gprT1); - if (!_XYZW_SS) { mVUunpack_xyzw(xmmT1, xmmT1, 0); } - mVUsaveReg(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); + if (!_XYZW_SS) { mVUunpack_xyzw(xmmT1, xmmT1, 0); } + mVUsaveReg(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); } pass3 { mVUlog("MFIR.%s vf%02d, vi%02d", _XYZW_String, _Ft_, _Fs_); } } -microVUf(void) mVU_MFP() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeMFP(_Ft_); } +mVUop(mVU_MFP) { + pass1 { mVUanalyzeMFP(mVU, _Ft_); } pass2 { getPreg(xmmFt); - mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); + mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); } pass3 { mVUlog("MFP.%s vf%02d, P", _XYZW_String, _Ft_); } } -microVUf(void) mVU_MOVE() { - microVU* mVU = mVUx; - pass1 { if (!_Ft_ || (_Ft_ == _Fs_)) { mVUinfo |= _isNOP; } analyzeReg1(_Fs_); analyzeReg2(_Ft_); } +mVUop(mVU_MOVE) { + pass1 { mVUanalyzeMOVE(mVU, _Fs_, _Ft_); } pass2 { - mVUloadReg(xmmT1, (uptr)&mVU->regs->VF[_Fs_].UL[0], _X_Y_Z_W); - mVUsaveReg(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); + mVUloadReg(xmmT1, (uptr)&mVU->regs->VF[_Fs_].UL[0], _X_Y_Z_W); + mVUsaveReg(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); } pass3 { mVUlog("MOVE.%s vf%02d, vf%02d", _XYZW_String, _Ft_, _Fs_); } } -microVUf(void) mVU_MR32() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeMR32(_Fs_, _Ft_); } +mVUop(mVU_MR32) { + pass1 { mVUanalyzeMR32(mVU, _Fs_, _Ft_); } pass2 { - mVUloadReg(xmmT1, (uptr)&mVU->regs->VF[_Fs_].UL[0], (_X_Y_Z_W == 8) ? 4 : 15); + mVUloadReg(xmmT1, (uptr)&mVU->regs->VF[_Fs_].UL[0], (_X_Y_Z_W == 8) ? 4 : 15); if (_X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(xmmT1, xmmT1, 0x39); } - mVUsaveReg(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 0); + mVUsaveReg(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 0); } pass3 { mVUlog("MR32.%s vf%02d, vf%02d", _XYZW_String, _Ft_, _Fs_); } } -microVUf(void) mVU_MTIR() { - microVU* mVU = mVUx; - pass1 { if (!_Ft_) { mVUinfo |= _isNOP; } analyzeReg5(_Fs_, _Fsf_); analyzeVIreg2(_Ft_, 1); } +mVUop(mVU_MTIR) { + pass1 { if (!_It_) { mVUlow.isNOP = 1; } analyzeReg5(_Fs_, _Fsf_, mVUlow.VF_read[0]); analyzeVIreg2(_It_, mVUlow.VI_write, 1); } pass2 { MOVZX32M16toR(gprT1, (uptr)&mVU->regs->VF[_Fs_].UL[_Fsf_]); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("MTIR vi%02d, vf%02d%s", _Ft_, _Fs_, _Fsf_String); } } @@ -740,38 +742,36 @@ microVUf(void) mVU_MTIR() { // ILW/ILWR //------------------------------------------------------------------ -microVUf(void) mVU_ILW() { - microVU* mVU = mVUx; - pass1 { if (!_Ft_) { mVUinfo |= _isNOP; } analyzeVIreg1(_Fs_); analyzeVIreg2(_Ft_, 4); } +mVUop(mVU_ILW) { + pass1 { if (!_It_) { mVUlow.isNOP = 1; } analyzeVIreg1(_Is_, mVUlow.VI_read[0]); analyzeVIreg2(_It_, mVUlow.VI_write, 4); } pass2 { - if (!_Fs_) { + if (!_Is_) { MOVZX32M16toR(gprT1, (uptr)mVU->regs->Mem + getVUmem(_Imm11_) + offsetSS); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } else { - mVUallocVIa(gprT1, _Fs_); + mVUallocVIa(mVU, gprT1, _Is_); ADD32ItoR(gprT1, _Imm11_); - mVUaddrFix(gprT1); + mVUaddrFix(mVU, gprT1); MOVZX32Rm16toR(gprT1, gprT1, (uptr)mVU->regs->Mem + offsetSS); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } } pass3 { mVUlog("ILW.%s vi%02d, vi%02d + %d", _XYZW_String, _Ft_, _Fs_, _Imm11_); } } -microVUf(void) mVU_ILWR() { - microVU* mVU = mVUx; - pass1 { if (!_Ft_) { mVUinfo |= _isNOP; } analyzeVIreg1(_Fs_); analyzeVIreg2(_Ft_, 4); } +mVUop(mVU_ILWR) { + pass1 { if (!_It_) { mVUlow.isNOP = 1; } analyzeVIreg1(_Is_, mVUlow.VI_read[0]); analyzeVIreg2(_It_, mVUlow.VI_write, 4); } pass2 { - if (!_Fs_) { + if (!_Is_) { MOVZX32M16toR(gprT1, (uptr)mVU->regs->Mem + offsetSS); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } else { - mVUallocVIa(gprT1, _Fs_); - mVUaddrFix(gprT1); + mVUallocVIa(mVU, gprT1, _Is_); + mVUaddrFix(mVU, gprT1); MOVZX32Rm16toR(gprT1, gprT1, (uptr)mVU->regs->Mem + offsetSS); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } } pass3 { mVUlog("ILWR.%s vi%02d, vi%02d", _XYZW_String, _Ft_, _Fs_); } @@ -781,23 +781,22 @@ microVUf(void) mVU_ILWR() { // ISW/ISWR //------------------------------------------------------------------ -microVUf(void) mVU_ISW() { - microVU* mVU = mVUx; - pass1 { analyzeVIreg1(_Fs_); analyzeVIreg1(_Ft_); } +mVUop(mVU_ISW) { + pass1 { analyzeVIreg1(_Is_, mVUlow.VI_read[0]); analyzeVIreg1(_It_, mVUlow.VI_read[1]); } pass2 { - if (!_Fs_) { + if (!_Is_) { int imm = getVUmem(_Imm11_); - mVUallocVIa(gprT1, _Ft_); + mVUallocVIa(mVU, gprT1, _It_); if (_X) MOV32RtoM((uptr)mVU->regs->Mem + imm, gprT1); if (_Y) MOV32RtoM((uptr)mVU->regs->Mem + imm + 4, gprT1); if (_Z) MOV32RtoM((uptr)mVU->regs->Mem + imm + 8, gprT1); if (_W) MOV32RtoM((uptr)mVU->regs->Mem + imm + 12, gprT1); } else { - mVUallocVIa(gprT1, _Fs_); - mVUallocVIa(gprT2, _Ft_); + mVUallocVIa(mVU, gprT1, _Is_); + mVUallocVIa(mVU, gprT2, _It_); ADD32ItoR(gprT1, _Imm11_); - mVUaddrFix(gprT1); + mVUaddrFix(mVU, gprT1); if (_X) MOV32RtoRm(gprT1, gprT2, (uptr)mVU->regs->Mem); if (_Y) MOV32RtoRm(gprT1, gprT2, (uptr)mVU->regs->Mem+4); if (_Z) MOV32RtoRm(gprT1, gprT2, (uptr)mVU->regs->Mem+8); @@ -807,21 +806,20 @@ microVUf(void) mVU_ISW() { pass3 { mVUlog("ISW.%s vi%02d, vi%02d + %d", _XYZW_String, _Ft_, _Fs_, _Imm11_); } } -microVUf(void) mVU_ISWR() { - microVU* mVU = mVUx; - pass1 { analyzeVIreg1(_Fs_); analyzeVIreg1(_Ft_); } +mVUop(mVU_ISWR) { + pass1 { analyzeVIreg1(_Is_, mVUlow.VI_read[0]); analyzeVIreg1(_It_, mVUlow.VI_read[1]); } pass2 { - if (!_Fs_) { - mVUallocVIa(gprT1, _Ft_); + if (!_Is_) { + mVUallocVIa(mVU, gprT1, _It_); if (_X) MOV32RtoM((uptr)mVU->regs->Mem, gprT1); if (_Y) MOV32RtoM((uptr)mVU->regs->Mem+4, gprT1); if (_Z) MOV32RtoM((uptr)mVU->regs->Mem+8, gprT1); if (_W) MOV32RtoM((uptr)mVU->regs->Mem+12, gprT1); } else { - mVUallocVIa(gprT1, _Fs_); - mVUallocVIa(gprT2, _Ft_); - mVUaddrFix(gprT1); + mVUallocVIa(mVU, gprT1, _Is_); + mVUallocVIa(mVU, gprT2, _It_); + mVUaddrFix(mVU, gprT1); if (_X) MOV32RtoRm(gprT1, gprT2, (uptr)mVU->regs->Mem); if (_Y) MOV32RtoRm(gprT1, gprT2, (uptr)mVU->regs->Mem+4); if (_Z) MOV32RtoRm(gprT1, gprT2, (uptr)mVU->regs->Mem+8); @@ -835,65 +833,62 @@ microVUf(void) mVU_ISWR() { // LQ/LQD/LQI //------------------------------------------------------------------ -microVUf(void) mVU_LQ() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeLQ(_Ft_, _Fs_, 0); } +mVUop(mVU_LQ) { + pass1 { mVUanalyzeLQ(mVU, _Ft_, _Is_, 0); } pass2 { - if (!_Fs_) { - mVUloadReg(xmmFt, (uptr)mVU->regs->Mem + getVUmem(_Imm11_), _X_Y_Z_W); - mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); + if (!_Is_) { + mVUloadReg(xmmFt, (uptr)mVU->regs->Mem + getVUmem(_Imm11_), _X_Y_Z_W); + mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); } else { - mVUallocVIa(gprT1, _Fs_); + mVUallocVIa(mVU, gprT1, _Is_); ADD32ItoR(gprT1, _Imm11_); - mVUaddrFix(gprT1); - mVUloadReg2(xmmFt, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W); - mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); + mVUaddrFix(mVU, gprT1); + mVUloadReg2(xmmFt, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W); + mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); } } pass3 { mVUlog("LQ.%s vf%02d, vi%02d + %d", _XYZW_String, _Ft_, _Fs_, _Imm11_); } } -microVUf(void) mVU_LQD() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeLQ(_Ft_, _Fs_, 1); } +mVUop(mVU_LQD) { + pass1 { mVUanalyzeLQ(mVU, _Ft_, _Is_, 1); } pass2 { - if (!_Fs_ && !noWriteVF) { - mVUloadReg(xmmFt, (uptr)mVU->regs->Mem, _X_Y_Z_W); - mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); + if (!_Is_ && !mVUlow.noWriteVF) { + mVUloadReg(xmmFt, (uptr)mVU->regs->Mem, _X_Y_Z_W); + mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); } else { - mVUallocVIa(gprT1, _Fs_); + mVUallocVIa(mVU, gprT1, _Is_); SUB16ItoR(gprT1, 1); - mVUallocVIb(gprT1, _Fs_); - if (!noWriteVF) { - mVUaddrFix(gprT1); - mVUloadReg2(xmmFt, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W); - mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); + mVUallocVIb(mVU, gprT1, _Is_); + if (!mVUlow.noWriteVF) { + mVUaddrFix(mVU, gprT1); + mVUloadReg2(xmmFt, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W); + mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); } } } - pass3 { mVUlog("LQD.%s vf%02d, --vi%02d", _XYZW_String, _Ft_, _Fs_); } + pass3 { mVUlog("LQD.%s vf%02d, --vi%02d", _XYZW_String, _Ft_, _Is_); } } -microVUf(void) mVU_LQI() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeLQ(_Ft_, _Fs_, 1); } +mVUop(mVU_LQI) { + pass1 { mVUanalyzeLQ(mVU, _Ft_, _Is_, 1); } pass2 { - if (!_Fs_ && !noWriteVF) { - mVUloadReg(xmmFt, (uptr)mVU->regs->Mem, _X_Y_Z_W); - mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); + if (!_Is_ && !mVUlow.noWriteVF) { + mVUloadReg(xmmFt, (uptr)mVU->regs->Mem, _X_Y_Z_W); + mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); } else { - mVUallocVIa((!noWriteVF) ? gprT1 : gprT2, _Fs_); - if (!noWriteVF) { + mVUallocVIa(mVU, (!mVUlow.noWriteVF) ? gprT1 : gprT2, _Is_); + if (!mVUlow.noWriteVF) { MOV32RtoR(gprT2, gprT1); - mVUaddrFix(gprT1); - mVUloadReg2(xmmFt, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W); - mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); + mVUaddrFix(mVU, gprT1); + mVUloadReg2(xmmFt, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W); + mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); } ADD16ItoR(gprT2, 1); - mVUallocVIb(gprT2, _Fs_); + mVUallocVIb(mVU, gprT2, _Is_); } } pass3 { mVUlog("LQI.%s vf%02d, vi%02d++", _XYZW_String, _Ft_, _Fs_); } @@ -903,61 +898,58 @@ microVUf(void) mVU_LQI() { // SQ/SQD/SQI //------------------------------------------------------------------ -microVUf(void) mVU_SQ() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeSQ(_Fs_, _Ft_, 0); } +mVUop(mVU_SQ) { + pass1 { mVUanalyzeSQ(mVU, _Fs_, _It_, 0); } pass2 { - if (!_Ft_) { + if (!_It_) { getReg7(xmmFs, _Fs_); - mVUsaveReg(xmmFs, (uptr)mVU->regs->Mem + getVUmem(_Imm11_), _X_Y_Z_W, 1); + mVUsaveReg(xmmFs, (uptr)mVU->regs->Mem + getVUmem(_Imm11_), _X_Y_Z_W, 1); } else { - mVUallocVIa(gprT1, _Ft_); + mVUallocVIa(mVU, gprT1, _It_); ADD32ItoR(gprT1, _Imm11_); - mVUaddrFix(gprT1); + mVUaddrFix(mVU, gprT1); getReg7(xmmFs, _Fs_); - mVUsaveReg2(xmmFs, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W); + mVUsaveReg2(xmmFs, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W); } } pass3 { mVUlog("SQ.%s vf%02d, vi%02d + %d", _XYZW_String, _Fs_, _Ft_, _Imm11_); } } -microVUf(void) mVU_SQD() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeSQ(_Fs_, _Ft_, 1); } +mVUop(mVU_SQD) { + pass1 { mVUanalyzeSQ(mVU, _Fs_, _It_, 1); } pass2 { - if (!_Ft_) { + if (!_It_) { getReg7(xmmFs, _Fs_); - mVUsaveReg(xmmFs, (uptr)mVU->regs->Mem, _X_Y_Z_W, 1); + mVUsaveReg(xmmFs, (uptr)mVU->regs->Mem, _X_Y_Z_W, 1); } else { - mVUallocVIa(gprT1, _Ft_); + mVUallocVIa(mVU, gprT1, _It_); SUB16ItoR(gprT1, 1); - mVUallocVIb(gprT1, _Ft_); - mVUaddrFix(gprT1); + mVUallocVIb(mVU, gprT1, _It_); + mVUaddrFix(mVU, gprT1); getReg7(xmmFs, _Fs_); - mVUsaveReg2(xmmFs, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W); + mVUsaveReg2(xmmFs, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W); } } pass3 { mVUlog("SQD.%s vf%02d, --vi%02d", _XYZW_String, _Fs_, _Ft_); } } -microVUf(void) mVU_SQI() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeSQ(_Fs_, _Ft_, 1); } +mVUop(mVU_SQI) { + pass1 { mVUanalyzeSQ(mVU, _Fs_, _It_, 1); } pass2 { - if (!_Ft_) { + if (!_It_) { getReg7(xmmFs, _Fs_); - mVUsaveReg(xmmFs, (uptr)mVU->regs->Mem, _X_Y_Z_W, 1); + mVUsaveReg(xmmFs, (uptr)mVU->regs->Mem, _X_Y_Z_W, 1); } else { - mVUallocVIa(gprT1, _Ft_); + mVUallocVIa(mVU, gprT1, _It_); MOV32RtoR(gprT2, gprT1); - mVUaddrFix(gprT1); + mVUaddrFix(mVU, gprT1); getReg7(xmmFs, _Fs_); - mVUsaveReg2(xmmFs, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W); + mVUsaveReg2(xmmFs, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W); ADD16ItoR(gprT2, 1); - mVUallocVIb(gprT2, _Ft_); + mVUallocVIb(mVU, gprT2, _It_); } } pass3 { mVUlog("SQI.%s vf%02d, vi%02d++", _XYZW_String, _Fs_, _Ft_); } @@ -967,42 +959,40 @@ microVUf(void) mVU_SQI() { // RINIT/RGET/RNEXT/RXOR //------------------------------------------------------------------ -microVUf(void) mVU_RINIT() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeR1(_Fs_, _Fsf_); } +mVUop(mVU_RINIT) { + pass1 { mVUanalyzeR1(mVU, _Fs_, _Fsf_); } pass2 { if (_Fs_ || (_Fsf_ == 3)) { - getReg8(gprR, _Fs_, _Fsf_); - AND32ItoR(gprR, 0x007fffff); - OR32ItoR (gprR, 0x3f800000); + getReg8(gprT1, _Fs_, _Fsf_); + AND32ItoR(gprT1, 0x007fffff); + OR32ItoR (gprT1, 0x3f800000); + MOV32RtoM(Rmem, gprT1); } - else MOV32ItoR(gprR, 0x3f800000); + else MOV32ItoM(Rmem, 0x3f800000); } pass3 { mVUlog("RINIT R, vf%02d%s", _Fs_, _Fsf_String); } } -microVUt(void) mVU_RGET_() { - microVU* mVU = mVUx; - if (!noWriteVF) { - if (_X) MOV32RtoM((uptr)&mVU->regs->VF[_Ft_].UL[0], gprR); - if (_Y) MOV32RtoM((uptr)&mVU->regs->VF[_Ft_].UL[1], gprR); - if (_Z) MOV32RtoM((uptr)&mVU->regs->VF[_Ft_].UL[2], gprR); - if (_W) MOV32RtoM((uptr)&mVU->regs->VF[_Ft_].UL[3], gprR); +microVUt(void) mVU_RGET_(mV, int Rreg) { + if (!mVUlow.noWriteVF) { + if (_X) MOV32RtoM((uptr)&mVU->regs->VF[_Ft_].UL[0], Rreg); + if (_Y) MOV32RtoM((uptr)&mVU->regs->VF[_Ft_].UL[1], Rreg); + if (_Z) MOV32RtoM((uptr)&mVU->regs->VF[_Ft_].UL[2], Rreg); + if (_W) MOV32RtoM((uptr)&mVU->regs->VF[_Ft_].UL[3], Rreg); } } -microVUf(void) mVU_RGET() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeR2(_Ft_, 1); } - pass2 { mVU_RGET_(); } +mVUop(mVU_RGET) { + pass1 { mVUanalyzeR2(mVU, _Ft_, 1); } + pass2 { MOV32MtoR(gprT1, Rmem); mVU_RGET_(mVU, gprT1); } pass3 { mVUlog("RGET.%s vf%02d, R", _XYZW_String, _Ft_); } } -microVUf(void) mVU_RNEXT() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeR2(_Ft_, 0); } +mVUop(mVU_RNEXT) { + pass1 { mVUanalyzeR2(mVU, _Ft_, 0); } pass2 { // algorithm from www.project-fao.org + MOV32MtoR(gprR, Rmem); MOV32RtoR(gprT1, gprR); SHR32ItoR(gprT1, 4); AND32ItoR(gprT1, 1); @@ -1016,19 +1006,20 @@ microVUf(void) mVU_RNEXT() { XOR32RtoR(gprR, gprT1); AND32ItoR(gprR, 0x007fffff); OR32ItoR (gprR, 0x3f800000); - mVU_RGET_(); + MOV32RtoM(Rmem, gprR); + mVU_RGET_(mVU, gprR); + MOV32ItoR(gprR, Roffset); // Restore gprR } pass3 { mVUlog("RNEXT.%s vf%02d, R", _XYZW_String, _Ft_); } } -microVUf(void) mVU_RXOR() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeR1(_Fs_, _Fsf_); } +mVUop(mVU_RXOR) { + pass1 { mVUanalyzeR1(mVU, _Fs_, _Fsf_); } pass2 { if (_Fs_ || (_Fsf_ == 3)) { getReg8(gprT1, _Fs_, _Fsf_); AND32ItoR(gprT1, 0x7fffff); - XOR32RtoR(gprR, gprT1); + XOR32RtoM(Rmem, gprT1); } } pass3 { mVUlog("RXOR R, vf%02d%s", _Fs_, _Fsf_String); } @@ -1038,14 +1029,12 @@ microVUf(void) mVU_RXOR() { // WaitP/WaitQ //------------------------------------------------------------------ -microVUf(void) mVU_WAITP() { - microVU* mVU = mVUx; +mVUop(mVU_WAITP) { pass1 { mVUstall = aMax(mVUstall, ((mVUregs.p) ? (mVUregs.p - 1) : 0)); } pass3 { mVUlog("WAITP"); } } -microVUf(void) mVU_WAITQ() { - microVU* mVU = mVUx; +mVUop(mVU_WAITQ) { pass1 { mVUstall = aMax(mVUstall, mVUregs.q); } pass3 { mVUlog("WAITQ"); } } @@ -1054,22 +1043,21 @@ microVUf(void) mVU_WAITQ() { // XTOP/XITOP //------------------------------------------------------------------ -microVUf(void) mVU_XTOP() { - microVU* mVU = mVUx; - pass1 { if (!_Ft_) { mVUinfo |= _isNOP; } analyzeVIreg2(_Ft_, 1); } +mVUop(mVU_XTOP) { + pass1 { if (!_It_) { mVUlow.isNOP = 1; } analyzeVIreg2(_It_, mVUlow.VI_write, 1); } pass2 { MOVZX32M16toR(gprT1, (uptr)&mVU->regs->vifRegs->top); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("XTOP vi%02d", _Ft_); } } -microVUf(void) mVU_XITOP() { - microVU* mVU = mVUx; - pass1 { if (!_Ft_) { mVUinfo |= _isNOP; } analyzeVIreg2(_Ft_, 1); } +mVUop(mVU_XITOP) { + pass1 { if (!_It_) { mVUlow.isNOP = 1; } analyzeVIreg2(_It_, mVUlow.VI_write, 1); } pass2 { MOVZX32M16toR(gprT1, (uptr)&mVU->regs->vifRegs->itop); - mVUallocVIb(gprT1, _Ft_); + AND32ItoR(gprT1, isVU1 ? 0x3ff : 0xff); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("XITOP vi%02d", _Ft_); } } @@ -1080,10 +1068,20 @@ microVUf(void) mVU_XITOP() { void __fastcall mVU_XGKICK_(u32 addr) { addr = (addr<<4) & 0x3fff; // Multiply addr by 16 to get real address - u32 *data = (u32*)(microVU1.regs->Mem + (addr&0x3fff)); - u32 size = mtgsThread->PrepDataPacket( GIF_PATH_1, data, (0x4000-(addr&0x3fff)) >> 4); + u32 *data = (u32*)(microVU1.regs->Mem + addr); + u32 size = mtgsThread->PrepDataPacket(GIF_PATH_1, data, (0x4000-addr) >> 4); u8 *pDest = mtgsThread->GetDataPacketPtr(); - memcpy_aligned(pDest, microVU1.regs->Mem + addr, size<<4); +/* if((size << 4) > (0x4000-(addr&0x3fff))) { + //DevCon::Notice("addr + Size = 0x%x, transferring %x then doing %x", params (addr&0x3fff) + (size << 4), (0x4000-(addr&0x3fff)) >> 4, size - ((0x4000-(addr&0x3fff)) >> 4)); + memcpy_aligned(pDest, microVU1.regs->Mem + addr, 0x4000-(addr&0x3fff)); + size -= (0x4000-(addr&0x3fff)) >> 4; + //DevCon::Notice("Size left %x", params size); + pDest += 0x4000-(addr&0x3fff); + memcpy_aligned(pDest, microVU1.regs->Mem, size<<4); + } + else { */ + memcpy_aligned(pDest, microVU1.regs->Mem + addr, size<<4); +// } mtgsThread->SendDataPacket(); } @@ -1091,16 +1089,22 @@ void __fastcall mVU_XGKICK__(u32 addr) { GSGIFTRANSFER1((u32*)microVU1.regs->Mem, ((addr<<4)&0x3fff)); } -microVUf(void) mVU_XGKICK() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeXGkick(_Fs_, 4); } +microVUt(void) mVU_XGKICK_DELAY(mV, bool memVI) { + mVUbackupRegs(mVU); + if (memVI) MOV32MtoR(gprT2, (uptr)&mVU->VIxgkick); + else mVUallocVIa(mVU, gprT2, _Is_); + if (mtgsThread) CALLFunc((uptr)mVU_XGKICK_); + else CALLFunc((uptr)mVU_XGKICK__); + mVUrestoreRegs(mVU); +} + +mVUop(mVU_XGKICK) { + pass1 { mVUanalyzeXGkick(mVU, _Is_, mVU_XGKICK_CYCLES); } pass2 { - mVUprint("XGkick"); - mVUallocVIa(gprT2, _Fs_); // gprT2 = ECX for __fastcall - mVUbackupRegs(); - if (mtgsThread != NULL) CALLFunc((uptr)mVU_XGKICK_); - else CALLFunc((uptr)mVU_XGKICK__); - mVUrestoreRegs(); + if (!mVU_XGKICK_CYCLES) { mVU_XGKICK_DELAY(mVU, 0); return; } + else if (mVUinfo.doXGKICK) { mVU_XGKICK_DELAY(mVU, 1); mVUinfo.doXGKICK = 0; } + mVUallocVIa(mVU, gprT1, _Is_); + MOV32RtoM((uptr)&mVU->VIxgkick, gprT1); } pass3 { mVUlog("XGKICK vi%02d", _Fs_); } } @@ -1109,118 +1113,121 @@ microVUf(void) mVU_XGKICK() { // Branches/Jumps //------------------------------------------------------------------ -microVUf(void) mVU_B() { - microVU* mVU = mVUx; - mVUbranch = 1; +#define setBranchA(x, _x_) { \ + pass1 { if (_Imm11_ == 1 && !_x_) { mVUlow.isNOP = 1; return; } mVUbranch = x; } \ + pass2 { if (_Imm11_ == 1 && !_x_) { return; } mVUbranch = x; } \ + pass3 { mVUbranch = x; } \ + pass4 { if (_Imm11_ == 1 && !_x_) { return; } mVUbranch = x; } \ +} + +mVUop(mVU_B) { + setBranchA(1, 0); pass3 { mVUlog("B [%04x]", branchAddr, branchAddr); } } -microVUf(void) mVU_BAL() { - microVU* mVU = mVUx; - mVUbranch = 2; - pass1 { analyzeVIreg2(_Ft_, 1); } + +mVUop(mVU_BAL) { + setBranchA(2, _It_); + pass1 { analyzeVIreg2(_It_, mVUlow.VI_write, 1); } pass2 { MOV32ItoR(gprT1, bSaveAddr); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("BAL vi%02d [%04x]", _Ft_, branchAddr, branchAddr); } } -microVUf(void) mVU_IBEQ() { - microVU* mVU = mVUx; - mVUbranch = 3; - pass1 { mVUanalyzeBranch2(_Fs_, _Ft_); } + +mVUop(mVU_IBEQ) { + setBranchA(3, 0); + pass1 { mVUanalyzeBranch2(mVU, _Is_, _It_); } pass2 { - if (memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup[0]); - else mVUallocVIa(gprT1, _Fs_); - if (memReadIt) XOR32MtoR(gprT1, (uptr)&mVU->VIbackup[0]); - else { mVUallocVIa(gprT2, _Ft_); XOR32RtoR(gprT1, gprT2); } + if (mVUlow.memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup); + else mVUallocVIa(mVU, gprT1, _Is_); + if (mVUlow.memReadIt) XOR32MtoR(gprT1, (uptr)&mVU->VIbackup); + else { mVUallocVIa(mVU, gprT2, _It_); XOR32RtoR(gprT1, gprT2); } MOV32RtoM((uptr)&mVU->branch, gprT1); } pass3 { mVUlog("IBEQ vi%02d, vi%02d [%04x]", _Ft_, _Fs_, branchAddr, branchAddr); } } -microVUf(void) mVU_IBGEZ() { - microVU* mVU = mVUx; - mVUbranch = 4; - pass1 { mVUanalyzeBranch1(_Fs_); } + +mVUop(mVU_IBGEZ) { + setBranchA(4, 0); + pass1 { mVUanalyzeBranch1(mVU, _Is_); } pass2 { - if (memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup[0]); - else mVUallocVIa(gprT1, _Fs_); + if (mVUlow.memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup); + else mVUallocVIa(mVU, gprT1, _Is_); MOV32RtoM((uptr)&mVU->branch, gprT1); } pass3 { mVUlog("IBGEZ vi%02d [%04x]", _Fs_, branchAddr, branchAddr); } } -microVUf(void) mVU_IBGTZ() { - microVU* mVU = mVUx; - mVUbranch = 5; - pass1 { mVUanalyzeBranch1(_Fs_); } + +mVUop(mVU_IBGTZ) { + setBranchA(5, 0); + pass1 { mVUanalyzeBranch1(mVU, _Is_); } pass2 { - if (memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup[0]); - else mVUallocVIa(gprT1, _Fs_); + if (mVUlow.memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup); + else mVUallocVIa(mVU, gprT1, _Is_); MOV32RtoM((uptr)&mVU->branch, gprT1); } pass3 { mVUlog("IBGTZ vi%02d [%04x]", _Fs_, branchAddr, branchAddr); } } -microVUf(void) mVU_IBLEZ() { - microVU* mVU = mVUx; - mVUbranch = 6; - pass1 { mVUanalyzeBranch1(_Fs_); } + +mVUop(mVU_IBLEZ) { + setBranchA(6, 0); + pass1 { mVUanalyzeBranch1(mVU, _Is_); } pass2 { - if (memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup[0]); - else mVUallocVIa(gprT1, _Fs_); + if (mVUlow.memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup); + else mVUallocVIa(mVU, gprT1, _Is_); MOV32RtoM((uptr)&mVU->branch, gprT1); } pass3 { mVUlog("IBLEZ vi%02d [%04x]", _Fs_, branchAddr, branchAddr); } } -microVUf(void) mVU_IBLTZ() { - microVU* mVU = mVUx; - mVUbranch = 7; - pass1 { mVUanalyzeBranch1(_Fs_); } + +mVUop(mVU_IBLTZ) { + setBranchA(7, 0); + pass1 { mVUanalyzeBranch1(mVU, _Is_); } pass2 { - if (memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup[0]); - else mVUallocVIa(gprT1, _Fs_); + if (mVUlow.memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup); + else mVUallocVIa(mVU, gprT1, _Is_); MOV32RtoM((uptr)&mVU->branch, gprT1); } pass3 { mVUlog("IBLTZ vi%02d [%04x]", _Fs_, branchAddr, branchAddr); } } -microVUf(void) mVU_IBNE() { - microVU* mVU = mVUx; - mVUbranch = 8; - pass1 { mVUanalyzeBranch2(_Fs_, _Ft_); } + +mVUop(mVU_IBNE) { + setBranchA(8, 0); + pass1 { mVUanalyzeBranch2(mVU, _Is_, _It_); } pass2 { - if (memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup[0]); - else mVUallocVIa(gprT1, _Fs_); - if (memReadIt) XOR32MtoR(gprT1, (uptr)&mVU->VIbackup[0]); - else { mVUallocVIa(gprT2, _Ft_); XOR32RtoR(gprT1, gprT2); } + if (mVUlow.memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup); + else mVUallocVIa(mVU, gprT1, _Is_); + if (mVUlow.memReadIt) XOR32MtoR(gprT1, (uptr)&mVU->VIbackup); + else { mVUallocVIa(mVU, gprT2, _It_); XOR32RtoR(gprT1, gprT2); } MOV32RtoM((uptr)&mVU->branch, gprT1); } pass3 { mVUlog("IBNE vi%02d, vi%02d [%04x]", _Ft_, _Fs_, branchAddr, branchAddr); } } -microVUf(void) mVU_JR() { - microVU* mVU = mVUx; + +mVUop(mVU_JR) { mVUbranch = 9; - pass1 { mVUanalyzeBranch1(_Fs_); } + pass1 { analyzeVIreg1(_Is_, mVUlow.VI_read[0]); } pass2 { - if (memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup[0]); - else mVUallocVIa(gprT1, _Fs_); + mVUallocVIa(mVU, gprT1, _Is_); SHL32ItoR(gprT1, 3); - AND32ItoR(gprT1, vuIndex ? 0x3ff8 : 0xff8); + AND32ItoR(gprT1, isVU1 ? 0x3ff8 : 0xff8); MOV32RtoM((uptr)&mVU->branch, gprT1); } pass3 { mVUlog("JR [vi%02d]", _Fs_); } } -microVUf(void) mVU_JALR() { - microVU* mVU = mVUx; + +mVUop(mVU_JALR) { mVUbranch = 10; - pass1 { mVUanalyzeBranch1(_Fs_); analyzeVIreg2(_Ft_, 1); } + pass1 { analyzeVIreg1(_Is_, mVUlow.VI_read[0]); analyzeVIreg2(_It_, mVUlow.VI_write, 1); } pass2 { - if (memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup[0]); - else mVUallocVIa(gprT1, _Fs_); + mVUallocVIa(mVU, gprT1, _Is_); SHL32ItoR(gprT1, 3); - AND32ItoR(gprT1, vuIndex ? 0x3ff8 : 0xff8); + AND32ItoR(gprT1, isVU1 ? 0x3ff8 : 0xff8); MOV32RtoM((uptr)&mVU->branch, gprT1); MOV32ItoR(gprT1, bSaveAddr); - mVUallocVIb(gprT1, _Ft_); + mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("JALR vi%02d, [vi%02d]", _Ft_, _Fs_); } } -#endif //PCSX2_MICROVU diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h index 97980dc8a2..5f4d22bcf0 100644 --- a/pcsx2/x86/microVU_Misc.h +++ b/pcsx2/x86/microVU_Misc.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2009 Pcsx2-Playground Team + * Copyright (C) 2009 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -66,9 +66,14 @@ declareAllVariables //------------------------------------------------------------------ // Helper Macros //------------------------------------------------------------------ -#define _Ft_ ((mVU->code >> 16) & 0x1F) // The ft/it part of the instruction register -#define _Fs_ ((mVU->code >> 11) & 0x1F) // The fs/is part of the instruction register -#define _Fd_ ((mVU->code >> 6) & 0x1F) // The fd/id part of the instruction register + +#define _Ft_ ((mVU->code >> 16) & 0x1F) // The ft part of the instruction register +#define _Fs_ ((mVU->code >> 11) & 0x1F) // The fs part of the instruction register +#define _Fd_ ((mVU->code >> 6) & 0x1F) // The fd part of the instruction register + +#define _It_ ((mVU->code >> 16) & 0xF) // The it part of the instruction register +#define _Is_ ((mVU->code >> 11) & 0xF) // The is part of the instruction register +#define _Id_ ((mVU->code >> 6) & 0xF) // The id part of the instruction register #define _X ((mVU->code>>24) & 0x1) #define _Y ((mVU->code>>23) & 0x1) @@ -89,7 +94,7 @@ declareAllVariables #define _Ftf_ ((mVU->code >> 23) & 0x03) #define _Imm5_ (s16)(((mVU->code & 0x400) ? 0xfff0 : 0) | ((mVU->code >> 6) & 0xf)) -#define _Imm11_ (s32)((mVU->code & 0x400) ? (0xfffffc00 | (mVU->code & 0x3ff)) : mVU->code & 0x3ff) +#define _Imm11_ (s32)((mVU->code & 0x400) ? (0xfffffc00 | (mVU->code & 0x3ff)) : (mVU->code & 0x3ff)) #define _Imm12_ (((mVU->code >> 21) & 0x1) << 11) | (mVU->code & 0x7ff) #define _Imm15_ (((mVU->code >> 10) & 0x7800) | (mVU->code & 0x7ff)) #define _Imm24_ (u32)(mVU->code & 0xffffff) @@ -99,10 +104,16 @@ declareAllVariables #define _Mbit_ (1<<29) #define _Dbit_ (1<<28) #define _Tbit_ (1<<27) -#define _MDTbit_ 0 //( _Mbit_ | _Dbit_ | _Tbit_ ) // ToDo: Implement this stuff... +#define _DTbit_ 0 //( _Dbit_ | _Tbit_ ) // ToDo: Implement this stuff... -#define getVUmem(x) (((vuIndex == 1) ? (x & 0x3ff) : ((x >= 0x400) ? (x & 0x43f) : (x & 0xff))) * 16) +#define divI 0x1040000 +#define divD 0x2080000 + +#define isVU1 (mVU->index != 0) +#define getIndex (isVU1 ? 1 : 0) +#define getVUmem(x) (((isVU1) ? (x & 0x3ff) : ((x >= 0x400) ? (x & 0x43f) : (x & 0xff))) * 16) #define offsetSS ((_X) ? (0) : ((_Y) ? (4) : ((_Z) ? 8: 12))) +#define offsetReg ((_X) ? (0) : ((_Y) ? (1) : ((_Z) ? 2: 3))) #define xmmT1 0 // Temp Reg #define xmmFs 1 // Holds the Value of Fs (writes back result Fd) @@ -124,116 +135,115 @@ declareAllVariables #define gprT1 0 // Temp Reg #define gprT2 1 // Temp Reg -#define gprR 2 // R Reg -#define gprF0 3 // MAC Flag::Status Flag 0 +#define gprR 2 // VI Reg Offset +#define gprF0 3 // Status Flag 0 #define gprESP 4 // Don't use? -#define gprF1 5 // MAC Flag::Status Flag 1 -#define gprF2 6 // MAC Flag::Status Flag 2 -#define gprF3 7 // MAC Flag::Status Flag 3 +#define gprF1 5 // Status Flag 1 +#define gprF2 6 // Status Flag 2 +#define gprF3 7 // Status Flag 3 -// Template Stuff +// Function Params +#define mP microVU* mVU, int recPass +#define mV microVU* mVU +#define mF int recPass +#define mX mVU, recPass + +// Recursive Inline +#ifndef __LINUX__ +#define __recInline __forceinline +#else +#define __recInline inline +#endif + +// Function/Template Stuff #define mVUx (vuIndex ? µVU1 : µVU0) -#define microVUt(aType) template __forceinline aType +#define mVUop(opName) void opName (mP) +#define microVUr(aType) __recInline aType +#define microVUt(aType) __forceinline aType #define microVUx(aType) template aType -#define microVUf(aType) template aType -#define microVUq(aType) template __forceinline aType +#define microVUf(aType) template __forceinline aType +// Define Passes #define pass1 if (recPass == 0) #define pass2 if (recPass == 1) #define pass3 if (recPass == 2) +#define pass4 if (recPass == 3) +// Define mVUquickSearch +#ifndef __LINUX__ +PCSX2_ALIGNED16_EXTERN( u8 mVUsearchXMM[0x1000] ); +typedef u32 (__fastcall *mVUCall)(void*, void*); +#define mVUquickSearch(dest, src, size) ((((mVUCall)((void*)mVUsearchXMM))(dest, src)) == 0xf) +#define mVUemitSearch() { mVUcustomSearch(); } +#else +// Note: GCC builds crash with custom search function, because +// they're not guaranteeing 16-byte alignment on the structs :( +// #define mVUquickSearch(dest, src, size) (!memcmp(dest, src, size)) +#define mVUquickSearch(dest, src, size) (!memcmp_mmx(dest, src, size)) +#define mVUemitSearch() +#endif + +// Misc Macros... +#define mVUprogI mVU->prog.prog[progIndex] #define mVUcurProg mVU->prog.prog[mVU->prog.cur] #define mVUblocks mVU->prog.prog[mVU->prog.cur].block #define mVUallocInfo mVU->prog.prog[mVU->prog.cur].allocInfo #define mVUbranch mVUallocInfo.branch #define mVUcycles mVUallocInfo.cycles #define mVUcount mVUallocInfo.count +#define mVUpBlock mVUallocInfo.pBlock #define mVUblock mVUallocInfo.block #define mVUregs mVUallocInfo.block.pState #define mVUregsTemp mVUallocInfo.regsTemp #define iPC mVUallocInfo.curPC +#define mVUsFlagHack mVUallocInfo.sFlagHack #define mVUinfo mVUallocInfo.info[iPC / 2] -#define mVUstall mVUallocInfo.stall[iPC / 2] +#define mVUstall mVUinfo.stall +#define mVUup mVUinfo.uOp +#define mVUlow mVUinfo.lOp +#define sFLAG mVUinfo.sFlag +#define mFLAG mVUinfo.mFlag +#define cFLAG mVUinfo.cFlag #define mVUstartPC mVUallocInfo.startPC +#define mVUflagInfo mVUregs.needExactMatch +#define mVUrange mVUcurProg.ranges.range[mVUcurProg.ranges.total] #define xPC ((iPC / 2) * 8) -#define curI mVUcurProg.data[iPC] +#define curI ((u32*)mVU->regs->Micro)[iPC] //mVUcurProg.data[iPC] #define setCode() { mVU->code = curI; } #define incPC(x) { iPC = ((iPC + x) & (mVU->progSize-1)); setCode(); } #define incPC2(x) { iPC = ((iPC + x) & (mVU->progSize-1)); } -#define incCycles(x) { mVUincCycles(x); } -#define bSaveAddr (((xPC + (2 * 8)) & ((vuIndex) ? 0x3ff8:0xff8)) / 8) -#define branchAddr ((xPC + 8 + (_Imm11_ * 8)) & ((vuIndex) ? 0x3ff8:0xff8)) +#define bSaveAddr (((xPC + (2 * 8)) & ((isVU1) ? 0x3ff8:0xff8)) / 8) +#define branchAddr ((xPC + 8 + (_Imm11_ * 8)) & (mVU->microMemSize-8)) #define shufflePQ (((mVU->p) ? 0xb0 : 0xe0) | ((mVU->q) ? 0x01 : 0x04)) +#define cmpOffset(x) ((u8*)&(((u8*)x)[mVUprogI.ranges.range[i][0]])) +#define Rmem (uptr)&mVU->regs->VI[REG_R].UL +#define Roffset (uptr)&mVU->regs->VI[9].UL + +// Flag Info +#define __Status (mVUflagInfo & (0xf<<0)) +#define __Mac (mVUflagInfo & (0xf<<4)) +#define __Clip (mVUflagInfo & (0xf<<8)) + +// Pass 3 Helper Macros #define _Fsf_String ((_Fsf_ == 3) ? "w" : ((_Fsf_ == 2) ? "z" : ((_Fsf_ == 1) ? "y" : "x"))) #define _Ftf_String ((_Ftf_ == 3) ? "w" : ((_Ftf_ == 2) ? "z" : ((_Ftf_ == 1) ? "y" : "x"))) #define xyzwStr(x,s) (_X_Y_Z_W == x) ? s : #define _XYZW_String (xyzwStr(1, "w") (xyzwStr(2, "z") (xyzwStr(3, "zw") (xyzwStr(4, "y") (xyzwStr(5, "yw") (xyzwStr(6, "yz") (xyzwStr(7, "yzw") (xyzwStr(8, "x") (xyzwStr(9, "xw") (xyzwStr(10, "xz") (xyzwStr(11, "xzw") (xyzwStr(12, "xy") (xyzwStr(13, "xyw") (xyzwStr(14, "xyz") "xyzw")))))))))))))) #define _BC_String (_bc_x ? "x" : (_bc_y ? "y" : (_bc_z ? "z" : "w"))) +#define mVUlogFtFs() { mVUlog(".%s vf%02d, vf%02d", _XYZW_String, _Ft_, _Fs_); } +#define mVUlogFd() { mVUlog(".%s vf%02d, vf%02d", _XYZW_String, _Fd_, _Fs_); } +#define mVUlogACC() { mVUlog(".%s ACC, vf%02d", _XYZW_String, _Fs_); } +#define mVUlogFt() { mVUlog(", vf%02d", _Ft_); } +#define mVUlogBC() { mVUlog(", vf%02d%s", _Ft_, _BC_String); } +#define mVUlogI() { mVUlog(", I"); } +#define mVUlogQ() { mVUlog(", Q"); } +#define mVUlogCLIP() { mVUlog("w.xyz vf%02d, vf%02dw", _Fs_, _Ft_); } - -#define _isNOP (1<<0) // Skip Lower Instruction -#define _isBranch (1<<1) // Cur Instruction is a Branch -#define _isEOB (1<<2) // End of Block -#define _isBdelay (1<<3) // Cur Instruction in Branch Delay slot -#define _isSflag (1<<4) // Cur Instruction uses status flag -#define _writeQ (1<<5) -#define _readQ (1<<6) -#define _writeP (1<<7) -#define _readP (1<<7) // same as writeP -#define _doFlags (3<<8) -#define _doMac (1<<8) -#define _doStatus (1<<9) -#define _fmInstance (3<<10) // Mac Write Instance -#define _fsInstance (3<<12) // Status Write Instance -#define _fcInstance (3<<14) // Clip Write Instance -#define _fpsInstance (3<<12) // Prev.S. Write Instance -#define _fpcInstance (3<<14) // Prev.C. Write Instance -#define _fvmInstance (3<<16) // Mac Read Instance (at T-stage for lower instruction) -#define _fvsInstance (3<<18) // Status Read Instance (at T-stage for lower instruction) -#define _fvcInstance (3<<20) // Clip Read Instance (at T-stage for lower instruction) -#define _noWriteVF (1<<21) // Don't write back the result of a lower op to VF reg if upper op writes to same reg (or if VF = 0) -#define _backupVI (1<<22) // Backup VI reg to memory if modified before branch (branch uses old VI value unless opcode is ILW or ILWR) -#define _memReadIs (1<<23) // Read Is (VI reg) from memory (used by branches) -#define _memReadIt (1<<24) // Read If (VI reg) from memory (used by branches) -#define _writesVI (1<<25) // Current Instruction writes to VI -#define _swapOps (1<<26) // Runs Lower Instruction Before Upper Instruction -#define _isFSSET (1<<27) // Cur Instruction is FSSET -#define _doDivFlag (1<<28) // Transfer Div flag to Status Flag -#define _doClip (1<<29) - -#define isNOP (mVUinfo & (1<<0)) -#define isBranch (mVUinfo & (1<<1)) -#define isEOB (mVUinfo & (1<<2)) -#define isBdelay (mVUinfo & (1<<3)) -#define isSflag (mVUinfo & (1<<4)) -#define writeQ ((mVUinfo >> 5) & 1) -#define readQ ((mVUinfo >> 6) & 1) -#define writeP ((mVUinfo >> 7) & 1) -#define readP ((mVUinfo >> 7) & 1) // same as writeP -#define doFlags (mVUinfo & (3<<8)) -#define doMac (mVUinfo & (1<<8)) -#define doStatus (mVUinfo & (1<<9)) -#define fmInstance ((mVUinfo >> 10) & 3) -#define fsInstance ((mVUinfo >> 12) & 3) -#define fpsInstance ((((mVUinfo>>12) & 3) - 1) & 0x3) -#define fcInstance ((mVUinfo >> 14) & 3) -#define fpcInstance ((((mVUinfo>>14) & 3) - 1) & 0x3) -#define fvmInstance ((mVUinfo >> 16) & 3) -#define fvsInstance ((mVUinfo >> 18) & 3) -#define fvcInstance ((mVUinfo >> 20) & 3) -#define noWriteVF (mVUinfo & (1<<21)) -#define backupVI (mVUinfo & (1<<22)) -#define memReadIs (mVUinfo & (1<<23)) -#define memReadIt (mVUinfo & (1<<24)) -#define writesVI (mVUinfo & (1<<25)) -#define swapOps (mVUinfo & (1<<26)) -#define isFSSET (mVUinfo & (1<<27)) -#define doDivFlag (mVUinfo & (1<<28)) -#define doClip (mVUinfo & (1<<29)) - -#define isMMX(_VIreg_) 0//(_VIreg_ >= 1 && _VIreg_ <=8) +// Store VI regs in mmx regs? +#define isMMX(_VIreg_) 0 //(_VIreg_ >= 1 && _VIreg_ <=8) #define mmVI(_VIreg_) (_VIreg_ - 1) +// Debug Stuff... #ifdef mVUdebug #define mVUprint Console::Status #define mVUdebug1() { \ @@ -245,18 +255,46 @@ declareAllVariables } #else #define mVUprint 0&& -#define mVUdebug1() {} +#define mVUdebug1() { \ + if (curI & _Mbit_) { Console::Status("microVU%d: M-bit set!", params getIndex); } \ + if (curI & _Dbit_) { DevCon::Status ("microVU%d: D-bit set!", params getIndex); } \ + if (curI & _Tbit_) { DevCon::Status ("microVU%d: T-bit set!", params getIndex); } \ +} #endif +// Program Logging... #ifdef mVUlogProg -#define mVUlog __mVULog +#define mVUlog ((isVU1) ? __mVULog<1> : __mVULog<0>) #define mVUdumpProg __mVUdumpProgram #else #define mVUlog 0&& #define mVUdumpProg 0&& #endif -#define mVUcacheCheck(ptr, start, limit) { \ - uptr diff = ptr - start; \ - if (diff >= limit) { Console::Error("microVU Error: Program went over it's cache limit. Size = %x", params diff); } \ +// Speed Hacks +#define CHECK_VU_FLAGHACK (u32)Config.Hacks.vuFlagHack // (Can cause Infinite loops, SPS, etc...) +#define CHECK_VU_MINMAXHACK (u32)Config.Hacks.vuMinMax // (Can cause SPS, Black Screens, etc...) + +// Unknown Data +#define mVU_XGKICK_CYCLES ((CHECK_XGKICKHACK) ? 3 : 1) +// Its unknown at recompile time how long the xgkick transfer will take +// so give it a value that makes games happy :) (SO3 is fine at 1 cycle delay) + + +// Cache Limit Check +#define mVUcacheCheck(ptr, start, limit) { \ + uptr diff = ptr - start; \ + if (diff >= limit) { \ + Console::Error("microVU Error: Program went over its cache limit. Size = 0x%x", params diff); \ + mVUreset(mVU); \ + } \ +} + +#define mVUdebugNOW(isEndPC) { \ + if (mVUdebugNow) { \ + MOV32ItoR(gprT2, xPC); \ + if (isEndPC) { CALLFunc((uptr)mVUprintPC2); } \ + else { CALLFunc((uptr)mVUprintPC1); } \ + MOV32ItoR(gprR, Roffset); \ + } \ } diff --git a/pcsx2/x86/microVU_Misc.inl b/pcsx2/x86/microVU_Misc.inl index 48c91520e7..81534987f1 100644 --- a/pcsx2/x86/microVU_Misc.inl +++ b/pcsx2/x86/microVU_Misc.inl @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2009 Pcsx2-Playground Team +* Copyright (C) 2009 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,14 +17,13 @@ */ #pragma once -#ifdef PCSX2_MICROVU //------------------------------------------------------------------ // Micro VU - Clamp Functions //------------------------------------------------------------------ // Used for Result Clamping -microVUx(void) mVUclamp1(int reg, int regT1, int xyzw) { +void mVUclamp1(int reg, int regT1, int xyzw) { switch (xyzw) { case 1: case 2: case 4: case 8: SSE_MINSS_XMM_to_XMM(reg, xmmMax); @@ -38,7 +37,7 @@ microVUx(void) mVUclamp1(int reg, int regT1, int xyzw) { } // Used for Operand Clamping -microVUx(void) mVUclamp2(int reg, int regT1, int xyzw) { +void mVUclamp2(int reg, int regT1, int xyzw) { if (CHECK_VU_SIGN_OVERFLOW) { switch (xyzw) { case 1: case 2: case 4: case 8: @@ -57,14 +56,14 @@ microVUx(void) mVUclamp2(int reg, int regT1, int xyzw) { break; } } - else mVUclamp1(reg, regT1, xyzw); + else mVUclamp1(reg, regT1, xyzw); } //------------------------------------------------------------------ -// Micro VU - Misc Functions +// Micro VU - Reg Loading/Saving/Shuffling/Unpacking/Merging... //------------------------------------------------------------------ -microVUx(void) mVUunpack_xyzw(int dstreg, int srcreg, int xyzw) { +void mVUunpack_xyzw(int dstreg, int srcreg, int xyzw) { switch ( xyzw ) { case 0: SSE2_PSHUFD_XMM_to_XMM(dstreg, srcreg, 0x00); break; case 1: SSE2_PSHUFD_XMM_to_XMM(dstreg, srcreg, 0x55); break; @@ -73,7 +72,7 @@ microVUx(void) mVUunpack_xyzw(int dstreg, int srcreg, int xyzw) { } } -microVUx(void) mVUloadReg(int reg, uptr offset, int xyzw) { +void mVUloadReg(int reg, uptr offset, int xyzw) { switch( xyzw ) { case 8: SSE_MOVSS_M32_to_XMM(reg, offset); break; // X case 4: SSE_MOVSS_M32_to_XMM(reg, offset+4); break; // Y @@ -83,7 +82,7 @@ microVUx(void) mVUloadReg(int reg, uptr offset, int xyzw) { } } -microVUx(void) mVUloadReg2(int reg, int gprReg, uptr offset, int xyzw) { +void mVUloadReg2(int reg, int gprReg, uptr offset, int xyzw) { switch( xyzw ) { case 8: SSE_MOVSS_Rm_to_XMM(reg, gprReg, offset); break; // X case 4: SSE_MOVSS_Rm_to_XMM(reg, gprReg, offset+4); break; // Y @@ -94,12 +93,12 @@ microVUx(void) mVUloadReg2(int reg, int gprReg, uptr offset, int xyzw) { } // Modifies the Source Reg! -microVUx(void) mVUsaveReg(int reg, uptr offset, int xyzw, bool modXYZW) { +void mVUsaveReg(int reg, uptr offset, int xyzw, bool modXYZW) { /*SSE_MOVAPS_M128_to_XMM(xmmT2, offset); if (modXYZW && (xyzw == 8 || xyzw == 4 || xyzw == 2 || xyzw == 1)) { mVUunpack_xyzw(reg, reg, 0); } - mVUmergeRegs(xmmT2, reg, xyzw); + mVUmergeRegs(xmmT2, reg, xyzw); SSE_MOVAPS_XMM_to_M128(offset, xmmT2); return;*/ @@ -136,13 +135,13 @@ microVUx(void) mVUsaveReg(int reg, uptr offset, int xyzw, bool modXYZW) { SSE_MOVHLPS_XMM_to_XMM(reg, reg); SSE_MOVSS_XMM_to_M32(offset+8, reg); break; // XYZ - case 4: if (!modXYZW) mVUunpack_xyzw(reg, reg, 1); + case 4: if (!modXYZW) mVUunpack_xyzw(reg, reg, 1); SSE_MOVSS_XMM_to_M32(offset+4, reg); break; // Y - case 2: if (!modXYZW) mVUunpack_xyzw(reg, reg, 2); + case 2: if (!modXYZW) mVUunpack_xyzw(reg, reg, 2); SSE_MOVSS_XMM_to_M32(offset+8, reg); break; // Z - case 1: if (!modXYZW) mVUunpack_xyzw(reg, reg, 3); + case 1: if (!modXYZW) mVUunpack_xyzw(reg, reg, 3); SSE_MOVSS_XMM_to_M32(offset+12, reg); break; // W case 8: SSE_MOVSS_XMM_to_M32(offset, reg); break; // X @@ -153,12 +152,12 @@ microVUx(void) mVUsaveReg(int reg, uptr offset, int xyzw, bool modXYZW) { } // Modifies the Source Reg! -microVUx(void) mVUsaveReg2(int reg, int gprReg, u32 offset, int xyzw) { +void mVUsaveReg2(int reg, int gprReg, u32 offset, int xyzw) { /*SSE_MOVAPSRmtoR(xmmT2, gprReg, offset); if (xyzw == 8 || xyzw == 4 || xyzw == 2 || xyzw == 1) { mVUunpack_xyzw(reg, reg, 0); } - mVUmergeRegs(xmmT2, reg, xyzw); + mVUmergeRegs(xmmT2, reg, xyzw); SSE_MOVAPSRtoRm(gprReg, xmmT2, offset); return;*/ @@ -205,7 +204,7 @@ microVUx(void) mVUsaveReg2(int reg, int gprReg, u32 offset, int xyzw) { } // Modifies the Source Reg! -microVUx(void) mVUmergeRegs(int dest, int src, int xyzw) { +void mVUmergeRegs(int dest, int src, int xyzw) { xyzw &= 0xf; if ( (dest != src) && (xyzw != 0) ) { if ( cpucaps.hasStreamingSIMD4Extensions && (xyzw != 0x8) && (xyzw != 0xf) ) { @@ -262,9 +261,13 @@ microVUx(void) mVUmergeRegs(int dest, int src, int xyzw) { } } +//------------------------------------------------------------------ +// Micro VU - Misc Functions +//------------------------------------------------------------------ + // Transforms the Address in gprReg to valid VU0/VU1 Address -microVUt(void) mVUaddrFix(int gprReg) { - if (vuIndex) { +microVUt(void) mVUaddrFix(mV, int gprReg) { + if (mVU == µVU1) { AND32ItoR(gprReg, 0x3ff); // wrap around SHL32ItoR(gprReg, 4); } @@ -282,21 +285,209 @@ microVUt(void) mVUaddrFix(int gprReg) { } // Backup Volatile Regs (EAX, ECX, EDX, MM0~7, XMM0~7, are all volatile according to 32bit Win/Linux ABI) -microVUt(void) mVUbackupRegs() { - microVU* mVU = mVUx; +microVUt(void) mVUbackupRegs(mV) { SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->ACC.UL[0], xmmACC); SSE_MOVAPS_XMM_to_M128((uptr)&mVU->xmmPQb[0], xmmPQ); - PUSH32R(gprR); // Backup EDX } // Restore Volatile Regs -microVUt(void) mVUrestoreRegs() { - microVU* mVU = mVUx; +microVUt(void) mVUrestoreRegs(mV) { SSE_MOVAPS_M128_to_XMM(xmmACC, (uptr)&mVU->regs->ACC.UL[0]); SSE_MOVAPS_M128_to_XMM(xmmPQ, (uptr)&mVU->xmmPQb[0]); SSE_MOVAPS_M128_to_XMM(xmmMax, (uptr)mVU_maxvals); SSE_MOVAPS_M128_to_XMM(xmmMin, (uptr)mVU_minvals); - POP32R(gprR); // Restore EDX + MOV32ItoR(gprR, Roffset); // Restore gprR } -#endif //PCSX2_MICROVU +//------------------------------------------------------------------ +// Micro VU - Custom SSE Instructions +//------------------------------------------------------------------ + +static const u32 PCSX2_ALIGNED16(MIN_MAX_MASK1[4]) = {0xffffffff, 0x80000000, 0xffffffff, 0x80000000}; +static const u32 PCSX2_ALIGNED16(MIN_MAX_MASK2[4]) = {0x00000000, 0x40000000, 0x00000000, 0x40000000}; + +// Warning: Modifies xmmT1 and xmmT2 +void MIN_MAX_(x86SSERegType to, x86SSERegType from, bool min) { + + // ZW + SSE2_PSHUFD_XMM_to_XMM(xmmT1, to, 0xfa); + SSE2_PAND_M128_to_XMM (xmmT1, (uptr)MIN_MAX_MASK1); + SSE2_POR_M128_to_XMM (xmmT1, (uptr)MIN_MAX_MASK2); + SSE2_PSHUFD_XMM_to_XMM(xmmT2, from, 0xfa); + SSE2_PAND_M128_to_XMM (xmmT2, (uptr)MIN_MAX_MASK1); + SSE2_POR_M128_to_XMM (xmmT2, (uptr)MIN_MAX_MASK2); + if (min) SSE2_MINPD_XMM_to_XMM(xmmT1, xmmT2); + else SSE2_MAXPD_XMM_to_XMM(xmmT1, xmmT2); + + // XY + SSE2_PSHUFD_XMM_to_XMM(xmmT2, from, 0x50); + SSE2_PAND_M128_to_XMM (xmmT2, (uptr)MIN_MAX_MASK1); + SSE2_POR_M128_to_XMM (xmmT2, (uptr)MIN_MAX_MASK2); + SSE2_PSHUFD_XMM_to_XMM(to, to, 0x50); + SSE2_PAND_M128_to_XMM (to, (uptr)MIN_MAX_MASK1); + SSE2_POR_M128_to_XMM (to, (uptr)MIN_MAX_MASK2); + if (min) SSE2_MINPD_XMM_to_XMM(to, xmmT2); + else SSE2_MAXPD_XMM_to_XMM(to, xmmT2); + + SSE_SHUFPS_XMM_to_XMM(to, xmmT1, 0x88); +} + +// Warning: Modifies from and to's upper 3 vectors +void MIN_MAX_SS(x86SSERegType to, x86SSERegType from, bool min) { + SSE_SHUFPS_XMM_to_XMM (to, from, 0); + SSE2_PAND_M128_to_XMM (to, (uptr)MIN_MAX_MASK1); + SSE2_POR_M128_to_XMM (to, (uptr)MIN_MAX_MASK2); + SSE2_PSHUFD_XMM_to_XMM(from, to, 0xee); + if (min) SSE2_MINPD_XMM_to_XMM(to, from); + else SSE2_MAXPD_XMM_to_XMM(to, from); +} + +void SSE_MAX2PS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { + if (CHECK_VU_MINMAXHACK) { SSE_MAXPS_XMM_to_XMM(to, from); } + else { MIN_MAX_(to, from, 0); } +} +void SSE_MIN2PS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { + if (CHECK_VU_MINMAXHACK) { SSE_MINPS_XMM_to_XMM(to, from); } + else { MIN_MAX_(to, from, 1); } +} +void SSE_MAX2SS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { + if (CHECK_VU_MINMAXHACK) { SSE_MAXSS_XMM_to_XMM(to, from); } + else { MIN_MAX_SS(to, from, 0); } +} +void SSE_MIN2SS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { + if (CHECK_VU_MINMAXHACK) { SSE_MINSS_XMM_to_XMM(to, from); } + else { MIN_MAX_SS(to, from, 1); } +} + +// Warning: Modifies all vectors in 'to' and 'from', and Modifies xmmT1 and xmmT2 +void SSE_ADD2SS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { + + if (!CHECK_VUADDSUBHACK) { SSE_ADDSS_XMM_to_XMM(to, from); return; } + u8 *localptr[8]; + + SSE_MOVAPS_XMM_to_XMM(xmmT1, to); + SSE_MOVAPS_XMM_to_XMM(xmmT2, from); + SSE2_MOVD_XMM_to_R(gprT2, to); + SHR32ItoR(gprT2, 23); + SSE2_MOVD_XMM_to_R(gprT1, from); + SHR32ItoR(gprT1, 23); + AND32ItoR(gprT2, 0xff); + AND32ItoR(gprT1, 0xff); + SUB32RtoR(gprT2, gprT1); //gprT2 = exponent difference + + CMP32ItoR(gprT2, 25); + localptr[0] = JGE8(0); + CMP32ItoR(gprT2, 0); + localptr[1] = JG8(0); + localptr[2] = JE8(0); + CMP32ItoR(gprT2, -25); + localptr[3] = JLE8(0); + NEG32R(gprT2); + DEC32R(gprT2); + MOV32ItoR(gprT1, 0xffffffff); + SHL32CLtoR(gprT1); + SSE2_PCMPEQB_XMM_to_XMM(to, to); + SSE2_MOVD_R_to_XMM(from, gprT1); + SSE_MOVSS_XMM_to_XMM(to, from); + SSE2_PCMPEQB_XMM_to_XMM(from, from); + localptr[4] = JMP8(0); + + x86SetJ8(localptr[0]); + MOV32ItoR(gprT1, 0x80000000); + SSE2_PCMPEQB_XMM_to_XMM(from, from); + SSE2_MOVD_R_to_XMM(to, gprT1); + SSE_MOVSS_XMM_to_XMM(from, to); + SSE2_PCMPEQB_XMM_to_XMM(to, to); + localptr[5] = JMP8(0); + + x86SetJ8(localptr[1]); + DEC32R(gprT2); + MOV32ItoR(gprT1, 0xffffffff); + SHL32CLtoR(gprT1); + SSE2_PCMPEQB_XMM_to_XMM(from, from); + SSE2_MOVD_R_to_XMM(to, gprT1); + SSE_MOVSS_XMM_to_XMM(from, to); + SSE2_PCMPEQB_XMM_to_XMM(to, to); + localptr[6] = JMP8(0); + + x86SetJ8(localptr[3]); + MOV32ItoR(gprT1, 0x80000000); + SSE2_PCMPEQB_XMM_to_XMM(to, to); + SSE2_MOVD_R_to_XMM(from, gprT1); + SSE_MOVSS_XMM_to_XMM(to, from); + SSE2_PCMPEQB_XMM_to_XMM(from, from); + localptr[7] = JMP8(0); + + x86SetJ8(localptr[2]); + x86SetJ8(localptr[4]); + x86SetJ8(localptr[5]); + x86SetJ8(localptr[6]); + x86SetJ8(localptr[7]); + + SSE_ANDPS_XMM_to_XMM(to, xmmT1); //to contains mask + SSE_ANDPS_XMM_to_XMM(from, xmmT2); //from contains mask + SSE_ADDSS_XMM_to_XMM(to, from); +} + +// Note: Wrapper function, Tri-Ace Games just need the SS implementation +void SSE_ADD2PS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { + SSE_ADDPS_XMM_to_XMM(to, from); +} + +//------------------------------------------------------------------ +// Micro VU - Custom Quick Search +//------------------------------------------------------------------ + +PCSX2_ALIGNED(0x1000, static u8 mVUsearchXMM[0x1000]); + +// Generates a custom optimized block-search function +// Note: Structs must be 16-byte aligned! (GCC doesn't guarantee this) +void mVUcustomSearch() { + using namespace x86Emitter; + HostSys::MemProtect(mVUsearchXMM, 0x1000, Protect_ReadWrite, false); + memset_8<0xcc,0x1000>(mVUsearchXMM); + xSetPtr(mVUsearchXMM); + + xMOVAPS (xmm0, ptr32[ecx]); + xPCMP.EQD(xmm0, ptr32[edx]); + xMOVAPS (xmm1, ptr32[ecx + 0x10]); + xPCMP.EQD(xmm1, ptr32[edx + 0x10]); + xPAND (xmm0, xmm1); + + xMOVMSKPS(eax, xmm0); + xCMP (eax, 0xf); + xForwardJL8 exitPoint; + + xMOVAPS (xmm0, ptr32[ecx + 0x20]); + xPCMP.EQD(xmm0, ptr32[edx + 0x20]); + xMOVAPS (xmm1, ptr32[ecx + 0x30]); + xPCMP.EQD(xmm1, ptr32[edx + 0x30]); + xPAND (xmm0, xmm1); + + xMOVAPS (xmm2, ptr32[ecx + 0x40]); + xPCMP.EQD(xmm2, ptr32[edx + 0x40]); + xMOVAPS (xmm3, ptr32[ecx + 0x50]); + xPCMP.EQD(xmm3, ptr32[edx + 0x50]); + xPAND (xmm2, xmm3); + + xMOVAPS (xmm4, ptr32[ecx + 0x60]); + xPCMP.EQD(xmm4, ptr32[edx + 0x60]); + xMOVAPS (xmm5, ptr32[ecx + 0x70]); + xPCMP.EQD(xmm5, ptr32[edx + 0x70]); + xPAND (xmm4, xmm5); + + xMOVAPS (xmm6, ptr32[ecx + 0x80]); + xPCMP.EQD(xmm6, ptr32[edx + 0x80]); + xMOVAPS (xmm7, ptr32[ecx + 0x90]); + xPCMP.EQD(xmm7, ptr32[edx + 0x90]); + xPAND (xmm6, xmm7); + + xPAND (xmm0, xmm2); + xPAND (xmm4, xmm6); + xPAND (xmm0, xmm4); + xMOVMSKPS(eax, xmm0); + + exitPoint.SetTarget(); + xRET(); + HostSys::MemProtect(mVUsearchXMM, 0x1000, Protect_ReadOnly, true ); +} diff --git a/pcsx2/x86/microVU_Tables.inl b/pcsx2/x86/microVU_Tables.inl index 26dc6ea8cd..65ed7e9559 100644 --- a/pcsx2/x86/microVU_Tables.inl +++ b/pcsx2/x86/microVU_Tables.inl @@ -1,1084 +1,244 @@ /* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2009 Pcsx2-Playground Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have meived a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ + * Copyright (C) 2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #pragma once -#ifdef PCSX2_MICROVU //------------------------------------------------------------------ // Declarations //------------------------------------------------------------------ -#define mVUgetCode (vuIndex ? microVU1.code : microVU0.code) +#define mVUgetCode (mVU->code) -microVUf(void) mVU_UPPER_FD_00(); -microVUf(void) mVU_UPPER_FD_01(); -microVUf(void) mVU_UPPER_FD_10(); -microVUf(void) mVU_UPPER_FD_11(); -microVUf(void) mVULowerOP(); -microVUf(void) mVULowerOP_T3_00(); -microVUf(void) mVULowerOP_T3_01(); -microVUf(void) mVULowerOP_T3_10(); -microVUf(void) mVULowerOP_T3_11(); -microVUf(void) mVUunknown(); +mVUop(mVU_UPPER_FD_00); +mVUop(mVU_UPPER_FD_01); +mVUop(mVU_UPPER_FD_10); +mVUop(mVU_UPPER_FD_11); +mVUop(mVULowerOP); +mVUop(mVULowerOP_T3_00); +mVUop(mVULowerOP_T3_01); +mVUop(mVULowerOP_T3_10); +mVUop(mVULowerOP_T3_11); +mVUop(mVUunknown); //------------------------------------------------------------------ //------------------------------------------------------------------ -// mVULOWER_OPCODE +// Opcode Tables //------------------------------------------------------------------ -void (* mVULOWER_OPCODE00 [128])() = { - mVU_LQ<0,0> , mVU_SQ<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVU_ILW<0,0> , mVU_ISW<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVU_IADDIU<0,0> , mVU_ISUBIU<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVU_FCEQ<0,0> , mVU_FCSET<0,0> , mVU_FCAND<0,0> , mVU_FCOR<0,0>, /* 0x10 */ - mVU_FSEQ<0,0> , mVU_FSSET<0,0> , mVU_FSAND<0,0> , mVU_FSOR<0,0>, - mVU_FMEQ<0,0> , mVUunknown<0,0> , mVU_FMAND<0,0> , mVU_FMOR<0,0>, - mVU_FCGET<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVU_B<0,0> , mVU_BAL<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x20 */ - mVU_JR<0,0> , mVU_JALR<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVU_IBEQ<0,0> , mVU_IBNE<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVU_IBLTZ<0,0> , mVU_IBGTZ<0,0> , mVU_IBLEZ<0,0> , mVU_IBGEZ<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x30 */ - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVULowerOP<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x40*/ - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x50 */ - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x60 */ - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x70 */ - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, +#define microVU_LOWER_OPCODE(x) void (*mVULOWER_OPCODE##x [128])(mP) = { \ + mVU_LQ , mVU_SQ , mVUunknown , mVUunknown, \ + mVU_ILW , mVU_ISW , mVUunknown , mVUunknown, \ + mVU_IADDIU , mVU_ISUBIU , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVU_FCEQ , mVU_FCSET , mVU_FCAND , mVU_FCOR, /* 0x10 */ \ + mVU_FSEQ , mVU_FSSET , mVU_FSAND , mVU_FSOR, \ + mVU_FMEQ , mVUunknown , mVU_FMAND , mVU_FMOR, \ + mVU_FCGET , mVUunknown , mVUunknown , mVUunknown, \ + mVU_B , mVU_BAL , mVUunknown , mVUunknown, /* 0x20 */ \ + mVU_JR , mVU_JALR , mVUunknown , mVUunknown, \ + mVU_IBEQ , mVU_IBNE , mVUunknown , mVUunknown, \ + mVU_IBLTZ , mVU_IBGTZ , mVU_IBLEZ , mVU_IBGEZ, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x30 */ \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVULowerOP , mVUunknown , mVUunknown , mVUunknown, /* 0x40*/ \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x50 */ \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x60 */ \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x70 */ \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ }; -void (* mVULOWER_OPCODE01 [128])() = { - mVU_LQ<0,1> , mVU_SQ<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVU_ILW<0,1> , mVU_ISW<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVU_IADDIU<0,1> , mVU_ISUBIU<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVU_FCEQ<0,1> , mVU_FCSET<0,1> , mVU_FCAND<0,1> , mVU_FCOR<0,1>, /* 0x10 */ - mVU_FSEQ<0,1> , mVU_FSSET<0,1> , mVU_FSAND<0,1> , mVU_FSOR<0,1>, - mVU_FMEQ<0,1> , mVUunknown<0,1> , mVU_FMAND<0,1> , mVU_FMOR<0,1>, - mVU_FCGET<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVU_B<0,1> , mVU_BAL<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x20 */ - mVU_JR<0,1> , mVU_JALR<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVU_IBEQ<0,1> , mVU_IBNE<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVU_IBLTZ<0,1> , mVU_IBGTZ<0,1> , mVU_IBLEZ<0,1> , mVU_IBGEZ<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x30 */ - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVULowerOP<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x40*/ - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x50 */ - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x60 */ - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x70 */ - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, +#define microVU_LowerOP_T3_00_OPCODE(x) void (*mVULowerOP_T3_00_OPCODE##x [32])(mP) = { \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVU_MOVE , mVU_LQI , mVU_DIV , mVU_MTIR, \ + mVU_RNEXT , mVUunknown , mVUunknown , mVUunknown, /* 0x10 */ \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVU_MFP , mVU_XTOP , mVU_XGKICK, \ + mVU_ESADD , mVU_EATANxy , mVU_ESQRT , mVU_ESIN, \ }; -void (* mVULOWER_OPCODE10 [128])() = { - mVU_LQ<1,0> , mVU_SQ<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVU_ILW<1,0> , mVU_ISW<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVU_IADDIU<1,0> , mVU_ISUBIU<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVU_FCEQ<1,0> , mVU_FCSET<1,0> , mVU_FCAND<1,0> , mVU_FCOR<1,0>, /* 0x10 */ - mVU_FSEQ<1,0> , mVU_FSSET<1,0> , mVU_FSAND<1,0> , mVU_FSOR<1,0>, - mVU_FMEQ<1,0> , mVUunknown<1,0> , mVU_FMAND<1,0> , mVU_FMOR<1,0>, - mVU_FCGET<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVU_B<1,0> , mVU_BAL<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x20 */ - mVU_JR<1,0> , mVU_JALR<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVU_IBEQ<1,0> , mVU_IBNE<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVU_IBLTZ<1,0> , mVU_IBGTZ<1,0> , mVU_IBLEZ<1,0> , mVU_IBGEZ<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x30 */ - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVULowerOP<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x40*/ - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x50 */ - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x60 */ - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x70 */ - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, +#define microVU_LowerOP_T3_01_OPCODE(x) void (*mVULowerOP_T3_01_OPCODE##x [32])(mP) = { \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVU_MR32 , mVU_SQI , mVU_SQRT , mVU_MFIR, \ + mVU_RGET , mVUunknown , mVUunknown , mVUunknown, /* 0x10 */ \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVU_XITOP , mVUunknown, \ + mVU_ERSADD , mVU_EATANxz , mVU_ERSQRT , mVU_EATAN, \ }; -void (* mVULOWER_OPCODE11 [128])() = { - mVU_LQ<1,1> , mVU_SQ<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVU_ILW<1,1> , mVU_ISW<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVU_IADDIU<1,1> , mVU_ISUBIU<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVU_FCEQ<1,1> , mVU_FCSET<1,1> , mVU_FCAND<1,1> , mVU_FCOR<1,1>, /* 0x10 */ - mVU_FSEQ<1,1> , mVU_FSSET<1,1> , mVU_FSAND<1,1> , mVU_FSOR<1,1>, - mVU_FMEQ<1,1> , mVUunknown<1,1> , mVU_FMAND<1,1> , mVU_FMOR<1,1>, - mVU_FCGET<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVU_B<1,1> , mVU_BAL<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x20 */ - mVU_JR<1,1> , mVU_JALR<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVU_IBEQ<1,1> , mVU_IBNE<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVU_IBLTZ<1,1> , mVU_IBGTZ<1,1> , mVU_IBLEZ<1,1> , mVU_IBGEZ<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x30 */ - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVULowerOP<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x40*/ - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x50 */ - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x60 */ - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x70 */ - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, +#define microVU_LowerOP_T3_10_OPCODE(x) void (*mVULowerOP_T3_10_OPCODE##x [32])(mP) = { \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVU_LQD , mVU_RSQRT , mVU_ILWR, \ + mVU_RINIT , mVUunknown , mVUunknown , mVUunknown, /* 0x10 */ \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVU_ELENG , mVU_ESUM , mVU_ERCPR , mVU_EEXP, \ }; -void (* mVULOWER_OPCODE02 [128])() = { - mVU_LQ<0,2> , mVU_SQ<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVU_ILW<0,2> , mVU_ISW<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVU_IADDIU<0,2> , mVU_ISUBIU<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVU_FCEQ<0,2> , mVU_FCSET<0,2> , mVU_FCAND<0,2> , mVU_FCOR<0,2>, /* 0x10 */ - mVU_FSEQ<0,2> , mVU_FSSET<0,2> , mVU_FSAND<0,2> , mVU_FSOR<0,2>, - mVU_FMEQ<0,2> , mVUunknown<0,2> , mVU_FMAND<0,2> , mVU_FMOR<0,2>, - mVU_FCGET<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVU_B<0,2> , mVU_BAL<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x20 */ - mVU_JR<0,2> , mVU_JALR<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVU_IBEQ<0,2> , mVU_IBNE<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVU_IBLTZ<0,2> , mVU_IBGTZ<0,2> , mVU_IBLEZ<0,2> , mVU_IBGEZ<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x30 */ - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVULowerOP<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x40*/ - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x50 */ - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x60 */ - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x70 */ - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, +#define microVU_LowerOP_T3_11_OPCODE(x) void (*mVULowerOP_T3_11_OPCODE##x [32])(mP) = { \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVU_SQD , mVU_WAITQ , mVU_ISWR, \ + mVU_RXOR , mVUunknown , mVUunknown , mVUunknown, /* 0x10 */ \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVU_ERLENG , mVUunknown , mVU_WAITP , mVUunknown, \ }; -void (* mVULOWER_OPCODE12 [128])() = { - mVU_LQ<1,2> , mVU_SQ<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVU_ILW<1,2> , mVU_ISW<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVU_IADDIU<1,2> , mVU_ISUBIU<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVU_FCEQ<1,2> , mVU_FCSET<1,2> , mVU_FCAND<1,2> , mVU_FCOR<1,2>, /* 0x10 */ - mVU_FSEQ<1,2> , mVU_FSSET<1,2> , mVU_FSAND<1,2> , mVU_FSOR<1,2>, - mVU_FMEQ<1,2> , mVUunknown<1,2> , mVU_FMAND<1,2> , mVU_FMOR<1,2>, - mVU_FCGET<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVU_B<1,2> , mVU_BAL<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x20 */ - mVU_JR<1,2> , mVU_JALR<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVU_IBEQ<1,2> , mVU_IBNE<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVU_IBLTZ<1,2> , mVU_IBGTZ<1,2> , mVU_IBLEZ<1,2> , mVU_IBGEZ<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x30 */ - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVULowerOP<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x40*/ - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x50 */ - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x60 */ - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x70 */ - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, -}; -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// mVULowerOP_T3_00_OPCODE -//------------------------------------------------------------------ -void (* mVULowerOP_T3_00_OPCODE00 [32])() = { - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVU_MOVE<0,0> , mVU_LQI<0,0> , mVU_DIV<0,0> , mVU_MTIR<0,0>, - mVU_RNEXT<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x10 */ - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVU_MFP<0,0> , mVU_XTOP<0,0> , mVU_XGKICK<0,0>, - mVU_ESADD<0,0> , mVU_EATANxy<0,0> , mVU_ESQRT<0,0> , mVU_ESIN<0,0>, +#define microVU_LowerOP_OPCODE(x) void (*mVULowerOP_OPCODE##x [64])(mP) = { \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x10 */ \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x20 */ \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVU_IADD , mVU_ISUB , mVU_IADDI , mVUunknown, /* 0x30 */ \ + mVU_IAND , mVU_IOR , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVULowerOP_T3_00, mVULowerOP_T3_01, mVULowerOP_T3_10, mVULowerOP_T3_11, \ }; -void (* mVULowerOP_T3_00_OPCODE01 [32])() = { - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVU_MOVE<0,1> , mVU_LQI<0,1> , mVU_DIV<0,1> , mVU_MTIR<0,1>, - mVU_RNEXT<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x10 */ - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVU_MFP<0,1> , mVU_XTOP<0,1> , mVU_XGKICK<0,1>, - mVU_ESADD<0,1> , mVU_EATANxy<0,1> , mVU_ESQRT<0,1> , mVU_ESIN<0,1>, +#define microVU_UPPER_OPCODE(x) void (*mVU_UPPER_OPCODE##x [64])(mP) = { \ + mVU_ADDx , mVU_ADDy , mVU_ADDz , mVU_ADDw, \ + mVU_SUBx , mVU_SUBy , mVU_SUBz , mVU_SUBw, \ + mVU_MADDx , mVU_MADDy , mVU_MADDz , mVU_MADDw, \ + mVU_MSUBx , mVU_MSUBy , mVU_MSUBz , mVU_MSUBw, \ + mVU_MAXx , mVU_MAXy , mVU_MAXz , mVU_MAXw, /* 0x10 */ \ + mVU_MINIx , mVU_MINIy , mVU_MINIz , mVU_MINIw, \ + mVU_MULx , mVU_MULy , mVU_MULz , mVU_MULw, \ + mVU_MULq , mVU_MAXi , mVU_MULi , mVU_MINIi, \ + mVU_ADDq , mVU_MADDq , mVU_ADDi , mVU_MADDi, /* 0x20 */ \ + mVU_SUBq , mVU_MSUBq , mVU_SUBi , mVU_MSUBi, \ + mVU_ADD , mVU_MADD , mVU_MUL , mVU_MAX, \ + mVU_SUB , mVU_MSUB , mVU_OPMSUB , mVU_MINI, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x30 */ \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVU_UPPER_FD_00, mVU_UPPER_FD_01, mVU_UPPER_FD_10, mVU_UPPER_FD_11, \ }; -void (* mVULowerOP_T3_00_OPCODE10 [32])() = { - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVU_MOVE<1,0> , mVU_LQI<1,0> , mVU_DIV<1,0> , mVU_MTIR<1,0>, - mVU_RNEXT<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x10 */ - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVU_MFP<1,0> , mVU_XTOP<1,0> , mVU_XGKICK<1,0>, - mVU_ESADD<1,0> , mVU_EATANxy<1,0> , mVU_ESQRT<1,0> , mVU_ESIN<1,0>, +#define microVU_UPPER_FD_00_TABLE(x) void (*mVU_UPPER_FD_00_TABLE##x [32])(mP) = { \ + mVU_ADDAx , mVU_SUBAx , mVU_MADDAx , mVU_MSUBAx, \ + mVU_ITOF0 , mVU_FTOI0 , mVU_MULAx , mVU_MULAq, \ + mVU_ADDAq , mVU_SUBAq , mVU_ADDA , mVU_SUBA, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ }; -void (* mVULowerOP_T3_00_OPCODE11 [32])() = { - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVU_MOVE<1,1> , mVU_LQI<1,1> , mVU_DIV<1,1> , mVU_MTIR<1,1>, - mVU_RNEXT<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x10 */ - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVU_MFP<1,1> , mVU_XTOP<1,1> , mVU_XGKICK<1,1>, - mVU_ESADD<1,1> , mVU_EATANxy<1,1> , mVU_ESQRT<1,1> , mVU_ESIN<1,1>, +#define microVU_UPPER_FD_01_TABLE(x) void (* mVU_UPPER_FD_01_TABLE##x [32])(mP) = { \ + mVU_ADDAy , mVU_SUBAy , mVU_MADDAy , mVU_MSUBAy, \ + mVU_ITOF4 , mVU_FTOI4 , mVU_MULAy , mVU_ABS, \ + mVU_MADDAq , mVU_MSUBAq , mVU_MADDA , mVU_MSUBA, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ }; -void (* mVULowerOP_T3_00_OPCODE02 [32])() = { - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVU_MOVE<0,2> , mVU_LQI<0,2> , mVU_DIV<0,2> , mVU_MTIR<0,2>, - mVU_RNEXT<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x10 */ - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVU_MFP<0,2> , mVU_XTOP<0,2> , mVU_XGKICK<0,2>, - mVU_ESADD<0,2> , mVU_EATANxy<0,2> , mVU_ESQRT<0,2> , mVU_ESIN<0,2>, +#define microVU_UPPER_FD_10_TABLE(x) void (* mVU_UPPER_FD_10_TABLE##x [32])(mP) = { \ + mVU_ADDAz , mVU_SUBAz , mVU_MADDAz , mVU_MSUBAz, \ + mVU_ITOF12 , mVU_FTOI12 , mVU_MULAz , mVU_MULAi, \ + mVU_ADDAi , mVU_SUBAi , mVU_MULA , mVU_OPMULA, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ }; -void (* mVULowerOP_T3_00_OPCODE12 [32])() = { - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVU_MOVE<1,2> , mVU_LQI<1,2> , mVU_DIV<1,2> , mVU_MTIR<1,2>, - mVU_RNEXT<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x10 */ - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVU_MFP<1,2> , mVU_XTOP<1,2> , mVU_XGKICK<1,2>, - mVU_ESADD<1,2> , mVU_EATANxy<1,2> , mVU_ESQRT<1,2> , mVU_ESIN<1,2>, -}; -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// mVULowerOP_T3_01_OPCODE -//------------------------------------------------------------------ -void (* mVULowerOP_T3_01_OPCODE00 [32])() = { - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVU_MR32<0,0> , mVU_SQI<0,0> , mVU_SQRT<0,0> , mVU_MFIR<0,0>, - mVU_RGET<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x10 */ - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVU_XITOP<0,0> , mVUunknown<0,0>, - mVU_ERSADD<0,0> , mVU_EATANxz<0,0> , mVU_ERSQRT<0,0> , mVU_EATAN<0,0>, -}; - -void (* mVULowerOP_T3_01_OPCODE01 [32])() = { - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVU_MR32<0,1> , mVU_SQI<0,1> , mVU_SQRT<0,1> , mVU_MFIR<0,1>, - mVU_RGET<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x10 */ - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVU_XITOP<0,1> , mVUunknown<0,1>, - mVU_ERSADD<0,1> , mVU_EATANxz<0,1> , mVU_ERSQRT<0,1> , mVU_EATAN<0,1>, -}; - -void (* mVULowerOP_T3_01_OPCODE10 [32])() = { - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVU_MR32<1,0> , mVU_SQI<1,0> , mVU_SQRT<1,0> , mVU_MFIR<1,0>, - mVU_RGET<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x10 */ - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVU_XITOP<1,0> , mVUunknown<1,0>, - mVU_ERSADD<1,0> , mVU_EATANxz<1,0> , mVU_ERSQRT<1,0> , mVU_EATAN<1,0>, -}; - -void (* mVULowerOP_T3_01_OPCODE11 [32])() = { - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVU_MR32<1,1> , mVU_SQI<1,1> , mVU_SQRT<1,1> , mVU_MFIR<1,1>, - mVU_RGET<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x10 */ - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVU_XITOP<1,1> , mVUunknown<1,1>, - mVU_ERSADD<1,1> , mVU_EATANxz<1,1> , mVU_ERSQRT<1,1> , mVU_EATAN<1,1>, -}; - -void (* mVULowerOP_T3_01_OPCODE02 [32])() = { - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVU_MR32<0,2> , mVU_SQI<0,2> , mVU_SQRT<0,2> , mVU_MFIR<0,2>, - mVU_RGET<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x10 */ - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVU_XITOP<0,2> , mVUunknown<0,2>, - mVU_ERSADD<0,2> , mVU_EATANxz<0,2> , mVU_ERSQRT<0,2> , mVU_EATAN<0,2>, -}; - -void (* mVULowerOP_T3_01_OPCODE12 [32])() = { - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVU_MR32<1,2> , mVU_SQI<1,2> , mVU_SQRT<1,2> , mVU_MFIR<1,2>, - mVU_RGET<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x10 */ - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVU_XITOP<1,2> , mVUunknown<1,2>, - mVU_ERSADD<1,2> , mVU_EATANxz<1,2> , mVU_ERSQRT<1,2> , mVU_EATAN<1,2>, +#define microVU_UPPER_FD_11_TABLE(x) void (* mVU_UPPER_FD_11_TABLE##x [32])(mP) = { \ + mVU_ADDAw , mVU_SUBAw , mVU_MADDAw , mVU_MSUBAw, \ + mVU_ITOF15 , mVU_FTOI15 , mVU_MULAw , mVU_CLIP, \ + mVU_MADDAi , mVU_MSUBAi , mVUunknown , mVU_NOP, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ + mVUunknown , mVUunknown , mVUunknown , mVUunknown, \ }; //------------------------------------------------------------------ //------------------------------------------------------------------ -// mVULowerOP_T3_10_OPCODE +// Create Table Instances //------------------------------------------------------------------ -void (* mVULowerOP_T3_10_OPCODE00 [32])() = { - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVU_LQD<0,0> , mVU_RSQRT<0,0> , mVU_ILWR<0,0>, - mVU_RINIT<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x10 */ - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVU_ELENG<0,0> , mVU_ESUM<0,0> , mVU_ERCPR<0,0> , mVU_EEXP<0,0>, -}; +#define mVUcreateTable(x) \ +microVU_LOWER_OPCODE(x) \ +microVU_LowerOP_T3_00_OPCODE(x) \ +microVU_LowerOP_T3_01_OPCODE(x) \ +microVU_LowerOP_T3_10_OPCODE(x) \ +microVU_LowerOP_T3_11_OPCODE(x) \ +microVU_LowerOP_OPCODE(x) \ +microVU_UPPER_OPCODE(x) \ +microVU_UPPER_FD_00_TABLE(x) \ +microVU_UPPER_FD_01_TABLE(x) \ +microVU_UPPER_FD_10_TABLE(x) \ +microVU_UPPER_FD_11_TABLE(x) -void (* mVULowerOP_T3_10_OPCODE01 [32])() = { - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVU_LQD<0,1> , mVU_RSQRT<0,1> , mVU_ILWR<0,1>, - mVU_RINIT<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x10 */ - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVU_ELENG<0,1> , mVU_ESUM<0,1> , mVU_ERCPR<0,1> , mVU_EEXP<0,1>, -}; - -void (* mVULowerOP_T3_10_OPCODE10 [32])() = { - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVU_LQD<1,0> , mVU_RSQRT<1,0> , mVU_ILWR<1,0>, - mVU_RINIT<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x10 */ - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVU_ELENG<1,0> , mVU_ESUM<1,0> , mVU_ERCPR<1,0> , mVU_EEXP<1,0>, -}; - -void (* mVULowerOP_T3_10_OPCODE11 [32])() = { - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVU_LQD<1,1> , mVU_RSQRT<1,1> , mVU_ILWR<1,1>, - mVU_RINIT<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x10 */ - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVU_ELENG<1,1> , mVU_ESUM<1,1> , mVU_ERCPR<1,1> , mVU_EEXP<1,1>, -}; - -void (* mVULowerOP_T3_10_OPCODE02 [32])() = { - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVU_LQD<0,2> , mVU_RSQRT<0,2> , mVU_ILWR<0,2>, - mVU_RINIT<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x10 */ - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVU_ELENG<0,2> , mVU_ESUM<0,2> , mVU_ERCPR<0,2> , mVU_EEXP<0,2>, -}; - -void (* mVULowerOP_T3_10_OPCODE12 [32])() = { - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVU_LQD<1,2> , mVU_RSQRT<1,2> , mVU_ILWR<1,2>, - mVU_RINIT<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x10 */ - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVU_ELENG<1,2> , mVU_ESUM<1,2> , mVU_ERCPR<1,2> , mVU_EEXP<1,2>, -}; -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// mVULowerOP_T3_11_OPCODE -//------------------------------------------------------------------ -void (* mVULowerOP_T3_11_OPCODE00 [32])() = { - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVU_SQD<0,0> , mVU_WAITQ<0,0> , mVU_ISWR<0,0>, - mVU_RXOR<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x10 */ - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVU_ERLENG<0,0> , mVUunknown<0,0> , mVU_WAITP<0,0> , mVUunknown<0,0>, -}; - -void (* mVULowerOP_T3_11_OPCODE01 [32])() = { - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVU_SQD<0,1> , mVU_WAITQ<0,1> , mVU_ISWR<0,1>, - mVU_RXOR<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x10 */ - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVU_ERLENG<0,1> , mVUunknown<0,1> , mVU_WAITP<0,1> , mVUunknown<0,1>, -}; - -void (* mVULowerOP_T3_11_OPCODE10 [32])() = { - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVU_SQD<1,0> , mVU_WAITQ<1,0> , mVU_ISWR<1,0>, - mVU_RXOR<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x10 */ - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVU_ERLENG<1,0> , mVUunknown<1,0> , mVU_WAITP<1,0> , mVUunknown<1,0>, -}; - -void (* mVULowerOP_T3_11_OPCODE11 [32])() = { - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVU_SQD<1,1> , mVU_WAITQ<1,1> , mVU_ISWR<1,1>, - mVU_RXOR<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x10 */ - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVU_ERLENG<1,1> , mVUunknown<1,1> , mVU_WAITP<1,1> , mVUunknown<1,1>, -}; - -void (* mVULowerOP_T3_11_OPCODE02 [32])() = { - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVU_SQD<0,2> , mVU_WAITQ<0,2> , mVU_ISWR<0,2>, - mVU_RXOR<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x10 */ - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVU_ERLENG<0,2> , mVUunknown<0,2> , mVU_WAITP<0,2> , mVUunknown<0,2>, -}; - -void (* mVULowerOP_T3_11_OPCODE12 [32])() = { - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVU_SQD<1,2> , mVU_WAITQ<1,2> , mVU_ISWR<1,2>, - mVU_RXOR<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x10 */ - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVU_ERLENG<1,2> , mVUunknown<1,2> , mVU_WAITP<1,2> , mVUunknown<1,2>, -}; -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// mVULowerOP_OPCODE -//------------------------------------------------------------------ -void (* mVULowerOP_OPCODE00 [64])() = { - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x10 */ - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x20 */ - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVU_IADD<0,0> , mVU_ISUB<0,0> , mVU_IADDI<0,0> , mVUunknown<0,0>, /* 0x30 */ - mVU_IAND<0,0> , mVU_IOR<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVULowerOP_T3_00<0,0>, mVULowerOP_T3_01<0,0>, mVULowerOP_T3_10<0,0>, mVULowerOP_T3_11<0,0>, -}; - -void (* mVULowerOP_OPCODE01 [64])() = { - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x10 */ - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x20 */ - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVU_IADD<0,1> , mVU_ISUB<0,1> , mVU_IADDI<0,1> , mVUunknown<0,1>, /* 0x30 */ - mVU_IAND<0,1> , mVU_IOR<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVULowerOP_T3_00<0,1>, mVULowerOP_T3_01<0,1>, mVULowerOP_T3_10<0,1>, mVULowerOP_T3_11<0,1>, -}; - -void (* mVULowerOP_OPCODE10 [64])() = { - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x10 */ - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x20 */ - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVU_IADD<1,0> , mVU_ISUB<1,0> , mVU_IADDI<1,0> , mVUunknown<1,0>, /* 0x30 */ - mVU_IAND<1,0> , mVU_IOR<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVULowerOP_T3_00<1,0>, mVULowerOP_T3_01<1,0>, mVULowerOP_T3_10<1,0>, mVULowerOP_T3_11<1,0>, -}; - -void (* mVULowerOP_OPCODE11 [64])() = { - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x10 */ - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x20 */ - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVU_IADD<1,1> , mVU_ISUB<1,1> , mVU_IADDI<1,1> , mVUunknown<1,1>, /* 0x30 */ - mVU_IAND<1,1> , mVU_IOR<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVULowerOP_T3_00<1,1>, mVULowerOP_T3_01<1,1>, mVULowerOP_T3_10<1,1>, mVULowerOP_T3_11<1,1>, -}; - -void (* mVULowerOP_OPCODE02 [64])() = { - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x10 */ - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x20 */ - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVU_IADD<0,2> , mVU_ISUB<0,2> , mVU_IADDI<0,2> , mVUunknown<0,2>, /* 0x30 */ - mVU_IAND<0,2> , mVU_IOR<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVULowerOP_T3_00<0,2>, mVULowerOP_T3_01<0,2>, mVULowerOP_T3_10<0,2>, mVULowerOP_T3_11<0,2>, -}; - -void (* mVULowerOP_OPCODE12 [64])() = { - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x10 */ - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x20 */ - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVU_IADD<1,2> , mVU_ISUB<1,2> , mVU_IADDI<1,2> , mVUunknown<1,2>, /* 0x30 */ - mVU_IAND<1,2> , mVU_IOR<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVULowerOP_T3_00<1,2>, mVULowerOP_T3_01<1,2>, mVULowerOP_T3_10<1,2>, mVULowerOP_T3_11<1,2>, -}; -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// mVU_UPPER_OPCODE -//------------------------------------------------------------------ -void (* mVU_UPPER_OPCODE00 [64])() = { - mVU_ADDx<0,0> , mVU_ADDy<0,0> , mVU_ADDz<0,0> , mVU_ADDw<0,0>, - mVU_SUBx<0,0> , mVU_SUBy<0,0> , mVU_SUBz<0,0> , mVU_SUBw<0,0>, - mVU_MADDx<0,0> , mVU_MADDy<0,0> , mVU_MADDz<0,0> , mVU_MADDw<0,0>, - mVU_MSUBx<0,0> , mVU_MSUBy<0,0> , mVU_MSUBz<0,0> , mVU_MSUBw<0,0>, - mVU_MAXx<0,0> , mVU_MAXy<0,0> , mVU_MAXz<0,0> , mVU_MAXw<0,0>, /* 0x10 */ - mVU_MINIx<0,0> , mVU_MINIy<0,0> , mVU_MINIz<0,0> , mVU_MINIw<0,0>, - mVU_MULx<0,0> , mVU_MULy<0,0> , mVU_MULz<0,0> , mVU_MULw<0,0>, - mVU_MULq<0,0> , mVU_MAXi<0,0> , mVU_MULi<0,0> , mVU_MINIi<0,0>, - mVU_ADDq<0,0> , mVU_MADDq<0,0> , mVU_ADDi<0,0> , mVU_MADDi<0,0>, /* 0x20 */ - mVU_SUBq<0,0> , mVU_MSUBq<0,0> , mVU_SUBi<0,0> , mVU_MSUBi<0,0>, - mVU_ADD<0,0> , mVU_MADD<0,0> , mVU_MUL<0,0> , mVU_MAX<0,0>, - mVU_SUB<0,0> , mVU_MSUB<0,0> , mVU_OPMSUB<0,0> , mVU_MINI<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, /* 0x30 */ - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVU_UPPER_FD_00<0,0>, mVU_UPPER_FD_01<0,0>, mVU_UPPER_FD_10<0,0>, mVU_UPPER_FD_11<0,0>, -}; - -void (* mVU_UPPER_OPCODE01 [64])() = { - mVU_ADDx<0,1> , mVU_ADDy<0,1> , mVU_ADDz<0,1> , mVU_ADDw<0,1>, - mVU_SUBx<0,1> , mVU_SUBy<0,1> , mVU_SUBz<0,1> , mVU_SUBw<0,1>, - mVU_MADDx<0,1> , mVU_MADDy<0,1> , mVU_MADDz<0,1> , mVU_MADDw<0,1>, - mVU_MSUBx<0,1> , mVU_MSUBy<0,1> , mVU_MSUBz<0,1> , mVU_MSUBw<0,1>, - mVU_MAXx<0,1> , mVU_MAXy<0,1> , mVU_MAXz<0,1> , mVU_MAXw<0,1>, /* 0x10 */ - mVU_MINIx<0,1> , mVU_MINIy<0,1> , mVU_MINIz<0,1> , mVU_MINIw<0,1>, - mVU_MULx<0,1> , mVU_MULy<0,1> , mVU_MULz<0,1> , mVU_MULw<0,1>, - mVU_MULq<0,1> , mVU_MAXi<0,1> , mVU_MULi<0,1> , mVU_MINIi<0,1>, - mVU_ADDq<0,1> , mVU_MADDq<0,1> , mVU_ADDi<0,1> , mVU_MADDi<0,1>, /* 0x20 */ - mVU_SUBq<0,1> , mVU_MSUBq<0,1> , mVU_SUBi<0,1> , mVU_MSUBi<0,1>, - mVU_ADD<0,1> , mVU_MADD<0,1> , mVU_MUL<0,1> , mVU_MAX<0,1>, - mVU_SUB<0,1> , mVU_MSUB<0,1> , mVU_OPMSUB<0,1> , mVU_MINI<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, /* 0x30 */ - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVU_UPPER_FD_00<0,1>, mVU_UPPER_FD_01<0,1>, mVU_UPPER_FD_10<0,1>, mVU_UPPER_FD_11<0,1>, -}; - -void (* mVU_UPPER_OPCODE10 [64])() = { - mVU_ADDx<1,0> , mVU_ADDy<1,0> , mVU_ADDz<1,0> , mVU_ADDw<1,0>, - mVU_SUBx<1,0> , mVU_SUBy<1,0> , mVU_SUBz<1,0> , mVU_SUBw<1,0>, - mVU_MADDx<1,0> , mVU_MADDy<1,0> , mVU_MADDz<1,0> , mVU_MADDw<1,0>, - mVU_MSUBx<1,0> , mVU_MSUBy<1,0> , mVU_MSUBz<1,0> , mVU_MSUBw<1,0>, - mVU_MAXx<1,0> , mVU_MAXy<1,0> , mVU_MAXz<1,0> , mVU_MAXw<1,0>, /* 0x10 */ - mVU_MINIx<1,0> , mVU_MINIy<1,0> , mVU_MINIz<1,0> , mVU_MINIw<1,0>, - mVU_MULx<1,0> , mVU_MULy<1,0> , mVU_MULz<1,0> , mVU_MULw<1,0>, - mVU_MULq<1,0> , mVU_MAXi<1,0> , mVU_MULi<1,0> , mVU_MINIi<1,0>, - mVU_ADDq<1,0> , mVU_MADDq<1,0> , mVU_ADDi<1,0> , mVU_MADDi<1,0>, /* 0x20 */ - mVU_SUBq<1,0> , mVU_MSUBq<1,0> , mVU_SUBi<1,0> , mVU_MSUBi<1,0>, - mVU_ADD<1,0> , mVU_MADD<1,0> , mVU_MUL<1,0> , mVU_MAX<1,0>, - mVU_SUB<1,0> , mVU_MSUB<1,0> , mVU_OPMSUB<1,0> , mVU_MINI<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, /* 0x30 */ - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVU_UPPER_FD_00<1,0>, mVU_UPPER_FD_01<1,0>, mVU_UPPER_FD_10<1,0>, mVU_UPPER_FD_11<1,0>, -}; - -void (* mVU_UPPER_OPCODE11 [64])() = { - mVU_ADDx<1,1> , mVU_ADDy<1,1> , mVU_ADDz<1,1> , mVU_ADDw<1,1>, - mVU_SUBx<1,1> , mVU_SUBy<1,1> , mVU_SUBz<1,1> , mVU_SUBw<1,1>, - mVU_MADDx<1,1> , mVU_MADDy<1,1> , mVU_MADDz<1,1> , mVU_MADDw<1,1>, - mVU_MSUBx<1,1> , mVU_MSUBy<1,1> , mVU_MSUBz<1,1> , mVU_MSUBw<1,1>, - mVU_MAXx<1,1> , mVU_MAXy<1,1> , mVU_MAXz<1,1> , mVU_MAXw<1,1>, /* 0x10 */ - mVU_MINIx<1,1> , mVU_MINIy<1,1> , mVU_MINIz<1,1> , mVU_MINIw<1,1>, - mVU_MULx<1,1> , mVU_MULy<1,1> , mVU_MULz<1,1> , mVU_MULw<1,1>, - mVU_MULq<1,1> , mVU_MAXi<1,1> , mVU_MULi<1,1> , mVU_MINIi<1,1>, - mVU_ADDq<1,1> , mVU_MADDq<1,1> , mVU_ADDi<1,1> , mVU_MADDi<1,1>, /* 0x20 */ - mVU_SUBq<1,1> , mVU_MSUBq<1,1> , mVU_SUBi<1,1> , mVU_MSUBi<1,1>, - mVU_ADD<1,1> , mVU_MADD<1,1> , mVU_MUL<1,1> , mVU_MAX<1,1>, - mVU_SUB<1,1> , mVU_MSUB<1,1> , mVU_OPMSUB<1,1> , mVU_MINI<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, /* 0x30 */ - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVU_UPPER_FD_00<1,1>, mVU_UPPER_FD_01<1,1>, mVU_UPPER_FD_10<1,1>, mVU_UPPER_FD_11<1,1>, -}; - -void (* mVU_UPPER_OPCODE02 [64])() = { - mVU_ADDx<0,2> , mVU_ADDy<0,2> , mVU_ADDz<0,2> , mVU_ADDw<0,2>, - mVU_SUBx<0,2> , mVU_SUBy<0,2> , mVU_SUBz<0,2> , mVU_SUBw<0,2>, - mVU_MADDx<0,2> , mVU_MADDy<0,2> , mVU_MADDz<0,2> , mVU_MADDw<0,2>, - mVU_MSUBx<0,2> , mVU_MSUBy<0,2> , mVU_MSUBz<0,2> , mVU_MSUBw<0,2>, - mVU_MAXx<0,2> , mVU_MAXy<0,2> , mVU_MAXz<0,2> , mVU_MAXw<0,2>, /* 0x10 */ - mVU_MINIx<0,2> , mVU_MINIy<0,2> , mVU_MINIz<0,2> , mVU_MINIw<0,2>, - mVU_MULx<0,2> , mVU_MULy<0,2> , mVU_MULz<0,2> , mVU_MULw<0,2>, - mVU_MULq<0,2> , mVU_MAXi<0,2> , mVU_MULi<0,2> , mVU_MINIi<0,2>, - mVU_ADDq<0,2> , mVU_MADDq<0,2> , mVU_ADDi<0,2> , mVU_MADDi<0,2>, /* 0x20 */ - mVU_SUBq<0,2> , mVU_MSUBq<0,2> , mVU_SUBi<0,2> , mVU_MSUBi<0,2>, - mVU_ADD<0,2> , mVU_MADD<0,2> , mVU_MUL<0,2> , mVU_MAX<0,2>, - mVU_SUB<0,2> , mVU_MSUB<0,2> , mVU_OPMSUB<0,2> , mVU_MINI<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, /* 0x30 */ - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVU_UPPER_FD_00<0,2>, mVU_UPPER_FD_01<0,2>, mVU_UPPER_FD_10<0,2>, mVU_UPPER_FD_11<0,2>, -}; - -void (* mVU_UPPER_OPCODE12 [64])() = { - mVU_ADDx<1,2> , mVU_ADDy<1,2> , mVU_ADDz<1,2> , mVU_ADDw<1,2>, - mVU_SUBx<1,2> , mVU_SUBy<1,2> , mVU_SUBz<1,2> , mVU_SUBw<1,2>, - mVU_MADDx<1,2> , mVU_MADDy<1,2> , mVU_MADDz<1,2> , mVU_MADDw<1,2>, - mVU_MSUBx<1,2> , mVU_MSUBy<1,2> , mVU_MSUBz<1,2> , mVU_MSUBw<1,2>, - mVU_MAXx<1,2> , mVU_MAXy<1,2> , mVU_MAXz<1,2> , mVU_MAXw<1,2>, /* 0x10 */ - mVU_MINIx<1,2> , mVU_MINIy<1,2> , mVU_MINIz<1,2> , mVU_MINIw<1,2>, - mVU_MULx<1,2> , mVU_MULy<1,2> , mVU_MULz<1,2> , mVU_MULw<1,2>, - mVU_MULq<1,2> , mVU_MAXi<1,2> , mVU_MULi<1,2> , mVU_MINIi<1,2>, - mVU_ADDq<1,2> , mVU_MADDq<1,2> , mVU_ADDi<1,2> , mVU_MADDi<1,2>, /* 0x20 */ - mVU_SUBq<1,2> , mVU_MSUBq<1,2> , mVU_SUBi<1,2> , mVU_MSUBi<1,2>, - mVU_ADD<1,2> , mVU_MADD<1,2> , mVU_MUL<1,2> , mVU_MAX<1,2>, - mVU_SUB<1,2> , mVU_MSUB<1,2> , mVU_OPMSUB<1,2> , mVU_MINI<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, /* 0x30 */ - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVU_UPPER_FD_00<1,2>, mVU_UPPER_FD_01<1,2>, mVU_UPPER_FD_10<1,2>, mVU_UPPER_FD_11<1,2>, -}; -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// mVU_UPPER_FD_00_TABLE -//------------------------------------------------------------------ -void (* mVU_UPPER_FD_00_TABLE00 [32])() = { - mVU_ADDAx<0,0> , mVU_SUBAx<0,0> , mVU_MADDAx<0,0> , mVU_MSUBAx<0,0>, - mVU_ITOF0<0,0> , mVU_FTOI0<0,0> , mVU_MULAx<0,0> , mVU_MULAq<0,0>, - mVU_ADDAq<0,0> , mVU_SUBAq<0,0> , mVU_ADDA<0,0> , mVU_SUBA<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, -}; - -void (* mVU_UPPER_FD_00_TABLE01 [32])() = { - mVU_ADDAx<0,1> , mVU_SUBAx<0,1> , mVU_MADDAx<0,1> , mVU_MSUBAx<0,1>, - mVU_ITOF0<0,1> , mVU_FTOI0<0,1> , mVU_MULAx<0,1> , mVU_MULAq<0,1>, - mVU_ADDAq<0,1> , mVU_SUBAq<0,1> , mVU_ADDA<0,1> , mVU_SUBA<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, -}; - -void (* mVU_UPPER_FD_00_TABLE10 [32])() = { - mVU_ADDAx<1,0> , mVU_SUBAx<1,0> , mVU_MADDAx<1,0> , mVU_MSUBAx<1,0>, - mVU_ITOF0<1,0> , mVU_FTOI0<1,0> , mVU_MULAx<1,0> , mVU_MULAq<1,0>, - mVU_ADDAq<1,0> , mVU_SUBAq<1,0> , mVU_ADDA<1,0> , mVU_SUBA<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, -}; - -void (* mVU_UPPER_FD_00_TABLE11 [32])() = { - mVU_ADDAx<1,1> , mVU_SUBAx<1,1> , mVU_MADDAx<1,1> , mVU_MSUBAx<1,1>, - mVU_ITOF0<1,1> , mVU_FTOI0<1,1> , mVU_MULAx<1,1> , mVU_MULAq<1,1>, - mVU_ADDAq<1,1> , mVU_SUBAq<1,1> , mVU_ADDA<1,1> , mVU_SUBA<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, -}; - -void (* mVU_UPPER_FD_00_TABLE02 [32])() = { - mVU_ADDAx<0,2> , mVU_SUBAx<0,2> , mVU_MADDAx<0,2> , mVU_MSUBAx<0,2>, - mVU_ITOF0<0,2> , mVU_FTOI0<0,2> , mVU_MULAx<0,2> , mVU_MULAq<0,2>, - mVU_ADDAq<0,2> , mVU_SUBAq<0,2> , mVU_ADDA<0,2> , mVU_SUBA<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, -}; - -void (* mVU_UPPER_FD_00_TABLE12 [32])() = { - mVU_ADDAx<1,2> , mVU_SUBAx<1,2> , mVU_MADDAx<1,2> , mVU_MSUBAx<1,2>, - mVU_ITOF0<1,2> , mVU_FTOI0<1,2> , mVU_MULAx<1,2> , mVU_MULAq<1,2>, - mVU_ADDAq<1,2> , mVU_SUBAq<1,2> , mVU_ADDA<1,2> , mVU_SUBA<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, -}; -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// mVU_UPPER_FD_01_TABLE -//------------------------------------------------------------------ -void (* mVU_UPPER_FD_01_TABLE00 [32])() = { - mVU_ADDAy<0,0> , mVU_SUBAy<0,0> , mVU_MADDAy<0,0> , mVU_MSUBAy<0,0>, - mVU_ITOF4<0,0> , mVU_FTOI4<0,0> , mVU_MULAy<0,0> , mVU_ABS<0,0>, - mVU_MADDAq<0,0> , mVU_MSUBAq<0,0> , mVU_MADDA<0,0> , mVU_MSUBA<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, -}; - -void (* mVU_UPPER_FD_01_TABLE01 [32])() = { - mVU_ADDAy<0,1> , mVU_SUBAy<0,1> , mVU_MADDAy<0,1> , mVU_MSUBAy<0,1>, - mVU_ITOF4<0,1> , mVU_FTOI4<0,1> , mVU_MULAy<0,1> , mVU_ABS<0,1>, - mVU_MADDAq<0,1> , mVU_MSUBAq<0,1> , mVU_MADDA<0,1> , mVU_MSUBA<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, -}; - -void (* mVU_UPPER_FD_01_TABLE10 [32])() = { - mVU_ADDAy<1,0> , mVU_SUBAy<1,0> , mVU_MADDAy<1,0> , mVU_MSUBAy<1,0>, - mVU_ITOF4<1,0> , mVU_FTOI4<1,0> , mVU_MULAy<1,0> , mVU_ABS<1,0>, - mVU_MADDAq<1,0> , mVU_MSUBAq<1,0> , mVU_MADDA<1,0> , mVU_MSUBA<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, -}; - -void (* mVU_UPPER_FD_01_TABLE11 [32])() = { - mVU_ADDAy<1,1> , mVU_SUBAy<1,1> , mVU_MADDAy<1,1> , mVU_MSUBAy<1,1>, - mVU_ITOF4<1,1> , mVU_FTOI4<1,1> , mVU_MULAy<1,1> , mVU_ABS<1,1>, - mVU_MADDAq<1,1> , mVU_MSUBAq<1,1> , mVU_MADDA<1,1> , mVU_MSUBA<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, -}; - -void (* mVU_UPPER_FD_01_TABLE02 [32])() = { - mVU_ADDAy<0,2> , mVU_SUBAy<0,2> , mVU_MADDAy<0,2> , mVU_MSUBAy<0,2>, - mVU_ITOF4<0,2> , mVU_FTOI4<0,2> , mVU_MULAy<0,2> , mVU_ABS<0,2>, - mVU_MADDAq<0,2> , mVU_MSUBAq<0,2> , mVU_MADDA<0,2> , mVU_MSUBA<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, -}; - -void (* mVU_UPPER_FD_01_TABLE12 [32])() = { - mVU_ADDAy<1,2> , mVU_SUBAy<1,2> , mVU_MADDAy<1,2> , mVU_MSUBAy<1,2>, - mVU_ITOF4<1,2> , mVU_FTOI4<1,2> , mVU_MULAy<1,2> , mVU_ABS<1,2>, - mVU_MADDAq<1,2> , mVU_MSUBAq<1,2> , mVU_MADDA<1,2> , mVU_MSUBA<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, -}; -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// mVU_UPPER_FD_10_TABLE -//------------------------------------------------------------------ -void (* mVU_UPPER_FD_10_TABLE00 [32])() = { - mVU_ADDAz<0,0> , mVU_SUBAz<0,0> , mVU_MADDAz<0,0> , mVU_MSUBAz<0,0>, - mVU_ITOF12<0,0> , mVU_FTOI12<0,0> , mVU_MULAz<0,0> , mVU_MULAi<0,0>, - mVU_ADDAi<0,0> , mVU_SUBAi<0,0> , mVU_MULA<0,0> , mVU_OPMULA<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, -}; - -void (* mVU_UPPER_FD_10_TABLE01 [32])() = { - mVU_ADDAz<0,1> , mVU_SUBAz<0,1> , mVU_MADDAz<0,1> , mVU_MSUBAz<0,1>, - mVU_ITOF12<0,1> , mVU_FTOI12<0,1> , mVU_MULAz<0,1> , mVU_MULAi<0,1>, - mVU_ADDAi<0,1> , mVU_SUBAi<0,1> , mVU_MULA<0,1> , mVU_OPMULA<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, -}; - -void (* mVU_UPPER_FD_10_TABLE10 [32])() = { - mVU_ADDAz<1,0> , mVU_SUBAz<1,0> , mVU_MADDAz<1,0> , mVU_MSUBAz<1,0>, - mVU_ITOF12<1,0> , mVU_FTOI12<1,0> , mVU_MULAz<1,0> , mVU_MULAi<1,0>, - mVU_ADDAi<1,0> , mVU_SUBAi<1,0> , mVU_MULA<1,0> , mVU_OPMULA<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, -}; - -void (* mVU_UPPER_FD_10_TABLE11 [32])() = { - mVU_ADDAz<1,1> , mVU_SUBAz<1,1> , mVU_MADDAz<1,1> , mVU_MSUBAz<1,1>, - mVU_ITOF12<1,1> , mVU_FTOI12<1,1> , mVU_MULAz<1,1> , mVU_MULAi<1,1>, - mVU_ADDAi<1,1> , mVU_SUBAi<1,1> , mVU_MULA<1,1> , mVU_OPMULA<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, -}; - -void (* mVU_UPPER_FD_10_TABLE02 [32])() = { - mVU_ADDAz<0,2> , mVU_SUBAz<0,2> , mVU_MADDAz<0,2> , mVU_MSUBAz<0,2>, - mVU_ITOF12<0,2> , mVU_FTOI12<0,2> , mVU_MULAz<0,2> , mVU_MULAi<0,2>, - mVU_ADDAi<0,2> , mVU_SUBAi<0,2> , mVU_MULA<0,2> , mVU_OPMULA<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, -}; - -void (* mVU_UPPER_FD_10_TABLE12 [32])() = { - mVU_ADDAz<1,2> , mVU_SUBAz<1,2> , mVU_MADDAz<1,2> , mVU_MSUBAz<1,2>, - mVU_ITOF12<1,2> , mVU_FTOI12<1,2> , mVU_MULAz<1,2> , mVU_MULAi<1,2>, - mVU_ADDAi<1,2> , mVU_SUBAi<1,2> , mVU_MULA<1,2> , mVU_OPMULA<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, -}; -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// mVU_UPPER_FD_11_TABLE -//------------------------------------------------------------------ -void (* mVU_UPPER_FD_11_TABLE00 [32])() = { - mVU_ADDAw<0,0> , mVU_SUBAw<0,0> , mVU_MADDAw<0,0> , mVU_MSUBAw<0,0>, - mVU_ITOF15<0,0> , mVU_FTOI15<0,0> , mVU_MULAw<0,0> , mVU_CLIP<0,0>, - mVU_MADDAi<0,0> , mVU_MSUBAi<0,0> , mVUunknown<0,0> , mVU_NOP<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, - mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0> , mVUunknown<0,0>, -}; - -void (* mVU_UPPER_FD_11_TABLE01 [32])() = { - mVU_ADDAw<0,1> , mVU_SUBAw<0,1> , mVU_MADDAw<0,1> , mVU_MSUBAw<0,1>, - mVU_ITOF15<0,1> , mVU_FTOI15<0,1> , mVU_MULAw<0,1> , mVU_CLIP<0,1>, - mVU_MADDAi<0,1> , mVU_MSUBAi<0,1> , mVUunknown<0,1> , mVU_NOP<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, - mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1> , mVUunknown<0,1>, -}; - -void (* mVU_UPPER_FD_11_TABLE10 [32])() = { - mVU_ADDAw<1,0> , mVU_SUBAw<1,0> , mVU_MADDAw<1,0> , mVU_MSUBAw<1,0>, - mVU_ITOF15<1,0> , mVU_FTOI15<1,0> , mVU_MULAw<1,0> , mVU_CLIP<1,0>, - mVU_MADDAi<1,0> , mVU_MSUBAi<1,0> , mVUunknown<1,0> , mVU_NOP<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, - mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0> , mVUunknown<1,0>, -}; - -void (* mVU_UPPER_FD_11_TABLE11 [32])() = { - mVU_ADDAw<1,1> , mVU_SUBAw<1,1> , mVU_MADDAw<1,1> , mVU_MSUBAw<1,1>, - mVU_ITOF15<1,1> , mVU_FTOI15<1,1> , mVU_MULAw<1,1> , mVU_CLIP<1,1>, - mVU_MADDAi<1,1> , mVU_MSUBAi<1,1> , mVUunknown<1,1> , mVU_NOP<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, - mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1> , mVUunknown<1,1>, -}; - -void (* mVU_UPPER_FD_11_TABLE02 [32])() = { - mVU_ADDAw<0,2> , mVU_SUBAw<0,2> , mVU_MADDAw<0,2> , mVU_MSUBAw<0,2>, - mVU_ITOF15<0,2> , mVU_FTOI15<0,2> , mVU_MULAw<0,2> , mVU_CLIP<0,2>, - mVU_MADDAi<0,2> , mVU_MSUBAi<0,2> , mVUunknown<0,2> , mVU_NOP<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, - mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2> , mVUunknown<0,2>, -}; - -void (* mVU_UPPER_FD_11_TABLE12 [32])() = { - mVU_ADDAw<1,2> , mVU_SUBAw<1,2> , mVU_MADDAw<1,2> , mVU_MSUBAw<1,2>, - mVU_ITOF15<1,2> , mVU_FTOI15<1,2> , mVU_MULAw<1,2> , mVU_CLIP<1,2>, - mVU_MADDAi<1,2> , mVU_MSUBAi<1,2> , mVUunknown<1,2> , mVU_NOP<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, - mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2> , mVUunknown<1,2>, -}; -//------------------------------------------------------------------ +mVUcreateTable(0) //------------------------------------------------------------------ // Table Functions //------------------------------------------------------------------ -#define doTableStuff(tableName, args) { \ - pass1 { \ - if (vuIndex) tableName##10[ args ](); \ - else tableName##00[ args ](); \ - } \ - pass2 { \ - if (vuIndex) tableName##11[ args ](); \ - else tableName##01[ args ](); \ - } \ - pass3 { \ - if (vuIndex) tableName##12[ args ](); \ - else tableName##02[ args ](); \ - } \ +#define doTableStuff(tableName, args) { \ + tableName##0[ args ](mX); \ } -microVUf(void) mVU_UPPER_FD_00() { doTableStuff(mVU_UPPER_FD_00_TABLE, ((mVUgetCode >> 6) & 0x1f)); } -microVUf(void) mVU_UPPER_FD_01() { doTableStuff(mVU_UPPER_FD_01_TABLE, ((mVUgetCode >> 6) & 0x1f)); } -microVUf(void) mVU_UPPER_FD_10() { doTableStuff(mVU_UPPER_FD_10_TABLE, ((mVUgetCode >> 6) & 0x1f)); } -microVUf(void) mVU_UPPER_FD_11() { doTableStuff(mVU_UPPER_FD_11_TABLE, ((mVUgetCode >> 6) & 0x1f)); } -microVUf(void) mVULowerOP() { doTableStuff(mVULowerOP_OPCODE, (mVUgetCode & 0x3f)); } -microVUf(void) mVULowerOP_T3_00() { doTableStuff(mVULowerOP_T3_00_OPCODE, ((mVUgetCode >> 6) & 0x1f)); } -microVUf(void) mVULowerOP_T3_01() { doTableStuff(mVULowerOP_T3_01_OPCODE, ((mVUgetCode >> 6) & 0x1f)); } -microVUf(void) mVULowerOP_T3_10() { doTableStuff(mVULowerOP_T3_10_OPCODE, ((mVUgetCode >> 6) & 0x1f)); } -microVUf(void) mVULowerOP_T3_11() { doTableStuff(mVULowerOP_T3_11_OPCODE, ((mVUgetCode >> 6) & 0x1f)); } -microVUf(void) mVUopU() { doTableStuff(mVU_UPPER_OPCODE, (mVUgetCode & 0x3f)); } // Gets Upper Opcode -microVUf(void) mVUopL() { doTableStuff(mVULOWER_OPCODE, (mVUgetCode >> 25)); } // Gets Lower Opcode -microVUf(void) mVUunknown() { - pass2 { SysPrintf("microVU%d: Unknown Micro VU opcode called (%x)\n", vuIndex, mVUgetCode); } +mVUop(mVU_UPPER_FD_00) { doTableStuff(mVU_UPPER_FD_00_TABLE, ((mVUgetCode >> 6) & 0x1f)); } +mVUop(mVU_UPPER_FD_01) { doTableStuff(mVU_UPPER_FD_01_TABLE, ((mVUgetCode >> 6) & 0x1f)); } +mVUop(mVU_UPPER_FD_10) { doTableStuff(mVU_UPPER_FD_10_TABLE, ((mVUgetCode >> 6) & 0x1f)); } +mVUop(mVU_UPPER_FD_11) { doTableStuff(mVU_UPPER_FD_11_TABLE, ((mVUgetCode >> 6) & 0x1f)); } +mVUop(mVULowerOP) { doTableStuff(mVULowerOP_OPCODE, (mVUgetCode & 0x3f)); } +mVUop(mVULowerOP_T3_00) { doTableStuff(mVULowerOP_T3_00_OPCODE, ((mVUgetCode >> 6) & 0x1f)); } +mVUop(mVULowerOP_T3_01) { doTableStuff(mVULowerOP_T3_01_OPCODE, ((mVUgetCode >> 6) & 0x1f)); } +mVUop(mVULowerOP_T3_10) { doTableStuff(mVULowerOP_T3_10_OPCODE, ((mVUgetCode >> 6) & 0x1f)); } +mVUop(mVULowerOP_T3_11) { doTableStuff(mVULowerOP_T3_11_OPCODE, ((mVUgetCode >> 6) & 0x1f)); } +mVUop(mVUopU) { doTableStuff(mVU_UPPER_OPCODE, (mVUgetCode & 0x3f)); } // Gets Upper Opcode +mVUop(mVUopL) { doTableStuff(mVULOWER_OPCODE, (mVUgetCode >> 25)); } // Gets Lower Opcode +mVUop(mVUunknown) { + pass2 { Console::Error("microVU%d: Unknown Micro VU opcode called (%08x)\n", params getIndex, mVUgetCode); } pass3 { mVUlog("Unknown", mVUgetCode); } } -#endif //PCSX2_MICROVU diff --git a/pcsx2/x86/microVU_Upper.inl b/pcsx2/x86/microVU_Upper.inl index f265db53a9..380a2a4727 100644 --- a/pcsx2/x86/microVU_Upper.inl +++ b/pcsx2/x86/microVU_Upper.inl @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator -* Copyright (C) 2009 Pcsx2-Playground Team +* Copyright (C) 2009 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,31 +15,31 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ + #pragma once -#ifdef PCSX2_MICROVU //------------------------------------------------------------------ // mVUupdateFlags() - Updates status/mac flags //------------------------------------------------------------------ -#define AND_XYZW ((_XYZW_SS && modXYZW) ? (1) : (doMac ? (_X_Y_Z_W) : (flipMask[_X_Y_Z_W]))) +#define AND_XYZW ((_XYZW_SS && modXYZW) ? (1) : (mFLAG.doFlag ? (_X_Y_Z_W) : (flipMask[_X_Y_Z_W]))) #define ADD_XYZW ((_XYZW_SS && modXYZW) ? (_X ? 3 : (_Y ? 2 : (_Z ? 1 : 0))) : 0) -#define SHIFT_XYZW(gprReg) { if (_XYZW_SS && modXYZW && !_W) { SHL16ItoR(gprReg, ADD_XYZW); } } +#define SHIFT_XYZW(gprReg) { if (_XYZW_SS && modXYZW && !_W) { SHL32ItoR(gprReg, ADD_XYZW); } } // Note: If modXYZW is true, then it adjusts XYZW for Single Scalar operations -microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modXYZW) { - microVU* mVU = mVUx; +microVUt(void) mVUupdateFlags(mV, int reg, int regT1, int regT2, int xyzw, bool modXYZW) { int sReg, mReg = gprT1; - static u8 *pjmp, *pjmp2; static const u16 flipMask[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}; - if (!doFlags) return; - if (!doMac) { regT1 = reg; } - else { SSE2_PSHUFD_XMM_to_XMM(regT1, reg, 0x1B); } // Flip wzyx to xyzw - if (doStatus) { - getFlagReg(sReg, fsInstance); // Set sReg to valid GPR by Cur Flag Instance - mVUallocSFLAGa(sReg, fpsInstance); // Get Prev Status Flag - AND16ItoR(sReg, 0xff0); // Keep Sticky and D/I flags + //SysPrintf("Status = %d; Mac = %d\n", sFLAG.doFlag, mFLAG.doFlag); + if (mVUsFlagHack) { sFLAG.doFlag = 0; } + if (!sFLAG.doFlag && !mFLAG.doFlag) { return; } + if (!mFLAG.doFlag || (_XYZW_SS && modXYZW)) { regT1 = reg; } + else { SSE2_PSHUFD_XMM_to_XMM(regT1, reg, 0x1B); } // Flip wzyx to xyzw + if (sFLAG.doFlag) { + getFlagReg(sReg, sFLAG.write); // Set sReg to valid GPR by Cur Flag Instance + mVUallocSFLAGa(sReg, sFLAG.lastWrite); // Get Prev Status Flag + if (sFLAG.doNonSticky) AND32ItoR(sReg, 0xfffc00ff); // Clear O,U,S,Z flags } //-------------------------Check for Signed flags------------------------------ @@ -52,132 +52,115 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MOVMSKPS_XMM_to_R32(mReg, regT2); // Move the sign bits of the t1reg - AND16ItoR(mReg, AND_XYZW); // Grab "Is Signed" bits from the previous calculation - pjmp = JZ8(0); // Skip if none are - if (doMac) SHL16ItoR(mReg, 4 + ADD_XYZW); - if (doStatus) OR16ItoR(sReg, 0x82); // SS, S flags - if (_XYZW_SS) pjmp2 = JMP8(0); // If negative and not Zero, we can skip the Zero Flag checking - x86SetJ8(pjmp); + AND32ItoR(mReg, AND_XYZW); // Grab "Is Signed" bits from the previous calculation + SHL32ItoR(mReg, 4 + ADD_XYZW); //-------------------------Check for Zero flags------------------------------ - AND16ItoR(gprT2, AND_XYZW); // Grab "Is Zero" bits from the previous calculation - pjmp = JZ8(0); // Skip if none are - if (doMac) { SHIFT_XYZW(gprT2); OR32RtoR(mReg, gprT2); } - if (doStatus) { OR16ItoR(sReg, 0x41); } // ZS, Z flags - x86SetJ8(pjmp); + AND32ItoR(gprT2, AND_XYZW); // Grab "Is Zero" bits from the previous calculation + if (mFLAG.doFlag) { SHIFT_XYZW(gprT2); } + OR32RtoR(mReg, gprT2); //-------------------------Write back flags------------------------------ - if (_XYZW_SS) x86SetJ8(pjmp2); // If we skipped the Zero Flag Checking, return here - - if (doMac) mVUallocMFLAGb(mReg, fmInstance); // Set Mac Flag + if (mFLAG.doFlag) mVUallocMFLAGb(mVU, mReg, mFLAG.write); // Set Mac Flag + if (sFLAG.doFlag) { + OR32RtoR (sReg, mReg); + if (sFLAG.doNonSticky) { + SHL32ItoR(mReg, 8); + OR32RtoR (sReg, mReg); + } + } } //------------------------------------------------------------------ // Helper Macros //------------------------------------------------------------------ -#define mVUlogFtFs() { mVUlog(".%s vf%02d, vf%02d", _XYZW_String, _Ft_, _Fs_); } -#define mVUlogFd() { mVUlog(".%s vf%02d, vf%02d", _XYZW_String, _Fd_, _Fs_); } -#define mVUlogACC() { mVUlog(".%s ACC, vf%02d", _XYZW_String, _Fs_); } -#define mVUlogFt() { mVUlog(", vf%02d", _Ft_); } -#define mVUlogBC() { mVUlog(", vf%02d%s", _Ft_, _BC_String); } -#define mVUlogI() { mVUlog(", I"); } -#define mVUlogQ() { mVUlog(", Q"); } -#define mVUlogCLIP() { mVUlog("w.xyz vf%02d, vf%02dw", _Fs_, _Ft_); } - // FMAC1 - Normal FMAC Opcodes #define mVU_FMAC1(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(_Fd_, _Fs_, _Ft_); } \ + pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, _Ft_); } \ pass2 { \ int Fd, Fs, Ft; \ - mVUallocFMAC1a(Fd, Fs, Ft); \ + mVUallocFMAC1a(mVU, Fd, Fs, Ft); \ if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \ - mVUallocFMAC1b(Fd); \ + mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \ + mVUallocFMAC1b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogFt(); } \ } // FMAC3 - BC(xyzw) FMAC Opcodes #define mVU_FMAC3(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC3(_Fd_, _Fs_, _Ft_); } \ + pass1 { mVUanalyzeFMAC3(mVU, _Fd_, _Fs_, _Ft_); } \ pass2 { \ int Fd, Fs, Ft; \ - mVUallocFMAC3a(Fd, Fs, Ft); \ + mVUallocFMAC3a(mVU, Fd, Fs, Ft); \ if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \ - mVUallocFMAC3b(Fd); \ + mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \ + mVUallocFMAC3b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogBC(); } \ } // FMAC4 - FMAC Opcodes Storing Result to ACC #define mVU_FMAC4(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(0, _Fs_, _Ft_); } \ + pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, _Ft_); } \ pass2 { \ int ACC, Fs, Ft; \ - mVUallocFMAC4a(ACC, Fs, Ft); \ + mVUallocFMAC4a(mVU, ACC, Fs, Ft); \ if (_X_Y_Z_W == 8) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC4b(ACC, Fs); \ + mVUupdateFlags(mVU, Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC4b(mVU, ACC, Fs); \ } \ pass3 { mVUlog(OPname); mVUlogACC(); mVUlogFt(); } \ } // FMAC5 - FMAC BC(xyzw) Opcodes Storing Result to ACC #define mVU_FMAC5(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC3(0, _Fs_, _Ft_); } \ + pass1 { mVUanalyzeFMAC3(mVU, 0, _Fs_, _Ft_); } \ pass2 { \ int ACC, Fs, Ft; \ - mVUallocFMAC5a(ACC, Fs, Ft); \ + mVUallocFMAC5a(mVU, ACC, Fs, Ft); \ if (_X_Y_Z_W == 8) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC5b(ACC, Fs); \ + mVUupdateFlags(mVU, Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC5b(mVU, ACC, Fs); \ } \ pass3 { mVUlog(OPname); mVUlogACC(); mVUlogBC(); } \ } // FMAC6 - Normal FMAC Opcodes (I Reg) #define mVU_FMAC6(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(_Fd_, _Fs_, 0); } \ + pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, 0); } \ pass2 { \ int Fd, Fs, Ft; \ - mVUallocFMAC6a(Fd, Fs, Ft); \ + mVUallocFMAC6a(mVU, Fd, Fs, Ft); \ if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \ - mVUallocFMAC6b(Fd); \ + mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \ + mVUallocFMAC6b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogI(); } \ } // FMAC7 - FMAC Opcodes Storing Result to ACC (I Reg) #define mVU_FMAC7(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(0, _Fs_, 0); } \ + pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, 0); } \ pass2 { \ int ACC, Fs, Ft; \ - mVUallocFMAC7a(ACC, Fs, Ft); \ + mVUallocFMAC7a(mVU, ACC, Fs, Ft); \ if (_X_Y_Z_W == 8) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC7b(ACC, Fs); \ + mVUupdateFlags(mVU, Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC7b(mVU, ACC, Fs); \ } \ pass3 { mVUlog(OPname); mVUlogACC(); mVUlogI(); } \ } // FMAC8 - MADD FMAC Opcode Storing Result to Fd #define mVU_FMAC8(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(_Fd_, _Fs_, _Ft_); } \ + pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, _Ft_); } \ pass2 { \ int Fd, ACC, Fs, Ft; \ - mVUallocFMAC8a(Fd, ACC, Fs, Ft); \ + mVUallocFMAC8a(mVU, Fd, ACC, Fs, Ft); \ if (_X_Y_Z_W == 8) { \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##SS_XMM_to_XMM(Fs, ACC); \ @@ -186,18 +169,17 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(Fs, ACC); \ } \ - mVUupdateFlags(Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC8b(Fd); \ + mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC8b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogFt(); } \ } // FMAC9 - MSUB FMAC Opcode Storing Result to Fd #define mVU_FMAC9(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(_Fd_, _Fs_, _Ft_); } \ + pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, _Ft_); } \ pass2 { \ int Fd, ACC, Fs, Ft; \ - mVUallocFMAC9a(Fd, ACC, Fs, Ft); \ + mVUallocFMAC9a(mVU, Fd, ACC, Fs, Ft); \ if (_X_Y_Z_W == 8) { \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##SS_XMM_to_XMM(ACC, Fs); \ @@ -206,18 +188,17 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(ACC, Fs); \ } \ - mVUupdateFlags(Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC9b(Fd); \ + mVUupdateFlags(mVU, Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC9b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogFt(); } \ } // FMAC10 - MADD FMAC BC(xyzw) Opcode Storing Result to Fd #define mVU_FMAC10(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC3(_Fd_, _Fs_, _Ft_); } \ + pass1 { mVUanalyzeFMAC3(mVU, _Fd_, _Fs_, _Ft_); } \ pass2 { \ int Fd, ACC, Fs, Ft; \ - mVUallocFMAC10a(Fd, ACC, Fs, Ft); \ + mVUallocFMAC10a(mVU, Fd, ACC, Fs, Ft); \ if (_X_Y_Z_W == 8) { \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##SS_XMM_to_XMM(Fs, ACC); \ @@ -226,18 +207,17 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(Fs, ACC); \ } \ - mVUupdateFlags(Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC10b(Fd); \ + mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC10b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogBC(); } \ } // FMAC11 - MSUB FMAC BC(xyzw) Opcode Storing Result to Fd #define mVU_FMAC11(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC3(_Fd_, _Fs_, _Ft_); } \ + pass1 { mVUanalyzeFMAC3(mVU, _Fd_, _Fs_, _Ft_); } \ pass2 { \ int Fd, ACC, Fs, Ft; \ - mVUallocFMAC11a(Fd, ACC, Fs, Ft); \ + mVUallocFMAC11a(mVU, Fd, ACC, Fs, Ft); \ if (_X_Y_Z_W == 8) { \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##SS_XMM_to_XMM(ACC, Fs); \ @@ -246,18 +226,17 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(ACC, Fs); \ } \ - mVUupdateFlags(Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC11b(Fd); \ + mVUupdateFlags(mVU, Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC11b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogBC(); } \ } // FMAC12 - MADD FMAC Opcode Storing Result to Fd (I Reg) #define mVU_FMAC12(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(_Fd_, _Fs_, 0); } \ + pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, 0); } \ pass2 { \ int Fd, ACC, Fs, Ft; \ - mVUallocFMAC12a(Fd, ACC, Fs, Ft); \ + mVUallocFMAC12a(mVU, Fd, ACC, Fs, Ft); \ if (_X_Y_Z_W == 8) { \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##SS_XMM_to_XMM(Fs, ACC); \ @@ -266,18 +245,17 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(Fs, ACC); \ } \ - mVUupdateFlags(Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC12b(Fd); \ + mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC12b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogI(); } \ } // FMAC13 - MSUB FMAC Opcode Storing Result to Fd (I Reg) #define mVU_FMAC13(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(_Fd_, _Fs_, 0); } \ + pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, 0); } \ pass2 { \ int Fd, ACC, Fs, Ft; \ - mVUallocFMAC13a(Fd, ACC, Fs, Ft); \ + mVUallocFMAC13a(mVU, Fd, ACC, Fs, Ft); \ if (_X_Y_Z_W == 8) { \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##SS_XMM_to_XMM(ACC, Fs); \ @@ -286,18 +264,17 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(ACC, Fs); \ } \ - mVUupdateFlags(Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC13b(Fd); \ + mVUupdateFlags(mVU, Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC13b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogI(); } \ } // FMAC14 - MADDA/MSUBA FMAC Opcode #define mVU_FMAC14(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(0, _Fs_, _Ft_); } \ + pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, _Ft_); } \ pass2 { \ int ACCw, ACCr, Fs, Ft; \ - mVUallocFMAC14a(ACCw, ACCr, Fs, Ft); \ + mVUallocFMAC14a(mVU, ACCw, ACCr, Fs, Ft); \ if (_X_Y_Z_W == 8) { \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##SS_XMM_to_XMM(ACCr, Fs); \ @@ -306,18 +283,17 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(ACCr, Fs); \ } \ - mVUupdateFlags(ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC14b(ACCw, ACCr); \ + mVUupdateFlags(mVU, ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC14b(mVU, ACCw, ACCr); \ } \ pass3 { mVUlog(OPname); mVUlogACC(); mVUlogFt(); } \ } // FMAC15 - MADDA/MSUBA BC(xyzw) FMAC Opcode #define mVU_FMAC15(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC3(0, _Fs_, _Ft_); } \ + pass1 { mVUanalyzeFMAC3(mVU, 0, _Fs_, _Ft_); } \ pass2 { \ int ACCw, ACCr, Fs, Ft; \ - mVUallocFMAC15a(ACCw, ACCr, Fs, Ft); \ + mVUallocFMAC15a(mVU, ACCw, ACCr, Fs, Ft); \ if (_X_Y_Z_W == 8) { \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##SS_XMM_to_XMM(ACCr, Fs); \ @@ -326,18 +302,17 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(ACCr, Fs); \ } \ - mVUupdateFlags(ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC15b(ACCw, ACCr); \ + mVUupdateFlags(mVU, ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC15b(mVU, ACCw, ACCr); \ } \ pass3 { mVUlog(OPname); mVUlogACC(); mVUlogBC(); } \ } // FMAC16 - MADDA/MSUBA FMAC Opcode (I Reg) #define mVU_FMAC16(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(0, _Fs_, 0); } \ + pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, 0); } \ pass2 { \ int ACCw, ACCr, Fs, Ft; \ - mVUallocFMAC16a(ACCw, ACCr, Fs, Ft); \ + mVUallocFMAC16a(mVU, ACCw, ACCr, Fs, Ft); \ if (_X_Y_Z_W == 8) { \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##SS_XMM_to_XMM(ACCr, Fs); \ @@ -346,73 +321,68 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(ACCr, Fs); \ } \ - mVUupdateFlags(ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC16b(ACCw, ACCr); \ + mVUupdateFlags(mVU, ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC16b(mVU, ACCw, ACCr); \ } \ pass3 { mVUlog(OPname); mVUlogACC(); mVUlogI(); } \ } // FMAC18 - OPMULA FMAC Opcode #define mVU_FMAC18(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(0, _Fs_, _Ft_); } \ + pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, _Ft_); } \ pass2 { \ int ACC, Fs, Ft; \ - mVUallocFMAC18a(ACC, Fs, Ft); \ + mVUallocFMAC18a(mVU, ACC, Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC18b(ACC, Fs); \ + mVUupdateFlags(mVU, Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC18b(mVU, ACC, Fs); \ } \ pass3 { mVUlog(OPname); mVUlogACC(); mVUlogFt(); } \ } // FMAC19 - OPMSUB FMAC Opcode #define mVU_FMAC19(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(_Fd_, _Fs_, _Ft_); } \ + pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, _Ft_); } \ pass2 { \ int Fd, ACC, Fs, Ft; \ - mVUallocFMAC19a(Fd, ACC, Fs, Ft); \ + mVUallocFMAC19a(mVU, Fd, ACC, Fs, Ft); \ SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(ACC, Fs); \ - mVUupdateFlags(Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC19b(Fd); \ + mVUupdateFlags(mVU, Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC19b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogFt(); } \ } // FMAC22 - Normal FMAC Opcodes (Q Reg) #define mVU_FMAC22(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(_Fd_, _Fs_, 0); } \ + pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, 0); } \ pass2 { \ int Fd, Fs, Ft; \ - mVUallocFMAC22a(Fd, Fs, Ft); \ + mVUallocFMAC22a(mVU, Fd, Fs, Ft); \ if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \ - mVUallocFMAC22b(Fd); \ + mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \ + mVUallocFMAC22b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogQ(); } \ } // FMAC23 - FMAC Opcodes Storing Result to ACC (Q Reg) #define mVU_FMAC23(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(0, _Fs_, 0); } \ + pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, 0); } \ pass2 { \ int ACC, Fs, Ft; \ - mVUallocFMAC23a(ACC, Fs, Ft); \ + mVUallocFMAC23a(mVU, ACC, Fs, Ft); \ if (_X_Y_Z_W == 8) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC23b(ACC, Fs); \ + mVUupdateFlags(mVU, Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC23b(mVU, ACC, Fs); \ } \ pass3 { mVUlog(OPname); mVUlogACC(); mVUlogQ();} \ } // FMAC24 - MADD FMAC Opcode Storing Result to Fd (Q Reg) #define mVU_FMAC24(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(_Fd_, _Fs_, 0); } \ + pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, 0); } \ pass2 { \ int Fd, ACC, Fs, Ft; \ - mVUallocFMAC24a(Fd, ACC, Fs, Ft); \ + mVUallocFMAC24a(mVU, Fd, ACC, Fs, Ft); \ if (_X_Y_Z_W == 8) { \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##SS_XMM_to_XMM(Fs, ACC); \ @@ -421,18 +391,17 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(Fs, ACC); \ } \ - mVUupdateFlags(Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC24b(Fd); \ + mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC24b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogQ(); } \ } // FMAC25 - MSUB FMAC Opcode Storing Result to Fd (Q Reg) #define mVU_FMAC25(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(_Fd_, _Fs_, 0); } \ + pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, 0); } \ pass2 { \ int Fd, ACC, Fs, Ft; \ - mVUallocFMAC25a(Fd, ACC, Fs, Ft); \ + mVUallocFMAC25a(mVU, Fd, ACC, Fs, Ft); \ if (_X_Y_Z_W == 8) { \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##SS_XMM_to_XMM(ACC, Fs); \ @@ -441,18 +410,17 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(ACC, Fs); \ } \ - mVUupdateFlags(Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC25b(Fd); \ + mVUupdateFlags(mVU, Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC25b(mVU, Fd); \ } \ pass3 { mVUlog(OPname); mVUlogFd(); mVUlogQ(); } \ } // FMAC26 - MADDA/MSUBA FMAC Opcode (Q Reg) #define mVU_FMAC26(operation, OPname) { \ - microVU* mVU = mVUx; \ - pass1 { mVUanalyzeFMAC1(0, _Fs_, 0); } \ + pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, 0); } \ pass2 { \ int ACCw, ACCr, Fs, Ft; \ - mVUallocFMAC26a(ACCw, ACCr, Fs, Ft); \ + mVUallocFMAC26a(mVU, ACCw, ACCr, Fs, Ft); \ if (_X_Y_Z_W == 8) { \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##SS_XMM_to_XMM(ACCr, Fs); \ @@ -461,118 +429,121 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(ACCr, Fs); \ } \ - mVUupdateFlags(ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC26b(ACCw, ACCr); \ + mVUupdateFlags(mVU, ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \ + mVUallocFMAC26b(mVU, ACCw, ACCr); \ } \ pass3 { mVUlog(OPname); mVUlogACC(); mVUlogQ(); } \ } +// FMAC27~29 - MAX/MINI FMAC Opcodes +#define mVU_FMAC27(operation, OPname) { mVU_FMAC1 (operation, OPname); pass1 { sFLAG.doFlag = 0; } } +#define mVU_FMAC28(operation, OPname) { mVU_FMAC6 (operation, OPname); pass1 { sFLAG.doFlag = 0; } } +#define mVU_FMAC29(operation, OPname) { mVU_FMAC3 (operation, OPname); pass1 { sFLAG.doFlag = 0; } } + //------------------------------------------------------------------ // Micro VU Micromode Upper instructions //------------------------------------------------------------------ -microVUf(void) mVU_ABS() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeFMAC2(_Fs_, _Ft_); } +mVUop(mVU_ABS) { + pass1 { mVUanalyzeFMAC2(mVU, _Fs_, _Ft_); } pass2 { int Fs, Ft; - mVUallocFMAC2a(Fs, Ft); + mVUallocFMAC2a(mVU, Fs, Ft); SSE_ANDPS_M128_to_XMM(Fs, (uptr)mVU_absclip); - mVUallocFMAC2b(Ft); + mVUallocFMAC2b(mVU, Ft); } pass3 { mVUlog("ABS"); mVUlogFtFs(); } } -microVUf(void) mVU_ADD() { mVU_FMAC1 (ADD, "ADD"); } -microVUf(void) mVU_ADDi() { mVU_FMAC6 (ADD, "ADDi"); } -microVUf(void) mVU_ADDq() { mVU_FMAC22(ADD, "ADDq"); } -microVUf(void) mVU_ADDx() { mVU_FMAC3 (ADD, "ADDx"); } -microVUf(void) mVU_ADDy() { mVU_FMAC3 (ADD, "ADDy"); } -microVUf(void) mVU_ADDz() { mVU_FMAC3 (ADD, "ADDz"); } -microVUf(void) mVU_ADDw() { mVU_FMAC3 (ADD, "ADDw"); } -microVUf(void) mVU_ADDA() { mVU_FMAC4 (ADD, "ADDA"); } -microVUf(void) mVU_ADDAi() { mVU_FMAC7 (ADD, "ADDAi"); } -microVUf(void) mVU_ADDAq() { mVU_FMAC23(ADD, "ADDAq"); } -microVUf(void) mVU_ADDAx() { mVU_FMAC5 (ADD, "ADDAx"); } -microVUf(void) mVU_ADDAy() { mVU_FMAC5 (ADD, "ADDAy"); } -microVUf(void) mVU_ADDAz() { mVU_FMAC5 (ADD, "ADDAz"); } -microVUf(void) mVU_ADDAw() { mVU_FMAC5 (ADD, "ADDAw"); } -microVUf(void) mVU_SUB() { mVU_FMAC1 (SUB, "SUB"); } -microVUf(void) mVU_SUBi() { mVU_FMAC6 (SUB, "SUBi"); } -microVUf(void) mVU_SUBq() { mVU_FMAC22(SUB, "SUBq"); } -microVUf(void) mVU_SUBx() { mVU_FMAC3 (SUB, "SUBx"); } -microVUf(void) mVU_SUBy() { mVU_FMAC3 (SUB, "SUBy"); } -microVUf(void) mVU_SUBz() { mVU_FMAC3 (SUB, "SUBz"); } -microVUf(void) mVU_SUBw() { mVU_FMAC3 (SUB, "SUBw"); } -microVUf(void) mVU_SUBA() { mVU_FMAC4 (SUB, "SUBA"); } -microVUf(void) mVU_SUBAi() { mVU_FMAC7 (SUB, "SUBAi"); } -microVUf(void) mVU_SUBAq() { mVU_FMAC23(SUB, "SUBAq"); } -microVUf(void) mVU_SUBAx() { mVU_FMAC5 (SUB, "SUBAx"); } -microVUf(void) mVU_SUBAy() { mVU_FMAC5 (SUB, "SUBAy"); } -microVUf(void) mVU_SUBAz() { mVU_FMAC5 (SUB, "SUBAz"); } -microVUf(void) mVU_SUBAw() { mVU_FMAC5 (SUB, "SUBAw"); } -microVUf(void) mVU_MUL() { mVU_FMAC1 (MUL, "MUL"); } -microVUf(void) mVU_MULi() { mVU_FMAC6 (MUL, "MULi"); } -microVUf(void) mVU_MULq() { mVU_FMAC22(MUL, "MULq"); } -microVUf(void) mVU_MULx() { mVU_FMAC3 (MUL, "MULx"); } -microVUf(void) mVU_MULy() { mVU_FMAC3 (MUL, "MULy"); } -microVUf(void) mVU_MULz() { mVU_FMAC3 (MUL, "MULz"); } -microVUf(void) mVU_MULw() { mVU_FMAC3 (MUL, "MULw"); } -microVUf(void) mVU_MULA() { mVU_FMAC4 (MUL, "MULA"); } -microVUf(void) mVU_MULAi() { mVU_FMAC7 (MUL, "MULAi"); } -microVUf(void) mVU_MULAq() { mVU_FMAC23(MUL, "MULAq"); } -microVUf(void) mVU_MULAx() { mVU_FMAC5 (MUL, "MULAx"); } -microVUf(void) mVU_MULAy() { mVU_FMAC5 (MUL, "MULAy"); } -microVUf(void) mVU_MULAz() { mVU_FMAC5 (MUL, "MULAz"); } -microVUf(void) mVU_MULAw() { mVU_FMAC5 (MUL, "MULAw"); } -microVUf(void) mVU_MADD() { mVU_FMAC8 (ADD, "MADD"); } -microVUf(void) mVU_MADDi() { mVU_FMAC12(ADD, "MADDi"); } -microVUf(void) mVU_MADDq() { mVU_FMAC24(ADD, "MADDq"); } -microVUf(void) mVU_MADDx() { mVU_FMAC10(ADD, "MADDx"); } -microVUf(void) mVU_MADDy() { mVU_FMAC10(ADD, "MADDy"); } -microVUf(void) mVU_MADDz() { mVU_FMAC10(ADD, "MADDz"); } -microVUf(void) mVU_MADDw() { mVU_FMAC10(ADD, "MADDw"); } -microVUf(void) mVU_MADDA() { mVU_FMAC14(ADD, "MADDA"); } -microVUf(void) mVU_MADDAi() { mVU_FMAC16(ADD, "MADDAi"); } -microVUf(void) mVU_MADDAq() { mVU_FMAC26(ADD, "MADDAq"); } -microVUf(void) mVU_MADDAx() { mVU_FMAC15(ADD, "MADDAx"); } -microVUf(void) mVU_MADDAy() { mVU_FMAC15(ADD, "MADDAy"); } -microVUf(void) mVU_MADDAz() { mVU_FMAC15(ADD, "MADDAz"); } -microVUf(void) mVU_MADDAw() { mVU_FMAC15(ADD, "MADDAw"); } -microVUf(void) mVU_MSUB() { mVU_FMAC9 (SUB, "MSUB"); } -microVUf(void) mVU_MSUBi() { mVU_FMAC13(SUB, "MSUBi"); } -microVUf(void) mVU_MSUBq() { mVU_FMAC25(SUB, "MSUBq"); } -microVUf(void) mVU_MSUBx() { mVU_FMAC11(SUB, "MSUBx"); } -microVUf(void) mVU_MSUBy() { mVU_FMAC11(SUB, "MSUBy"); } -microVUf(void) mVU_MSUBz() { mVU_FMAC11(SUB, "MSUBz"); } -microVUf(void) mVU_MSUBw() { mVU_FMAC11(SUB, "MSUBw"); } -microVUf(void) mVU_MSUBA() { mVU_FMAC14(SUB, "MSUBA"); } -microVUf(void) mVU_MSUBAi() { mVU_FMAC16(SUB, "MSUBAi"); } -microVUf(void) mVU_MSUBAq() { mVU_FMAC26(SUB, "MSUBAq"); } -microVUf(void) mVU_MSUBAx() { mVU_FMAC15(SUB, "MSUBAx"); } -microVUf(void) mVU_MSUBAy() { mVU_FMAC15(SUB, "MSUBAy"); } -microVUf(void) mVU_MSUBAz() { mVU_FMAC15(SUB, "MSUBAz"); } -microVUf(void) mVU_MSUBAw() { mVU_FMAC15(SUB, "MSUBAw"); } -microVUf(void) mVU_MAX() { mVU_FMAC1 (MAX, "MAX"); } -microVUf(void) mVU_MAXi() { mVU_FMAC6 (MAX, "MAXi"); } -microVUf(void) mVU_MAXx() { mVU_FMAC3 (MAX, "MAXx"); } -microVUf(void) mVU_MAXy() { mVU_FMAC3 (MAX, "MAXy"); } -microVUf(void) mVU_MAXz() { mVU_FMAC3 (MAX, "MAXz"); } -microVUf(void) mVU_MAXw() { mVU_FMAC3 (MAX, "MAXw"); } -microVUf(void) mVU_MINI() { mVU_FMAC1 (MIN, "MINI"); } -microVUf(void) mVU_MINIi() { mVU_FMAC6 (MIN, "MINIi"); } -microVUf(void) mVU_MINIx() { mVU_FMAC3 (MIN, "MINIx"); } -microVUf(void) mVU_MINIy() { mVU_FMAC3 (MIN, "MINIy"); } -microVUf(void) mVU_MINIz() { mVU_FMAC3 (MIN, "MINIz"); } -microVUf(void) mVU_MINIw() { mVU_FMAC3 (MIN, "MINIw"); } -microVUf(void) mVU_OPMULA() { mVU_FMAC18(MUL, "OPMULA"); } -microVUf(void) mVU_OPMSUB() { mVU_FMAC19(SUB, "OPMSUB"); } -microVUf(void) mVU_NOP() { pass3 { mVUlog("NOP"); } } -microVUq(void) mVU_FTOIx(uptr addr) { - microVU* mVU = mVUx; - pass1 { mVUanalyzeFMAC2(_Fs_, _Ft_); } +mVUop(mVU_ADD) { mVU_FMAC1 (ADD, "ADD"); } +mVUop(mVU_ADDi) { mVU_FMAC6 (ADD2, "ADDi"); } +mVUop(mVU_ADDq) { mVU_FMAC22(ADD, "ADDq"); } +mVUop(mVU_ADDx) { mVU_FMAC3 (ADD, "ADDx"); } +mVUop(mVU_ADDy) { mVU_FMAC3 (ADD, "ADDy"); } +mVUop(mVU_ADDz) { mVU_FMAC3 (ADD, "ADDz"); } +mVUop(mVU_ADDw) { mVU_FMAC3 (ADD, "ADDw"); } +mVUop(mVU_ADDA) { mVU_FMAC4 (ADD, "ADDA"); } +mVUop(mVU_ADDAi) { mVU_FMAC7 (ADD, "ADDAi"); } +mVUop(mVU_ADDAq) { mVU_FMAC23(ADD, "ADDAq"); } +mVUop(mVU_ADDAx) { mVU_FMAC5 (ADD, "ADDAx"); } +mVUop(mVU_ADDAy) { mVU_FMAC5 (ADD, "ADDAy"); } +mVUop(mVU_ADDAz) { mVU_FMAC5 (ADD, "ADDAz"); } +mVUop(mVU_ADDAw) { mVU_FMAC5 (ADD, "ADDAw"); } +mVUop(mVU_SUB) { mVU_FMAC1 (SUB, "SUB"); } +mVUop(mVU_SUBi) { mVU_FMAC6 (SUB, "SUBi"); } +mVUop(mVU_SUBq) { mVU_FMAC22(SUB, "SUBq"); } +mVUop(mVU_SUBx) { mVU_FMAC3 (SUB, "SUBx"); } +mVUop(mVU_SUBy) { mVU_FMAC3 (SUB, "SUBy"); } +mVUop(mVU_SUBz) { mVU_FMAC3 (SUB, "SUBz"); } +mVUop(mVU_SUBw) { mVU_FMAC3 (SUB, "SUBw"); } +mVUop(mVU_SUBA) { mVU_FMAC4 (SUB, "SUBA"); } +mVUop(mVU_SUBAi) { mVU_FMAC7 (SUB, "SUBAi"); } +mVUop(mVU_SUBAq) { mVU_FMAC23(SUB, "SUBAq"); } +mVUop(mVU_SUBAx) { mVU_FMAC5 (SUB, "SUBAx"); } +mVUop(mVU_SUBAy) { mVU_FMAC5 (SUB, "SUBAy"); } +mVUop(mVU_SUBAz) { mVU_FMAC5 (SUB, "SUBAz"); } +mVUop(mVU_SUBAw) { mVU_FMAC5 (SUB, "SUBAw"); } +mVUop(mVU_MUL) { mVU_FMAC1 (MUL, "MUL"); } +mVUop(mVU_MULi) { mVU_FMAC6 (MUL, "MULi"); } +mVUop(mVU_MULq) { mVU_FMAC22(MUL, "MULq"); } +mVUop(mVU_MULx) { mVU_FMAC3 (MUL, "MULx"); } +mVUop(mVU_MULy) { mVU_FMAC3 (MUL, "MULy"); } +mVUop(mVU_MULz) { mVU_FMAC3 (MUL, "MULz"); } +mVUop(mVU_MULw) { mVU_FMAC3 (MUL, "MULw"); } +mVUop(mVU_MULA) { mVU_FMAC4 (MUL, "MULA"); } +mVUop(mVU_MULAi) { mVU_FMAC7 (MUL, "MULAi"); } +mVUop(mVU_MULAq) { mVU_FMAC23(MUL, "MULAq"); } +mVUop(mVU_MULAx) { mVU_FMAC5 (MUL, "MULAx"); } +mVUop(mVU_MULAy) { mVU_FMAC5 (MUL, "MULAy"); } +mVUop(mVU_MULAz) { mVU_FMAC5 (MUL, "MULAz"); } +mVUop(mVU_MULAw) { mVU_FMAC5 (MUL, "MULAw"); } +mVUop(mVU_MADD) { mVU_FMAC8 (ADD, "MADD"); } +mVUop(mVU_MADDi) { mVU_FMAC12(ADD, "MADDi"); } +mVUop(mVU_MADDq) { mVU_FMAC24(ADD, "MADDq"); } +mVUop(mVU_MADDx) { mVU_FMAC10(ADD, "MADDx"); } +mVUop(mVU_MADDy) { mVU_FMAC10(ADD, "MADDy"); } +mVUop(mVU_MADDz) { mVU_FMAC10(ADD, "MADDz"); } +mVUop(mVU_MADDw) { mVU_FMAC10(ADD, "MADDw"); } +mVUop(mVU_MADDA) { mVU_FMAC14(ADD, "MADDA"); } +mVUop(mVU_MADDAi) { mVU_FMAC16(ADD, "MADDAi"); } +mVUop(mVU_MADDAq) { mVU_FMAC26(ADD, "MADDAq"); } +mVUop(mVU_MADDAx) { mVU_FMAC15(ADD, "MADDAx"); } +mVUop(mVU_MADDAy) { mVU_FMAC15(ADD, "MADDAy"); } +mVUop(mVU_MADDAz) { mVU_FMAC15(ADD, "MADDAz"); } +mVUop(mVU_MADDAw) { mVU_FMAC15(ADD, "MADDAw"); } +mVUop(mVU_MSUB) { mVU_FMAC9 (SUB, "MSUB"); } +mVUop(mVU_MSUBi) { mVU_FMAC13(SUB, "MSUBi"); } +mVUop(mVU_MSUBq) { mVU_FMAC25(SUB, "MSUBq"); } +mVUop(mVU_MSUBx) { mVU_FMAC11(SUB, "MSUBx"); } +mVUop(mVU_MSUBy) { mVU_FMAC11(SUB, "MSUBy"); } +mVUop(mVU_MSUBz) { mVU_FMAC11(SUB, "MSUBz"); } +mVUop(mVU_MSUBw) { mVU_FMAC11(SUB, "MSUBw"); } +mVUop(mVU_MSUBA) { mVU_FMAC14(SUB, "MSUBA"); } +mVUop(mVU_MSUBAi) { mVU_FMAC16(SUB, "MSUBAi"); } +mVUop(mVU_MSUBAq) { mVU_FMAC26(SUB, "MSUBAq"); } +mVUop(mVU_MSUBAx) { mVU_FMAC15(SUB, "MSUBAx"); } +mVUop(mVU_MSUBAy) { mVU_FMAC15(SUB, "MSUBAy"); } +mVUop(mVU_MSUBAz) { mVU_FMAC15(SUB, "MSUBAz"); } +mVUop(mVU_MSUBAw) { mVU_FMAC15(SUB, "MSUBAw"); } +mVUop(mVU_MAX) { mVU_FMAC27(MAX2, "MAX"); } +mVUop(mVU_MAXi) { mVU_FMAC28(MAX2, "MAXi"); } +mVUop(mVU_MAXx) { mVU_FMAC29(MAX2, "MAXx"); } +mVUop(mVU_MAXy) { mVU_FMAC29(MAX2, "MAXy"); } +mVUop(mVU_MAXz) { mVU_FMAC29(MAX2, "MAXz"); } +mVUop(mVU_MAXw) { mVU_FMAC29(MAX2, "MAXw"); } +mVUop(mVU_MINI) { mVU_FMAC27(MIN2, "MINI"); } +mVUop(mVU_MINIi) { mVU_FMAC28(MIN2, "MINIi"); } +mVUop(mVU_MINIx) { mVU_FMAC29(MIN2, "MINIx"); } +mVUop(mVU_MINIy) { mVU_FMAC29(MIN2, "MINIy"); } +mVUop(mVU_MINIz) { mVU_FMAC29(MIN2, "MINIz"); } +mVUop(mVU_MINIw) { mVU_FMAC29(MIN2, "MINIw"); } +mVUop(mVU_OPMULA) { mVU_FMAC18(MUL, "OPMULA"); } +mVUop(mVU_OPMSUB) { mVU_FMAC19(SUB, "OPMSUB"); } +mVUop(mVU_NOP) { pass3 { mVUlog("NOP"); } } +void mVU_FTOIx(mP, uptr addr) { + pass1 { mVUanalyzeFMAC2(mVU, _Fs_, _Ft_); } pass2 { int Fs, Ft; - mVUallocFMAC2a(Fs, Ft); + mVUallocFMAC2a(mVU, Fs, Ft); // Note: For help understanding this algorithm see recVUMI_FTOI_Saturate() SSE_MOVAPS_XMM_to_XMM(xmmT1, Fs); @@ -585,38 +556,36 @@ microVUq(void) mVU_FTOIx(uptr addr) { SSE_ANDPS_XMM_to_XMM(xmmT1, xmmFt); SSE2_PADDD_XMM_to_XMM(Fs, xmmT1); - mVUallocFMAC2b(Ft); + mVUallocFMAC2b(mVU, Ft); } } -microVUf(void) mVU_FTOI0() { mVU_FTOIx((uptr)0); pass3 { microVU* mVU = mVUx; mVUlog("FTOI0"); mVUlogFtFs(); } } -microVUf(void) mVU_FTOI4() { mVU_FTOIx((uptr)mVU_FTOI_4); pass3 { microVU* mVU = mVUx; mVUlog("FTOI4"); mVUlogFtFs(); } } -microVUf(void) mVU_FTOI12() { mVU_FTOIx((uptr)mVU_FTOI_12); pass3 { microVU* mVU = mVUx; mVUlog("FTOI12"); mVUlogFtFs(); } } -microVUf(void) mVU_FTOI15() { mVU_FTOIx((uptr)mVU_FTOI_15); pass3 { microVU* mVU = mVUx; mVUlog("FTOI15"); mVUlogFtFs(); } } -microVUq(void) mVU_ITOFx(uptr addr) { - microVU* mVU = mVUx; - pass1 { mVUanalyzeFMAC2(_Fs_, _Ft_); } +mVUop(mVU_FTOI0) { mVU_FTOIx(mX, (uptr)0); pass3 { mVUlog("FTOI0"); mVUlogFtFs(); } } +mVUop(mVU_FTOI4) { mVU_FTOIx(mX, (uptr)mVU_FTOI_4); pass3 { mVUlog("FTOI4"); mVUlogFtFs(); } } +mVUop(mVU_FTOI12) { mVU_FTOIx(mX, (uptr)mVU_FTOI_12); pass3 { mVUlog("FTOI12"); mVUlogFtFs(); } } +mVUop(mVU_FTOI15) { mVU_FTOIx(mX, (uptr)mVU_FTOI_15); pass3 { mVUlog("FTOI15"); mVUlogFtFs(); } } +void mVU_ITOFx(mP, uptr addr) { + pass1 { mVUanalyzeFMAC2(mVU, _Fs_, _Ft_); } pass2 { int Fs, Ft; - mVUallocFMAC2a(Fs, Ft); + mVUallocFMAC2a(mVU, Fs, Ft); SSE2_CVTDQ2PS_XMM_to_XMM(Ft, Fs); if (addr) { SSE_MULPS_M128_to_XMM(Ft, addr); } //mVUclamp2(Ft, xmmT1, 15); // Clamp (not sure if this is needed) - mVUallocFMAC2b(Ft); + mVUallocFMAC2b(mVU, Ft); } } -microVUf(void) mVU_ITOF0() { mVU_ITOFx((uptr)0); pass3 { microVU* mVU = mVUx; mVUlog("ITOF0"); mVUlogFtFs(); } } -microVUf(void) mVU_ITOF4() { mVU_ITOFx((uptr)mVU_ITOF_4); pass3 { microVU* mVU = mVUx; mVUlog("ITOF4"); mVUlogFtFs(); } } -microVUf(void) mVU_ITOF12() { mVU_ITOFx((uptr)mVU_ITOF_12); pass3 { microVU* mVU = mVUx; mVUlog("ITOF12"); mVUlogFtFs(); } } -microVUf(void) mVU_ITOF15() { mVU_ITOFx((uptr)mVU_ITOF_15); pass3 { microVU* mVU = mVUx; mVUlog("ITOF15"); mVUlogFtFs(); } } -microVUf(void) mVU_CLIP() { - microVU* mVU = mVUx; - pass1 { mVUanalyzeFMAC4(_Fs_, _Ft_); } +mVUop(mVU_ITOF0) { mVU_ITOFx(mX, (uptr)0); pass3 { mVUlog("ITOF0"); mVUlogFtFs(); } } +mVUop(mVU_ITOF4) { mVU_ITOFx(mX, (uptr)mVU_ITOF_4); pass3 { mVUlog("ITOF4"); mVUlogFtFs(); } } +mVUop(mVU_ITOF12) { mVU_ITOFx(mX, (uptr)mVU_ITOF_12); pass3 { mVUlog("ITOF12"); mVUlogFtFs(); } } +mVUop(mVU_ITOF15) { mVU_ITOFx(mX, (uptr)mVU_ITOF_15); pass3 { mVUlog("ITOF15"); mVUlogFtFs(); } } +mVUop(mVU_CLIP) { + pass1 { mVUanalyzeFMAC4(mVU, _Fs_, _Ft_); } pass2 { int Fs, Ft; - mVUallocFMAC17a(Fs, Ft); - mVUallocCFLAGa(gprT1, fpcInstance); + mVUallocFMAC17a(mVU, Fs, Ft); + mVUallocCFLAGa(mVU, gprT1, cFLAG.lastWrite); SHL32ItoR(gprT1, 6); SSE_ANDPS_M128_to_XMM(Ft, (uptr)mVU_absclip); @@ -640,8 +609,8 @@ microVUf(void) mVU_CLIP() { OR32RtoR (gprT1, gprT2); AND32ItoR(gprT1, 0xffffff); - mVUallocCFLAGb(gprT1, fcInstance); + mVUallocCFLAGb(mVU, gprT1, cFLAG.write); } pass3 { mVUlog("CLIP"); mVUlogCLIP(); } } -#endif //PCSX2_MICROVU + diff --git a/pcsx2/x86/iVUops.h b/pcsx2/x86/sVU_Debug.h similarity index 95% rename from pcsx2/x86/iVUops.h rename to pcsx2/x86/sVU_Debug.h index e369935c19..9c6c023e9a 100644 --- a/pcsx2/x86/iVUops.h +++ b/pcsx2/x86/sVU_Debug.h @@ -1,57 +1,59 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#define REC_VUOP(VU, f) { \ - _freeXMMregs(/*&VU*/); \ - _freeMMXregs(); \ - SetFPUstate();) \ - MOV32ItoM((uptr)&VU.code, (u32)VU.code); \ - CALLFunc((uptr)VU##MI_##f); \ -} - -#define REC_VUOPs(VU, f) { \ - _freeXMMregs(); \ - _freeMMXregs(); \ - SetFPUstate();) \ - if (VU==&VU1) { \ - MOV32ItoM((uptr)&VU1.code, (u32)VU1.code); \ - CALLFunc((uptr)VU1MI_##f); \ - } \ - else { \ - MOV32ItoM((uptr)&VU0.code, (u32)VU0.code); \ - CALLFunc((uptr)VU0MI_##f); \ - } \ -} - -#define REC_VUOPFLAGS(VU, f) { \ - _freeXMMregs(/*&VU*/); \ - _freeMMXregs(); \ - SetFPUstate(); \ - MOV32ItoM((uptr)&VU.code, (u32)VU.code); \ - CALLFunc((uptr)VU##MI_##f); \ -} - -#define REC_VUBRANCH(VU, f) { \ - _freeXMMregs(/*&VU*/); \ - _freeMMXregs(); \ - SetFPUstate(); \ - MOV32ItoM((uptr)&VU.code, (u32)VU.code); \ - MOV32ItoM((uptr)&VU.VI[REG_TPC].UL, (u32)pc); \ - CALLFunc((uptr)VU##MI_##f); \ - branch = 1; \ -} +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +#define REC_VUOP(VU, f) { \ + _freeXMMregs(/*&VU*/); \ + _freeMMXregs(); \ + SetFPUstate();) \ + MOV32ItoM((uptr)&VU.code, (u32)VU.code); \ + CALLFunc((uptr)VU##MI_##f); \ +} + +#define REC_VUOPs(VU, f) { \ + _freeXMMregs(); \ + _freeMMXregs(); \ + SetFPUstate();) \ + if (VU==&VU1) { \ + MOV32ItoM((uptr)&VU1.code, (u32)VU1.code); \ + CALLFunc((uptr)VU1MI_##f); \ + } \ + else { \ + MOV32ItoM((uptr)&VU0.code, (u32)VU0.code); \ + CALLFunc((uptr)VU0MI_##f); \ + } \ +} + +#define REC_VUOPFLAGS(VU, f) { \ + _freeXMMregs(/*&VU*/); \ + _freeMMXregs(); \ + SetFPUstate(); \ + MOV32ItoM((uptr)&VU.code, (u32)VU.code); \ + CALLFunc((uptr)VU##MI_##f); \ +} + +#define REC_VUBRANCH(VU, f) { \ + _freeXMMregs(/*&VU*/); \ + _freeMMXregs(); \ + SetFPUstate(); \ + MOV32ItoM((uptr)&VU.code, (u32)VU.code); \ + MOV32ItoM((uptr)&VU.VI[REG_TPC].UL, (u32)pc); \ + CALLFunc((uptr)VU##MI_##f); \ + branch = 1; \ +} diff --git a/pcsx2/x86/iVUmicroLower.cpp b/pcsx2/x86/sVU_Lower.cpp similarity index 80% rename from pcsx2/x86/iVUmicroLower.cpp rename to pcsx2/x86/sVU_Lower.cpp index f98ed4549c..fae6df31ee 100644 --- a/pcsx2/x86/iVUmicroLower.cpp +++ b/pcsx2/x86/sVU_Lower.cpp @@ -1,1993 +1,2009 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "PrecompiledHeader.h" - -#include "Common.h" -#include "GS.h" -#include "R5900OpcodeTables.h" -#include "iR5900.h" -#include "iMMI.h" -#include "iFPU.h" -#include "iCOP0.h" -#include "VUmicro.h" -#include "VUflags.h" -#include "iVUmicro.h" -#include "iVUops.h" -#include "iVUzerorec.h" -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// Helper Macros -//------------------------------------------------------------------ -#define _Ft_ (( VU->code >> 16) & 0x1F) // The rt part of the instruction register -#define _Fs_ (( VU->code >> 11) & 0x1F) // The rd part of the instruction register -#define _Fd_ (( VU->code >> 6) & 0x1F) // The sa part of the instruction register - -#define _X (( VU->code>>24) & 0x1) -#define _Y (( VU->code>>23) & 0x1) -#define _Z (( VU->code>>22) & 0x1) -#define _W (( VU->code>>21) & 0x1) - -#define _XYZW_SS (_X+_Y+_Z+_W==1) - -#define _Fsf_ (( VU->code >> 21) & 0x03) -#define _Ftf_ (( VU->code >> 23) & 0x03) - -#define _Imm11_ (s32)(VU->code & 0x400 ? 0xfffffc00 | (VU->code & 0x3ff) : VU->code & 0x3ff) -#define _UImm11_ (s32)(VU->code & 0x7ff) - -#define VU_VFx_ADDR(x) (uptr)&VU->VF[x].UL[0] -#define VU_VFy_ADDR(x) (uptr)&VU->VF[x].UL[1] -#define VU_VFz_ADDR(x) (uptr)&VU->VF[x].UL[2] -#define VU_VFw_ADDR(x) (uptr)&VU->VF[x].UL[3] - -#define VU_REGR_ADDR (uptr)&VU->VI[REG_R] -#define VU_REGQ_ADDR (uptr)&VU->VI[REG_Q] -#define VU_REGMAC_ADDR (uptr)&VU->VI[REG_MAC_FLAG] - -#define VU_VI_ADDR(x, read) GetVIAddr(VU, x, read, info) - -#define VU_ACCx_ADDR (uptr)&VU->ACC.UL[0] -#define VU_ACCy_ADDR (uptr)&VU->ACC.UL[1] -#define VU_ACCz_ADDR (uptr)&VU->ACC.UL[2] -#define VU_ACCw_ADDR (uptr)&VU->ACC.UL[3] - -#define _X_Y_Z_W ((( VU->code >> 21 ) & 0xF ) ) - - -static const PCSX2_ALIGNED16(u32 VU_ONE[4]) = {0x3f800000, 0xffffffff, 0xffffffff, 0xffffffff}; -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// *VU Lower Instructions!* -// -// Note: * = Checked for errors by cottonvibes -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// DIV* -//------------------------------------------------------------------ -PCSX2_ALIGNED16(u64 DIV_TEMP_XMM[2]); -void recVUMI_DIV(VURegs *VU, int info) -{ - u8 *pjmp, *pjmp1; - u32 *ajmp32, *bjmp32; - - //Console::WriteLn("recVUMI_DIV()"); - AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags - - // FT can be zero here! so we need to check if its zero and set the correct flag. - SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); // Clear EEREC_TEMP - SSE_CMPEQPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); // Set all F's if each vector is zero - - SSE_MOVMSKPS_XMM_to_R32( EAX, EEREC_TEMP); // Move the sign bits of the previous calculation - - AND32ItoR( EAX, (1<<_Ftf_) ); // Grab "Is Zero" bits from the previous calculation - ajmp32 = JZ32(0); // Skip if none are - - SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); // Clear EEREC_TEMP - SSE_CMPEQPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); // Set all F's if each vector is zero - SSE_MOVMSKPS_XMM_to_R32(EAX, EEREC_TEMP); // Move the sign bits of the previous calculation - - AND32ItoR( EAX, (1<<_Fsf_) ); // Grab "Is Zero" bits from the previous calculation - pjmp = JZ8(0); - OR32ItoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x410 ); // Set invalid flag (0/0) - pjmp1 = JMP8(0); - x86SetJ8(pjmp); - OR32ItoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x820 ); // Zero divide (only when not 0/0) - x86SetJ8(pjmp1); - - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); - - _vuFlipRegSS_xyzw(EEREC_T, _Ftf_); - SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - _vuFlipRegSS_xyzw(EEREC_T, _Ftf_); - - SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); - SSE_ORPS_M128_to_XMM(EEREC_TEMP, (uptr)&g_maxvals[0]); // If division by zero, then EEREC_TEMP = +/- fmax - - bjmp32 = JMP32(0); - - x86SetJ32(ajmp32); - - if (CHECK_VU_EXTRA_OVERFLOW) { - vuFloat5_useEAX(EEREC_S, EEREC_TEMP, (1 << (3-_Fsf_))); - vuFloat5_useEAX(EEREC_T, EEREC_TEMP, (1 << (3-_Ftf_))); - } - - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); - - _vuFlipRegSS_xyzw(EEREC_T, _Ftf_); - SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - _vuFlipRegSS_xyzw(EEREC_T, _Ftf_); - - vuFloat_useEAX(info, EEREC_TEMP, 0x8); - - x86SetJ32(bjmp32); - - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), EEREC_TEMP); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// SQRT* -//------------------------------------------------------------------ -void recVUMI_SQRT( VURegs *VU, int info ) -{ - u8* pjmp; - //Console::WriteLn("recVUMI_SQRT()"); - - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, _Ftf_); - AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags - - /* Check for negative sqrt */ - SSE_MOVMSKPS_XMM_to_R32(EAX, EEREC_TEMP); - AND32ItoR(EAX, 1); //Check sign - pjmp = JZ8(0); //Skip if none are - OR32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x410); // Invalid Flag - Negative number sqrt - x86SetJ8(pjmp); - - SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)const_clip); // Do a cardinal sqrt - if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Clamp infinities (only need to do positive clamp since EEREC_TEMP is positive) - SSE_SQRTSS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), EEREC_TEMP); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// RSQRT* -//------------------------------------------------------------------ -PCSX2_ALIGNED16(u64 RSQRT_TEMP_XMM[2]); -void recVUMI_RSQRT(VURegs *VU, int info) -{ - u8 *ajmp8, *bjmp8; - u8 *qjmp1, *qjmp2; - int t1reg, t1boolean; - //Console::WriteLn("recVUMI_RSQRT()"); - - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, _Ftf_); - AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags - - /* Check for negative divide */ - SSE_MOVMSKPS_XMM_to_R32(EAX, EEREC_TEMP); - AND32ItoR(EAX, 1); //Check sign - ajmp8 = JZ8(0); //Skip if none are - OR32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x410); // Invalid Flag - Negative number sqrt - x86SetJ8(ajmp8); - - SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)const_clip); // Do a cardinal sqrt - if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Clamp Infinities to Fmax - SSE_SQRTSS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); - - t1reg = _vuGetTempXMMreg(info); - if( t1reg < 0 ) { - for (t1reg = 0; ( (t1reg == EEREC_TEMP) || (t1reg == EEREC_S) ); t1reg++) - ; // Makes t1reg not be EEREC_TEMP or EEREC_S. - SSE_MOVAPS_XMM_to_M128( (uptr)&RSQRT_TEMP_XMM[0], t1reg ); // backup data in t1reg to a temp address - t1boolean = 1; - } - else t1boolean = 0; - - // Ft can still be zero here! so we need to check if its zero and set the correct flag. - SSE_XORPS_XMM_to_XMM(t1reg, t1reg); // Clear t1reg - SSE_CMPEQSS_XMM_to_XMM(t1reg, EEREC_TEMP); // Set all F's if each vector is zero - - SSE_MOVMSKPS_XMM_to_R32(EAX, t1reg); // Move the sign bits of the previous calculation - - AND32ItoR( EAX, 0x01 ); // Grab "Is Zero" bits from the previous calculation - ajmp8 = JZ8(0); // Skip if none are - - //check for 0/0 - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); - - SSE_XORPS_XMM_to_XMM(t1reg, t1reg); // Clear EEREC_TEMP - SSE_CMPEQPS_XMM_to_XMM(t1reg, EEREC_TEMP); // Set all F's if each vector is zero - SSE_MOVMSKPS_XMM_to_R32(EAX, t1reg); // Move the sign bits of the previous calculation - - AND32ItoR( EAX, 0x01 ); // Grab "Is Zero" bits from the previous calculation - qjmp1 = JZ8(0); - OR32ItoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x410 ); // Set invalid flag (0/0) - qjmp2 = JMP8(0); - x86SetJ8(qjmp1); - OR32ItoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x820 ); // Zero divide (only when not 0/0) - x86SetJ8(qjmp2); - - SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); - SSE_ORPS_M128_to_XMM(EEREC_TEMP, (uptr)&g_maxvals[0]); // If division by zero, then EEREC_TEMP = +/- fmax - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), EEREC_TEMP); - bjmp8 = JMP8(0); - x86SetJ8(ajmp8); - - _unpackVFSS_xyzw(t1reg, EEREC_S, _Fsf_); - if (CHECK_VU_EXTRA_OVERFLOW) vuFloat_useEAX(info, t1reg, 0x8); // Clamp Infinities - SSE_DIVSS_XMM_to_XMM(t1reg, EEREC_TEMP); - vuFloat_useEAX(info, t1reg, 0x8); - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), t1reg); - - x86SetJ8(bjmp8); - - if (t1boolean) SSE_MOVAPS_M128_to_XMM( t1reg, (uptr)&RSQRT_TEMP_XMM[0] ); // restore t1reg data - else _freeXMMreg(t1reg); // free t1reg -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// _addISIMMtoIT() - Used in IADDI, IADDIU, and ISUBIU instructions -//------------------------------------------------------------------ -void _addISIMMtoIT(VURegs *VU, s16 imm, int info) -{ - int fsreg = -1, ftreg; - if (_Ft_ == 0) return; - - if( _Fs_ == 0 ) { - ftreg = ALLOCVI(_Ft_, MODE_WRITE); - MOV32ItoR(ftreg, imm&0xffff); - return; - } - - ADD_VI_NEEDED(_Ft_); - fsreg = ALLOCVI(_Fs_, MODE_READ); - ftreg = ALLOCVI(_Ft_, MODE_WRITE); - - if ( _Ft_ == _Fs_ ) { - if (imm != 0 ) ADD16ItoR(ftreg, imm); - } - else { - if( imm ) { - LEA32RtoR(ftreg, fsreg, imm); - MOVZX32R16toR(ftreg, ftreg); - } - else MOV32RtoR(ftreg, fsreg); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// IADDI -//------------------------------------------------------------------ -void recVUMI_IADDI(VURegs *VU, int info) -{ - s16 imm; - - if ( _Ft_ == 0 ) return; - //Console::WriteLn("recVUMI_IADDI"); - imm = ( VU->code >> 6 ) & 0x1f; - imm = ( imm & 0x10 ? 0xfff0 : 0) | ( imm & 0xf ); - _addISIMMtoIT(VU, imm, info); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// IADDIU -//------------------------------------------------------------------ -void recVUMI_IADDIU(VURegs *VU, int info) -{ - s16 imm; - - if ( _Ft_ == 0 ) return; - //Console::WriteLn("recVUMI_IADDIU"); - imm = ( ( VU->code >> 10 ) & 0x7800 ) | ( VU->code & 0x7ff ); - _addISIMMtoIT(VU, imm, info); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// IADD -//------------------------------------------------------------------ -void recVUMI_IADD( VURegs *VU, int info ) -{ - int fdreg, fsreg = -1, ftreg = -1; - if ( _Fd_ == 0 ) return; - //Console::WriteLn("recVUMI_IADD"); - if ( ( _Ft_ == 0 ) && ( _Fs_ == 0 ) ) { - fdreg = ALLOCVI(_Fd_, MODE_WRITE); - XOR32RtoR(fdreg, fdreg); - return; - } - - ADD_VI_NEEDED(_Fs_); - ADD_VI_NEEDED(_Ft_); - fdreg = ALLOCVI(_Fd_, MODE_WRITE); - - if ( _Fs_ == 0 ) - { - if( (ftreg = _checkX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Ft_, MODE_READ)) >= 0 ) { - if( fdreg != ftreg ) MOV32RtoR(fdreg, ftreg); - } - else MOVZX32M16toR(fdreg, VU_VI_ADDR(_Ft_, 1)); - } - else if ( _Ft_ == 0 ) - { - if( (fsreg = _checkX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Fs_, MODE_READ)) >= 0 ) { - if( fdreg != fsreg ) MOV32RtoR(fdreg, fsreg); - } - else MOVZX32M16toR(fdreg, VU_VI_ADDR(_Fs_, 1)); - } - else { - //ADD_VI_NEEDED(_Ft_); - fsreg = ALLOCVI(_Fs_, MODE_READ); - ftreg = ALLOCVI(_Ft_, MODE_READ); - - if( fdreg == fsreg ) ADD32RtoR(fdreg, ftreg); - else if( fdreg == ftreg ) ADD32RtoR(fdreg, fsreg); - else LEA32RRtoR(fdreg, fsreg, ftreg); - MOVZX32R16toR(fdreg, fdreg); // needed since don't know if fdreg's upper bits are 0 - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// IAND -//------------------------------------------------------------------ -void recVUMI_IAND( VURegs *VU, int info ) -{ - int fdreg, fsreg = -1, ftreg = -1; - if ( _Fd_ == 0 ) return; - //Console::WriteLn("recVUMI_IAND"); - if ( ( _Fs_ == 0 ) || ( _Ft_ == 0 ) ) { - fdreg = ALLOCVI(_Fd_, MODE_WRITE); - XOR32RtoR(fdreg, fdreg); - return; - } - - ADD_VI_NEEDED(_Fs_); - ADD_VI_NEEDED(_Ft_); - fdreg = ALLOCVI(_Fd_, MODE_WRITE); - - fsreg = ALLOCVI(_Fs_, MODE_READ); - ftreg = ALLOCVI(_Ft_, MODE_READ); - - if( fdreg == fsreg ) AND16RtoR(fdreg, ftreg); - else if( fdreg == ftreg ) AND16RtoR(fdreg, fsreg); - else { - MOV32RtoR(fdreg, ftreg); - AND32RtoR(fdreg, fsreg); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// IOR -//------------------------------------------------------------------ -void recVUMI_IOR( VURegs *VU, int info ) -{ - int fdreg, fsreg = -1, ftreg = -1; - if ( _Fd_ == 0 ) return; - //Console::WriteLn("recVUMI_IOR"); - if ( ( _Ft_ == 0 ) && ( _Fs_ == 0 ) ) { - fdreg = ALLOCVI(_Fd_, MODE_WRITE); - XOR32RtoR(fdreg, fdreg); - return; - } - - ADD_VI_NEEDED(_Fs_); - ADD_VI_NEEDED(_Ft_); - fdreg = ALLOCVI(_Fd_, MODE_WRITE); - - if ( _Fs_ == 0 ) - { - if( (ftreg = _checkX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Ft_, MODE_READ)) >= 0 ) { - if( fdreg != ftreg ) MOV32RtoR(fdreg, ftreg); - } - else MOVZX32M16toR(fdreg, VU_VI_ADDR(_Ft_, 1)); - } - else if ( _Ft_ == 0 ) - { - if( (fsreg = _checkX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Fs_, MODE_READ)) >= 0 ) { - if( fdreg != fsreg ) MOV32RtoR(fdreg, fsreg); - } - else MOVZX32M16toR(fdreg, VU_VI_ADDR(_Fs_, 1)); - } - else - { - fsreg = ALLOCVI(_Fs_, MODE_READ); - ftreg = ALLOCVI(_Ft_, MODE_READ); - - if( fdreg == fsreg ) OR16RtoR(fdreg, ftreg); - else if( fdreg == ftreg ) OR16RtoR(fdreg, fsreg); - else { - MOV32RtoR(fdreg, fsreg); - OR32RtoR(fdreg, ftreg); - } - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ISUB -//------------------------------------------------------------------ -void recVUMI_ISUB( VURegs *VU, int info ) -{ - int fdreg, fsreg = -1, ftreg = -1; - if ( _Fd_ == 0 ) return; - //Console::WriteLn("recVUMI_ISUB"); - if ( ( _Ft_ == 0 ) && ( _Fs_ == 0 ) ) { - fdreg = ALLOCVI(_Fd_, MODE_WRITE); - XOR32RtoR(fdreg, fdreg); - return; - } - - ADD_VI_NEEDED(_Fs_); - ADD_VI_NEEDED(_Ft_); - fdreg = ALLOCVI(_Fd_, MODE_WRITE); - - if ( _Fs_ == 0 ) - { - if( (ftreg = _checkX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Ft_, MODE_READ)) >= 0 ) { - if( fdreg != ftreg ) MOV32RtoR(fdreg, ftreg); - } - else MOVZX32M16toR(fdreg, VU_VI_ADDR(_Ft_, 1)); - NEG16R(fdreg); - } - else if ( _Ft_ == 0 ) - { - if( (fsreg = _checkX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Fs_, MODE_READ)) >= 0 ) { - if( fdreg != fsreg ) MOV32RtoR(fdreg, fsreg); - } - else MOVZX32M16toR(fdreg, VU_VI_ADDR(_Fs_, 1)); - } - else - { - fsreg = ALLOCVI(_Fs_, MODE_READ); - ftreg = ALLOCVI(_Ft_, MODE_READ); - - if( fdreg == fsreg ) SUB16RtoR(fdreg, ftreg); - else if( fdreg == ftreg ) { - SUB16RtoR(fdreg, fsreg); - NEG16R(fdreg); - } - else { - MOV32RtoR(fdreg, fsreg); - SUB16RtoR(fdreg, ftreg); - } - } -} -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// ISUBIU -//------------------------------------------------------------------ -void recVUMI_ISUBIU( VURegs *VU, int info ) -{ - s16 imm; - - if ( _Ft_ == 0 ) return; - //Console::WriteLn("recVUMI_ISUBIU"); - imm = ( ( VU->code >> 10 ) & 0x7800 ) | ( VU->code & 0x7ff ); - imm = -imm; - _addISIMMtoIT(VU, imm, info); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// MOVE* -//------------------------------------------------------------------ -void recVUMI_MOVE( VURegs *VU, int info ) -{ - if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; - //Console::WriteLn("recVUMI_MOVE"); - if (_X_Y_Z_W == 0x8) SSE_MOVSS_XMM_to_XMM(EEREC_T, EEREC_S); - else if (_X_Y_Z_W == 0xf) SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_S); - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_T, EEREC_TEMP); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// MFIR* -//------------------------------------------------------------------ -void recVUMI_MFIR( VURegs *VU, int info ) -{ - if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; - //Console::WriteLn("recVUMI_MFIR"); - _deleteX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Fs_, 1); - - if( _XYZW_SS ) { - SSE2_MOVD_M32_to_XMM(EEREC_TEMP, VU_VI_ADDR(_Fs_, 1)-2); - _vuFlipRegSS(VU, EEREC_T); - SSE2_PSRAD_I8_to_XMM(EEREC_TEMP, 16); - SSE_MOVSS_XMM_to_XMM(EEREC_T, EEREC_TEMP); - _vuFlipRegSS(VU, EEREC_T); - } - else if (_X_Y_Z_W != 0xf) { - SSE2_MOVD_M32_to_XMM(EEREC_TEMP, VU_VI_ADDR(_Fs_, 1)-2); - SSE2_PSRAD_I8_to_XMM(EEREC_TEMP, 16); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0); - VU_MERGE_REGS(EEREC_T, EEREC_TEMP); - } - else { - SSE2_MOVD_M32_to_XMM(EEREC_T, VU_VI_ADDR(_Fs_, 1)-2); - SSE2_PSRAD_I8_to_XMM(EEREC_T, 16); - SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// MTIR* -//------------------------------------------------------------------ -void recVUMI_MTIR( VURegs *VU, int info ) -{ - if ( _Ft_ == 0 ) return; - //Console::WriteLn("recVUMI_MTIR"); - _deleteX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Ft_, 2); - - if( _Fsf_ == 0 ) { - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(_Ft_, 0), EEREC_S); - } - else { - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(_Ft_, 0), EEREC_TEMP); - } - - AND32ItoM(VU_VI_ADDR(_Ft_, 0), 0xffff); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// MR32* -//------------------------------------------------------------------ -void recVUMI_MR32( VURegs *VU, int info ) -{ - if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; - //Console::WriteLn("recVUMI_MR32"); - if (_X_Y_Z_W != 0xf) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x39); - VU_MERGE_REGS(EEREC_T, EEREC_TEMP); - } - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_S); - SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0x39); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// _loadEAX() -// -// NOTE: If x86reg < 0, reads directly from offset -//------------------------------------------------------------------ -void _loadEAX(VURegs *VU, int x86reg, uptr offset, int info) -{ - assert( offset < 0x80000000 ); - - if( x86reg >= 0 ) { - switch(_X_Y_Z_W) { - case 3: // ZW - SSE_MOVHPS_Rm_to_XMM(EEREC_T, x86reg, offset+8); - break; - case 6: // YZ - SSE_SHUFPS_Rm_to_XMM(EEREC_T, x86reg, offset, 0x9c); - SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0x78); - break; - - case 8: // X - SSE_MOVSS_Rm_to_XMM(EEREC_TEMP, x86reg, offset); - SSE_MOVSS_XMM_to_XMM(EEREC_T, EEREC_TEMP); - break; - case 9: // XW - SSE_SHUFPS_Rm_to_XMM(EEREC_T, x86reg, offset, 0xc9); - SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0xd2); - break; - case 12: // XY - SSE_MOVLPS_Rm_to_XMM(EEREC_T, x86reg, offset); - break; - case 15: - if( VU == &VU1 ) SSE_MOVAPSRmtoR(EEREC_T, x86reg, offset); - else SSE_MOVUPSRmtoR(EEREC_T, x86reg, offset); - break; - default: - if( VU == &VU1 ) SSE_MOVAPSRmtoR(EEREC_TEMP, x86reg, offset); - else SSE_MOVUPSRmtoR(EEREC_TEMP, x86reg, offset); - - VU_MERGE_REGS(EEREC_T, EEREC_TEMP); - break; - } - } - else { - switch(_X_Y_Z_W) { - case 3: // ZW - SSE_MOVHPS_M64_to_XMM(EEREC_T, offset+8); - break; - case 6: // YZ - SSE_SHUFPS_M128_to_XMM(EEREC_T, offset, 0x9c); - SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0x78); - break; - case 8: // X - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, offset); - SSE_MOVSS_XMM_to_XMM(EEREC_T, EEREC_TEMP); - break; - case 9: // XW - SSE_SHUFPS_M128_to_XMM(EEREC_T, offset, 0xc9); - SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0xd2); - break; - case 12: // XY - SSE_MOVLPS_M64_to_XMM(EEREC_T, offset); - break; - case 15: - if( VU == &VU1 ) SSE_MOVAPS_M128_to_XMM(EEREC_T, offset); - else SSE_MOVUPS_M128_to_XMM(EEREC_T, offset); - break; - default: - if( VU == &VU1 ) SSE_MOVAPS_M128_to_XMM(EEREC_TEMP, offset); - else SSE_MOVUPS_M128_to_XMM(EEREC_TEMP, offset); - VU_MERGE_REGS(EEREC_T, EEREC_TEMP); - break; - } - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// recVUTransformAddr() -//------------------------------------------------------------------ -int recVUTransformAddr(int x86reg, VURegs* VU, int vireg, int imm) -{ - u8* pjmp[2]; - if( x86reg == EAX ) { - if (imm) ADD32ItoR(x86reg, imm); - } - else { - if( imm ) LEA32RtoR(EAX, x86reg, imm); - else MOV32RtoR(EAX, x86reg); - } - - if( VU == &VU1 ) { - AND32ItoR(EAX, 0x3ff); // wrap around - SHL32ItoR(EAX, 4); - } - else { - - // VU0 has a somewhat interesting memory mapping: - // if addr >= 0x4000, reads VU1's VF regs and VI regs - // if addr < 0x4000, wrap around at 0x1000 - - CMP32ItoR(EAX, 0x400); - pjmp[0] = JL8(0); // if addr >= 0x4000, reads VU1's VF regs and VI regs - AND32ItoR(EAX, 0x43f); - pjmp[1] = JMP8(0); - x86SetJ8(pjmp[0]); - AND32ItoR(EAX, 0xff); // if addr < 0x4000, wrap around - x86SetJ8(pjmp[1]); - - SHL32ItoR(EAX, 4); // multiply by 16 (shift left by 4) - } - - return EAX; -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// LQ -//------------------------------------------------------------------ -void recVUMI_LQ(VURegs *VU, int info) -{ - s16 imm; - if ( _Ft_ == 0 ) return; - //Console::WriteLn("recVUMI_LQ"); - imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); - if (_Fs_ == 0) { - _loadEAX(VU, -1, (uptr)GET_VU_MEM(VU, (u32)imm*16), info); - } - else { - int fsreg = ALLOCVI(_Fs_, MODE_READ); - _loadEAX(VU, recVUTransformAddr(fsreg, VU, _Fs_, imm), (uptr)VU->Mem, info); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// LQD -//------------------------------------------------------------------ -void recVUMI_LQD( VURegs *VU, int info ) -{ - int fsreg; - //Console::WriteLn("recVUMI_LQD"); - if ( _Fs_ != 0 ) { - fsreg = ALLOCVI(_Fs_, MODE_READ|MODE_WRITE); - SUB16ItoR( fsreg, 1 ); - } - - if ( _Ft_ == 0 ) return; - - if ( _Fs_ == 0 ) _loadEAX(VU, -1, (uptr)VU->Mem, info); - else _loadEAX(VU, recVUTransformAddr(fsreg, VU, _Fs_, 0), (uptr)VU->Mem, info); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// LQI -//------------------------------------------------------------------ -void recVUMI_LQI(VURegs *VU, int info) -{ - int fsreg; - //Console::WriteLn("recVUMI_LQI"); - if ( _Ft_ == 0 ) { - if( _Fs_ != 0 ) { - if( (fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_WRITE|MODE_READ)) >= 0 ) { - ADD16ItoR(fsreg, 1); - } - else { - ADD16ItoM( VU_VI_ADDR( _Fs_, 0 ), 1 ); - } - } - return; - } - - if (_Fs_ == 0) { - _loadEAX(VU, -1, (uptr)VU->Mem, info); - } - else { - fsreg = ALLOCVI(_Fs_, MODE_READ|MODE_WRITE); - _loadEAX(VU, recVUTransformAddr(fsreg, VU, _Fs_, 0), (uptr)VU->Mem, info); - ADD16ItoR( fsreg, 1 ); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// _saveEAX() -//------------------------------------------------------------------ -void _saveEAX(VURegs *VU, int x86reg, uptr offset, int info) -{ - assert( offset < 0x80000000 ); - - if ( _Fs_ == 0 ) { - if ( _XYZW_SS ) { - u32 c = _W ? 0x3f800000 : 0; - if ( x86reg >= 0 ) MOV32ItoRm(x86reg, c, offset+(_W?12:(_Z?8:(_Y?4:0)))); - else MOV32ItoM(offset+(_W?12:(_Z?8:(_Y?4:0))), c); - } - else { - - // (this is one of my test cases for the new emitter --air) - using namespace x86Emitter; - xAddressReg thisreg( x86reg ); - - if ( _X ) xMOV(ptr32[thisreg+offset], 0x00000000); - if ( _Y ) xMOV(ptr32[thisreg+offset+4], 0x00000000); - if ( _Z ) xMOV(ptr32[thisreg+offset+8], 0x00000000); - if ( _W ) xMOV(ptr32[thisreg+offset+12], 0x3f800000); - } - return; - } - - switch ( _X_Y_Z_W ) { - case 1: // W - SSE2_PSHUFD_XMM_to_XMM(EEREC_TEMP, EEREC_S, 0x27); - if ( x86reg >= 0 ) SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+12); - else SSE_MOVSS_XMM_to_M32(offset+12, EEREC_TEMP); - break; - case 2: // Z - SSE_MOVHLPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if ( x86reg >= 0 ) SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+8); - else SSE_MOVSS_XMM_to_M32(offset+8, EEREC_TEMP); - break; - case 3: // ZW - if ( x86reg >= 0 ) SSE_MOVHPS_XMM_to_Rm(x86reg, EEREC_S, offset+8); - else SSE_MOVHPS_XMM_to_M64(offset+8, EEREC_S); - break; - case 4: // Y - SSE2_PSHUFLW_XMM_to_XMM(EEREC_TEMP, EEREC_S, 0x4e); - if ( x86reg >= 0 ) SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+4); - else SSE_MOVSS_XMM_to_M32(offset+4, EEREC_TEMP); - break; - case 5: // YW - SSE_SHUFPS_XMM_to_XMM(EEREC_S, EEREC_S, 0xB1); - SSE_MOVHLPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if ( x86reg >= 0 ) { - SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_S, offset+4); - SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+12); - } - else { - SSE_MOVSS_XMM_to_M32(offset+4, EEREC_S); - SSE_MOVSS_XMM_to_M32(offset+12, EEREC_TEMP); - } - SSE_SHUFPS_XMM_to_XMM(EEREC_S, EEREC_S, 0xB1); - break; - case 6: // YZ - SSE2_PSHUFD_XMM_to_XMM(EEREC_TEMP, EEREC_S, 0xc9); - if ( x86reg >= 0 ) SSE_MOVLPS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+4); - else SSE_MOVLPS_XMM_to_M64(offset+4, EEREC_TEMP); - break; - case 7: // YZW - SSE2_PSHUFD_XMM_to_XMM(EEREC_TEMP, EEREC_S, 0x93); //ZYXW - if ( x86reg >= 0 ) { - SSE_MOVHPS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+4); - SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+12); - } - else { - SSE_MOVHPS_XMM_to_M64(offset+4, EEREC_TEMP); - SSE_MOVSS_XMM_to_M32(offset+12, EEREC_TEMP); - } - break; - case 8: // X - if ( x86reg >= 0 ) SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_S, offset); - else SSE_MOVSS_XMM_to_M32(offset, EEREC_S); - break; - case 9: // XW - if ( x86reg >= 0 ) SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_S, offset); - else SSE_MOVSS_XMM_to_M32(offset, EEREC_S); - - SSE2_PSHUFD_XMM_to_XMM(EEREC_TEMP, EEREC_S, 0xff); //WWWW - - if ( x86reg >= 0 ) SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+12); - else SSE_MOVSS_XMM_to_M32(offset+12, EEREC_TEMP); - - break; - case 10: //XZ - SSE_MOVHLPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if ( x86reg >= 0 ) { - SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_S, offset); - SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+8); - } - else { - SSE_MOVSS_XMM_to_M32(offset, EEREC_S); - SSE_MOVSS_XMM_to_M32(offset+8, EEREC_TEMP); - } - break; - case 11: //XZW - if ( x86reg >= 0 ) { - SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_S, offset); - SSE_MOVHPS_XMM_to_Rm(x86reg, EEREC_S, offset+8); - } - else { - SSE_MOVSS_XMM_to_M32(offset, EEREC_S); - SSE_MOVHPS_XMM_to_M64(offset+8, EEREC_S); - } - break; - case 12: // XY - if ( x86reg >= 0 ) SSE_MOVLPS_XMM_to_Rm(x86reg, EEREC_S, offset+0); - else SSE_MOVLPS_XMM_to_M64(offset, EEREC_S); - break; - case 13: // XYW - SSE2_PSHUFD_XMM_to_XMM(EEREC_TEMP, EEREC_S, 0x4b); //YXZW - if ( x86reg >= 0 ) { - SSE_MOVHPS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+0); - SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+12); - } - else { - SSE_MOVHPS_XMM_to_M64(offset, EEREC_TEMP); - SSE_MOVSS_XMM_to_M32(offset+12, EEREC_TEMP); - } - break; - case 14: // XYZ - SSE_MOVHLPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if ( x86reg >= 0 ) { - SSE_MOVLPS_XMM_to_Rm(x86reg, EEREC_S, offset+0); - SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+8); - } - else { - SSE_MOVLPS_XMM_to_M64(offset, EEREC_S); - SSE_MOVSS_XMM_to_M32(offset+8, EEREC_TEMP); - } - break; - case 15: // XYZW - if ( VU == &VU1 ) { - if( x86reg >= 0 ) SSE_MOVAPSRtoRm(x86reg, EEREC_S, offset+0); - else SSE_MOVAPS_XMM_to_M128(offset, EEREC_S); - } - else { - if( x86reg >= 0 ) SSE_MOVUPSRtoRm(x86reg, EEREC_S, offset+0); - else { - if( offset & 15 ) SSE_MOVUPS_XMM_to_M128(offset, EEREC_S); - else SSE_MOVAPS_XMM_to_M128(offset, EEREC_S); - } - } - break; - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// SQ -//------------------------------------------------------------------ -void recVUMI_SQ(VURegs *VU, int info) -{ - s16 imm; - //Console::WriteLn("recVUMI_SQ"); - imm = ( VU->code & 0x400) ? ( VU->code & 0x3ff) | 0xfc00 : ( VU->code & 0x3ff); - if ( _Ft_ == 0 ) _saveEAX(VU, -1, (uptr)GET_VU_MEM(VU, (int)imm * 16), info); - else { - int ftreg = ALLOCVI(_Ft_, MODE_READ); - _saveEAX(VU, recVUTransformAddr(ftreg, VU, _Ft_, imm), (uptr)VU->Mem, info); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// SQD -//------------------------------------------------------------------ -void recVUMI_SQD(VURegs *VU, int info) -{ - //Console::WriteLn("recVUMI_SQD"); - if (_Ft_ == 0) _saveEAX(VU, -1, (uptr)VU->Mem, info); - else { - int ftreg = ALLOCVI(_Ft_, MODE_READ|MODE_WRITE); - SUB16ItoR( ftreg, 1 ); - _saveEAX(VU, recVUTransformAddr(ftreg, VU, _Ft_, 0), (uptr)VU->Mem, info); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// SQI -//------------------------------------------------------------------ -void recVUMI_SQI(VURegs *VU, int info) -{ - //Console::WriteLn("recVUMI_SQI"); - if (_Ft_ == 0) _saveEAX(VU, -1, (uptr)VU->Mem, info); - else { - int ftreg = ALLOCVI(_Ft_, MODE_READ|MODE_WRITE); - _saveEAX(VU, recVUTransformAddr(ftreg, VU, _Ft_, 0), (uptr)VU->Mem, info); - ADD16ItoR( ftreg, 1 ); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ILW -//------------------------------------------------------------------ -void recVUMI_ILW(VURegs *VU, int info) -{ - int ftreg; - s16 imm, off; - - if ( ( _Ft_ == 0 ) || ( _X_Y_Z_W == 0 ) ) return; - //Console::WriteLn("recVUMI_ILW"); - imm = ( VU->code & 0x400) ? ( VU->code & 0x3ff) | 0xfc00 : ( VU->code & 0x3ff); - if (_X) off = 0; - else if (_Y) off = 4; - else if (_Z) off = 8; - else if (_W) off = 12; - - ADD_VI_NEEDED(_Fs_); - ftreg = ALLOCVI(_Ft_, MODE_WRITE); - - if ( _Fs_ == 0 ) { - MOVZX32M16toR( ftreg, (uptr)GET_VU_MEM(VU, (int)imm * 16 + off) ); - } - else { - int fsreg = ALLOCVI(_Fs_, MODE_READ); - MOV32RmtoR(ftreg, recVUTransformAddr(fsreg, VU, _Fs_, imm), (uptr)VU->Mem + off); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ISW -//------------------------------------------------------------------ -void recVUMI_ISW( VURegs *VU, int info ) -{ - s16 imm; - //Console::WriteLn("recVUMI_ISW"); - imm = ( VU->code & 0x400) ? ( VU->code & 0x3ff) | 0xfc00 : ( VU->code & 0x3ff); - - if (_Fs_ == 0) { - uptr off = (uptr)GET_VU_MEM(VU, (int)imm * 16); - int ftreg = ALLOCVI(_Ft_, MODE_READ); - - if (_X) MOV32RtoM(off, ftreg); - if (_Y) MOV32RtoM(off+4, ftreg); - if (_Z) MOV32RtoM(off+8, ftreg); - if (_W) MOV32RtoM(off+12, ftreg); - } - else { - int x86reg, fsreg, ftreg; - - ADD_VI_NEEDED(_Ft_); - fsreg = ALLOCVI(_Fs_, MODE_READ); - ftreg = ALLOCVI(_Ft_, MODE_READ); - - x86reg = recVUTransformAddr(fsreg, VU, _Fs_, imm); - - if (_X) MOV32RtoRm(x86reg, ftreg, (uptr)VU->Mem); - if (_Y) MOV32RtoRm(x86reg, ftreg, (uptr)VU->Mem+4); - if (_Z) MOV32RtoRm(x86reg, ftreg, (uptr)VU->Mem+8); - if (_W) MOV32RtoRm(x86reg, ftreg, (uptr)VU->Mem+12); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ILWR -//------------------------------------------------------------------ -void recVUMI_ILWR( VURegs *VU, int info ) -{ - int off, ftreg; - - if ( ( _Ft_ == 0 ) || ( _X_Y_Z_W == 0 ) ) return; - //Console::WriteLn("recVUMI_ILWR"); - if (_X) off = 0; - else if (_Y) off = 4; - else if (_Z) off = 8; - else if (_W) off = 12; - - ADD_VI_NEEDED(_Fs_); - ftreg = ALLOCVI(_Ft_, MODE_WRITE); - - if ( _Fs_ == 0 ) { - MOVZX32M16toR( ftreg, (uptr)VU->Mem + off ); - } - else { - int fsreg = ALLOCVI(_Fs_, MODE_READ); - MOVZX32Rm16toR(ftreg, recVUTransformAddr(fsreg, VU, _Fs_, 0), (uptr)VU->Mem + off); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ISWR -//------------------------------------------------------------------ -void recVUMI_ISWR( VURegs *VU, int info ) -{ - int ftreg; - //Console::WriteLn("recVUMI_ISWR"); - ADD_VI_NEEDED(_Fs_); - ftreg = ALLOCVI(_Ft_, MODE_READ); - - if (_Fs_ == 0) { - if (_X) MOV32RtoM((uptr)VU->Mem, ftreg); - if (_Y) MOV32RtoM((uptr)VU->Mem+4, ftreg); - if (_Z) MOV32RtoM((uptr)VU->Mem+8, ftreg); - if (_W) MOV32RtoM((uptr)VU->Mem+12, ftreg); - } - else { - int x86reg; - int fsreg = ALLOCVI(_Fs_, MODE_READ); - x86reg = recVUTransformAddr(fsreg, VU, _Fs_, 0); - - if (_X) MOV32RtoRm(x86reg, ftreg, (uptr)VU->Mem); - if (_Y) MOV32RtoRm(x86reg, ftreg, (uptr)VU->Mem+4); - if (_Z) MOV32RtoRm(x86reg, ftreg, (uptr)VU->Mem+8); - if (_W) MOV32RtoRm(x86reg, ftreg, (uptr)VU->Mem+12); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// RINIT* -//------------------------------------------------------------------ -void recVUMI_RINIT(VURegs *VU, int info) -{ - //Console::WriteLn("recVUMI_RINIT()"); - if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode & MODE_NOFLUSH) ) { - _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 2); - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); - - SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)s_mask); - SSE_ORPS_M128_to_XMM(EEREC_TEMP, (uptr)VU_ONE); - SSE_MOVSS_XMM_to_M32(VU_REGR_ADDR, EEREC_TEMP); - } - else { - int rreg = ALLOCVI(REG_R, MODE_WRITE); - - if( xmmregs[EEREC_S].mode & MODE_WRITE ) { - SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); - xmmregs[EEREC_S].mode &= ~MODE_WRITE; - } - - MOV32MtoR( rreg, VU_VFx_ADDR( _Fs_ ) + 4 * _Fsf_ ); - AND32ItoR( rreg, 0x7fffff ); - OR32ItoR( rreg, 0x7f << 23 ); - - _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// RGET* -//------------------------------------------------------------------ -void recVUMI_RGET(VURegs *VU, int info) -{ - //Console::WriteLn("recVUMI_RGET()"); - if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; - - _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1); - - if (_X_Y_Z_W != 0xf) { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, VU_REGR_ADDR); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0); - VU_MERGE_REGS(EEREC_T, EEREC_TEMP); - } - else { - SSE_MOVSS_M32_to_XMM(EEREC_T, VU_REGR_ADDR); - SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// RNEXT* -//------------------------------------------------------------------ -void recVUMI_RNEXT( VURegs *VU, int info ) -{ - int rreg, x86temp0, x86temp1; - //Console::WriteLn("recVUMI_RNEXT()"); - - rreg = ALLOCVI(REG_R, MODE_WRITE|MODE_READ); - - x86temp0 = ALLOCTEMPX86(0); - x86temp1 = ALLOCTEMPX86(0); - - // code from www.project-fao.org - //MOV32MtoR(rreg, VU_REGR_ADDR); - MOV32RtoR(x86temp0, rreg); - SHR32ItoR(x86temp0, 4); - AND32ItoR(x86temp0, 1); - - MOV32RtoR(x86temp1, rreg); - SHR32ItoR(x86temp1, 22); - AND32ItoR(x86temp1, 1); - - SHL32ItoR(rreg, 1); - XOR32RtoR(x86temp0, x86temp1); - XOR32RtoR(rreg, x86temp0); - AND32ItoR(rreg, 0x7fffff); - OR32ItoR(rreg, 0x3f800000); - - _freeX86reg(x86temp0); - _freeX86reg(x86temp1); - - if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) { - _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1); - return; - } - - recVUMI_RGET(VU, info); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// RXOR* -//------------------------------------------------------------------ -void recVUMI_RXOR( VURegs *VU, int info ) -{ - //Console::WriteLn("recVUMI_RXOR()"); - if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode & MODE_NOFLUSH) ) { - _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1); - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); - - SSE_XORPS_M128_to_XMM(EEREC_TEMP, VU_REGR_ADDR); - SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)s_mask); - SSE_ORPS_M128_to_XMM(EEREC_TEMP, (uptr)s_fones); - SSE_MOVSS_XMM_to_M32(VU_REGR_ADDR, EEREC_TEMP); - } - else { - int rreg = ALLOCVI(REG_R, MODE_WRITE|MODE_READ); - - if( xmmregs[EEREC_S].mode & MODE_WRITE ) { - SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); - xmmregs[EEREC_S].mode &= ~MODE_WRITE; - } - - XOR32MtoR( rreg, VU_VFx_ADDR( _Fs_ ) + 4 * _Fsf_ ); - AND32ItoR( rreg, 0x7fffff ); - OR32ItoR ( rreg, 0x3f800000 ); - - _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// WAITQ -//------------------------------------------------------------------ -void recVUMI_WAITQ( VURegs *VU, int info ) -{ - //Console::WriteLn("recVUMI_WAITQ"); -// if( info & PROCESS_VU_SUPER ) { -// //CALLFunc(waitqfn); -// SuperVUFlush(0, 1); -// } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FSAND -//------------------------------------------------------------------ -void recVUMI_FSAND( VURegs *VU, int info ) -{ - int ftreg; - u16 imm; - //Console::WriteLn("recVUMI_FSAND"); - imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); - if(_Ft_ == 0) return; - - ftreg = ALLOCVI(_Ft_, MODE_WRITE); - MOV32MtoR( ftreg, VU_VI_ADDR(REG_STATUS_FLAG, 1) ); - AND32ItoR( ftreg, imm ); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FSEQ -//------------------------------------------------------------------ -void recVUMI_FSEQ( VURegs *VU, int info ) -{ - int ftreg; - u16 imm; - if ( _Ft_ == 0 ) return; - //Console::WriteLn("recVUMI_FSEQ"); - imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); - - ftreg = ALLOCVI(_Ft_, MODE_WRITE|MODE_8BITREG); - - MOVZX32M16toR( EAX, VU_VI_ADDR(REG_STATUS_FLAG, 1) ); - XOR32RtoR(ftreg, ftreg); - CMP16ItoR(EAX, imm); - SETE8R(ftreg); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FSOR -//------------------------------------------------------------------ -void recVUMI_FSOR( VURegs *VU, int info ) -{ - int ftreg; - u32 imm; - if(_Ft_ == 0) return; - //Console::WriteLn("recVUMI_FSOR"); - imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); - - ftreg = ALLOCVI(_Ft_, MODE_WRITE); - - MOVZX32M16toR( ftreg, VU_VI_ADDR(REG_STATUS_FLAG, 1) ); - OR32ItoR( ftreg, imm ); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FSSET -//------------------------------------------------------------------ -void recVUMI_FSSET(VURegs *VU, int info) -{ - u32 writeaddr = VU_VI_ADDR(REG_STATUS_FLAG, 0); - u32 prevaddr = VU_VI_ADDR(REG_STATUS_FLAG, 2); - - u16 imm = 0; - //Console::WriteLn("recVUMI_FSSET"); - imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7FF); - - // keep the low 6 bits ONLY if the upper instruction is an fmac instruction (otherwise rewrite) - metal gear solid 3 - //if( (info & PROCESS_VU_SUPER) && VUREC_FMAC ) { - MOV32MtoR(EAX, prevaddr); - AND32ItoR(EAX, 0x3f); - if ((imm&0xfc0) != 0) OR32ItoR(EAX, imm & 0xFC0); - MOV32RtoM(writeaddr ? writeaddr : prevaddr, EAX); - //} - //else { - // MOV32ItoM(writeaddr ? writeaddr : prevaddr, imm&0xfc0); - //} -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FMAND -//------------------------------------------------------------------ -void recVUMI_FMAND( VURegs *VU, int info ) -{ - int fsreg, ftreg; - if ( _Ft_ == 0 ) return; - //Console::WriteLn("recVUMI_FMAND"); - fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_READ); - ftreg = ALLOCVI(_Ft_, MODE_WRITE);//|MODE_8BITREG); - - if( fsreg >= 0 ) { - if( ftreg != fsreg ) MOV32RtoR(ftreg, fsreg); - } - else MOVZX32M16toR(ftreg, VU_VI_ADDR(_Fs_, 1)); - - AND16MtoR( ftreg, VU_VI_ADDR(REG_MAC_FLAG, 1)); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FMEQ -//------------------------------------------------------------------ -void recVUMI_FMEQ( VURegs *VU, int info ) -{ - int ftreg, fsreg; - if ( _Ft_ == 0 ) return; - //Console::WriteLn("recVUMI_FMEQ"); - if( _Ft_ == _Fs_ ) { - ftreg = ALLOCVI(_Ft_, MODE_WRITE|MODE_READ);//|MODE_8BITREG - - CMP16MtoR(ftreg, VU_VI_ADDR(REG_MAC_FLAG, 1)); - SETE8R(EAX); - MOVZX32R8toR(ftreg, EAX); - } - else { - ADD_VI_NEEDED(_Fs_); - ftreg = ALLOCVI(_Ft_, MODE_WRITE|MODE_8BITREG); - fsreg = ALLOCVI(_Fs_, MODE_READ); - - XOR32RtoR(ftreg, ftreg); - - CMP16MtoR(fsreg, VU_VI_ADDR(REG_MAC_FLAG, 1)); - SETE8R(ftreg); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FMOR -//------------------------------------------------------------------ -void recVUMI_FMOR( VURegs *VU, int info ) -{ - int fsreg, ftreg; - if ( _Ft_ == 0 ) return; - //Console::WriteLn("recVUMI_FMOR"); - if( _Fs_ == 0 ) { - ftreg = ALLOCVI(_Ft_, MODE_WRITE);//|MODE_8BITREG); - MOVZX32M16toR( ftreg, VU_VI_ADDR(REG_MAC_FLAG, 1) ); - } - else if( _Ft_ == _Fs_ ) { - ftreg = ALLOCVI(_Ft_, MODE_WRITE|MODE_READ);//|MODE_8BITREG); - OR16MtoR( ftreg, VU_VI_ADDR(REG_MAC_FLAG, 1) ); - } - else { - fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_READ); - ftreg = ALLOCVI(_Ft_, MODE_WRITE); - - MOVZX32M16toR( ftreg, VU_VI_ADDR(REG_MAC_FLAG, 1) ); - - if( fsreg >= 0 ) - OR16RtoR( ftreg, fsreg ); - else - OR16MtoR( ftreg, VU_VI_ADDR(_Fs_, 1) ); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FCAND -//------------------------------------------------------------------ -void recVUMI_FCAND( VURegs *VU, int info ) -{ - int ftreg = ALLOCVI(1, MODE_WRITE|MODE_8BITREG); - //Console::WriteLn("recVUMI_FCAND"); - MOV32MtoR( EAX, VU_VI_ADDR(REG_CLIP_FLAG, 1) ); - XOR32RtoR( ftreg, ftreg ); - AND32ItoR( EAX, VU->code & 0xFFFFFF ); - - SETNZ8R(ftreg); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FCEQ -//------------------------------------------------------------------ -void recVUMI_FCEQ( VURegs *VU, int info ) -{ - int ftreg = ALLOCVI(1, MODE_WRITE|MODE_8BITREG); - //Console::WriteLn("recVUMI_FCEQ"); - MOV32MtoR( EAX, VU_VI_ADDR(REG_CLIP_FLAG, 1) ); - AND32ItoR( EAX, 0xffffff ); - XOR32RtoR( ftreg, ftreg ); - CMP32ItoR( EAX, VU->code&0xffffff ); - - SETE8R(ftreg); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FCOR -//------------------------------------------------------------------ -void recVUMI_FCOR( VURegs *VU, int info ) -{ - int ftreg; - //Console::WriteLn("recVUMI_FCOR"); - ftreg = ALLOCVI(1, MODE_WRITE); - MOV32MtoR( ftreg, VU_VI_ADDR(REG_CLIP_FLAG, 1) ); - OR32ItoR ( ftreg, VU->code ); - AND32ItoR( ftreg, 0xffffff ); - ADD32ItoR( ftreg, 1 ); // If 24 1's will make 25th bit 1, else 0 - SHR32ItoR( ftreg, 24 ); // Get the 25th bit (also clears the rest of the garbage in the reg) -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FCSET -//------------------------------------------------------------------ -void recVUMI_FCSET( VURegs *VU, int info ) -{ - u32 addr = VU_VI_ADDR(REG_CLIP_FLAG, 0); - //Console::WriteLn("recVUMI_FCSET"); - MOV32ItoM(addr ? addr : VU_VI_ADDR(REG_CLIP_FLAG, 2), VU->code&0xffffff ); - - if( !(info & (PROCESS_VU_SUPER|PROCESS_VU_COP2)) ) - MOV32ItoM( VU_VI_ADDR(REG_CLIP_FLAG, 1), VU->code&0xffffff ); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FCGET -//------------------------------------------------------------------ -void recVUMI_FCGET( VURegs *VU, int info ) -{ - int ftreg; - if(_Ft_ == 0) return; - //Console::WriteLn("recVUMI_FCGET"); - ftreg = ALLOCVI(_Ft_, MODE_WRITE); - - MOV32MtoR(ftreg, VU_VI_ADDR(REG_CLIP_FLAG, 1)); - AND32ItoR(ftreg, 0x0fff); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// _recbranchAddr() -// -// NOTE: Due to static var dependencies, several SuperVU branch instructions -// are still located in iVUzerorec.cpp. -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// MFP* -//------------------------------------------------------------------ -void recVUMI_MFP(VURegs *VU, int info) -{ - if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; - //Console::WriteLn("recVUMI_MFP"); - if( _XYZW_SS ) { - _vuFlipRegSS(VU, EEREC_T); - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, VU_VI_ADDR(REG_P, 1)); - SSE_MOVSS_XMM_to_XMM(EEREC_T, EEREC_TEMP); - _vuFlipRegSS(VU, EEREC_T); - } - else if (_X_Y_Z_W != 0xf) { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, VU_VI_ADDR(REG_P, 1)); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0); - VU_MERGE_REGS(EEREC_T, EEREC_TEMP); - } - else { - SSE_MOVSS_M32_to_XMM(EEREC_T, VU_VI_ADDR(REG_P, 1)); - SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// WAITP -//------------------------------------------------------------------ -static PCSX2_ALIGNED16(float s_tempmem[4]); -void recVUMI_WAITP(VURegs *VU, int info) -{ - //Console::WriteLn("recVUMI_WAITP"); -// if( info & PROCESS_VU_SUPER ) -// SuperVUFlush(1, 1); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// vuSqSumXYZ()* -// -// NOTE: In all EFU insts, EEREC_D is a temp reg -//------------------------------------------------------------------ -void vuSqSumXYZ(int regd, int regs, int regtemp) // regd.x = x ^ 2 + y ^ 2 + z ^ 2 -{ - //Console::WriteLn("VU: SUMXYZ"); - if( cpucaps.hasStreamingSIMD4Extensions ) - { - SSE_MOVAPS_XMM_to_XMM(regd, regs); - if (CHECK_VU_EXTRA_OVERFLOW) vuFloat2(regd, regtemp, 0xf); - SSE4_DPPS_XMM_to_XMM(regd, regd, 0x71); - } - else - { - SSE_MOVAPS_XMM_to_XMM(regtemp, regs); - if (CHECK_VU_EXTRA_OVERFLOW) vuFloat2(regtemp, regd, 0xf); - SSE_MULPS_XMM_to_XMM(regtemp, regtemp); // xyzw ^ 2 - - if( cpucaps.hasStreamingSIMD3Extensions ) { - SSE3_HADDPS_XMM_to_XMM(regd, regtemp); - SSE_ADDPS_XMM_to_XMM(regd, regtemp); // regd.z = x ^ 2 + y ^ 2 + z ^ 2 - SSE_MOVHLPS_XMM_to_XMM(regd, regd); // regd.x = regd.z - } - else { - SSE_MOVSS_XMM_to_XMM(regd, regtemp); - SSE2_PSHUFLW_XMM_to_XMM(regtemp, regtemp, 0x4e); // wzyx -> wzxy - SSE_ADDSS_XMM_to_XMM(regd, regtemp); // x ^ 2 + y ^ 2 - SSE_SHUFPS_XMM_to_XMM(regtemp, regtemp, 0xD2); // wzxy -> wxyz - SSE_ADDSS_XMM_to_XMM(regd, regtemp); // x ^ 2 + y ^ 2 + z ^ 2 - } - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ESADD* -//------------------------------------------------------------------ -void recVUMI_ESADD( VURegs *VU, int info) -{ - //Console::WriteLn("VU: ESADD"); - assert( VU == &VU1 ); - if( EEREC_TEMP == EEREC_D ) { // special code to reset P ( FixMe: don't know if this is still needed! (cottonvibes) ) - Console::Notice("ESADD: Resetting P reg!!!\n"); - MOV32ItoM(VU_VI_ADDR(REG_P, 0), 0); - return; - } - vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP); - if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_D, (uptr)g_maxvals); // Only need to do positive clamp since (x ^ 2 + y ^ 2 + z ^ 2) is positive - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_D); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ERSADD* -//------------------------------------------------------------------ -void recVUMI_ERSADD( VURegs *VU, int info ) -{ - //Console::WriteLn("VU: ERSADD"); - assert( VU == &VU1 ); - vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP); - // don't use RCPSS (very bad precision) - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); - SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_D); - if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Only need to do positive clamp since (x ^ 2 + y ^ 2 + z ^ 2) is positive - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ELENG* -//------------------------------------------------------------------ -void recVUMI_ELENG( VURegs *VU, int info ) -{ - //Console::WriteLn("VU: ELENG"); - assert( VU == &VU1 ); - vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP); - if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_D, (uptr)g_maxvals); // Only need to do positive clamp since (x ^ 2 + y ^ 2 + z ^ 2) is positive - SSE_SQRTSS_XMM_to_XMM(EEREC_D, EEREC_D); - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_D); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ERLENG* -//------------------------------------------------------------------ -void recVUMI_ERLENG( VURegs *VU, int info ) -{ - //Console::WriteLn("VU: ERLENG"); - assert( VU == &VU1 ); - vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP); - if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_D, (uptr)g_maxvals); // Only need to do positive clamp since (x ^ 2 + y ^ 2 + z ^ 2) is positive - SSE_SQRTSS_XMM_to_XMM(EEREC_D, EEREC_D); // regd <- sqrt(x^2 + y^2 + z^2) - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); // temp <- 1 - SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_D); // temp = 1 / sqrt(x^2 + y^2 + z^2) - if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Only need to do positive clamp - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// EATANxy -//------------------------------------------------------------------ -void recVUMI_EATANxy( VURegs *VU, int info ) -{ - assert( VU == &VU1 ); - //Console::WriteLn("recVUMI_EATANxy"); - if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { - SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S); - FLD32((uptr)&s_tempmem[0]); - FLD32((uptr)&s_tempmem[1]); - } - else { - if( xmmregs[EEREC_S].mode & MODE_WRITE ) { - SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); - xmmregs[EEREC_S].mode &= ~MODE_WRITE; - } - - FLD32((uptr)&VU->VF[_Fs_].UL[0]); - FLD32((uptr)&VU->VF[_Fs_].UL[1]); - } - - FPATAN(); - FSTP32(VU_VI_ADDR(REG_P, 0)); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// EATANxz -//------------------------------------------------------------------ -void recVUMI_EATANxz( VURegs *VU, int info ) -{ - assert( VU == &VU1 ); - //Console::WriteLn("recVUMI_EATANxz"); - if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { - SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S); - FLD32((uptr)&s_tempmem[0]); - FLD32((uptr)&s_tempmem[2]); - } - else { - if( xmmregs[EEREC_S].mode & MODE_WRITE ) { - SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); - xmmregs[EEREC_S].mode &= ~MODE_WRITE; - } - - FLD32((uptr)&VU->VF[_Fs_].UL[0]); - FLD32((uptr)&VU->VF[_Fs_].UL[2]); - } - FPATAN(); - FSTP32(VU_VI_ADDR(REG_P, 0)); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ESUM* -//------------------------------------------------------------------ -void recVUMI_ESUM( VURegs *VU, int info ) -{ - //Console::WriteLn("VU: ESUM"); - assert( VU == &VU1 ); - - if( cpucaps.hasStreamingSIMD3Extensions ) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) vuFloat_useEAX(info, EEREC_TEMP, 0xf); - SSE3_HADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); - SSE3_HADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); - } - else { - SSE_MOVHLPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); // z, w, z, w - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); // z+x, w+y, z+z, w+w - SSE_UNPCKLPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); // z+x, z+x, w+y, w+y - SSE_MOVHLPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); // w+y, w+y, w+y, w+y - SSE_ADDSS_XMM_to_XMM(EEREC_TEMP, EEREC_D); // x+y+z+w, w+y, w+y, w+y - } - - vuFloat_useEAX(info, EEREC_TEMP, 8); - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ERCPR* -//------------------------------------------------------------------ -void recVUMI_ERCPR( VURegs *VU, int info ) -{ - assert( VU == &VU1 ); - //Console::WriteLn("VU1: ERCPR"); - - // don't use RCPSS (very bad precision) - switch ( _Fsf_ ) { - case 0: //0001 - if (CHECK_VU_EXTRA_OVERFLOW) vuFloat5_useEAX(EEREC_S, EEREC_TEMP, 8); - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); // temp <- 1 - SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - break; - case 1: //0010 - SSE2_PSHUFLW_XMM_to_XMM(EEREC_S, EEREC_S, 0x4e); - if (CHECK_VU_EXTRA_OVERFLOW) vuFloat5_useEAX(EEREC_S, EEREC_TEMP, 8); - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); // temp <- 1 - SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE2_PSHUFLW_XMM_to_XMM(EEREC_S, EEREC_S, 0x4e); - break; - case 2: //0100 - SSE_SHUFPS_XMM_to_XMM(EEREC_S, EEREC_S, 0xc6); - if (CHECK_VU_EXTRA_OVERFLOW) vuFloat5_useEAX(EEREC_S, EEREC_TEMP, 8); - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); // temp <- 1 - SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_SHUFPS_XMM_to_XMM(EEREC_S, EEREC_S, 0xc6); - break; - case 3: //1000 - SSE_SHUFPS_XMM_to_XMM(EEREC_S, EEREC_S, 0x27); - if (CHECK_VU_EXTRA_OVERFLOW) vuFloat5_useEAX(EEREC_S, EEREC_TEMP, 8); - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); // temp <- 1 - SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_SHUFPS_XMM_to_XMM(EEREC_S, EEREC_S, 0x27); - break; - } - - vuFloat_useEAX(info, EEREC_TEMP, 8); - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ESQRT* -//------------------------------------------------------------------ -void recVUMI_ESQRT( VURegs *VU, int info ) -{ - assert( VU == &VU1 ); - - //Console::WriteLn("VU1: ESQRT"); - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); - SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)const_clip); // abs(x) - if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Only need to do positive clamp - SSE_SQRTSS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); - - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ERSQRT* -//------------------------------------------------------------------ -void recVUMI_ERSQRT( VURegs *VU, int info ) -{ - int t1reg = _vuGetTempXMMreg(info); - - assert( VU == &VU1 ); - //Console::WriteLn("VU1: ERSQRT"); - - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); - SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)const_clip); // abs(x) - SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Clamp Infinities to Fmax - SSE_SQRTSS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); // SQRT(abs(x)) - - if( t1reg >= 0 ) - { - SSE_MOVSS_M32_to_XMM(t1reg, (uptr)VU_ONE); - SSE_DIVSS_XMM_to_XMM(t1reg, EEREC_TEMP); - vuFloat_useEAX(info, t1reg, 8); - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), t1reg); - _freeXMMreg(t1reg); - } - else - { - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); - SSE_DIVSS_M32_to_XMM(EEREC_TEMP, VU_VI_ADDR(REG_P, 0)); - vuFloat_useEAX(info, EEREC_TEMP, 8); - SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ESIN -//------------------------------------------------------------------ -void recVUMI_ESIN( VURegs *VU, int info ) -{ - assert( VU == &VU1 ); - - //Console::WriteLn("recVUMI_ESIN"); - if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { - switch(_Fsf_) { - case 0: SSE_MOVSS_XMM_to_M32((uptr)s_tempmem, EEREC_S); - case 1: SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S); - default: SSE_MOVHPS_XMM_to_M64((uptr)&s_tempmem[2], EEREC_S); - } - FLD32((uptr)&s_tempmem[_Fsf_]); - } - else { - if( xmmregs[EEREC_S].mode & MODE_WRITE ) { - SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); - xmmregs[EEREC_S].mode &= ~MODE_WRITE; - } - - FLD32((uptr)&VU->VF[_Fs_].UL[_Fsf_]); - } - - FSIN(); - FSTP32(VU_VI_ADDR(REG_P, 0)); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// EATAN -//------------------------------------------------------------------ -void recVUMI_EATAN( VURegs *VU, int info ) -{ - assert( VU == &VU1 ); - - //Console::WriteLn("recVUMI_EATAN"); - if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { - switch(_Fsf_) { - case 0: SSE_MOVSS_XMM_to_M32((uptr)s_tempmem, EEREC_S); - case 1: SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S); - default: SSE_MOVHPS_XMM_to_M64((uptr)&s_tempmem[2], EEREC_S); - } - FLD32((uptr)&s_tempmem[_Fsf_]); - } - else { - if( xmmregs[EEREC_S].mode & MODE_WRITE ) { - SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); - xmmregs[EEREC_S].mode &= ~MODE_WRITE; - } - } - - FLD1(); - FLD32((uptr)&VU->VF[_Fs_].UL[_Fsf_]); - FPATAN(); - FSTP32(VU_VI_ADDR(REG_P, 0)); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// EEXP -//------------------------------------------------------------------ -void recVUMI_EEXP( VURegs *VU, int info ) -{ - assert( VU == &VU1 ); - //Console::WriteLn("recVUMI_EEXP"); - FLDL2E(); - - if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { - switch(_Fsf_) { - case 0: SSE_MOVSS_XMM_to_M32((uptr)s_tempmem, EEREC_S); - case 1: SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S); - default: SSE_MOVHPS_XMM_to_M64((uptr)&s_tempmem[2], EEREC_S); - } - FMUL32((uptr)&s_tempmem[_Fsf_]); - } - else { - if( xmmregs[EEREC_S].mode & MODE_WRITE ) { - SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); - xmmregs[EEREC_S].mode &= ~MODE_WRITE; - } - - FMUL32((uptr)&VU->VF[_Fs_].UL[_Fsf_]); - } - - // basically do 2^(log_2(e) * val) - FLD(0); - FRNDINT(); - FXCH(1); - FSUB32Rto0(1); - F2XM1(); - FLD1(); - FADD320toR(1); - FSCALE(); - FSTP(1); - - FSTP32(VU_VI_ADDR(REG_P, 0)); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// XITOP -//------------------------------------------------------------------ -void recVUMI_XITOP( VURegs *VU, int info ) -{ - int ftreg; - if (_Ft_ == 0) return; - //Console::WriteLn("recVUMI_XITOP"); - ftreg = ALLOCVI(_Ft_, MODE_WRITE); - MOVZX32M16toR( ftreg, (uptr)&VU->vifRegs->itop ); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// XTOP -//------------------------------------------------------------------ -void recVUMI_XTOP( VURegs *VU, int info ) -{ - int ftreg; - if ( _Ft_ == 0 ) return; - //Console::WriteLn("recVUMI_XTOP"); - ftreg = ALLOCVI(_Ft_, MODE_WRITE); - MOVZX32M16toR( ftreg, (uptr)&VU->vifRegs->top ); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// VU1XGKICK_MTGSTransfer() - Called by ivuZerorec.cpp -//------------------------------------------------------------------ -void VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr) -{ - u32 size; - u32* data = (u32*)((u8*)pMem + (addr&0x3fff)); - - // fixme: The gifTagDummy function in the MTGS (called by PrepDataPacket) has a - // hack that aborts the packet if it goes past the end of VU1 memory. - // Chances are this should be a "loops around memory" situation, and the packet - // should be continued starting at addr zero (0). - - size = mtgsThread->PrepDataPacket( GIF_PATH_1, data, (0x4000-(addr&0x3fff)) >> 4); - jASSUME( size > 0 ); - - //if( size > 0 ) - { - u8* pmem = mtgsThread->GetDataPacketPtr(); - memcpy_aligned(pmem, (u8*)pMem+addr, size<<4); - mtgsThread->SendDataPacket(); - } -} -//------------------------------------------------------------------ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "PrecompiledHeader.h" + +#include "Common.h" +#include "GS.h" +#include "R5900OpcodeTables.h" +#include "iR5900.h" +#include "iMMI.h" +#include "iFPU.h" +#include "iCOP0.h" +#include "VUmicro.h" +#include "VUflags.h" +#include "sVU_Micro.h" +#include "sVU_Debug.h" +#include "sVU_zerorec.h" +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// Helper Macros +//------------------------------------------------------------------ +#define _Ft_ (( VU->code >> 16) & 0x1F) // The rt part of the instruction register +#define _Fs_ (( VU->code >> 11) & 0x1F) // The rd part of the instruction register +#define _Fd_ (( VU->code >> 6) & 0x1F) // The sa part of the instruction register +#define _It_ (_Ft_ & 15) +#define _Is_ (_Fs_ & 15) +#define _Id_ (_Fd_ & 15) + +#define _X (( VU->code>>24) & 0x1) +#define _Y (( VU->code>>23) & 0x1) +#define _Z (( VU->code>>22) & 0x1) +#define _W (( VU->code>>21) & 0x1) + +#define _XYZW_SS (_X+_Y+_Z+_W==1) + +#define _Fsf_ (( VU->code >> 21) & 0x03) +#define _Ftf_ (( VU->code >> 23) & 0x03) + +#define _Imm11_ (s32)(VU->code & 0x400 ? 0xfffffc00 | (VU->code & 0x3ff) : VU->code & 0x3ff) +#define _UImm11_ (s32)(VU->code & 0x7ff) + +#define VU_VFx_ADDR(x) (uptr)&VU->VF[x].UL[0] +#define VU_VFy_ADDR(x) (uptr)&VU->VF[x].UL[1] +#define VU_VFz_ADDR(x) (uptr)&VU->VF[x].UL[2] +#define VU_VFw_ADDR(x) (uptr)&VU->VF[x].UL[3] + +#define VU_REGR_ADDR (uptr)&VU->VI[REG_R] +#define VU_REGQ_ADDR (uptr)&VU->VI[REG_Q] +#define VU_REGMAC_ADDR (uptr)&VU->VI[REG_MAC_FLAG] + +#define VU_VI_ADDR(x, read) GetVIAddr(VU, x, read, info) + +#define VU_ACCx_ADDR (uptr)&VU->ACC.UL[0] +#define VU_ACCy_ADDR (uptr)&VU->ACC.UL[1] +#define VU_ACCz_ADDR (uptr)&VU->ACC.UL[2] +#define VU_ACCw_ADDR (uptr)&VU->ACC.UL[3] + +#define _X_Y_Z_W ((( VU->code >> 21 ) & 0xF ) ) + + +static const PCSX2_ALIGNED16(u32 VU_ONE[4]) = {0x3f800000, 0xffffffff, 0xffffffff, 0xffffffff}; +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// *VU Lower Instructions!* +// +// Note: * = Checked for errors by cottonvibes +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// DIV* +//------------------------------------------------------------------ +PCSX2_ALIGNED16(u64 DIV_TEMP_XMM[2]); +void recVUMI_DIV(VURegs *VU, int info) +{ + u8 *pjmp, *pjmp1; + u32 *ajmp32, *bjmp32; + + //Console::WriteLn("recVUMI_DIV()"); + AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags + + // FT can be zero here! so we need to check if its zero and set the correct flag. + SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); // Clear EEREC_TEMP + SSE_CMPEQPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); // Set all F's if each vector is zero + + SSE_MOVMSKPS_XMM_to_R32( EAX, EEREC_TEMP); // Move the sign bits of the previous calculation + + AND32ItoR( EAX, (1<<_Ftf_) ); // Grab "Is Zero" bits from the previous calculation + ajmp32 = JZ32(0); // Skip if none are + + SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); // Clear EEREC_TEMP + SSE_CMPEQPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); // Set all F's if each vector is zero + SSE_MOVMSKPS_XMM_to_R32(EAX, EEREC_TEMP); // Move the sign bits of the previous calculation + + AND32ItoR( EAX, (1<<_Fsf_) ); // Grab "Is Zero" bits from the previous calculation + pjmp = JZ8(0); + OR32ItoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x410 ); // Set invalid flag (0/0) + pjmp1 = JMP8(0); + x86SetJ8(pjmp); + OR32ItoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x820 ); // Zero divide (only when not 0/0) + x86SetJ8(pjmp1); + + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); + + _vuFlipRegSS_xyzw(EEREC_T, _Ftf_); + SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + _vuFlipRegSS_xyzw(EEREC_T, _Ftf_); + + SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); + SSE_ORPS_M128_to_XMM(EEREC_TEMP, (uptr)&g_maxvals[0]); // If division by zero, then EEREC_TEMP = +/- fmax + + bjmp32 = JMP32(0); + + x86SetJ32(ajmp32); + + if (CHECK_VU_EXTRA_OVERFLOW) { + vuFloat5_useEAX(EEREC_S, EEREC_TEMP, (1 << (3-_Fsf_))); + vuFloat5_useEAX(EEREC_T, EEREC_TEMP, (1 << (3-_Ftf_))); + } + + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); + + _vuFlipRegSS_xyzw(EEREC_T, _Ftf_); + SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + _vuFlipRegSS_xyzw(EEREC_T, _Ftf_); + + vuFloat_useEAX(info, EEREC_TEMP, 0x8); + + x86SetJ32(bjmp32); + + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), EEREC_TEMP); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// SQRT* +//------------------------------------------------------------------ +void recVUMI_SQRT( VURegs *VU, int info ) +{ + u8* pjmp; + //Console::WriteLn("recVUMI_SQRT()"); + + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, _Ftf_); + AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags + + /* Check for negative sqrt */ + SSE_MOVMSKPS_XMM_to_R32(EAX, EEREC_TEMP); + AND32ItoR(EAX, 1); //Check sign + pjmp = JZ8(0); //Skip if none are + OR32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x410); // Invalid Flag - Negative number sqrt + x86SetJ8(pjmp); + + SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)const_clip); // Do a cardinal sqrt + if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Clamp infinities (only need to do positive clamp since EEREC_TEMP is positive) + SSE_SQRTSS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), EEREC_TEMP); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// RSQRT* +//------------------------------------------------------------------ +PCSX2_ALIGNED16(u64 RSQRT_TEMP_XMM[2]); +void recVUMI_RSQRT(VURegs *VU, int info) +{ + u8 *ajmp8, *bjmp8; + u8 *qjmp1, *qjmp2; + int t1reg, t1boolean; + //Console::WriteLn("recVUMI_RSQRT()"); + + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, _Ftf_); + AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags + + /* Check for negative divide */ + SSE_MOVMSKPS_XMM_to_R32(EAX, EEREC_TEMP); + AND32ItoR(EAX, 1); //Check sign + ajmp8 = JZ8(0); //Skip if none are + OR32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x410); // Invalid Flag - Negative number sqrt + x86SetJ8(ajmp8); + + SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)const_clip); // Do a cardinal sqrt + if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Clamp Infinities to Fmax + SSE_SQRTSS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); + + t1reg = _vuGetTempXMMreg(info); + if( t1reg < 0 ) { + for (t1reg = 0; ( (t1reg == EEREC_TEMP) || (t1reg == EEREC_S) ); t1reg++) + ; // Makes t1reg not be EEREC_TEMP or EEREC_S. + SSE_MOVAPS_XMM_to_M128( (uptr)&RSQRT_TEMP_XMM[0], t1reg ); // backup data in t1reg to a temp address + t1boolean = 1; + } + else t1boolean = 0; + + // Ft can still be zero here! so we need to check if its zero and set the correct flag. + SSE_XORPS_XMM_to_XMM(t1reg, t1reg); // Clear t1reg + SSE_CMPEQSS_XMM_to_XMM(t1reg, EEREC_TEMP); // Set all F's if each vector is zero + + SSE_MOVMSKPS_XMM_to_R32(EAX, t1reg); // Move the sign bits of the previous calculation + + AND32ItoR( EAX, 0x01 ); // Grab "Is Zero" bits from the previous calculation + ajmp8 = JZ8(0); // Skip if none are + + //check for 0/0 + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); + + SSE_XORPS_XMM_to_XMM(t1reg, t1reg); // Clear EEREC_TEMP + SSE_CMPEQPS_XMM_to_XMM(t1reg, EEREC_TEMP); // Set all F's if each vector is zero + SSE_MOVMSKPS_XMM_to_R32(EAX, t1reg); // Move the sign bits of the previous calculation + + AND32ItoR( EAX, 0x01 ); // Grab "Is Zero" bits from the previous calculation + qjmp1 = JZ8(0); + OR32ItoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x410 ); // Set invalid flag (0/0) + qjmp2 = JMP8(0); + x86SetJ8(qjmp1); + OR32ItoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x820 ); // Zero divide (only when not 0/0) + x86SetJ8(qjmp2); + + SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); + SSE_ORPS_M128_to_XMM(EEREC_TEMP, (uptr)&g_maxvals[0]); // If division by zero, then EEREC_TEMP = +/- fmax + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), EEREC_TEMP); + bjmp8 = JMP8(0); + x86SetJ8(ajmp8); + + _unpackVFSS_xyzw(t1reg, EEREC_S, _Fsf_); + if (CHECK_VU_EXTRA_OVERFLOW) vuFloat_useEAX(info, t1reg, 0x8); // Clamp Infinities + SSE_DIVSS_XMM_to_XMM(t1reg, EEREC_TEMP); + vuFloat_useEAX(info, t1reg, 0x8); + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), t1reg); + + x86SetJ8(bjmp8); + + if (t1boolean) SSE_MOVAPS_M128_to_XMM( t1reg, (uptr)&RSQRT_TEMP_XMM[0] ); // restore t1reg data + else _freeXMMreg(t1reg); // free t1reg +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// _addISIMMtoIT() - Used in IADDI, IADDIU, and ISUBIU instructions +//------------------------------------------------------------------ +void _addISIMMtoIT(VURegs *VU, s16 imm, int info) +{ + int isreg = -1, itreg; + if (_It_ == 0) return; + + if( _Is_ == 0 ) { + itreg = ALLOCVI(_It_, MODE_WRITE); + MOV32ItoR(itreg, imm&0xffff); + return; + } + + ADD_VI_NEEDED(_It_); + isreg = ALLOCVI(_Is_, MODE_READ); + itreg = ALLOCVI(_It_, MODE_WRITE); + + if ( _It_ == _Is_ ) { + if (imm != 0 ) ADD16ItoR(itreg, imm); + } + else { + if( imm ) { + LEA32RtoR(itreg, isreg, imm); + MOVZX32R16toR(itreg, itreg); + } + else MOV32RtoR(itreg, isreg); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// IADDI +//------------------------------------------------------------------ +void recVUMI_IADDI(VURegs *VU, int info) +{ + s16 imm; + + if ( _It_ == 0 ) return; + //Console::WriteLn("recVUMI_IADDI"); + imm = ( VU->code >> 6 ) & 0x1f; + imm = ( imm & 0x10 ? 0xfff0 : 0) | ( imm & 0xf ); + _addISIMMtoIT(VU, imm, info); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// IADDIU +//------------------------------------------------------------------ +void recVUMI_IADDIU(VURegs *VU, int info) +{ + s16 imm; + + if ( _It_ == 0 ) return; + //Console::WriteLn("recVUMI_IADDIU"); + imm = ( ( VU->code >> 10 ) & 0x7800 ) | ( VU->code & 0x7ff ); + _addISIMMtoIT(VU, imm, info); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// IADD +//------------------------------------------------------------------ +void recVUMI_IADD( VURegs *VU, int info ) +{ + int idreg, isreg = -1, itreg = -1; + if ( _Id_ == 0 ) return; + //Console::WriteLn("recVUMI_IADD"); + if ( ( _It_ == 0 ) && ( _Is_ == 0 ) ) { + idreg = ALLOCVI(_Id_, MODE_WRITE); + XOR32RtoR(idreg, idreg); + return; + } + + ADD_VI_NEEDED(_Is_); + ADD_VI_NEEDED(_It_); + idreg = ALLOCVI(_Id_, MODE_WRITE); + + if ( _Is_ == 0 ) + { + if( (itreg = _checkX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _It_, MODE_READ)) >= 0 ) { + if( idreg != itreg ) MOV32RtoR(idreg, itreg); + } + else MOVZX32M16toR(idreg, VU_VI_ADDR(_It_, 1)); + } + else if ( _It_ == 0 ) + { + if( (isreg = _checkX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Is_, MODE_READ)) >= 0 ) { + if( idreg != isreg ) MOV32RtoR(idreg, isreg); + } + else MOVZX32M16toR(idreg, VU_VI_ADDR(_Is_, 1)); + } + else { + //ADD_VI_NEEDED(_It_); + isreg = ALLOCVI(_Is_, MODE_READ); + itreg = ALLOCVI(_It_, MODE_READ); + + if( idreg == isreg ) ADD32RtoR(idreg, itreg); + else if( idreg == itreg ) ADD32RtoR(idreg, isreg); + else LEA32RRtoR(idreg, isreg, itreg); + MOVZX32R16toR(idreg, idreg); // needed since don't know if idreg's upper bits are 0 + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// IAND +//------------------------------------------------------------------ +void recVUMI_IAND( VURegs *VU, int info ) +{ + int idreg, isreg = -1, itreg = -1; + if ( _Id_ == 0 ) return; + //Console::WriteLn("recVUMI_IAND"); + if ( ( _Is_ == 0 ) || ( _It_ == 0 ) ) { + idreg = ALLOCVI(_Id_, MODE_WRITE); + XOR32RtoR(idreg, idreg); + return; + } + + ADD_VI_NEEDED(_Is_); + ADD_VI_NEEDED(_It_); + idreg = ALLOCVI(_Id_, MODE_WRITE); + + isreg = ALLOCVI(_Is_, MODE_READ); + itreg = ALLOCVI(_It_, MODE_READ); + + if( idreg == isreg ) AND16RtoR(idreg, itreg); + else if( idreg == itreg ) AND16RtoR(idreg, isreg); + else { + MOV32RtoR(idreg, itreg); + AND32RtoR(idreg, isreg); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// IOR +//------------------------------------------------------------------ +void recVUMI_IOR( VURegs *VU, int info ) +{ + int idreg, isreg = -1, itreg = -1; + if ( _Id_ == 0 ) return; + //Console::WriteLn("recVUMI_IOR"); + if ( ( _It_ == 0 ) && ( _Is_ == 0 ) ) { + idreg = ALLOCVI(_Id_, MODE_WRITE); + XOR32RtoR(idreg, idreg); + return; + } + + ADD_VI_NEEDED(_Is_); + ADD_VI_NEEDED(_It_); + idreg = ALLOCVI(_Id_, MODE_WRITE); + + if ( _Is_ == 0 ) + { + if( (itreg = _checkX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _It_, MODE_READ)) >= 0 ) { + if( idreg != itreg ) MOV32RtoR(idreg, itreg); + } + else MOVZX32M16toR(idreg, VU_VI_ADDR(_It_, 1)); + } + else if ( _It_ == 0 ) + { + if( (isreg = _checkX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Is_, MODE_READ)) >= 0 ) { + if( idreg != isreg ) MOV32RtoR(idreg, isreg); + } + else MOVZX32M16toR(idreg, VU_VI_ADDR(_Is_, 1)); + } + else + { + isreg = ALLOCVI(_Is_, MODE_READ); + itreg = ALLOCVI(_It_, MODE_READ); + + if( idreg == isreg ) OR16RtoR(idreg, itreg); + else if( idreg == itreg ) OR16RtoR(idreg, isreg); + else { + MOV32RtoR(idreg, isreg); + OR32RtoR(idreg, itreg); + } + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ISUB +//------------------------------------------------------------------ +void recVUMI_ISUB( VURegs *VU, int info ) +{ + int idreg, isreg = -1, itreg = -1; + if ( _Id_ == 0 ) return; + //Console::WriteLn("recVUMI_ISUB"); + if ( ( _It_ == 0 ) && ( _Is_ == 0 ) ) { + idreg = ALLOCVI(_Id_, MODE_WRITE); + XOR32RtoR(idreg, idreg); + return; + } + + ADD_VI_NEEDED(_Is_); + ADD_VI_NEEDED(_It_); + idreg = ALLOCVI(_Id_, MODE_WRITE); + + if ( _Is_ == 0 ) + { + if( (itreg = _checkX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _It_, MODE_READ)) >= 0 ) { + if( idreg != itreg ) MOV32RtoR(idreg, itreg); + } + else MOVZX32M16toR(idreg, VU_VI_ADDR(_It_, 1)); + NEG16R(idreg); + } + else if ( _It_ == 0 ) + { + if( (isreg = _checkX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Is_, MODE_READ)) >= 0 ) { + if( idreg != isreg ) MOV32RtoR(idreg, isreg); + } + else MOVZX32M16toR(idreg, VU_VI_ADDR(_Is_, 1)); + } + else + { + isreg = ALLOCVI(_Is_, MODE_READ); + itreg = ALLOCVI(_It_, MODE_READ); + + if( idreg == isreg ) SUB16RtoR(idreg, itreg); + else if( idreg == itreg ) { + SUB16RtoR(idreg, isreg); + NEG16R(idreg); + } + else { + MOV32RtoR(idreg, isreg); + SUB16RtoR(idreg, itreg); + } + } +} +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// ISUBIU +//------------------------------------------------------------------ +void recVUMI_ISUBIU( VURegs *VU, int info ) +{ + s16 imm; + + if ( _It_ == 0 ) return; + //Console::WriteLn("recVUMI_ISUBIU"); + imm = ( ( VU->code >> 10 ) & 0x7800 ) | ( VU->code & 0x7ff ); + imm = -imm; + _addISIMMtoIT(VU, imm, info); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// MOVE* +//------------------------------------------------------------------ +void recVUMI_MOVE( VURegs *VU, int info ) +{ + if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; + //Console::WriteLn("recVUMI_MOVE"); + if (_X_Y_Z_W == 0x8) SSE_MOVSS_XMM_to_XMM(EEREC_T, EEREC_S); + else if (_X_Y_Z_W == 0xf) SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_S); + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_T, EEREC_TEMP); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// MFIR* +//------------------------------------------------------------------ +void recVUMI_MFIR( VURegs *VU, int info ) +{ + if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; + //Console::WriteLn("recVUMI_MFIR"); + _deleteX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Is_, 1); + + if( _XYZW_SS ) { + SSE2_MOVD_M32_to_XMM(EEREC_TEMP, VU_VI_ADDR(_Is_, 1)-2); + _vuFlipRegSS(VU, EEREC_T); + SSE2_PSRAD_I8_to_XMM(EEREC_TEMP, 16); + SSE_MOVSS_XMM_to_XMM(EEREC_T, EEREC_TEMP); + _vuFlipRegSS(VU, EEREC_T); + } + else if (_X_Y_Z_W != 0xf) { + SSE2_MOVD_M32_to_XMM(EEREC_TEMP, VU_VI_ADDR(_Is_, 1)-2); + SSE2_PSRAD_I8_to_XMM(EEREC_TEMP, 16); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0); + VU_MERGE_REGS(EEREC_T, EEREC_TEMP); + } + else { + SSE2_MOVD_M32_to_XMM(EEREC_T, VU_VI_ADDR(_Is_, 1)-2); + SSE2_PSRAD_I8_to_XMM(EEREC_T, 16); + SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// MTIR* +//------------------------------------------------------------------ +void recVUMI_MTIR( VURegs *VU, int info ) +{ + if ( _It_ == 0 ) return; + //Console::WriteLn("recVUMI_MTIR"); + _deleteX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _It_, 2); + + if( _Fsf_ == 0 ) { + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(_It_, 0), EEREC_S); + } + else { + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(_It_, 0), EEREC_TEMP); + } + + AND32ItoM(VU_VI_ADDR(_It_, 0), 0xffff); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// MR32* +//------------------------------------------------------------------ +void recVUMI_MR32( VURegs *VU, int info ) +{ + if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; + //Console::WriteLn("recVUMI_MR32"); + if (_X_Y_Z_W != 0xf) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x39); + VU_MERGE_REGS(EEREC_T, EEREC_TEMP); + } + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_S); + SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0x39); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// _loadEAX() +// +// NOTE: If x86reg < 0, reads directly from offset +//------------------------------------------------------------------ +void _loadEAX(VURegs *VU, int x86reg, uptr offset, int info) +{ + assert( offset < 0x80000000 ); + + if( x86reg >= 0 ) { + switch(_X_Y_Z_W) { + case 3: // ZW + SSE_MOVHPS_Rm_to_XMM(EEREC_T, x86reg, offset+8); + break; + case 6: // YZ + SSE_SHUFPS_Rm_to_XMM(EEREC_T, x86reg, offset, 0x9c); + SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0x78); + break; + + case 8: // X + SSE_MOVSS_Rm_to_XMM(EEREC_TEMP, x86reg, offset); + SSE_MOVSS_XMM_to_XMM(EEREC_T, EEREC_TEMP); + break; + case 9: // XW + SSE_SHUFPS_Rm_to_XMM(EEREC_T, x86reg, offset, 0xc9); + SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0xd2); + break; + case 12: // XY + SSE_MOVLPS_Rm_to_XMM(EEREC_T, x86reg, offset); + break; + case 15: + if( VU == &VU1 ) SSE_MOVAPSRmtoR(EEREC_T, x86reg, offset); + else SSE_MOVUPSRmtoR(EEREC_T, x86reg, offset); + break; + default: + if( VU == &VU1 ) SSE_MOVAPSRmtoR(EEREC_TEMP, x86reg, offset); + else SSE_MOVUPSRmtoR(EEREC_TEMP, x86reg, offset); + + VU_MERGE_REGS(EEREC_T, EEREC_TEMP); + break; + } + } + else { + switch(_X_Y_Z_W) { + case 3: // ZW + SSE_MOVHPS_M64_to_XMM(EEREC_T, offset+8); + break; + case 6: // YZ + SSE_SHUFPS_M128_to_XMM(EEREC_T, offset, 0x9c); + SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0x78); + break; + case 8: // X + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, offset); + SSE_MOVSS_XMM_to_XMM(EEREC_T, EEREC_TEMP); + break; + case 9: // XW + SSE_SHUFPS_M128_to_XMM(EEREC_T, offset, 0xc9); + SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0xd2); + break; + case 12: // XY + SSE_MOVLPS_M64_to_XMM(EEREC_T, offset); + break; + case 15: + if( VU == &VU1 ) SSE_MOVAPS_M128_to_XMM(EEREC_T, offset); + else SSE_MOVUPS_M128_to_XMM(EEREC_T, offset); + break; + default: + if( VU == &VU1 ) SSE_MOVAPS_M128_to_XMM(EEREC_TEMP, offset); + else SSE_MOVUPS_M128_to_XMM(EEREC_TEMP, offset); + VU_MERGE_REGS(EEREC_T, EEREC_TEMP); + break; + } + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// recVUTransformAddr() +//------------------------------------------------------------------ +int recVUTransformAddr(int x86reg, VURegs* VU, int vireg, int imm) +{ + u8* pjmp[2]; + if( x86reg == EAX ) { + if (imm) ADD32ItoR(x86reg, imm); + } + else { + if( imm ) LEA32RtoR(EAX, x86reg, imm); + else MOV32RtoR(EAX, x86reg); + } + + if( VU == &VU1 ) { + AND32ItoR(EAX, 0x3ff); // wrap around + SHL32ItoR(EAX, 4); + } + else { + + // VU0 has a somewhat interesting memory mapping: + // if addr >= 0x4000, reads VU1's VF regs and VI regs + // if addr < 0x4000, wrap around at 0x1000 + + CMP32ItoR(EAX, 0x400); + pjmp[0] = JL8(0); // if addr >= 0x4000, reads VU1's VF regs and VI regs + AND32ItoR(EAX, 0x43f); + pjmp[1] = JMP8(0); + x86SetJ8(pjmp[0]); + AND32ItoR(EAX, 0xff); // if addr < 0x4000, wrap around + x86SetJ8(pjmp[1]); + + SHL32ItoR(EAX, 4); // multiply by 16 (shift left by 4) + } + + return EAX; +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// LQ +//------------------------------------------------------------------ +void recVUMI_LQ(VURegs *VU, int info) +{ + s16 imm; + if ( _Ft_ == 0 ) return; + //Console::WriteLn("recVUMI_LQ"); + imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); + if (_Is_ == 0) { + _loadEAX(VU, -1, (uptr)GET_VU_MEM(VU, (u32)imm*16), info); + } + else { + int isreg = ALLOCVI(_Is_, MODE_READ); + _loadEAX(VU, recVUTransformAddr(isreg, VU, _Is_, imm), (uptr)VU->Mem, info); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// LQD +//------------------------------------------------------------------ +void recVUMI_LQD( VURegs *VU, int info ) +{ + int isreg; + //Console::WriteLn("recVUMI_LQD"); + if ( _Is_ != 0 ) { + isreg = ALLOCVI(_Is_, MODE_READ|MODE_WRITE); + SUB16ItoR( isreg, 1 ); + } + + if ( _Ft_ == 0 ) return; + + if ( _Is_ == 0 ) _loadEAX(VU, -1, (uptr)VU->Mem, info); + else _loadEAX(VU, recVUTransformAddr(isreg, VU, _Is_, 0), (uptr)VU->Mem, info); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// LQI +//------------------------------------------------------------------ +void recVUMI_LQI(VURegs *VU, int info) +{ + int isreg; + //Console::WriteLn("recVUMI_LQI"); + if ( _Ft_ == 0 ) { + if( _Is_ != 0 ) { + if( (isreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Is_, MODE_WRITE|MODE_READ)) >= 0 ) { + ADD16ItoR(isreg, 1); + } + else { + ADD16ItoM( VU_VI_ADDR( _Is_, 0 ), 1 ); + } + } + return; + } + + if (_Is_ == 0) { + _loadEAX(VU, -1, (uptr)VU->Mem, info); + } + else { + isreg = ALLOCVI(_Is_, MODE_READ|MODE_WRITE); + _loadEAX(VU, recVUTransformAddr(isreg, VU, _Is_, 0), (uptr)VU->Mem, info); + ADD16ItoR( isreg, 1 ); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// _saveEAX() +//------------------------------------------------------------------ +void _saveEAX(VURegs *VU, int x86reg, uptr offset, int info) +{ + assert( offset < 0x80000000 ); + + if ( _Fs_ == 0 ) { + if ( _XYZW_SS ) { + u32 c = _W ? 0x3f800000 : 0; + if ( x86reg >= 0 ) MOV32ItoRm(x86reg, c, offset+(_W?12:(_Z?8:(_Y?4:0)))); + else MOV32ItoM(offset+(_W?12:(_Z?8:(_Y?4:0))), c); + } + else { + + // (this is one of my test cases for the new emitter --air) + using namespace x86Emitter; + xAddressReg thisreg( x86reg ); + + if ( _X ) xMOV(ptr32[thisreg+offset], 0x00000000); + if ( _Y ) xMOV(ptr32[thisreg+offset+4], 0x00000000); + if ( _Z ) xMOV(ptr32[thisreg+offset+8], 0x00000000); + if ( _W ) xMOV(ptr32[thisreg+offset+12], 0x3f800000); + } + return; + } + + switch ( _X_Y_Z_W ) { + case 1: // W + SSE2_PSHUFD_XMM_to_XMM(EEREC_TEMP, EEREC_S, 0x27); + if ( x86reg >= 0 ) SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+12); + else SSE_MOVSS_XMM_to_M32(offset+12, EEREC_TEMP); + break; + case 2: // Z + SSE_MOVHLPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if ( x86reg >= 0 ) SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+8); + else SSE_MOVSS_XMM_to_M32(offset+8, EEREC_TEMP); + break; + case 3: // ZW + if ( x86reg >= 0 ) SSE_MOVHPS_XMM_to_Rm(x86reg, EEREC_S, offset+8); + else SSE_MOVHPS_XMM_to_M64(offset+8, EEREC_S); + break; + case 4: // Y + SSE2_PSHUFLW_XMM_to_XMM(EEREC_TEMP, EEREC_S, 0x4e); + if ( x86reg >= 0 ) SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+4); + else SSE_MOVSS_XMM_to_M32(offset+4, EEREC_TEMP); + break; + case 5: // YW + SSE_SHUFPS_XMM_to_XMM(EEREC_S, EEREC_S, 0xB1); + SSE_MOVHLPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if ( x86reg >= 0 ) { + SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_S, offset+4); + SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+12); + } + else { + SSE_MOVSS_XMM_to_M32(offset+4, EEREC_S); + SSE_MOVSS_XMM_to_M32(offset+12, EEREC_TEMP); + } + SSE_SHUFPS_XMM_to_XMM(EEREC_S, EEREC_S, 0xB1); + break; + case 6: // YZ + SSE2_PSHUFD_XMM_to_XMM(EEREC_TEMP, EEREC_S, 0xc9); + if ( x86reg >= 0 ) SSE_MOVLPS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+4); + else SSE_MOVLPS_XMM_to_M64(offset+4, EEREC_TEMP); + break; + case 7: // YZW + SSE2_PSHUFD_XMM_to_XMM(EEREC_TEMP, EEREC_S, 0x93); //ZYXW + if ( x86reg >= 0 ) { + SSE_MOVHPS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+4); + SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+12); + } + else { + SSE_MOVHPS_XMM_to_M64(offset+4, EEREC_TEMP); + SSE_MOVSS_XMM_to_M32(offset+12, EEREC_TEMP); + } + break; + case 8: // X + if ( x86reg >= 0 ) SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_S, offset); + else SSE_MOVSS_XMM_to_M32(offset, EEREC_S); + break; + case 9: // XW + if ( x86reg >= 0 ) SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_S, offset); + else SSE_MOVSS_XMM_to_M32(offset, EEREC_S); + + SSE2_PSHUFD_XMM_to_XMM(EEREC_TEMP, EEREC_S, 0xff); //WWWW + + if ( x86reg >= 0 ) SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+12); + else SSE_MOVSS_XMM_to_M32(offset+12, EEREC_TEMP); + + break; + case 10: //XZ + SSE_MOVHLPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if ( x86reg >= 0 ) { + SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_S, offset); + SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+8); + } + else { + SSE_MOVSS_XMM_to_M32(offset, EEREC_S); + SSE_MOVSS_XMM_to_M32(offset+8, EEREC_TEMP); + } + break; + case 11: //XZW + if ( x86reg >= 0 ) { + SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_S, offset); + SSE_MOVHPS_XMM_to_Rm(x86reg, EEREC_S, offset+8); + } + else { + SSE_MOVSS_XMM_to_M32(offset, EEREC_S); + SSE_MOVHPS_XMM_to_M64(offset+8, EEREC_S); + } + break; + case 12: // XY + if ( x86reg >= 0 ) SSE_MOVLPS_XMM_to_Rm(x86reg, EEREC_S, offset+0); + else SSE_MOVLPS_XMM_to_M64(offset, EEREC_S); + break; + case 13: // XYW + SSE2_PSHUFD_XMM_to_XMM(EEREC_TEMP, EEREC_S, 0x4b); //YXZW + if ( x86reg >= 0 ) { + SSE_MOVHPS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+0); + SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+12); + } + else { + SSE_MOVHPS_XMM_to_M64(offset, EEREC_TEMP); + SSE_MOVSS_XMM_to_M32(offset+12, EEREC_TEMP); + } + break; + case 14: // XYZ + SSE_MOVHLPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if ( x86reg >= 0 ) { + SSE_MOVLPS_XMM_to_Rm(x86reg, EEREC_S, offset+0); + SSE_MOVSS_XMM_to_Rm(x86reg, EEREC_TEMP, offset+8); + } + else { + SSE_MOVLPS_XMM_to_M64(offset, EEREC_S); + SSE_MOVSS_XMM_to_M32(offset+8, EEREC_TEMP); + } + break; + case 15: // XYZW + if ( VU == &VU1 ) { + if( x86reg >= 0 ) SSE_MOVAPSRtoRm(x86reg, EEREC_S, offset+0); + else SSE_MOVAPS_XMM_to_M128(offset, EEREC_S); + } + else { + if( x86reg >= 0 ) SSE_MOVUPSRtoRm(x86reg, EEREC_S, offset+0); + else { + if( offset & 15 ) SSE_MOVUPS_XMM_to_M128(offset, EEREC_S); + else SSE_MOVAPS_XMM_to_M128(offset, EEREC_S); + } + } + break; + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// SQ +//------------------------------------------------------------------ +void recVUMI_SQ(VURegs *VU, int info) +{ + s16 imm; + //Console::WriteLn("recVUMI_SQ"); + imm = ( VU->code & 0x400) ? ( VU->code & 0x3ff) | 0xfc00 : ( VU->code & 0x3ff); + if ( _It_ == 0 ) _saveEAX(VU, -1, (uptr)GET_VU_MEM(VU, (int)imm * 16), info); + else { + int itreg = ALLOCVI(_It_, MODE_READ); + _saveEAX(VU, recVUTransformAddr(itreg, VU, _It_, imm), (uptr)VU->Mem, info); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// SQD +//------------------------------------------------------------------ +void recVUMI_SQD(VURegs *VU, int info) +{ + //Console::WriteLn("recVUMI_SQD"); + if (_It_ == 0) _saveEAX(VU, -1, (uptr)VU->Mem, info); + else { + int itreg = ALLOCVI(_It_, MODE_READ|MODE_WRITE); + SUB16ItoR( itreg, 1 ); + _saveEAX(VU, recVUTransformAddr(itreg, VU, _It_, 0), (uptr)VU->Mem, info); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// SQI +//------------------------------------------------------------------ +void recVUMI_SQI(VURegs *VU, int info) +{ + //Console::WriteLn("recVUMI_SQI"); + if (_It_ == 0) _saveEAX(VU, -1, (uptr)VU->Mem, info); + else { + int itreg = ALLOCVI(_It_, MODE_READ|MODE_WRITE); + _saveEAX(VU, recVUTransformAddr(itreg, VU, _It_, 0), (uptr)VU->Mem, info); + ADD16ItoR( itreg, 1 ); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ILW +//------------------------------------------------------------------ +void recVUMI_ILW(VURegs *VU, int info) +{ + int itreg; + s16 imm, off; + + if ( ( _It_ == 0 ) || ( _X_Y_Z_W == 0 ) ) return; + //Console::WriteLn("recVUMI_ILW"); + imm = ( VU->code & 0x400) ? ( VU->code & 0x3ff) | 0xfc00 : ( VU->code & 0x3ff); + if (_X) off = 0; + else if (_Y) off = 4; + else if (_Z) off = 8; + else if (_W) off = 12; + + ADD_VI_NEEDED(_Is_); + itreg = ALLOCVI(_It_, MODE_WRITE); + + if ( _Is_ == 0 ) { + MOVZX32M16toR( itreg, (uptr)GET_VU_MEM(VU, (int)imm * 16 + off) ); + } + else { + int isreg = ALLOCVI(_Is_, MODE_READ); + MOV32RmtoR(itreg, recVUTransformAddr(isreg, VU, _Is_, imm), (uptr)VU->Mem + off); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ISW +//------------------------------------------------------------------ +void recVUMI_ISW( VURegs *VU, int info ) +{ + s16 imm; + //Console::WriteLn("recVUMI_ISW"); + imm = ( VU->code & 0x400) ? ( VU->code & 0x3ff) | 0xfc00 : ( VU->code & 0x3ff); + + if (_Is_ == 0) { + uptr off = (uptr)GET_VU_MEM(VU, (int)imm * 16); + int itreg = ALLOCVI(_It_, MODE_READ); + + if (_X) MOV32RtoM(off, itreg); + if (_Y) MOV32RtoM(off+4, itreg); + if (_Z) MOV32RtoM(off+8, itreg); + if (_W) MOV32RtoM(off+12, itreg); + } + else { + int x86reg, isreg, itreg; + + ADD_VI_NEEDED(_It_); + isreg = ALLOCVI(_Is_, MODE_READ); + itreg = ALLOCVI(_It_, MODE_READ); + + x86reg = recVUTransformAddr(isreg, VU, _Is_, imm); + + if (_X) MOV32RtoRm(x86reg, itreg, (uptr)VU->Mem); + if (_Y) MOV32RtoRm(x86reg, itreg, (uptr)VU->Mem+4); + if (_Z) MOV32RtoRm(x86reg, itreg, (uptr)VU->Mem+8); + if (_W) MOV32RtoRm(x86reg, itreg, (uptr)VU->Mem+12); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ILWR +//------------------------------------------------------------------ +void recVUMI_ILWR( VURegs *VU, int info ) +{ + int off, itreg; + + if ( ( _It_ == 0 ) || ( _X_Y_Z_W == 0 ) ) return; + //Console::WriteLn("recVUMI_ILWR"); + if (_X) off = 0; + else if (_Y) off = 4; + else if (_Z) off = 8; + else if (_W) off = 12; + + ADD_VI_NEEDED(_Is_); + itreg = ALLOCVI(_It_, MODE_WRITE); + + if ( _Is_ == 0 ) { + MOVZX32M16toR( itreg, (uptr)VU->Mem + off ); + } + else { + int isreg = ALLOCVI(_Is_, MODE_READ); + MOVZX32Rm16toR(itreg, recVUTransformAddr(isreg, VU, _Is_, 0), (uptr)VU->Mem + off); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ISWR +//------------------------------------------------------------------ +void recVUMI_ISWR( VURegs *VU, int info ) +{ + int itreg; + //Console::WriteLn("recVUMI_ISWR"); + ADD_VI_NEEDED(_Is_); + itreg = ALLOCVI(_It_, MODE_READ); + + if (_Is_ == 0) { + if (_X) MOV32RtoM((uptr)VU->Mem, itreg); + if (_Y) MOV32RtoM((uptr)VU->Mem+4, itreg); + if (_Z) MOV32RtoM((uptr)VU->Mem+8, itreg); + if (_W) MOV32RtoM((uptr)VU->Mem+12, itreg); + } + else { + int x86reg; + int isreg = ALLOCVI(_Is_, MODE_READ); + x86reg = recVUTransformAddr(isreg, VU, _Is_, 0); + + if (_X) MOV32RtoRm(x86reg, itreg, (uptr)VU->Mem); + if (_Y) MOV32RtoRm(x86reg, itreg, (uptr)VU->Mem+4); + if (_Z) MOV32RtoRm(x86reg, itreg, (uptr)VU->Mem+8); + if (_W) MOV32RtoRm(x86reg, itreg, (uptr)VU->Mem+12); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// RINIT* +//------------------------------------------------------------------ +void recVUMI_RINIT(VURegs *VU, int info) +{ + //Console::WriteLn("recVUMI_RINIT()"); + if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode & MODE_NOFLUSH) ) { + _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 2); + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); + + SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)s_mask); + SSE_ORPS_M128_to_XMM(EEREC_TEMP, (uptr)VU_ONE); + SSE_MOVSS_XMM_to_M32(VU_REGR_ADDR, EEREC_TEMP); + } + else { + int rreg = ALLOCVI(REG_R, MODE_WRITE); + + if( xmmregs[EEREC_S].mode & MODE_WRITE ) { + SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); + xmmregs[EEREC_S].mode &= ~MODE_WRITE; + } + + MOV32MtoR( rreg, VU_VFx_ADDR( _Fs_ ) + 4 * _Fsf_ ); + AND32ItoR( rreg, 0x7fffff ); + OR32ItoR( rreg, 0x7f << 23 ); + + _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// RGET* +//------------------------------------------------------------------ +void recVUMI_RGET(VURegs *VU, int info) +{ + //Console::WriteLn("recVUMI_RGET()"); + if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; + + _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1); + + if (_X_Y_Z_W != 0xf) { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, VU_REGR_ADDR); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0); + VU_MERGE_REGS(EEREC_T, EEREC_TEMP); + } + else { + SSE_MOVSS_M32_to_XMM(EEREC_T, VU_REGR_ADDR); + SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// RNEXT* +//------------------------------------------------------------------ +void recVUMI_RNEXT( VURegs *VU, int info ) +{ + int rreg, x86temp0, x86temp1; + //Console::WriteLn("recVUMI_RNEXT()"); + + rreg = ALLOCVI(REG_R, MODE_WRITE|MODE_READ); + + x86temp0 = ALLOCTEMPX86(0); + x86temp1 = ALLOCTEMPX86(0); + + // code from www.project-fao.org + //MOV32MtoR(rreg, VU_REGR_ADDR); + MOV32RtoR(x86temp0, rreg); + SHR32ItoR(x86temp0, 4); + AND32ItoR(x86temp0, 1); + + MOV32RtoR(x86temp1, rreg); + SHR32ItoR(x86temp1, 22); + AND32ItoR(x86temp1, 1); + + SHL32ItoR(rreg, 1); + XOR32RtoR(x86temp0, x86temp1); + XOR32RtoR(rreg, x86temp0); + AND32ItoR(rreg, 0x7fffff); + OR32ItoR(rreg, 0x3f800000); + + _freeX86reg(x86temp0); + _freeX86reg(x86temp1); + + if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) { + _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1); + return; + } + + recVUMI_RGET(VU, info); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// RXOR* +//------------------------------------------------------------------ +void recVUMI_RXOR( VURegs *VU, int info ) +{ + //Console::WriteLn("recVUMI_RXOR()"); + if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode & MODE_NOFLUSH) ) { + _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1); + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); + + SSE_XORPS_M128_to_XMM(EEREC_TEMP, VU_REGR_ADDR); + SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)s_mask); + SSE_ORPS_M128_to_XMM(EEREC_TEMP, (uptr)s_fones); + SSE_MOVSS_XMM_to_M32(VU_REGR_ADDR, EEREC_TEMP); + } + else { + int rreg = ALLOCVI(REG_R, MODE_WRITE|MODE_READ); + + if( xmmregs[EEREC_S].mode & MODE_WRITE ) { + SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); + xmmregs[EEREC_S].mode &= ~MODE_WRITE; + } + + XOR32MtoR( rreg, VU_VFx_ADDR( _Fs_ ) + 4 * _Fsf_ ); + AND32ItoR( rreg, 0x7fffff ); + OR32ItoR ( rreg, 0x3f800000 ); + + _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// WAITQ +//------------------------------------------------------------------ +void recVUMI_WAITQ( VURegs *VU, int info ) +{ + //Console::WriteLn("recVUMI_WAITQ"); +// if( info & PROCESS_VU_SUPER ) { +// //CALLFunc(waitqfn); +// SuperVUFlush(0, 1); +// } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FSAND +//------------------------------------------------------------------ +void recVUMI_FSAND( VURegs *VU, int info ) +{ + int itreg; + u16 imm; + //Console::WriteLn("recVUMI_FSAND"); + imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); + if(_It_ == 0) return; + + itreg = ALLOCVI(_It_, MODE_WRITE); + MOV32MtoR( itreg, VU_VI_ADDR(REG_STATUS_FLAG, 1) ); + AND32ItoR( itreg, imm ); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FSEQ +//------------------------------------------------------------------ +void recVUMI_FSEQ( VURegs *VU, int info ) +{ + int itreg; + u16 imm; + if ( _It_ == 0 ) return; + //Console::WriteLn("recVUMI_FSEQ"); + imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); + + itreg = ALLOCVI(_It_, MODE_WRITE|MODE_8BITREG); + + MOVZX32M16toR( EAX, VU_VI_ADDR(REG_STATUS_FLAG, 1) ); + XOR32RtoR(itreg, itreg); + CMP16ItoR(EAX, imm); + SETE8R(itreg); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FSOR +//------------------------------------------------------------------ +void recVUMI_FSOR( VURegs *VU, int info ) +{ + int itreg; + u32 imm; + if(_It_ == 0) return; + //Console::WriteLn("recVUMI_FSOR"); + imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); + + itreg = ALLOCVI(_It_, MODE_WRITE); + + MOVZX32M16toR( itreg, VU_VI_ADDR(REG_STATUS_FLAG, 1) ); + OR32ItoR( itreg, imm ); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FSSET +//------------------------------------------------------------------ +void recVUMI_FSSET(VURegs *VU, int info) +{ + u32 writeaddr = VU_VI_ADDR(REG_STATUS_FLAG, 0); + u32 prevaddr = VU_VI_ADDR(REG_STATUS_FLAG, 2); + + u16 imm = 0; + //Console::WriteLn("recVUMI_FSSET"); + imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7FF); + + // keep the low 6 bits ONLY if the upper instruction is an fmac instruction (otherwise rewrite) - metal gear solid 3 + //if( (info & PROCESS_VU_SUPER) && VUREC_FMAC ) { + MOV32MtoR(EAX, prevaddr); + AND32ItoR(EAX, 0x3f); + if ((imm&0xfc0) != 0) OR32ItoR(EAX, imm & 0xFC0); + MOV32RtoM(writeaddr ? writeaddr : prevaddr, EAX); + //} + //else { + // MOV32ItoM(writeaddr ? writeaddr : prevaddr, imm&0xfc0); + //} +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FMAND +//------------------------------------------------------------------ +void recVUMI_FMAND( VURegs *VU, int info ) +{ + int isreg, itreg; + if ( _It_ == 0 ) return; + //Console::WriteLn("recVUMI_FMAND"); + isreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Is_, MODE_READ); + itreg = ALLOCVI(_It_, MODE_WRITE);//|MODE_8BITREG); + + if( isreg >= 0 ) { + if( itreg != isreg ) MOV32RtoR(itreg, isreg); + } + else MOVZX32M16toR(itreg, VU_VI_ADDR(_Is_, 1)); + + AND16MtoR( itreg, VU_VI_ADDR(REG_MAC_FLAG, 1)); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FMEQ +//------------------------------------------------------------------ +void recVUMI_FMEQ( VURegs *VU, int info ) +{ + int itreg, isreg; + if ( _It_ == 0 ) return; + //Console::WriteLn("recVUMI_FMEQ"); + if( _It_ == _Is_ ) { + itreg = ALLOCVI(_It_, MODE_WRITE|MODE_READ);//|MODE_8BITREG + + CMP16MtoR(itreg, VU_VI_ADDR(REG_MAC_FLAG, 1)); + SETE8R(EAX); + MOVZX32R8toR(itreg, EAX); + } + else { + ADD_VI_NEEDED(_Is_); + itreg = ALLOCVI(_It_, MODE_WRITE|MODE_8BITREG); + isreg = ALLOCVI(_Is_, MODE_READ); + + XOR32RtoR(itreg, itreg); + + CMP16MtoR(isreg, VU_VI_ADDR(REG_MAC_FLAG, 1)); + SETE8R(itreg); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FMOR +//------------------------------------------------------------------ +void recVUMI_FMOR( VURegs *VU, int info ) +{ + int isreg, itreg; + if ( _It_ == 0 ) return; + //Console::WriteLn("recVUMI_FMOR"); + if( _Is_ == 0 ) { + itreg = ALLOCVI(_It_, MODE_WRITE);//|MODE_8BITREG); + MOVZX32M16toR( itreg, VU_VI_ADDR(REG_MAC_FLAG, 1) ); + } + else if( _It_ == _Is_ ) { + itreg = ALLOCVI(_It_, MODE_WRITE|MODE_READ);//|MODE_8BITREG); + OR16MtoR( itreg, VU_VI_ADDR(REG_MAC_FLAG, 1) ); + } + else { + isreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Is_, MODE_READ); + itreg = ALLOCVI(_It_, MODE_WRITE); + + MOVZX32M16toR( itreg, VU_VI_ADDR(REG_MAC_FLAG, 1) ); + + if( isreg >= 0 ) + OR16RtoR( itreg, isreg ); + else + OR16MtoR( itreg, VU_VI_ADDR(_Is_, 1) ); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FCAND +//------------------------------------------------------------------ +void recVUMI_FCAND( VURegs *VU, int info ) +{ + int itreg = ALLOCVI(1, MODE_WRITE|MODE_8BITREG); + //Console::WriteLn("recVUMI_FCAND"); + MOV32MtoR( EAX, VU_VI_ADDR(REG_CLIP_FLAG, 1) ); + XOR32RtoR( itreg, itreg ); + AND32ItoR( EAX, VU->code & 0xFFFFFF ); + + SETNZ8R(itreg); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FCEQ +//------------------------------------------------------------------ +void recVUMI_FCEQ( VURegs *VU, int info ) +{ + int itreg = ALLOCVI(1, MODE_WRITE|MODE_8BITREG); + //Console::WriteLn("recVUMI_FCEQ"); + MOV32MtoR( EAX, VU_VI_ADDR(REG_CLIP_FLAG, 1) ); + AND32ItoR( EAX, 0xffffff ); + XOR32RtoR( itreg, itreg ); + CMP32ItoR( EAX, VU->code&0xffffff ); + + SETE8R(itreg); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FCOR +//------------------------------------------------------------------ +void recVUMI_FCOR( VURegs *VU, int info ) +{ + int itreg; + //Console::WriteLn("recVUMI_FCOR"); + itreg = ALLOCVI(1, MODE_WRITE); + MOV32MtoR( itreg, VU_VI_ADDR(REG_CLIP_FLAG, 1) ); + OR32ItoR ( itreg, VU->code ); + AND32ItoR( itreg, 0xffffff ); + ADD32ItoR( itreg, 1 ); // If 24 1's will make 25th bit 1, else 0 + SHR32ItoR( itreg, 24 ); // Get the 25th bit (also clears the rest of the garbage in the reg) +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FCSET +//------------------------------------------------------------------ +void recVUMI_FCSET( VURegs *VU, int info ) +{ + u32 addr = VU_VI_ADDR(REG_CLIP_FLAG, 0); + //Console::WriteLn("recVUMI_FCSET"); + MOV32ItoM(addr ? addr : VU_VI_ADDR(REG_CLIP_FLAG, 2), VU->code&0xffffff ); + + if( !(info & (PROCESS_VU_SUPER|PROCESS_VU_COP2)) ) + MOV32ItoM( VU_VI_ADDR(REG_CLIP_FLAG, 1), VU->code&0xffffff ); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FCGET +//------------------------------------------------------------------ +void recVUMI_FCGET( VURegs *VU, int info ) +{ + int itreg; + if(_It_ == 0) return; + //Console::WriteLn("recVUMI_FCGET"); + itreg = ALLOCVI(_It_, MODE_WRITE); + + MOV32MtoR(itreg, VU_VI_ADDR(REG_CLIP_FLAG, 1)); + AND32ItoR(itreg, 0x0fff); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// _recbranchAddr() +// +// NOTE: Due to static var dependencies, several SuperVU branch instructions +// are still located in iVUzerorec.cpp. +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// MFP* +//------------------------------------------------------------------ +void recVUMI_MFP(VURegs *VU, int info) +{ + if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; + //Console::WriteLn("recVUMI_MFP"); + if( _XYZW_SS ) { + _vuFlipRegSS(VU, EEREC_T); + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, VU_VI_ADDR(REG_P, 1)); + SSE_MOVSS_XMM_to_XMM(EEREC_T, EEREC_TEMP); + _vuFlipRegSS(VU, EEREC_T); + } + else if (_X_Y_Z_W != 0xf) { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, VU_VI_ADDR(REG_P, 1)); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0); + VU_MERGE_REGS(EEREC_T, EEREC_TEMP); + } + else { + SSE_MOVSS_M32_to_XMM(EEREC_T, VU_VI_ADDR(REG_P, 1)); + SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// WAITP +//------------------------------------------------------------------ +static PCSX2_ALIGNED16(float s_tempmem[4]); +void recVUMI_WAITP(VURegs *VU, int info) +{ + //Console::WriteLn("recVUMI_WAITP"); +// if( info & PROCESS_VU_SUPER ) +// SuperVUFlush(1, 1); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// vuSqSumXYZ()* +// +// NOTE: In all EFU insts, EEREC_D is a temp reg +//------------------------------------------------------------------ +void vuSqSumXYZ(int regd, int regs, int regtemp) // regd.x = x ^ 2 + y ^ 2 + z ^ 2 +{ + //Console::WriteLn("VU: SUMXYZ"); + if( cpucaps.hasStreamingSIMD4Extensions ) + { + SSE_MOVAPS_XMM_to_XMM(regd, regs); + if (CHECK_VU_EXTRA_OVERFLOW) vuFloat2(regd, regtemp, 0xf); + SSE4_DPPS_XMM_to_XMM(regd, regd, 0x71); + } + else + { + SSE_MOVAPS_XMM_to_XMM(regtemp, regs); + if (CHECK_VU_EXTRA_OVERFLOW) vuFloat2(regtemp, regd, 0xf); + SSE_MULPS_XMM_to_XMM(regtemp, regtemp); // xyzw ^ 2 + + if( cpucaps.hasStreamingSIMD3Extensions ) { + SSE3_HADDPS_XMM_to_XMM(regd, regtemp); + SSE_ADDPS_XMM_to_XMM(regd, regtemp); // regd.z = x ^ 2 + y ^ 2 + z ^ 2 + SSE_MOVHLPS_XMM_to_XMM(regd, regd); // regd.x = regd.z + } + else { + SSE_MOVSS_XMM_to_XMM(regd, regtemp); + SSE2_PSHUFLW_XMM_to_XMM(regtemp, regtemp, 0x4e); // wzyx -> wzxy + SSE_ADDSS_XMM_to_XMM(regd, regtemp); // x ^ 2 + y ^ 2 + SSE_SHUFPS_XMM_to_XMM(regtemp, regtemp, 0xD2); // wzxy -> wxyz + SSE_ADDSS_XMM_to_XMM(regd, regtemp); // x ^ 2 + y ^ 2 + z ^ 2 + } + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ESADD* +//------------------------------------------------------------------ +void recVUMI_ESADD( VURegs *VU, int info) +{ + //Console::WriteLn("VU: ESADD"); + assert( VU == &VU1 ); + if( EEREC_TEMP == EEREC_D ) { // special code to reset P ( FixMe: don't know if this is still needed! (cottonvibes) ) + Console::Notice("ESADD: Resetting P reg!!!\n"); + MOV32ItoM(VU_VI_ADDR(REG_P, 0), 0); + return; + } + vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP); + if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_D, (uptr)g_maxvals); // Only need to do positive clamp since (x ^ 2 + y ^ 2 + z ^ 2) is positive + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_D); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ERSADD* +//------------------------------------------------------------------ +void recVUMI_ERSADD( VURegs *VU, int info ) +{ + //Console::WriteLn("VU: ERSADD"); + assert( VU == &VU1 ); + vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP); + // don't use RCPSS (very bad precision) + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); + SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_D); + if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Only need to do positive clamp since (x ^ 2 + y ^ 2 + z ^ 2) is positive + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ELENG* +//------------------------------------------------------------------ +void recVUMI_ELENG( VURegs *VU, int info ) +{ + //Console::WriteLn("VU: ELENG"); + assert( VU == &VU1 ); + vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP); + if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_D, (uptr)g_maxvals); // Only need to do positive clamp since (x ^ 2 + y ^ 2 + z ^ 2) is positive + SSE_SQRTSS_XMM_to_XMM(EEREC_D, EEREC_D); + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_D); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ERLENG* +//------------------------------------------------------------------ +void recVUMI_ERLENG( VURegs *VU, int info ) +{ + //Console::WriteLn("VU: ERLENG"); + assert( VU == &VU1 ); + vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP); + if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_D, (uptr)g_maxvals); // Only need to do positive clamp since (x ^ 2 + y ^ 2 + z ^ 2) is positive + SSE_SQRTSS_XMM_to_XMM(EEREC_D, EEREC_D); // regd <- sqrt(x^2 + y^2 + z^2) + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); // temp <- 1 + SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_D); // temp = 1 / sqrt(x^2 + y^2 + z^2) + if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Only need to do positive clamp + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// EATANxy +//------------------------------------------------------------------ +void recVUMI_EATANxy( VURegs *VU, int info ) +{ + assert( VU == &VU1 ); + //Console::WriteLn("recVUMI_EATANxy"); + if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { + SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S); + FLD32((uptr)&s_tempmem[0]); + FLD32((uptr)&s_tempmem[1]); + } + else { + if( xmmregs[EEREC_S].mode & MODE_WRITE ) { + SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); + xmmregs[EEREC_S].mode &= ~MODE_WRITE; + } + + FLD32((uptr)&VU->VF[_Fs_].UL[0]); + FLD32((uptr)&VU->VF[_Fs_].UL[1]); + } + + FPATAN(); + FSTP32(VU_VI_ADDR(REG_P, 0)); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// EATANxz +//------------------------------------------------------------------ +void recVUMI_EATANxz( VURegs *VU, int info ) +{ + assert( VU == &VU1 ); + //Console::WriteLn("recVUMI_EATANxz"); + if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { + SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S); + FLD32((uptr)&s_tempmem[0]); + FLD32((uptr)&s_tempmem[2]); + } + else { + if( xmmregs[EEREC_S].mode & MODE_WRITE ) { + SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); + xmmregs[EEREC_S].mode &= ~MODE_WRITE; + } + + FLD32((uptr)&VU->VF[_Fs_].UL[0]); + FLD32((uptr)&VU->VF[_Fs_].UL[2]); + } + FPATAN(); + FSTP32(VU_VI_ADDR(REG_P, 0)); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ESUM* +//------------------------------------------------------------------ +void recVUMI_ESUM( VURegs *VU, int info ) +{ + //Console::WriteLn("VU: ESUM"); + assert( VU == &VU1 ); + + if( cpucaps.hasStreamingSIMD3Extensions ) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) vuFloat_useEAX(info, EEREC_TEMP, 0xf); + SSE3_HADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); + SSE3_HADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); + } + else { + SSE_MOVHLPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); // z, w, z, w + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); // z+x, w+y, z+z, w+w + SSE_UNPCKLPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); // z+x, z+x, w+y, w+y + SSE_MOVHLPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); // w+y, w+y, w+y, w+y + SSE_ADDSS_XMM_to_XMM(EEREC_TEMP, EEREC_D); // x+y+z+w, w+y, w+y, w+y + } + + vuFloat_useEAX(info, EEREC_TEMP, 8); + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ERCPR* +//------------------------------------------------------------------ +void recVUMI_ERCPR( VURegs *VU, int info ) +{ + assert( VU == &VU1 ); + //Console::WriteLn("VU1: ERCPR"); + + // don't use RCPSS (very bad precision) + switch ( _Fsf_ ) { + case 0: //0001 + if (CHECK_VU_EXTRA_OVERFLOW) vuFloat5_useEAX(EEREC_S, EEREC_TEMP, 8); + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); // temp <- 1 + SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + break; + case 1: //0010 + SSE2_PSHUFLW_XMM_to_XMM(EEREC_S, EEREC_S, 0x4e); + if (CHECK_VU_EXTRA_OVERFLOW) vuFloat5_useEAX(EEREC_S, EEREC_TEMP, 8); + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); // temp <- 1 + SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE2_PSHUFLW_XMM_to_XMM(EEREC_S, EEREC_S, 0x4e); + break; + case 2: //0100 + SSE_SHUFPS_XMM_to_XMM(EEREC_S, EEREC_S, 0xc6); + if (CHECK_VU_EXTRA_OVERFLOW) vuFloat5_useEAX(EEREC_S, EEREC_TEMP, 8); + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); // temp <- 1 + SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_SHUFPS_XMM_to_XMM(EEREC_S, EEREC_S, 0xc6); + break; + case 3: //1000 + SSE_SHUFPS_XMM_to_XMM(EEREC_S, EEREC_S, 0x27); + if (CHECK_VU_EXTRA_OVERFLOW) vuFloat5_useEAX(EEREC_S, EEREC_TEMP, 8); + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); // temp <- 1 + SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_SHUFPS_XMM_to_XMM(EEREC_S, EEREC_S, 0x27); + break; + } + + vuFloat_useEAX(info, EEREC_TEMP, 8); + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ESQRT* +//------------------------------------------------------------------ +void recVUMI_ESQRT( VURegs *VU, int info ) +{ + assert( VU == &VU1 ); + + //Console::WriteLn("VU1: ESQRT"); + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); + SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)const_clip); // abs(x) + if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Only need to do positive clamp + SSE_SQRTSS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); + + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ERSQRT* +//------------------------------------------------------------------ +void recVUMI_ERSQRT( VURegs *VU, int info ) +{ + int t1reg = _vuGetTempXMMreg(info); + + assert( VU == &VU1 ); + //Console::WriteLn("VU1: ERSQRT"); + + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); + SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)const_clip); // abs(x) + SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Clamp Infinities to Fmax + SSE_SQRTSS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); // SQRT(abs(x)) + + if( t1reg >= 0 ) + { + SSE_MOVSS_M32_to_XMM(t1reg, (uptr)VU_ONE); + SSE_DIVSS_XMM_to_XMM(t1reg, EEREC_TEMP); + vuFloat_useEAX(info, t1reg, 8); + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), t1reg); + _freeXMMreg(t1reg); + } + else + { + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)VU_ONE); + SSE_DIVSS_M32_to_XMM(EEREC_TEMP, VU_VI_ADDR(REG_P, 0)); + vuFloat_useEAX(info, EEREC_TEMP, 8); + SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_P, 0), EEREC_TEMP); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ESIN +//------------------------------------------------------------------ +void recVUMI_ESIN( VURegs *VU, int info ) +{ + assert( VU == &VU1 ); + + //Console::WriteLn("recVUMI_ESIN"); + if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { + switch(_Fsf_) { + case 0: SSE_MOVSS_XMM_to_M32((uptr)s_tempmem, EEREC_S); + case 1: SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S); + default: SSE_MOVHPS_XMM_to_M64((uptr)&s_tempmem[2], EEREC_S); + } + FLD32((uptr)&s_tempmem[_Fsf_]); + } + else { + if( xmmregs[EEREC_S].mode & MODE_WRITE ) { + SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); + xmmregs[EEREC_S].mode &= ~MODE_WRITE; + } + + FLD32((uptr)&VU->VF[_Fs_].UL[_Fsf_]); + } + + FSIN(); + FSTP32(VU_VI_ADDR(REG_P, 0)); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// EATAN +//------------------------------------------------------------------ +void recVUMI_EATAN( VURegs *VU, int info ) +{ + assert( VU == &VU1 ); + + //Console::WriteLn("recVUMI_EATAN"); + if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { + switch(_Fsf_) { + case 0: SSE_MOVSS_XMM_to_M32((uptr)s_tempmem, EEREC_S); + case 1: SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S); + default: SSE_MOVHPS_XMM_to_M64((uptr)&s_tempmem[2], EEREC_S); + } + FLD32((uptr)&s_tempmem[_Fsf_]); + } + else { + if( xmmregs[EEREC_S].mode & MODE_WRITE ) { + SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); + xmmregs[EEREC_S].mode &= ~MODE_WRITE; + } + } + + FLD1(); + FLD32((uptr)&VU->VF[_Fs_].UL[_Fsf_]); + FPATAN(); + FSTP32(VU_VI_ADDR(REG_P, 0)); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// EEXP +//------------------------------------------------------------------ +void recVUMI_EEXP( VURegs *VU, int info ) +{ + assert( VU == &VU1 ); + //Console::WriteLn("recVUMI_EEXP"); + FLDL2E(); + + if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { + switch(_Fsf_) { + case 0: SSE_MOVSS_XMM_to_M32((uptr)s_tempmem, EEREC_S); + case 1: SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S); + default: SSE_MOVHPS_XMM_to_M64((uptr)&s_tempmem[2], EEREC_S); + } + FMUL32((uptr)&s_tempmem[_Fsf_]); + } + else { + if( xmmregs[EEREC_S].mode & MODE_WRITE ) { + SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[_Fs_], EEREC_S); + xmmregs[EEREC_S].mode &= ~MODE_WRITE; + } + + FMUL32((uptr)&VU->VF[_Fs_].UL[_Fsf_]); + } + + // basically do 2^(log_2(e) * val) + FLD(0); + FRNDINT(); + FXCH(1); + FSUB32Rto0(1); + F2XM1(); + FLD1(); + FADD320toR(1); + FSCALE(); + FSTP(1); + + FSTP32(VU_VI_ADDR(REG_P, 0)); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// XITOP +//------------------------------------------------------------------ +void recVUMI_XITOP( VURegs *VU, int info ) +{ + int itreg; + if (_It_ == 0) return; + //Console::WriteLn("recVUMI_XITOP"); + itreg = ALLOCVI(_It_, MODE_WRITE); + MOVZX32M16toR( itreg, (uptr)&VU->vifRegs->itop ); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// XTOP +//------------------------------------------------------------------ +void recVUMI_XTOP( VURegs *VU, int info ) +{ + int itreg; + if ( _It_ == 0 ) return; + //Console::WriteLn("recVUMI_XTOP"); + itreg = ALLOCVI(_It_, MODE_WRITE); + MOVZX32M16toR( itreg, (uptr)&VU->vifRegs->top ); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// VU1XGKICK_MTGSTransfer() - Called by ivuZerorec.cpp +//------------------------------------------------------------------ +void VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr) +{ + u32 size; + u32* data = (u32*)((u8*)pMem + (addr&0x3fff)); + + // fixme: The gifTagDummy function in the MTGS (called by PrepDataPacket) has a + // hack that aborts the packet if it goes past the end of VU1 memory. + // Chances are this should be a "loops around memory" situation, and the packet + // should be continued starting at addr zero (0). + + size = mtgsThread->PrepDataPacket(GIF_PATH_1, data, (0x4000-(addr&0x3fff)) >> 4); + jASSUME( size > 0 ); + + //if( size > 0 ) + { + u8* pmem = mtgsThread->GetDataPacketPtr(); + + /* if((size << 4) > (0x4000-(addr&0x3fff))) + { + //DevCon::Notice("addr + Size = 0x%x, transferring %x then doing %x", params (addr&0x3fff) + (size << 4), (0x4000-(addr&0x3fff)) >> 4, size - ((0x4000-(addr&0x3fff)) >> 4)); + memcpy_aligned(pmem, (u8*)pMem+addr, 0x4000-(addr&0x3fff)); + size -= (0x4000-(addr&0x3fff)) >> 4; + //DevCon::Notice("Size left %x", params size); + pmem += 0x4000-(addr&0x3fff); + memcpy_aligned(pmem, (u8*)pMem, size<<4); + } + else + {*/ + memcpy_aligned(pmem, (u8*)pMem+addr, size<<4); + // } + mtgsThread->SendDataPacket(); + } +} +//------------------------------------------------------------------ diff --git a/pcsx2/x86/iVUmicro.cpp b/pcsx2/x86/sVU_Micro.cpp similarity index 96% rename from pcsx2/x86/iVUmicro.cpp rename to pcsx2/x86/sVU_Micro.cpp index 9335151798..89ddd307e2 100644 --- a/pcsx2/x86/iVUmicro.cpp +++ b/pcsx2/x86/sVU_Micro.cpp @@ -1,1737 +1,1740 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "PrecompiledHeader.h" - -#include "Common.h" -#include "GS.h" -#include "R5900OpcodeTables.h" -#include "iR5900.h" -#include "iMMI.h" -#include "iFPU.h" -#include "iCOP0.h" -#include "VUmicro.h" -#include "VUflags.h" -#include "iVUmicro.h" -#include "iVUops.h" -#include "iVUzerorec.h" - -#ifdef _WIN32 -#pragma warning(disable:4244) -#pragma warning(disable:4761) -#endif -//------------------------------------------------------------------ - -// fixme - VUmicro should really use its own static vars for pc and branch. -// Sharing with the EE's copies of pc and branch is not cool! (air) - -//------------------------------------------------------------------ -// Helper Macros -//------------------------------------------------------------------ -#define _Ft_ (( VU->code >> 16) & 0x1F) // The rt part of the instruction register -#define _Fs_ (( VU->code >> 11) & 0x1F) // The rd part of the instruction register -#define _Fd_ (( VU->code >> 6) & 0x1F) // The sa part of the instruction register - -#define _X (( VU->code>>24) & 0x1) -#define _Y (( VU->code>>23) & 0x1) -#define _Z (( VU->code>>22) & 0x1) -#define _W (( VU->code>>21) & 0x1) - -#define _XYZW_SS (_X+_Y+_Z+_W==1) - -#define _Fsf_ (( VU->code >> 21) & 0x03) -#define _Ftf_ (( VU->code >> 23) & 0x03) - -#define _Imm11_ (s32)(VU->code & 0x400 ? 0xfffffc00 | (VU->code & 0x3ff) : VU->code & 0x3ff) -#define _UImm11_ (s32)(VU->code & 0x7ff) - -#define VU_VFx_ADDR(x) (uptr)&VU->VF[x].UL[0] -#define VU_VFy_ADDR(x) (uptr)&VU->VF[x].UL[1] -#define VU_VFz_ADDR(x) (uptr)&VU->VF[x].UL[2] -#define VU_VFw_ADDR(x) (uptr)&VU->VF[x].UL[3] - -#define VU_REGR_ADDR (uptr)&VU->VI[REG_R] -#define VU_REGQ_ADDR (uptr)&VU->VI[REG_Q] -#define VU_REGMAC_ADDR (uptr)&VU->VI[REG_MAC_FLAG] - -#define VU_VI_ADDR(x, read) GetVIAddr(VU, x, read, info) - -#define VU_ACCx_ADDR (uptr)&VU->ACC.UL[0] -#define VU_ACCy_ADDR (uptr)&VU->ACC.UL[1] -#define VU_ACCz_ADDR (uptr)&VU->ACC.UL[2] -#define VU_ACCw_ADDR (uptr)&VU->ACC.UL[3] - -#define _X_Y_Z_W ((( VU->code >> 21 ) & 0xF ) ) -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// Global Variables -//------------------------------------------------------------------ -int vucycle; - -PCSX2_ALIGNED16(const float s_fones[8]) = {1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f}; -PCSX2_ALIGNED16(const u32 s_mask[4]) = {0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff}; -PCSX2_ALIGNED16(const u32 s_expmask[4]) = {0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000}; -PCSX2_ALIGNED16(const u32 g_minvals[4]) = {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}; -PCSX2_ALIGNED16(const u32 g_maxvals[4]) = {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}; -PCSX2_ALIGNED16(const u32 const_clip[8]) = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, - 0x80000000, 0x80000000, 0x80000000, 0x80000000}; -PCSX2_ALIGNED(64, const u32 g_ones[4]) = {0x00000001, 0x00000001, 0x00000001, 0x00000001}; -PCSX2_ALIGNED16(const u32 g_minvals_XYZW[16][4]) = -{ - { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }, //0000 - { 0xffffffff, 0xffffffff, 0xffffffff, 0xff7fffff }, //0001 - { 0xffffffff, 0xffffffff, 0xff7fffff, 0xffffffff }, //0010 - { 0xffffffff, 0xffffffff, 0xff7fffff, 0xff7fffff }, //0011 - { 0xffffffff, 0xff7fffff, 0xffffffff, 0xffffffff }, //0100 - { 0xffffffff, 0xff7fffff, 0xffffffff, 0xff7fffff }, //0101 - { 0xffffffff, 0xff7fffff, 0xff7fffff, 0xffffffff }, //0110 - { 0xffffffff, 0xff7fffff, 0xff7fffff, 0xff7fffff }, //0111 - { 0xff7fffff, 0xffffffff, 0xffffffff, 0xffffffff }, //1000 - { 0xff7fffff, 0xffffffff, 0xffffffff, 0xff7fffff }, //1001 - { 0xff7fffff, 0xffffffff, 0xff7fffff, 0xffffffff }, //1010 - { 0xff7fffff, 0xffffffff, 0xff7fffff, 0xff7fffff }, //1011 - { 0xff7fffff, 0xff7fffff, 0xffffffff, 0xffffffff }, //1100 - { 0xff7fffff, 0xff7fffff, 0xffffffff, 0xff7fffff }, //1101 - { 0xff7fffff, 0xff7fffff, 0xff7fffff, 0xffffffff }, //1110 - { 0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff }, //1111 -}; -PCSX2_ALIGNED16(const u32 g_maxvals_XYZW[16][4])= -{ - { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff }, //0000 - { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7f7fffff }, //0001 - { 0x7fffffff, 0x7fffffff, 0x7f7fffff, 0x7fffffff }, //0010 - { 0x7fffffff, 0x7fffffff, 0x7f7fffff, 0x7f7fffff }, //0011 - { 0x7fffffff, 0x7f7fffff, 0x7fffffff, 0x7fffffff }, //0100 - { 0x7fffffff, 0x7f7fffff, 0x7fffffff, 0x7f7fffff }, //0101 - { 0x7fffffff, 0x7f7fffff, 0x7f7fffff, 0x7fffffff }, //0110 - { 0x7fffffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff }, //0111 - { 0x7f7fffff, 0x7fffffff, 0x7fffffff, 0x7fffffff }, //1000 - { 0x7f7fffff, 0x7fffffff, 0x7fffffff, 0x7f7fffff }, //1001 - { 0x7f7fffff, 0x7fffffff, 0x7f7fffff, 0x7fffffff }, //1010 - { 0x7f7fffff, 0x7fffffff, 0x7f7fffff, 0x7f7fffff }, //1011 - { 0x7f7fffff, 0x7f7fffff, 0x7fffffff, 0x7fffffff }, //1100 - { 0x7f7fffff, 0x7f7fffff, 0x7fffffff, 0x7f7fffff }, //1101 - { 0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7fffffff }, //1110 - { 0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff }, //1111 -}; -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -// VU Pipeline/Test Stalls/Analyzing Functions -//------------------------------------------------------------------ -void _recvuFMACflush(VURegs * VU, bool intermediate) { - int i; - - for (i=0; i<8; i++) { - if (VU->fmac[i].enable == 0) continue; - - if( intermediate ) { - if ((vucycle - VU->fmac[i].sCycle) > VU->fmac[i].Cycle) { -// VUM_LOG("flushing FMAC pipe[%d]", i); - VU->fmac[i].enable = 0; - } - } - else { - if ((vucycle - VU->fmac[i].sCycle) >= VU->fmac[i].Cycle) { -// VUM_LOG("flushing FMAC pipe[%d]", i); - VU->fmac[i].enable = 0; - } - } - } -} - -void _recvuFDIVflush(VURegs * VU, bool intermediate) { - if (VU->fdiv.enable == 0) return; - - if( intermediate ) { - if ((vucycle - VU->fdiv.sCycle) > VU->fdiv.Cycle) { -// Console::WriteLn("flushing FDIV pipe"); - VU->fdiv.enable = 0; - } - } - else { - if ((vucycle - VU->fdiv.sCycle) >= VU->fdiv.Cycle) { -// Console::WriteLn("flushing FDIV pipe"); - VU->fdiv.enable = 0; - } - } -} - -void _recvuEFUflush(VURegs * VU, bool intermediate) { - if (VU->efu.enable == 0) return; - - if( intermediate ) { - if ((vucycle - VU->efu.sCycle) > VU->efu.Cycle) { -// Console::WriteLn("flushing FDIV pipe"); - VU->efu.enable = 0; - } - } - else { - if ((vucycle - VU->efu.sCycle) >= VU->efu.Cycle) { -// Console::WriteLn("flushing FDIV pipe"); - VU->efu.enable = 0; - } - } -} - -void _recvuIALUflush(VURegs * VU, bool intermediate) { - int i; - - for (i=0; i<8; i++) { - if (VU->ialu[i].enable == 0) continue; - - if( intermediate ) { - if ((vucycle - VU->ialu[i].sCycle) > VU->ialu[i].Cycle) { -// VUM_LOG("flushing IALU pipe[%d]", i); - VU->ialu[i].enable = 0; - } - } - else { - if ((vucycle - VU->ialu[i].sCycle) >= VU->ialu[i].Cycle) { -// VUM_LOG("flushing IALU pipe[%d]", i); - VU->ialu[i].enable = 0; - } - } - } -} - -void _recvuTestPipes(VURegs * VU, bool intermediate) { // intermediate = true if called by upper FMAC stall detection - _recvuFMACflush(VU, intermediate); - _recvuFDIVflush(VU, intermediate); - _recvuEFUflush(VU, intermediate); - _recvuIALUflush(VU, intermediate); -} - -void _recvuFMACTestStall(VURegs * VU, int reg, int xyzw) { - int cycle; - int i; - u32 mask = 0; - - for (i=0; i<8; i++) { - if (VU->fmac[i].enable == 0) continue; - if (VU->fmac[i].reg == reg && (VU->fmac[i].xyzw & xyzw)) break; - } - - if (i == 8) return; - - // do a perchannel delay - // old code -// cycle = VU->fmac[i].Cycle - (vucycle - VU->fmac[i].sCycle); - - // new code - mask = 4; // w -// if( VU->fmac[i].xyzw & 1 ) mask = 4; // w -// else if( VU->fmac[i].xyzw & 2 ) mask = 3; // z -// else if( VU->fmac[i].xyzw & 4 ) mask = 2; // y -// else { -// assert(VU->fmac[i].xyzw & 8 ); -// mask = 1; // x -// } - -// mask = 0; -// if( VU->fmac[i].xyzw & 1 ) mask++; // w -// else if( VU->fmac[i].xyzw & 2 ) mask++; // z -// else if( VU->fmac[i].xyzw & 4 ) mask++; // y -// else if( VU->fmac[i].xyzw & 8 ) mask++; // x - - assert( (int)VU->fmac[i].sCycle < (int)vucycle ); - cycle = 0; - if( vucycle - VU->fmac[i].sCycle < mask ) - cycle = mask - (vucycle - VU->fmac[i].sCycle); - - VU->fmac[i].enable = 0; - vucycle+= cycle; - _recvuTestPipes(VU, true); // for lower instructions -} - -void _recvuIALUTestStall(VURegs * VU, int reg) { - int cycle; - int i; - u32 latency; - - for (i=0; i<8; i++) { - if (VU->ialu[i].enable == 0) continue; - if (VU->ialu[i].reg == reg) break; - } - - if (i == 8) return; - - latency = VU->ialu[i].Cycle + 1; - cycle = 0; - if( vucycle - VU->ialu[i].sCycle < latency ) - cycle = latency - (vucycle - VU->ialu[i].sCycle); - - VU->ialu[i].enable = 0; - vucycle+= cycle; - _recvuTestPipes(VU, true); -} - -void _recvuFMACAdd(VURegs * VU, int reg, int xyzw) { - int i; - - /* find a free fmac pipe */ - for (i=0; i<8; i++) { - if (VU->fmac[i].enable == 1) continue; - break; - } - - if (i==8) Console::Error("*PCSX2*: error , out of fmacs"); -// VUM_LOG("adding FMAC pipe[%d]; reg %d", i, reg); - - VU->fmac[i].enable = 1; - VU->fmac[i].sCycle = vucycle; - VU->fmac[i].Cycle = 3; - VU->fmac[i].xyzw = xyzw; - VU->fmac[i].reg = reg; -} - -void _recvuFDIVAdd(VURegs * VU, int cycles) { -// Console::WriteLn("adding FDIV pipe"); - VU->fdiv.enable = 1; - VU->fdiv.sCycle = vucycle; - VU->fdiv.Cycle = cycles; -} - -void _recvuEFUAdd(VURegs * VU, int cycles) { -// Console::WriteLn("adding EFU pipe"); - VU->efu.enable = 1; - VU->efu.sCycle = vucycle; - VU->efu.Cycle = cycles; -} - -void _recvuIALUAdd(VURegs * VU, int reg, int cycles) { - int i; - - /* find a free ialu pipe */ - for (i=0; i<8; i++) { - if (VU->ialu[i].enable == 1) continue; - break; - } - - if (i==8) Console::Error("*PCSX2*: error , out of ialus"); - - VU->ialu[i].enable = 1; - VU->ialu[i].sCycle = vucycle; - VU->ialu[i].Cycle = cycles; - VU->ialu[i].reg = reg; -} - -void _recvuTestIALUStalls(VURegs * VU, _VURegsNum *VUregsn) { - - int VIread0 = 0, VIread1 = 0; // max 2 integer registers are read simulataneously - int i; - - for(i=0;i<16;i++) { // find used integer(vi00-vi15) registers - if( (VUregsn->VIread >> i) & 1 ) { - if( VIread0 ) VIread1 = i; - else VIread0 = i; - } - } - - if( VIread0 ) _recvuIALUTestStall(VU, VIread0); - if( VIread1 ) _recvuIALUTestStall(VU, VIread1); -} - -void _recvuAddIALUStalls(VURegs * VU, _VURegsNum *VUregsn) { - if (VUregsn->VIwrite && VUregsn->cycles) { - int VIWrite0 = 0; - int i; - - for(i=0;i<16;i++) { // find used(vi00-vi15) registers - if( (VUregsn->VIwrite >> i) & 1 ) { - VIWrite0 = i; - } - } - if( VIWrite0 ) _recvuIALUAdd(VU, VIWrite0, VUregsn->cycles); - } -} - -void _recvuTestFMACStalls(VURegs * VU, _VURegsNum *VUregsn, bool upper) { - - if( VUregsn->VFread0 && (VUregsn->VFread0 == VUregsn->VFread1) ) { - _recvuFMACTestStall(VU, VUregsn->VFread0, VUregsn->VFr0xyzw|VUregsn->VFr1xyzw); - } - else { - if (VUregsn->VFread0) _recvuFMACTestStall(VU, VUregsn->VFread0, VUregsn->VFr0xyzw); - if (VUregsn->VFread1) _recvuFMACTestStall(VU, VUregsn->VFread1, VUregsn->VFr1xyzw); - } - - if( !upper && VUregsn->VIread ) _recvuTestIALUStalls(VU, VUregsn); // for lower instructions which read integer reg -} - -void _recvuAddFMACStalls(VURegs * VU, _VURegsNum *VUregsn) { - - if (VUregsn->VFwrite) _recvuFMACAdd(VU, VUregsn->VFwrite, VUregsn->VFwxyzw); - else if (VUregsn->VIwrite & (1 << REG_CLIP_FLAG)) _recvuFMACAdd(VU, -REG_CLIP_FLAG, 0); // REG_CLIP_FLAG pipe - else _recvuFMACAdd(VU, 0, 0); // cause no data dependency with fp registers -} - -void _recvuFlushFDIV(VURegs * VU) { - int cycle; - - if (VU->fdiv.enable == 0) return; - - cycle = VU->fdiv.Cycle + 1 - (vucycle - VU->fdiv.sCycle); //VU->fdiv.Cycle contains the latency minus 1 (6 or 12) -// Console::WriteLn("waiting FDIV pipe %d", params cycle); - VU->fdiv.enable = 0; - vucycle+= cycle; -} - -void _recvuFlushEFU(VURegs * VU) { - int cycle; - - if (VU->efu.enable == 0) return; - - cycle = VU->efu.Cycle - (vucycle - VU->efu.sCycle); -// Console::WriteLn("waiting FDIV pipe %d", params cycle); - VU->efu.enable = 0; - vucycle+= cycle; -} - -void _recvuTestFDIVStalls(VURegs * VU, _VURegsNum *VUregsn) { - _recvuTestFMACStalls(VU,VUregsn, false); - _recvuFlushFDIV(VU); -} - -void _recvuTestEFUStalls(VURegs * VU, _VURegsNum *VUregsn) { - _recvuTestFMACStalls(VU,VUregsn, false); - _recvuFlushEFU(VU); -} - -void _recvuAddFDIVStalls(VURegs * VU, _VURegsNum *VUregsn) { -// _vuTestFMACStalls(VURegs * VU, _VURegsNum *VUregsn); - if (VUregsn->VIwrite & (1 << REG_Q)) { - _recvuFDIVAdd(VU, VUregsn->cycles); - } -} - -void _recvuAddEFUStalls(VURegs * VU, _VURegsNum *VUregsn) { -// _vuTestFMACStalls(VURegs * VU, _VURegsNum *VUregsn); - if (VUregsn->VIwrite & (1 << REG_P)) { - _recvuEFUAdd(VU, VUregsn->cycles); - } -} - -void _recvuTestUpperStalls(VURegs * VU, _VURegsNum *VUregsn) { - switch (VUregsn->pipe) { - case VUPIPE_FMAC: _recvuTestFMACStalls(VU, VUregsn, true); break; - } -} - -void _recvuTestLowerStalls(VURegs * VU, _VURegsNum *VUregsn) { - switch (VUregsn->pipe) { - case VUPIPE_FMAC: _recvuTestFMACStalls(VU, VUregsn, false); break; - case VUPIPE_FDIV: _recvuTestFDIVStalls(VU, VUregsn); break; - case VUPIPE_EFU: _recvuTestEFUStalls(VU, VUregsn); break; - case VUPIPE_IALU: _recvuTestIALUStalls(VU, VUregsn); break; - case VUPIPE_BRANCH: _recvuTestIALUStalls(VU, VUregsn); break; - } -} - -void _recvuAddUpperStalls(VURegs * VU, _VURegsNum *VUregsn) { - switch (VUregsn->pipe) { - case VUPIPE_FMAC: _recvuAddFMACStalls(VU, VUregsn); break; - } -} - -void _recvuAddLowerStalls(VURegs * VU, _VURegsNum *VUregsn) { - switch (VUregsn->pipe) { - case VUPIPE_FMAC: _recvuAddFMACStalls(VU, VUregsn); break; - case VUPIPE_FDIV: _recvuAddFDIVStalls(VU, VUregsn); break; - case VUPIPE_EFU: _recvuAddEFUStalls(VU, VUregsn); break; - case VUPIPE_IALU: _recvuAddIALUStalls(VU, VUregsn); break; // note: only ILW and ILWR cause stall in IALU pipe - } -} - -void SuperVUAnalyzeOp(VURegs *VU, _vuopinfo *info, _VURegsNum* pCodeRegs) -{ - _VURegsNum* lregs; - _VURegsNum* uregs; - int *ptr; - - lregs = pCodeRegs; - uregs = pCodeRegs+1; - - ptr = (int*)&VU->Micro[pc]; - pc += 8; - - if (ptr[1] & 0x40000000) { // EOP - branch |= 8; - } - - VU->code = ptr[1]; - if (VU == &VU1) VU1regs_UPPER_OPCODE[VU->code & 0x3f](uregs); - else VU0regs_UPPER_OPCODE[VU->code & 0x3f](uregs); - - _recvuTestUpperStalls(VU, uregs); - switch(VU->code & 0x3f) { - case 0x10: case 0x11: case 0x12: case 0x13: - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x1d: case 0x1f: - case 0x2b: case 0x2f: - break; - - case 0x3c: - switch ((VU->code >> 6) & 0x1f) { - case 0x4: case 0x5: - break; - default: - info->statusflag = 4; - info->macflag = 4; - break; - } - break; - case 0x3d: - switch ((VU->code >> 6) & 0x1f) { - case 0x4: case 0x5: case 0x7: - break; - default: - info->statusflag = 4; - info->macflag = 4; - break; - } - break; - case 0x3e: - switch ((VU->code >> 6) & 0x1f) { - case 0x4: case 0x5: - break; - default: - info->statusflag = 4; - info->macflag = 4; - break; - } - break; - case 0x3f: - switch ((VU->code >> 6) & 0x1f) { - case 0x4: case 0x5: case 0x7: case 0xb: - break; - default: - info->statusflag = 4; - info->macflag = 4; - break; - } - break; - - default: - info->statusflag = 4; - info->macflag = 4; - break; - } - - if (uregs->VIread & (1 << REG_Q)) { info->q |= 2; } - if (uregs->VIread & (1 << REG_P)) { info->p |= 2; assert( VU == &VU1 ); } - - // check upper flags - if (ptr[1] & 0x80000000) { // I flag - info->cycle = vucycle; - memzero_obj(*lregs); - } - else { - - VU->code = ptr[0]; - if (VU == &VU1) VU1regs_LOWER_OPCODE[VU->code >> 25](lregs); - else VU0regs_LOWER_OPCODE[VU->code >> 25](lregs); - - _recvuTestLowerStalls(VU, lregs); - info->cycle = vucycle; - - if (lregs->pipe == VUPIPE_BRANCH) { - branch |= 1; - } - - if (lregs->VIwrite & (1 << REG_Q)) { - info->q |= 4; - info->cycles = lregs->cycles; - info->pqinst = (VU->code&2)>>1; // rsqrt is 2 - } - else if (lregs->pipe == VUPIPE_FDIV) { - info->q |= 8|1; - info->pqinst = 0; - } - - if (lregs->VIwrite & (1 << REG_P)) { - assert( VU == &VU1 ); - info->p |= 4; - info->cycles = lregs->cycles; - - switch( VU->code & 0xff ) { - case 0xfd: info->pqinst = 0; break; //eatan - case 0x7c: info->pqinst = 0; break; //eatanxy - case 0x7d: info->pqinst = 0; break; //eatanzy - case 0xfe: info->pqinst = 1; break; //eexp - case 0xfc: info->pqinst = 2; break; //esin - case 0x3f: info->pqinst = 3; break; //erleng - case 0x3e: info->pqinst = 4; break; //eleng - case 0x3d: info->pqinst = 4; break; //ersadd - case 0xbd: info->pqinst = 4; break; //ersqrt - case 0xbe: info->pqinst = 5; break; //ercpr - case 0xbc: info->pqinst = 5; break; //esqrt - case 0x7e: info->pqinst = 5; break; //esum - case 0x3c: info->pqinst = 6; break; //esadd - default: assert(0); - } - } - else if (lregs->pipe == VUPIPE_EFU) { - info->p |= 8|1; - } - - if (lregs->VIread & (1 << REG_STATUS_FLAG)) info->statusflag|= VUOP_READ; - if (lregs->VIread & (1 << REG_MAC_FLAG)) info->macflag|= VUOP_READ; - - if (lregs->VIwrite & (1 << REG_STATUS_FLAG)) info->statusflag|= VUOP_WRITE; - if (lregs->VIwrite & (1 << REG_MAC_FLAG)) info->macflag|= VUOP_WRITE; - - if (lregs->VIread & (1 << REG_Q)) { info->q |= 2; } - if (lregs->VIread & (1 << REG_P)) { info->p |= 2; assert( VU == &VU1 ); } - - _recvuAddLowerStalls(VU, lregs); - } - - _recvuAddUpperStalls(VU, uregs); - _recvuTestPipes(VU, false); - - vucycle++; -} - -int eeVURecompileCode(VURegs *VU, _VURegsNum* regs) -{ - int info = 0; - int vfread0=-1, vfread1 = -1, vfwrite = -1, vfacc = -1, vftemp=-1; - - assert( regs != NULL ); - - if( regs->VFread0 ) _addNeededVFtoXMMreg(regs->VFread0); - if( regs->VFread1 ) _addNeededVFtoXMMreg(regs->VFread1); - if( regs->VFwrite ) _addNeededVFtoXMMreg(regs->VFwrite); - if( regs->VIread & (1<VIread & (1<VFread0 ) vfread0 = _allocVFtoXMMreg(VU, -1, regs->VFread0, MODE_READ); - else if( regs->VIread & (1<VFread1 ) vfread1 = _allocVFtoXMMreg(VU, -1, regs->VFread1, MODE_READ); - else if( (regs->VIread & (1<VFr1xyzw != 0xff) vfread1 = _allocVFtoXMMreg(VU, -1, 0, MODE_READ); - - if( regs->VIread & (1<VIwrite&(1<VIwrite & (1<VFwxyzw != 0xf?MODE_READ:0)); - } - - if( regs->VFwrite ) { - assert( !(regs->VIwrite&(1<VFwrite, MODE_WRITE|(regs->VFwxyzw != 0xf?MODE_READ:0)); - } - - if( vfacc>= 0 ) info |= PROCESS_EE_SET_ACC(vfacc); - if( vfwrite >= 0 ) { - if( regs->VFwrite == _Ft_ && vfread1 < 0 ) { - info |= PROCESS_EE_SET_T(vfwrite); - } - else { - assert( regs->VFwrite == _Fd_ ); - info |= PROCESS_EE_SET_D(vfwrite); - } - } - - if( vfread0 >= 0 ) info |= PROCESS_EE_SET_S(vfread0); - if( vfread1 >= 0 ) info |= PROCESS_EE_SET_T(vfread1); - - vftemp = _allocTempXMMreg(XMMT_FPS, -1); - info |= PROCESS_VU_SET_TEMP(vftemp); - - if( regs->VIwrite & (1 << REG_CLIP_FLAG) ) { - // CLIP inst, need two extra temp registers, put it EEREC_D and EEREC_ACC - int t1reg = _allocTempXMMreg(XMMT_FPS, -1); - int t2reg = _allocTempXMMreg(XMMT_FPS, -1); - - info |= PROCESS_EE_SET_D(t1reg); - info |= PROCESS_EE_SET_ACC(t2reg); - - _freeXMMreg(t1reg); // don't need - _freeXMMreg(t2reg); // don't need - } - else if( regs->VIwrite & (1<VI[reg].UL; - - if( read != 1 ) { - if( reg == REG_MAC_FLAG ) return (uptr)&VU->macflag; - if( reg == REG_CLIP_FLAG ) return (uptr)&VU->clipflag; - if( reg == REG_STATUS_FLAG ) return (uptr)&VU->statusflag; - if( reg == REG_Q ) return (uptr)&VU->q; - if( reg == REG_P ) return (uptr)&VU->p; - } - - return (uptr)&VU->VI[reg].UL; -} - -// gets a temp reg that is not EEREC_TEMP -int _vuGetTempXMMreg(int info) -{ - int t1reg = -1; - - if( _hasFreeXMMreg() ) { - t1reg = _allocTempXMMreg(XMMT_FPS, -1); - - if( t1reg == EEREC_TEMP ) { - if( _hasFreeXMMreg() ) { - int t = _allocTempXMMreg(XMMT_FPS, -1); - _freeXMMreg(t1reg); - t1reg = t; - } - else { - _freeXMMreg(t1reg); - t1reg = -1; - } - } - } - - return t1reg; -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// Misc VU Reg Flipping/Merging Functions -//------------------------------------------------------------------ -void _unpackVF_xyzw(int dstreg, int srcreg, int xyzw) -{ - switch (xyzw) { - case 0: SSE2_PSHUFD_XMM_to_XMM(dstreg, srcreg, 0x00); break; - case 1: SSE2_PSHUFD_XMM_to_XMM(dstreg, srcreg, 0x55); break; - case 2: SSE2_PSHUFD_XMM_to_XMM(dstreg, srcreg, 0xaa); break; - case 3: SSE2_PSHUFD_XMM_to_XMM(dstreg, srcreg, 0xff); break; - } -} - -void _unpackVFSS_xyzw(int dstreg, int srcreg, int xyzw) -{ - switch (xyzw) { - case 0: SSE_MOVSS_XMM_to_XMM(dstreg, srcreg); break; - case 1: if ( cpucaps.hasStreamingSIMD4Extensions ) SSE4_INSERTPS_XMM_to_XMM(dstreg, srcreg, _MM_MK_INSERTPS_NDX(1, 0, 0)); - else SSE2_PSHUFLW_XMM_to_XMM(dstreg, srcreg, 0xee); - break; - case 2: SSE_MOVHLPS_XMM_to_XMM(dstreg, srcreg); break; - case 3: if ( cpucaps.hasStreamingSIMD4Extensions ) SSE4_INSERTPS_XMM_to_XMM(dstreg, srcreg, _MM_MK_INSERTPS_NDX(3, 0, 0)); - else { SSE_MOVHLPS_XMM_to_XMM(dstreg, srcreg); SSE2_PSHUFLW_XMM_to_XMM(dstreg, dstreg, 0xee); } - break; - } -} - -void _vuFlipRegSS(VURegs * VU, int reg) -{ - assert( _XYZW_SS ); - if( _Y ) SSE2_PSHUFLW_XMM_to_XMM(reg, reg, 0x4e); - else if( _Z ) SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xc6); - else if( _W ) SSE_SHUFPS_XMM_to_XMM(reg, reg, 0x27); -} - -void _vuFlipRegSS_xyzw(int reg, int xyzw) -{ - switch ( xyzw ) { - case 1: SSE2_PSHUFLW_XMM_to_XMM(reg, reg, 0x4e); break; - case 2: SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xc6); break; - case 3: SSE_SHUFPS_XMM_to_XMM(reg, reg, 0x27); break; - } -} - -void _vuMoveSS(VURegs * VU, int dstreg, int srcreg) -{ - assert( _XYZW_SS ); - if( _Y ) _unpackVFSS_xyzw(dstreg, srcreg, 1); - else if( _Z ) _unpackVFSS_xyzw(dstreg, srcreg, 2); - else if( _W ) _unpackVFSS_xyzw(dstreg, srcreg, 3); - else _unpackVFSS_xyzw(dstreg, srcreg, 0); -} - -// 1 - src, 0 - dest wzyx -void VU_MERGE0(int dest, int src) { // 0000s -} -void VU_MERGE1(int dest, int src) { // 1000 - SSE_MOVHLPS_XMM_to_XMM(src, dest); - SSE_SHUFPS_XMM_to_XMM(dest, src, 0xc4); -} -void VU_MERGE1b(int dest, int src) { // 1000s - SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); -} -void VU_MERGE2(int dest, int src) { // 0100 - SSE_MOVHLPS_XMM_to_XMM(src, dest); - SSE_SHUFPS_XMM_to_XMM(dest, src, 0x64); -} -void VU_MERGE2b(int dest, int src) { // 0100s - SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); -} -void VU_MERGE3(int dest, int src) { // 1100s - SSE_SHUFPS_XMM_to_XMM(dest, src, 0xe4); -} -void VU_MERGE4(int dest, int src) { // 0010 - SSE_MOVSS_XMM_to_XMM(src, dest); - SSE2_MOVSD_XMM_to_XMM(dest, src); -} -void VU_MERGE4b(int dest, int src) { // 0010s - SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); -} -void VU_MERGE5(int dest, int src) { // 1010 - SSE_SHUFPS_XMM_to_XMM(dest, src, 0xd8); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xd8); -} -void VU_MERGE5b(int dest, int src) { // 1010s - SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); -} -void VU_MERGE6(int dest, int src) { // 0110 - SSE_SHUFPS_XMM_to_XMM(dest, src, 0x9c); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x78); -} -void VU_MERGE6b(int dest, int src) { // 0110s - SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); -} -void VU_MERGE7(int dest, int src) { // 1110 - SSE_MOVSS_XMM_to_XMM(src, dest); - SSE_MOVAPS_XMM_to_XMM(dest, src); -} -void VU_MERGE7b(int dest, int src) { // 1110s - SSE_SHUFPS_XMM_to_XMM(dest, src, 0xe4); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); -} -void VU_MERGE8(int dest, int src) { // 0001s - SSE_MOVSS_XMM_to_XMM(dest, src); -} -void VU_MERGE9(int dest, int src) { // 1001 - SSE_SHUFPS_XMM_to_XMM(dest, src, 0xc9); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xd2); -} -void VU_MERGE9b(int dest, int src) { // 1001s - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); -} -void VU_MERGE10(int dest, int src) { // 0101 - SSE_SHUFPS_XMM_to_XMM(dest, src, 0x8d); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x72); -} -void VU_MERGE10b(int dest, int src) { // 0101s - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); -} -void VU_MERGE11(int dest, int src) { // 1101s - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(dest, src, 0xe4); -} -void VU_MERGE12(int dest, int src) { // 0011 - SSE2_MOVSD_XMM_to_XMM(dest, src); -} -void VU_MERGE13(int dest, int src) { // 1011 - SSE_MOVHLPS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, dest, 0x64); - SSE_MOVAPS_XMM_to_XMM(dest, src); -} -void VU_MERGE13b(int dest, int src) { // 1011s - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); -} -void VU_MERGE14(int dest, int src) { // 0111 - SSE_MOVHLPS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, dest, 0xc4); - SSE_MOVAPS_XMM_to_XMM(dest, src); -} -void VU_MERGE14b(int dest, int src) { // 0111s - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); - SSE_MOVSS_XMM_to_XMM(dest, src); - SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); - SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); -} -void VU_MERGE15(int dest, int src) { // 1111s - SSE_MOVAPS_XMM_to_XMM(dest, src); -} - -typedef void (*VUMERGEFN)(int dest, int src); - -static VUMERGEFN s_VuMerge[16] = { - VU_MERGE0, VU_MERGE1, VU_MERGE2, VU_MERGE3, - VU_MERGE4, VU_MERGE5, VU_MERGE6, VU_MERGE7, - VU_MERGE8, VU_MERGE9, VU_MERGE10, VU_MERGE11, - VU_MERGE12, VU_MERGE13, VU_MERGE14, VU_MERGE15 }; - -static VUMERGEFN s_VuMerge2[16] = { - VU_MERGE0, VU_MERGE1b, VU_MERGE2b, VU_MERGE3, - VU_MERGE4b, VU_MERGE5b, VU_MERGE6b, VU_MERGE7b, - VU_MERGE8, VU_MERGE9b, VU_MERGE10b, VU_MERGE11, - VU_MERGE12, VU_MERGE13b, VU_MERGE14b, VU_MERGE15 }; - -// Modifies the Source Reg! -void VU_MERGE_REGS_CUSTOM(int dest, int src, int xyzw) { - xyzw &= 0xf; - if ( (dest != src) && (xyzw != 0) ) { - if ( cpucaps.hasStreamingSIMD4Extensions && (xyzw != 0x8) && (xyzw != 0xf) ) { - xyzw = ((xyzw & 1) << 3) | ((xyzw & 2) << 1) | ((xyzw & 4) >> 1) | ((xyzw & 8) >> 3); - SSE4_BLENDPS_XMM_to_XMM(dest, src, xyzw); - } - else s_VuMerge[xyzw](dest, src); - } -} -// Doesn't Modify the Source Reg! (ToDo: s_VuMerge2() has room for optimization) -void VU_MERGE_REGS_SAFE(int dest, int src, int xyzw) { - xyzw &= 0xf; - if ( (dest != src) && (xyzw != 0) ) { - if ( cpucaps.hasStreamingSIMD4Extensions && (xyzw != 0x8) && (xyzw != 0xf) ) { - xyzw = ((xyzw & 1) << 3) | ((xyzw & 2) << 1) | ((xyzw & 4) >> 1) | ((xyzw & 8) >> 3); - SSE4_BLENDPS_XMM_to_XMM(dest, src, xyzw); - } - else s_VuMerge2[xyzw](dest, src); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// Misc VU Reg Clamping/Overflow Functions -//------------------------------------------------------------------ -#define CLAMP_NORMAL_SSE4(n) \ - SSE_MOVAPS_XMM_to_XMM(regTemp, regd);\ - SSE4_PMINUD_M128_to_XMM(regd, (uptr)&g_minvals_XYZW[n][0]);\ - SSE2_PSUBD_XMM_to_XMM(regTemp, regd);\ - SSE2_PCMPGTD_M128_to_XMM(regTemp, (uptr)&g_ones[0]);\ - SSE4_PMINSD_M128_to_XMM(regd, (uptr)&g_maxvals_XYZW[n][0]);\ - SSE2_PSLLD_I8_to_XMM(regTemp, 31);\ - SSE_XORPS_XMM_to_XMM(regd, regTemp); - -#define CLAMP_SIGN_SSE4(n) \ - SSE4_PMINSD_M128_to_XMM(regd, (uptr)&g_maxvals_XYZW[n][0]);\ - SSE4_PMINUD_M128_to_XMM(regd, (uptr)&g_minvals_XYZW[n][0]); - -void vFloat0(int regd, int regTemp) { } //0000 -void vFloat1(int regd, int regTemp) { //1000 - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); -} -void vFloat1c(int regd, int regTemp) { //1000 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(1); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat2(int regd, int regTemp) { //0100 - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); -} -void vFloat2c(int regd, int regTemp) { //0100 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(2); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat3(int regd, int regTemp) { //1100 - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x36); -} -void vFloat3b(int regd, int regTemp) { //1100 //regTemp is Modified - SSE2_MOVSD_XMM_to_XMM(regTemp, regd); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - SSE2_MOVSD_XMM_to_XMM(regd, regTemp); -} -void vFloat3c(int regd, int regTemp) { //1100 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(3); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x36); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat4(int regd, int regTemp) { //0010 - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); -} -void vFloat4c(int regd, int regTemp) { //0010 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(4); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat5(int regd, int regTemp) { //1010 - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x2d); -} -void vFloat5b(int regd, int regTemp) { //1010 //regTemp is Modified - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_NORMAL_SSE4(5); - } - else { - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x2d); - } -} -void vFloat5c(int regd, int regTemp) { //1010 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(5); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x2d); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat6(int regd, int regTemp) { //0110 - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc9); -} -void vFloat6b(int regd, int regTemp) { //0110 //regTemp is Modified - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_NORMAL_SSE4(6); - } - else { - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc9); - } -} -void vFloat6c(int regd, int regTemp) { //0110 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(6); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc9); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat7(int regd, int regTemp) { //1110 - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x39); -} -void vFloat7_useEAX(int regd, int regTemp) { //1110 //EAX is Modified - SSE2_MOVD_XMM_to_R(EAX, regd); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - if ( cpucaps.hasStreamingSIMD4Extensions ) - SSE4_PINSRD_R32_to_XMM(regd, EAX, 0x00); - else { - SSE_PINSRW_R32_to_XMM(regd, EAX, 0); - SHR32ItoR(EAX, 16); - SSE_PINSRW_R32_to_XMM(regd, EAX, 1); - } -} -void vFloat7b(int regd, int regTemp) { //1110 //regTemp is Modified - SSE_MOVSS_XMM_to_XMM(regTemp, regd); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - SSE_MOVSS_XMM_to_XMM(regd, regTemp); -} -void vFloat7c(int regd, int regTemp) { //1110 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(7); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x39); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat7c_useEAX(int regd, int regTemp) { //1110 //EAX is Modified - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(7); - } - else { - SSE2_MOVD_XMM_to_R(EAX, regd); - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - SSE2_MOVD_R_to_XMM(regTemp, EAX); - SSE_MOVSS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat8(int regd, int regTemp) { //0001 - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); -} -void vFloat8c(int regd, int regTemp) { //0001 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(8); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat9(int regd, int regTemp) { //1001 - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); -} -void vFloat9b(int regd, int regTemp) { //1001 //regTemp is Modified - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_NORMAL_SSE4(9); - } - else { - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - } -} -void vFloat9c(int regd, int regTemp) { //1001 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(9); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat10(int regd, int regTemp) { //0101 - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); -} -void vFloat10b(int regd, int regTemp) { //0101 //regTemp is Modified - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_NORMAL_SSE4(10); - } - else { - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - } -} -void vFloat10c(int regd, int regTemp) { //0101 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(10); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat11(int regd, int regTemp) { //1101 - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x36); -} -void vFloat11_useEAX(int regd, int regTemp) { //1101 //EAX is Modified - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE2_MOVD_XMM_to_R(EAX, regd); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - if ( cpucaps.hasStreamingSIMD4Extensions ) - SSE4_PINSRD_R32_to_XMM(regd, EAX, 0x00); - else { - SSE_PINSRW_R32_to_XMM(regd, EAX, 0); - SHR32ItoR(EAX, 16); - SSE_PINSRW_R32_to_XMM(regd, EAX, 1); - } - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); -} -void vFloat11b(int regd, int regTemp) { //1101 //regTemp is Modified - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - SSE_MOVSS_XMM_to_XMM(regTemp, regd); - SSE2_MOVSD_XMM_to_XMM(regd, regTemp); -} -void vFloat11c(int regd, int regTemp) { //1101 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(11); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x36); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat11c_useEAX(int regd, int regTemp) { //1101 // EAX is modified - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(11); - } - else { - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE2_MOVD_XMM_to_R(EAX, regd); - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - SSE2_MOVD_R_to_XMM(regTemp, EAX); - SSE_MOVSS_XMM_to_XMM(regd, regTemp); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - } -} -void vFloat12(int regd, int regTemp) { //0011 - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); -} -void vFloat12b(int regd, int regTemp) { //0011 //regTemp is Modified - SSE_MOVHLPS_XMM_to_XMM(regTemp, regd); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - SSE2_PUNPCKLQDQ_XMM_to_XMM(regd, regTemp); -} -void vFloat12c(int regd, int regTemp) { //0011 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(12); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat13(int regd, int regTemp) { //1011 - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x2d); -} -void vFloat13_useEAX(int regd, int regTemp) { //1011 // EAX is modified - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE2_MOVD_XMM_to_R(EAX, regd); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - if ( cpucaps.hasStreamingSIMD4Extensions ) - SSE4_PINSRD_R32_to_XMM(regd, EAX, 0x00); - else { - SSE_PINSRW_R32_to_XMM(regd, EAX, 0); - SHR32ItoR(EAX, 16); - SSE_PINSRW_R32_to_XMM(regd, EAX, 1); - } - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); -} -void vFloat13b(int regd, int regTemp) { //1011 //regTemp is Modified - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - SSE_MOVHLPS_XMM_to_XMM(regTemp, regd); - SSE_SHUFPS_XMM_to_XMM(regd, regTemp, 0x64); -} -void vFloat13c(int regd, int regTemp) { //1011 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(13); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x2d); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat13c_useEAX(int regd, int regTemp) { //1011 // EAX is modified - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(13); - } - else { - SSE2_PSHUFD_XMM_to_XMM(regd, regd, 0xc6); - SSE2_MOVD_XMM_to_R(EAX, regd); - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - SSE2_MOVD_R_to_XMM(regTemp, EAX); - SSE_MOVSS_XMM_to_XMM(regd, regTemp); - SSE2_PSHUFD_XMM_to_XMM(regd, regd, 0xc6); - } -} -void vFloat14(int regd, int regTemp) { //0111 - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc9); -} -void vFloat14_useEAX(int regd, int regTemp) { //0111 // EAX is modified - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); - SSE2_MOVD_XMM_to_R(EAX, regd); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - if ( cpucaps.hasStreamingSIMD4Extensions ) - SSE4_PINSRD_R32_to_XMM(regd, EAX, 0x00); - else { - SSE_PINSRW_R32_to_XMM(regd, EAX, 0); - SHR32ItoR(EAX, 16); - SSE_PINSRW_R32_to_XMM(regd, EAX, 1); - } - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); -} -void vFloat14b(int regd, int regTemp) { //0111 //regTemp is Modified - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - SSE_MOVHLPS_XMM_to_XMM(regTemp, regd); - SSE_SHUFPS_XMM_to_XMM(regd, regTemp, 0xc4); -} -void vFloat14c(int regd, int regTemp) { //0111 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(14); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); - SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc9); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} -void vFloat14c_useEAX(int regd, int regTemp) { //0111 // EAX is modified - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(14); - } - else { - SSE2_PSHUFD_XMM_to_XMM(regd, regd, 0x27); - SSE2_MOVD_XMM_to_R(EAX, regd); - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - SSE2_MOVD_R_to_XMM(regTemp, EAX); - SSE_MOVSS_XMM_to_XMM(regd, regTemp); - SSE2_PSHUFD_XMM_to_XMM(regd, regd, 0x27); - } -} -void vFloat15(int regd, int regTemp) { //1111 - SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); - SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); -} -void vFloat15c(int regd, int regTemp) { //1111 - if ( cpucaps.hasStreamingSIMD4Extensions ) { - CLAMP_SIGN_SSE4(15); - } - else { - SSE_MOVAPS_XMM_to_XMM(regTemp, regd); - SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); - SSE_MINPS_M128_to_XMM(regd, (uptr)&g_maxvals[0]); - SSE_MAXPS_M128_to_XMM(regd, (uptr)&g_minvals[0]); - SSE_ORPS_XMM_to_XMM(regd, regTemp); - } -} - -vFloat vFloats1[16] = { //regTemp is not modified - vFloat0, vFloat1, vFloat2, vFloat3, - vFloat4, vFloat5, vFloat6, vFloat7, - vFloat8, vFloat9, vFloat10, vFloat11, - vFloat12, vFloat13, vFloat14, vFloat15 }; - -vFloat vFloats1_useEAX[16] = { //regTemp is not modified but EAX is used - vFloat0, vFloat1, vFloat2, vFloat3, - vFloat4, vFloat5, vFloat6, vFloat7_useEAX, - vFloat8, vFloat9, vFloat10, vFloat11_useEAX, - vFloat12, vFloat13_useEAX, vFloat14_useEAX, vFloat15 }; - -vFloat vFloats2[16] = { //regTemp is modified - vFloat0, vFloat1, vFloat2, vFloat3b, - vFloat4, vFloat5b, vFloat6b, vFloat7b, - vFloat8, vFloat9b, vFloat10b, vFloat11b, - vFloat12b, vFloat13b, vFloat14b, vFloat15 }; - -vFloat vFloats4[16] = { //regTemp is modified - vFloat0, vFloat1c, vFloat2c, vFloat3c, - vFloat4c, vFloat5c, vFloat6c, vFloat7c, - vFloat8c, vFloat9c, vFloat10c, vFloat11c, - vFloat12c, vFloat13c, vFloat14c, vFloat15c }; - -vFloat vFloats4_useEAX[16] = { //regTemp is modified and EAX is used - vFloat0, vFloat1c, vFloat2c, vFloat3c, - vFloat4c, vFloat5c, vFloat6c, vFloat7c_useEAX, - vFloat8c, vFloat9c, vFloat10c, vFloat11c_useEAX, - vFloat12c, vFloat13c_useEAX, vFloat14c_useEAX, vFloat15c }; - -//------------------------------------------------------------------ -// Clamping Functions (wrapper for vFloat* functions) -// vuFloat : "normal" clamping -// vuFloat_useEAX : "normal" clamping (faster but EAX is modified) -// vuFloat2 : "normal" clamping (fastest but regTemp is modified) -// vuFloat3 : "preserve sign" clamping for pointer -// vuFloat4 : "preserve sign" clamping (regTemp is modified; *FASTEST* on SSE4 CPUs) -// vuFloat4_useEAX : "preserve sign" clamping (faster but regTemp and EAX are modified) -// vuFloat5 : wrapper function for vuFloat2 and vuFloat4 -// vuFloat5_useEAX : wrapper function for vuFloat2 and vuFloat4_useEAX -// vuFloatExtra : for debugging -// -// Notice 1: vuFloat*_useEAX may be slower on AMD CPUs, which have independent execution pipeline for -// vector and scalar instructions (need checks) -// Notice 2: recVUMI_MUL_xyzw_toD and recVUMI_MADD_xyzw_toD use vFloats directly! -//------------------------------------------------------------------ - -// Clamps +/-NaN to +fMax and +/-Inf to +/-fMax (doesn't use any temp regs) -void vuFloat( int info, int regd, int XYZW) { - if( CHECK_VU_OVERFLOW ) { - /*if ( (XYZW != 0) && (XYZW != 8) && (XYZW != 0xF) ) { - int t1reg = _vuGetTempXMMreg(info); - if (t1reg >= 0) { - vuFloat2( regd, t1reg, XYZW ); - _freeXMMreg( t1reg ); - return; - } - }*/ - //vuFloatExtra(regd, XYZW); - vFloats1[XYZW](regd, regd); - } -} - -// Clamps +/-NaN to +fMax and +/-Inf to +/-fMax (uses EAX as a temp register; faster but **destroys EAX**) -void vuFloat_useEAX( int info, int regd, int XYZW) { - if( CHECK_VU_OVERFLOW ) { - vFloats1_useEAX[XYZW](regd, regd); - } -} - -// Clamps +/-NaN to +fMax and +/-Inf to +/-fMax (uses a temp reg) -void vuFloat2(int regd, int regTemp, int XYZW) { - if( CHECK_VU_OVERFLOW ) { - //vuFloatExtra(regd, XYZW); - vFloats2[XYZW](regd, regTemp); - } -} - -// Clamps +/-NaN and +/-Inf to +/-fMax (uses a temp reg) -void vuFloat4(int regd, int regTemp, int XYZW) { - if( CHECK_VU_OVERFLOW ) { - vFloats4[XYZW](regd, regTemp); - } -} - -// Clamps +/-NaN and +/-Inf to +/-fMax (uses a temp reg, and uses EAX as a temp register; faster but **destroys EAX**) -void vuFloat4_useEAX(int regd, int regTemp, int XYZW) { - if( CHECK_VU_OVERFLOW ) { - vFloats4_useEAX[XYZW](regd, regTemp); - } -} - -// Uses vuFloat4 or vuFloat2 depending on the CHECK_VU_SIGN_OVERFLOW setting -void vuFloat5(int regd, int regTemp, int XYZW) { - if (CHECK_VU_SIGN_OVERFLOW) { - vuFloat4(regd, regTemp, XYZW); - } - else vuFloat2(regd, regTemp, XYZW); -} - -// Uses vuFloat4_useEAX or vuFloat2 depending on the CHECK_VU_SIGN_OVERFLOW setting (uses EAX as a temp register; faster but **destoroyes EAX**) -void vuFloat5_useEAX(int regd, int regTemp, int XYZW) { - if (CHECK_VU_SIGN_OVERFLOW) { - vuFloat4_useEAX(regd, regTemp, XYZW); - } - else vuFloat2(regd, regTemp, XYZW); -} - -// Clamps +/-infs to +/-fMax, and +/-NaNs to +/-fMax -void vuFloat3(uptr x86ptr) { - u8* pjmp; - - if( CHECK_VU_OVERFLOW ) { - CMP32ItoM(x86ptr, 0x7f800000 ); - pjmp = JL8(0); // Signed Comparison - MOV32ItoM(x86ptr, 0x7f7fffff ); - x86SetJ8(pjmp); - - CMP32ItoM(x86ptr, 0xff800000 ); - pjmp = JB8(0); // Unsigned Comparison - MOV32ItoM(x86ptr, 0xff7fffff ); - x86SetJ8(pjmp); - } -} - -PCSX2_ALIGNED16(u64 vuFloatData[2]); -PCSX2_ALIGNED16(u64 vuFloatData2[2]); -// Makes NaN == 0, Infinities stay the same; Very Slow - Use only for debugging -void vuFloatExtra( int regd, int XYZW) { - int t1reg = (regd == 0) ? (regd + 1) : (regd - 1); - int t2reg = (regd <= 1) ? (regd + 2) : (regd - 2); - SSE_MOVAPS_XMM_to_M128( (uptr)vuFloatData, t1reg ); - SSE_MOVAPS_XMM_to_M128( (uptr)vuFloatData2, t2reg ); - - SSE_XORPS_XMM_to_XMM(t1reg, t1reg); - SSE_CMPORDPS_XMM_to_XMM(t1reg, regd); - SSE_MOVAPS_XMM_to_XMM(t2reg, regd); - SSE_ANDPS_XMM_to_XMM(t2reg, t1reg); - VU_MERGE_REGS_CUSTOM(regd, t2reg, XYZW); - - SSE_MOVAPS_M128_to_XMM( t1reg, (uptr)vuFloatData ); - SSE_MOVAPS_M128_to_XMM( t2reg, (uptr)vuFloatData2 ); -} - -static PCSX2_ALIGNED16(u32 tempRegX[]) = {0x00000000, 0x00000000, 0x00000000, 0x00000000}; - -// Called by testWhenOverflow() function -void testPrintOverflow() { - tempRegX[0] &= 0xff800000; - tempRegX[1] &= 0xff800000; - tempRegX[2] &= 0xff800000; - tempRegX[3] &= 0xff800000; - if ( (tempRegX[0] == 0x7f800000) || (tempRegX[1] == 0x7f800000) || (tempRegX[2] == 0x7f800000) || (tempRegX[3] == 0x7f800000) ) - Console::Notice( "VU OVERFLOW!: Changing to +Fmax!!!!!!!!!!!!" ); - if ( (tempRegX[0] == 0xff800000) || (tempRegX[1] == 0xff800000) || (tempRegX[2] == 0xff800000) || (tempRegX[3] == 0xff800000) ) - Console::Notice( "VU OVERFLOW!: Changing to -Fmax!!!!!!!!!!!!" ); -} - -// Outputs to the console when overflow has occured. -void testWhenOverflow(int info, int regd, int t0reg) { - SSE_MOVAPS_XMM_to_M128((uptr)tempRegX, regd); - CALLFunc((uptr)testPrintOverflow); -} +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "PrecompiledHeader.h" + +#include "Common.h" +#include "GS.h" +#include "R5900OpcodeTables.h" +#include "iR5900.h" +#include "iMMI.h" +#include "iFPU.h" +#include "iCOP0.h" +#include "VUmicro.h" +#include "VUflags.h" +#include "sVU_Micro.h" +#include "sVU_Debug.h" +#include "sVU_zerorec.h" + +#ifdef _WIN32 +#pragma warning(disable:4244) +#pragma warning(disable:4761) +#endif +//------------------------------------------------------------------ + +// fixme - VUmicro should really use its own static vars for pc and branch. +// Sharing with the EE's copies of pc and branch is not cool! (air) + +//------------------------------------------------------------------ +// Helper Macros +//------------------------------------------------------------------ +#define _Ft_ (( VU->code >> 16) & 0x1F) // The rt part of the instruction register +#define _Fs_ (( VU->code >> 11) & 0x1F) // The rd part of the instruction register +#define _Fd_ (( VU->code >> 6) & 0x1F) // The sa part of the instruction register +#define _It_ (_Ft_ & 15) +#define _Is_ (_Fs_ & 15) +#define _Id_ (_Fd_ & 15) + +#define _X (( VU->code>>24) & 0x1) +#define _Y (( VU->code>>23) & 0x1) +#define _Z (( VU->code>>22) & 0x1) +#define _W (( VU->code>>21) & 0x1) + +#define _XYZW_SS (_X+_Y+_Z+_W==1) + +#define _Fsf_ (( VU->code >> 21) & 0x03) +#define _Ftf_ (( VU->code >> 23) & 0x03) + +#define _Imm11_ (s32)(VU->code & 0x400 ? 0xfffffc00 | (VU->code & 0x3ff) : VU->code & 0x3ff) +#define _UImm11_ (s32)(VU->code & 0x7ff) + +#define VU_VFx_ADDR(x) (uptr)&VU->VF[x].UL[0] +#define VU_VFy_ADDR(x) (uptr)&VU->VF[x].UL[1] +#define VU_VFz_ADDR(x) (uptr)&VU->VF[x].UL[2] +#define VU_VFw_ADDR(x) (uptr)&VU->VF[x].UL[3] + +#define VU_REGR_ADDR (uptr)&VU->VI[REG_R] +#define VU_REGQ_ADDR (uptr)&VU->VI[REG_Q] +#define VU_REGMAC_ADDR (uptr)&VU->VI[REG_MAC_FLAG] + +#define VU_VI_ADDR(x, read) GetVIAddr(VU, x, read, info) + +#define VU_ACCx_ADDR (uptr)&VU->ACC.UL[0] +#define VU_ACCy_ADDR (uptr)&VU->ACC.UL[1] +#define VU_ACCz_ADDR (uptr)&VU->ACC.UL[2] +#define VU_ACCw_ADDR (uptr)&VU->ACC.UL[3] + +#define _X_Y_Z_W ((( VU->code >> 21 ) & 0xF ) ) +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// Global Variables +//------------------------------------------------------------------ +int vucycle; + +PCSX2_ALIGNED16(const float s_fones[8]) = {1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f}; +PCSX2_ALIGNED16(const u32 s_mask[4]) = {0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff}; +PCSX2_ALIGNED16(const u32 s_expmask[4]) = {0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000}; +PCSX2_ALIGNED16(const u32 g_minvals[4]) = {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}; +PCSX2_ALIGNED16(const u32 g_maxvals[4]) = {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}; +PCSX2_ALIGNED16(const u32 const_clip[8]) = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, + 0x80000000, 0x80000000, 0x80000000, 0x80000000}; +PCSX2_ALIGNED(64, const u32 g_ones[4]) = {0x00000001, 0x00000001, 0x00000001, 0x00000001}; +PCSX2_ALIGNED16(const u32 g_minvals_XYZW[16][4]) = +{ + { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }, //0000 + { 0xffffffff, 0xffffffff, 0xffffffff, 0xff7fffff }, //0001 + { 0xffffffff, 0xffffffff, 0xff7fffff, 0xffffffff }, //0010 + { 0xffffffff, 0xffffffff, 0xff7fffff, 0xff7fffff }, //0011 + { 0xffffffff, 0xff7fffff, 0xffffffff, 0xffffffff }, //0100 + { 0xffffffff, 0xff7fffff, 0xffffffff, 0xff7fffff }, //0101 + { 0xffffffff, 0xff7fffff, 0xff7fffff, 0xffffffff }, //0110 + { 0xffffffff, 0xff7fffff, 0xff7fffff, 0xff7fffff }, //0111 + { 0xff7fffff, 0xffffffff, 0xffffffff, 0xffffffff }, //1000 + { 0xff7fffff, 0xffffffff, 0xffffffff, 0xff7fffff }, //1001 + { 0xff7fffff, 0xffffffff, 0xff7fffff, 0xffffffff }, //1010 + { 0xff7fffff, 0xffffffff, 0xff7fffff, 0xff7fffff }, //1011 + { 0xff7fffff, 0xff7fffff, 0xffffffff, 0xffffffff }, //1100 + { 0xff7fffff, 0xff7fffff, 0xffffffff, 0xff7fffff }, //1101 + { 0xff7fffff, 0xff7fffff, 0xff7fffff, 0xffffffff }, //1110 + { 0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff }, //1111 +}; +PCSX2_ALIGNED16(const u32 g_maxvals_XYZW[16][4])= +{ + { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff }, //0000 + { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7f7fffff }, //0001 + { 0x7fffffff, 0x7fffffff, 0x7f7fffff, 0x7fffffff }, //0010 + { 0x7fffffff, 0x7fffffff, 0x7f7fffff, 0x7f7fffff }, //0011 + { 0x7fffffff, 0x7f7fffff, 0x7fffffff, 0x7fffffff }, //0100 + { 0x7fffffff, 0x7f7fffff, 0x7fffffff, 0x7f7fffff }, //0101 + { 0x7fffffff, 0x7f7fffff, 0x7f7fffff, 0x7fffffff }, //0110 + { 0x7fffffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff }, //0111 + { 0x7f7fffff, 0x7fffffff, 0x7fffffff, 0x7fffffff }, //1000 + { 0x7f7fffff, 0x7fffffff, 0x7fffffff, 0x7f7fffff }, //1001 + { 0x7f7fffff, 0x7fffffff, 0x7f7fffff, 0x7fffffff }, //1010 + { 0x7f7fffff, 0x7fffffff, 0x7f7fffff, 0x7f7fffff }, //1011 + { 0x7f7fffff, 0x7f7fffff, 0x7fffffff, 0x7fffffff }, //1100 + { 0x7f7fffff, 0x7f7fffff, 0x7fffffff, 0x7f7fffff }, //1101 + { 0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7fffffff }, //1110 + { 0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff }, //1111 +}; +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +// VU Pipeline/Test Stalls/Analyzing Functions +//------------------------------------------------------------------ +void _recvuFMACflush(VURegs * VU, bool intermediate) { + int i; + + for (i=0; i<8; i++) { + if (VU->fmac[i].enable == 0) continue; + + if( intermediate ) { + if ((vucycle - VU->fmac[i].sCycle) > VU->fmac[i].Cycle) { +// VUM_LOG("flushing FMAC pipe[%d]", i); + VU->fmac[i].enable = 0; + } + } + else { + if ((vucycle - VU->fmac[i].sCycle) >= VU->fmac[i].Cycle) { +// VUM_LOG("flushing FMAC pipe[%d]", i); + VU->fmac[i].enable = 0; + } + } + } +} + +void _recvuFDIVflush(VURegs * VU, bool intermediate) { + if (VU->fdiv.enable == 0) return; + + if( intermediate ) { + if ((vucycle - VU->fdiv.sCycle) > VU->fdiv.Cycle) { +// Console::WriteLn("flushing FDIV pipe"); + VU->fdiv.enable = 0; + } + } + else { + if ((vucycle - VU->fdiv.sCycle) >= VU->fdiv.Cycle) { +// Console::WriteLn("flushing FDIV pipe"); + VU->fdiv.enable = 0; + } + } +} + +void _recvuEFUflush(VURegs * VU, bool intermediate) { + if (VU->efu.enable == 0) return; + + if( intermediate ) { + if ((vucycle - VU->efu.sCycle) > VU->efu.Cycle) { +// Console::WriteLn("flushing FDIV pipe"); + VU->efu.enable = 0; + } + } + else { + if ((vucycle - VU->efu.sCycle) >= VU->efu.Cycle) { +// Console::WriteLn("flushing FDIV pipe"); + VU->efu.enable = 0; + } + } +} + +void _recvuIALUflush(VURegs * VU, bool intermediate) { + int i; + + for (i=0; i<8; i++) { + if (VU->ialu[i].enable == 0) continue; + + if( intermediate ) { + if ((vucycle - VU->ialu[i].sCycle) > VU->ialu[i].Cycle) { +// VUM_LOG("flushing IALU pipe[%d]", i); + VU->ialu[i].enable = 0; + } + } + else { + if ((vucycle - VU->ialu[i].sCycle) >= VU->ialu[i].Cycle) { +// VUM_LOG("flushing IALU pipe[%d]", i); + VU->ialu[i].enable = 0; + } + } + } +} + +void _recvuTestPipes(VURegs * VU, bool intermediate) { // intermediate = true if called by upper FMAC stall detection + _recvuFMACflush(VU, intermediate); + _recvuFDIVflush(VU, intermediate); + _recvuEFUflush(VU, intermediate); + _recvuIALUflush(VU, intermediate); +} + +void _recvuFMACTestStall(VURegs * VU, int reg, int xyzw) { + int cycle; + int i; + u32 mask = 0; + + for (i=0; i<8; i++) { + if (VU->fmac[i].enable == 0) continue; + if (VU->fmac[i].reg == reg && (VU->fmac[i].xyzw & xyzw)) break; + } + + if (i == 8) return; + + // do a perchannel delay + // old code +// cycle = VU->fmac[i].Cycle - (vucycle - VU->fmac[i].sCycle); + + // new code + mask = 4; // w +// if( VU->fmac[i].xyzw & 1 ) mask = 4; // w +// else if( VU->fmac[i].xyzw & 2 ) mask = 3; // z +// else if( VU->fmac[i].xyzw & 4 ) mask = 2; // y +// else { +// assert(VU->fmac[i].xyzw & 8 ); +// mask = 1; // x +// } + +// mask = 0; +// if( VU->fmac[i].xyzw & 1 ) mask++; // w +// else if( VU->fmac[i].xyzw & 2 ) mask++; // z +// else if( VU->fmac[i].xyzw & 4 ) mask++; // y +// else if( VU->fmac[i].xyzw & 8 ) mask++; // x + + assert( (int)VU->fmac[i].sCycle < (int)vucycle ); + cycle = 0; + if( vucycle - VU->fmac[i].sCycle < mask ) + cycle = mask - (vucycle - VU->fmac[i].sCycle); + + VU->fmac[i].enable = 0; + vucycle+= cycle; + _recvuTestPipes(VU, true); // for lower instructions +} + +void _recvuIALUTestStall(VURegs * VU, int reg) { + int cycle; + int i; + u32 latency; + + for (i=0; i<8; i++) { + if (VU->ialu[i].enable == 0) continue; + if (VU->ialu[i].reg == reg) break; + } + + if (i == 8) return; + + latency = VU->ialu[i].Cycle + 1; + cycle = 0; + if( vucycle - VU->ialu[i].sCycle < latency ) + cycle = latency - (vucycle - VU->ialu[i].sCycle); + + VU->ialu[i].enable = 0; + vucycle+= cycle; + _recvuTestPipes(VU, true); +} + +void _recvuFMACAdd(VURegs * VU, int reg, int xyzw) { + int i; + + /* find a free fmac pipe */ + for (i=0; i<8; i++) { + if (VU->fmac[i].enable == 1) continue; + break; + } + + if (i==8) Console::Error("*PCSX2*: error , out of fmacs"); +// VUM_LOG("adding FMAC pipe[%d]; reg %d", i, reg); + + VU->fmac[i].enable = 1; + VU->fmac[i].sCycle = vucycle; + VU->fmac[i].Cycle = 3; + VU->fmac[i].xyzw = xyzw; + VU->fmac[i].reg = reg; +} + +void _recvuFDIVAdd(VURegs * VU, int cycles) { +// Console::WriteLn("adding FDIV pipe"); + VU->fdiv.enable = 1; + VU->fdiv.sCycle = vucycle; + VU->fdiv.Cycle = cycles; +} + +void _recvuEFUAdd(VURegs * VU, int cycles) { +// Console::WriteLn("adding EFU pipe"); + VU->efu.enable = 1; + VU->efu.sCycle = vucycle; + VU->efu.Cycle = cycles; +} + +void _recvuIALUAdd(VURegs * VU, int reg, int cycles) { + int i; + + /* find a free ialu pipe */ + for (i=0; i<8; i++) { + if (VU->ialu[i].enable == 1) continue; + break; + } + + if (i==8) Console::Error("*PCSX2*: error , out of ialus"); + + VU->ialu[i].enable = 1; + VU->ialu[i].sCycle = vucycle; + VU->ialu[i].Cycle = cycles; + VU->ialu[i].reg = reg; +} + +void _recvuTestIALUStalls(VURegs * VU, _VURegsNum *VUregsn) { + + int VIread0 = 0, VIread1 = 0; // max 2 integer registers are read simulataneously + int i; + + for(i=0;i<16;i++) { // find used integer(vi00-vi15) registers + if( (VUregsn->VIread >> i) & 1 ) { + if( VIread0 ) VIread1 = i; + else VIread0 = i; + } + } + + if( VIread0 ) _recvuIALUTestStall(VU, VIread0); + if( VIread1 ) _recvuIALUTestStall(VU, VIread1); +} + +void _recvuAddIALUStalls(VURegs * VU, _VURegsNum *VUregsn) { + if (VUregsn->VIwrite && VUregsn->cycles) { + int VIWrite0 = 0; + int i; + + for(i=0;i<16;i++) { // find used(vi00-vi15) registers + if( (VUregsn->VIwrite >> i) & 1 ) { + VIWrite0 = i; + } + } + if( VIWrite0 ) _recvuIALUAdd(VU, VIWrite0, VUregsn->cycles); + } +} + +void _recvuTestFMACStalls(VURegs * VU, _VURegsNum *VUregsn, bool upper) { + + if( VUregsn->VFread0 && (VUregsn->VFread0 == VUregsn->VFread1) ) { + _recvuFMACTestStall(VU, VUregsn->VFread0, VUregsn->VFr0xyzw|VUregsn->VFr1xyzw); + } + else { + if (VUregsn->VFread0) _recvuFMACTestStall(VU, VUregsn->VFread0, VUregsn->VFr0xyzw); + if (VUregsn->VFread1) _recvuFMACTestStall(VU, VUregsn->VFread1, VUregsn->VFr1xyzw); + } + + if( !upper && VUregsn->VIread ) _recvuTestIALUStalls(VU, VUregsn); // for lower instructions which read integer reg +} + +void _recvuAddFMACStalls(VURegs * VU, _VURegsNum *VUregsn) { + + if (VUregsn->VFwrite) _recvuFMACAdd(VU, VUregsn->VFwrite, VUregsn->VFwxyzw); + else if (VUregsn->VIwrite & (1 << REG_CLIP_FLAG)) _recvuFMACAdd(VU, -REG_CLIP_FLAG, 0); // REG_CLIP_FLAG pipe + else _recvuFMACAdd(VU, 0, 0); // cause no data dependency with fp registers +} + +void _recvuFlushFDIV(VURegs * VU) { + int cycle; + + if (VU->fdiv.enable == 0) return; + + cycle = VU->fdiv.Cycle + 1 - (vucycle - VU->fdiv.sCycle); //VU->fdiv.Cycle contains the latency minus 1 (6 or 12) +// Console::WriteLn("waiting FDIV pipe %d", params cycle); + VU->fdiv.enable = 0; + vucycle+= cycle; +} + +void _recvuFlushEFU(VURegs * VU) { + int cycle; + + if (VU->efu.enable == 0) return; + + cycle = VU->efu.Cycle - (vucycle - VU->efu.sCycle); +// Console::WriteLn("waiting FDIV pipe %d", params cycle); + VU->efu.enable = 0; + vucycle+= cycle; +} + +void _recvuTestFDIVStalls(VURegs * VU, _VURegsNum *VUregsn) { + _recvuTestFMACStalls(VU,VUregsn, false); + _recvuFlushFDIV(VU); +} + +void _recvuTestEFUStalls(VURegs * VU, _VURegsNum *VUregsn) { + _recvuTestFMACStalls(VU,VUregsn, false); + _recvuFlushEFU(VU); +} + +void _recvuAddFDIVStalls(VURegs * VU, _VURegsNum *VUregsn) { +// _vuTestFMACStalls(VURegs * VU, _VURegsNum *VUregsn); + if (VUregsn->VIwrite & (1 << REG_Q)) { + _recvuFDIVAdd(VU, VUregsn->cycles); + } +} + +void _recvuAddEFUStalls(VURegs * VU, _VURegsNum *VUregsn) { +// _vuTestFMACStalls(VURegs * VU, _VURegsNum *VUregsn); + if (VUregsn->VIwrite & (1 << REG_P)) { + _recvuEFUAdd(VU, VUregsn->cycles); + } +} + +void _recvuTestUpperStalls(VURegs * VU, _VURegsNum *VUregsn) { + switch (VUregsn->pipe) { + case VUPIPE_FMAC: _recvuTestFMACStalls(VU, VUregsn, true); break; + } +} + +void _recvuTestLowerStalls(VURegs * VU, _VURegsNum *VUregsn) { + switch (VUregsn->pipe) { + case VUPIPE_FMAC: _recvuTestFMACStalls(VU, VUregsn, false); break; + case VUPIPE_FDIV: _recvuTestFDIVStalls(VU, VUregsn); break; + case VUPIPE_EFU: _recvuTestEFUStalls(VU, VUregsn); break; + case VUPIPE_IALU: _recvuTestIALUStalls(VU, VUregsn); break; + case VUPIPE_BRANCH: _recvuTestIALUStalls(VU, VUregsn); break; + } +} + +void _recvuAddUpperStalls(VURegs * VU, _VURegsNum *VUregsn) { + switch (VUregsn->pipe) { + case VUPIPE_FMAC: _recvuAddFMACStalls(VU, VUregsn); break; + } +} + +void _recvuAddLowerStalls(VURegs * VU, _VURegsNum *VUregsn) { + switch (VUregsn->pipe) { + case VUPIPE_FMAC: _recvuAddFMACStalls(VU, VUregsn); break; + case VUPIPE_FDIV: _recvuAddFDIVStalls(VU, VUregsn); break; + case VUPIPE_EFU: _recvuAddEFUStalls(VU, VUregsn); break; + case VUPIPE_IALU: _recvuAddIALUStalls(VU, VUregsn); break; // note: only ILW and ILWR cause stall in IALU pipe + } +} + +void SuperVUAnalyzeOp(VURegs *VU, _vuopinfo *info, _VURegsNum* pCodeRegs) +{ + _VURegsNum* lregs; + _VURegsNum* uregs; + int *ptr; + + lregs = pCodeRegs; + uregs = pCodeRegs+1; + + ptr = (int*)&VU->Micro[pc]; + pc += 8; + + if (ptr[1] & 0x40000000) { // EOP + branch |= 8; + } + + VU->code = ptr[1]; + if (VU == &VU1) VU1regs_UPPER_OPCODE[VU->code & 0x3f](uregs); + else VU0regs_UPPER_OPCODE[VU->code & 0x3f](uregs); + + _recvuTestUpperStalls(VU, uregs); + switch(VU->code & 0x3f) { + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x14: case 0x15: case 0x16: case 0x17: + case 0x1d: case 0x1f: + case 0x2b: case 0x2f: + break; + + case 0x3c: + switch ((VU->code >> 6) & 0x1f) { + case 0x4: case 0x5: + break; + default: + info->statusflag = 4; + info->macflag = 4; + break; + } + break; + case 0x3d: + switch ((VU->code >> 6) & 0x1f) { + case 0x4: case 0x5: case 0x7: + break; + default: + info->statusflag = 4; + info->macflag = 4; + break; + } + break; + case 0x3e: + switch ((VU->code >> 6) & 0x1f) { + case 0x4: case 0x5: + break; + default: + info->statusflag = 4; + info->macflag = 4; + break; + } + break; + case 0x3f: + switch ((VU->code >> 6) & 0x1f) { + case 0x4: case 0x5: case 0x7: case 0xb: + break; + default: + info->statusflag = 4; + info->macflag = 4; + break; + } + break; + + default: + info->statusflag = 4; + info->macflag = 4; + break; + } + + if (uregs->VIread & (1 << REG_Q)) { info->q |= 2; } + if (uregs->VIread & (1 << REG_P)) { info->p |= 2; assert( VU == &VU1 ); } + + // check upper flags + if (ptr[1] & 0x80000000) { // I flag + info->cycle = vucycle; + memzero_obj(*lregs); + } + else { + + VU->code = ptr[0]; + if (VU == &VU1) VU1regs_LOWER_OPCODE[VU->code >> 25](lregs); + else VU0regs_LOWER_OPCODE[VU->code >> 25](lregs); + + _recvuTestLowerStalls(VU, lregs); + info->cycle = vucycle; + + if (lregs->pipe == VUPIPE_BRANCH) { + branch |= 1; + } + + if (lregs->VIwrite & (1 << REG_Q)) { + info->q |= 4; + info->cycles = lregs->cycles; + info->pqinst = (VU->code&2)>>1; // rsqrt is 2 + } + else if (lregs->pipe == VUPIPE_FDIV) { + info->q |= 8|1; + info->pqinst = 0; + } + + if (lregs->VIwrite & (1 << REG_P)) { + assert( VU == &VU1 ); + info->p |= 4; + info->cycles = lregs->cycles; + + switch( VU->code & 0xff ) { + case 0xfd: info->pqinst = 0; break; //eatan + case 0x7c: info->pqinst = 0; break; //eatanxy + case 0x7d: info->pqinst = 0; break; //eatanzy + case 0xfe: info->pqinst = 1; break; //eexp + case 0xfc: info->pqinst = 2; break; //esin + case 0x3f: info->pqinst = 3; break; //erleng + case 0x3e: info->pqinst = 4; break; //eleng + case 0x3d: info->pqinst = 4; break; //ersadd + case 0xbd: info->pqinst = 4; break; //ersqrt + case 0xbe: info->pqinst = 5; break; //ercpr + case 0xbc: info->pqinst = 5; break; //esqrt + case 0x7e: info->pqinst = 5; break; //esum + case 0x3c: info->pqinst = 6; break; //esadd + default: assert(0); + } + } + else if (lregs->pipe == VUPIPE_EFU) { + info->p |= 8|1; + } + + if (lregs->VIread & (1 << REG_STATUS_FLAG)) info->statusflag|= VUOP_READ; + if (lregs->VIread & (1 << REG_MAC_FLAG)) info->macflag|= VUOP_READ; + + if (lregs->VIwrite & (1 << REG_STATUS_FLAG)) info->statusflag|= VUOP_WRITE; + if (lregs->VIwrite & (1 << REG_MAC_FLAG)) info->macflag|= VUOP_WRITE; + + if (lregs->VIread & (1 << REG_Q)) { info->q |= 2; } + if (lregs->VIread & (1 << REG_P)) { info->p |= 2; assert( VU == &VU1 ); } + + _recvuAddLowerStalls(VU, lregs); + } + + _recvuAddUpperStalls(VU, uregs); + _recvuTestPipes(VU, false); + + vucycle++; +} + +int eeVURecompileCode(VURegs *VU, _VURegsNum* regs) +{ + int info = 0; + int vfread0=-1, vfread1 = -1, vfwrite = -1, vfacc = -1, vftemp=-1; + + assert( regs != NULL ); + + if( regs->VFread0 ) _addNeededVFtoXMMreg(regs->VFread0); + if( regs->VFread1 ) _addNeededVFtoXMMreg(regs->VFread1); + if( regs->VFwrite ) _addNeededVFtoXMMreg(regs->VFwrite); + if( regs->VIread & (1<VIread & (1<VFread0 ) vfread0 = _allocVFtoXMMreg(VU, -1, regs->VFread0, MODE_READ); + else if( regs->VIread & (1<VFread1 ) vfread1 = _allocVFtoXMMreg(VU, -1, regs->VFread1, MODE_READ); + else if( (regs->VIread & (1<VFr1xyzw != 0xff) vfread1 = _allocVFtoXMMreg(VU, -1, 0, MODE_READ); + + if( regs->VIread & (1<VIwrite&(1<VIwrite & (1<VFwxyzw != 0xf?MODE_READ:0)); + } + + if( regs->VFwrite ) { + assert( !(regs->VIwrite&(1<VFwrite, MODE_WRITE|(regs->VFwxyzw != 0xf?MODE_READ:0)); + } + + if( vfacc>= 0 ) info |= PROCESS_EE_SET_ACC(vfacc); + if( vfwrite >= 0 ) { + if( regs->VFwrite == _Ft_ && vfread1 < 0 ) { + info |= PROCESS_EE_SET_T(vfwrite); + } + else { + assert( regs->VFwrite == _Fd_ ); + info |= PROCESS_EE_SET_D(vfwrite); + } + } + + if( vfread0 >= 0 ) info |= PROCESS_EE_SET_S(vfread0); + if( vfread1 >= 0 ) info |= PROCESS_EE_SET_T(vfread1); + + vftemp = _allocTempXMMreg(XMMT_FPS, -1); + info |= PROCESS_VU_SET_TEMP(vftemp); + + if( regs->VIwrite & (1 << REG_CLIP_FLAG) ) { + // CLIP inst, need two extra temp registers, put it EEREC_D and EEREC_ACC + int t1reg = _allocTempXMMreg(XMMT_FPS, -1); + int t2reg = _allocTempXMMreg(XMMT_FPS, -1); + + info |= PROCESS_EE_SET_D(t1reg); + info |= PROCESS_EE_SET_ACC(t2reg); + + _freeXMMreg(t1reg); // don't need + _freeXMMreg(t2reg); // don't need + } + else if( regs->VIwrite & (1<VI[reg].UL; + + if( read != 1 ) { + if( reg == REG_MAC_FLAG ) return (uptr)&VU->macflag; + if( reg == REG_CLIP_FLAG ) return (uptr)&VU->clipflag; + if( reg == REG_STATUS_FLAG ) return (uptr)&VU->statusflag; + if( reg == REG_Q ) return (uptr)&VU->q; + if( reg == REG_P ) return (uptr)&VU->p; + } + + return (uptr)&VU->VI[reg].UL; +} + +// gets a temp reg that is not EEREC_TEMP +int _vuGetTempXMMreg(int info) +{ + int t1reg = -1; + + if( _hasFreeXMMreg() ) { + t1reg = _allocTempXMMreg(XMMT_FPS, -1); + + if( t1reg == EEREC_TEMP ) { + if( _hasFreeXMMreg() ) { + int t = _allocTempXMMreg(XMMT_FPS, -1); + _freeXMMreg(t1reg); + t1reg = t; + } + else { + _freeXMMreg(t1reg); + t1reg = -1; + } + } + } + + return t1reg; +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// Misc VU Reg Flipping/Merging Functions +//------------------------------------------------------------------ +void _unpackVF_xyzw(int dstreg, int srcreg, int xyzw) +{ + switch (xyzw) { + case 0: SSE2_PSHUFD_XMM_to_XMM(dstreg, srcreg, 0x00); break; + case 1: SSE2_PSHUFD_XMM_to_XMM(dstreg, srcreg, 0x55); break; + case 2: SSE2_PSHUFD_XMM_to_XMM(dstreg, srcreg, 0xaa); break; + case 3: SSE2_PSHUFD_XMM_to_XMM(dstreg, srcreg, 0xff); break; + } +} + +void _unpackVFSS_xyzw(int dstreg, int srcreg, int xyzw) +{ + switch (xyzw) { + case 0: SSE_MOVSS_XMM_to_XMM(dstreg, srcreg); break; + case 1: if ( cpucaps.hasStreamingSIMD4Extensions ) SSE4_INSERTPS_XMM_to_XMM(dstreg, srcreg, _MM_MK_INSERTPS_NDX(1, 0, 0)); + else SSE2_PSHUFLW_XMM_to_XMM(dstreg, srcreg, 0xee); + break; + case 2: SSE_MOVHLPS_XMM_to_XMM(dstreg, srcreg); break; + case 3: if ( cpucaps.hasStreamingSIMD4Extensions ) SSE4_INSERTPS_XMM_to_XMM(dstreg, srcreg, _MM_MK_INSERTPS_NDX(3, 0, 0)); + else { SSE_MOVHLPS_XMM_to_XMM(dstreg, srcreg); SSE2_PSHUFLW_XMM_to_XMM(dstreg, dstreg, 0xee); } + break; + } +} + +void _vuFlipRegSS(VURegs * VU, int reg) +{ + assert( _XYZW_SS ); + if( _Y ) SSE2_PSHUFLW_XMM_to_XMM(reg, reg, 0x4e); + else if( _Z ) SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xc6); + else if( _W ) SSE_SHUFPS_XMM_to_XMM(reg, reg, 0x27); +} + +void _vuFlipRegSS_xyzw(int reg, int xyzw) +{ + switch ( xyzw ) { + case 1: SSE2_PSHUFLW_XMM_to_XMM(reg, reg, 0x4e); break; + case 2: SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xc6); break; + case 3: SSE_SHUFPS_XMM_to_XMM(reg, reg, 0x27); break; + } +} + +void _vuMoveSS(VURegs * VU, int dstreg, int srcreg) +{ + assert( _XYZW_SS ); + if( _Y ) _unpackVFSS_xyzw(dstreg, srcreg, 1); + else if( _Z ) _unpackVFSS_xyzw(dstreg, srcreg, 2); + else if( _W ) _unpackVFSS_xyzw(dstreg, srcreg, 3); + else _unpackVFSS_xyzw(dstreg, srcreg, 0); +} + +// 1 - src, 0 - dest wzyx +void VU_MERGE0(int dest, int src) { // 0000s +} +void VU_MERGE1(int dest, int src) { // 1000 + SSE_MOVHLPS_XMM_to_XMM(src, dest); + SSE_SHUFPS_XMM_to_XMM(dest, src, 0xc4); +} +void VU_MERGE1b(int dest, int src) { // 1000s + SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); +} +void VU_MERGE2(int dest, int src) { // 0100 + SSE_MOVHLPS_XMM_to_XMM(src, dest); + SSE_SHUFPS_XMM_to_XMM(dest, src, 0x64); +} +void VU_MERGE2b(int dest, int src) { // 0100s + SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); +} +void VU_MERGE3(int dest, int src) { // 1100s + SSE_SHUFPS_XMM_to_XMM(dest, src, 0xe4); +} +void VU_MERGE4(int dest, int src) { // 0010 + SSE_MOVSS_XMM_to_XMM(src, dest); + SSE2_MOVSD_XMM_to_XMM(dest, src); +} +void VU_MERGE4b(int dest, int src) { // 0010s + SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); +} +void VU_MERGE5(int dest, int src) { // 1010 + SSE_SHUFPS_XMM_to_XMM(dest, src, 0xd8); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xd8); +} +void VU_MERGE5b(int dest, int src) { // 1010s + SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); +} +void VU_MERGE6(int dest, int src) { // 0110 + SSE_SHUFPS_XMM_to_XMM(dest, src, 0x9c); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x78); +} +void VU_MERGE6b(int dest, int src) { // 0110s + SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); +} +void VU_MERGE7(int dest, int src) { // 1110 + SSE_MOVSS_XMM_to_XMM(src, dest); + SSE_MOVAPS_XMM_to_XMM(dest, src); +} +void VU_MERGE7b(int dest, int src) { // 1110s + SSE_SHUFPS_XMM_to_XMM(dest, src, 0xe4); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); +} +void VU_MERGE8(int dest, int src) { // 0001s + SSE_MOVSS_XMM_to_XMM(dest, src); +} +void VU_MERGE9(int dest, int src) { // 1001 + SSE_SHUFPS_XMM_to_XMM(dest, src, 0xc9); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xd2); +} +void VU_MERGE9b(int dest, int src) { // 1001s + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); +} +void VU_MERGE10(int dest, int src) { // 0101 + SSE_SHUFPS_XMM_to_XMM(dest, src, 0x8d); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x72); +} +void VU_MERGE10b(int dest, int src) { // 0101s + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); +} +void VU_MERGE11(int dest, int src) { // 1101s + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(dest, src, 0xe4); +} +void VU_MERGE12(int dest, int src) { // 0011 + SSE2_MOVSD_XMM_to_XMM(dest, src); +} +void VU_MERGE13(int dest, int src) { // 1011 + SSE_MOVHLPS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, dest, 0x64); + SSE_MOVAPS_XMM_to_XMM(dest, src); +} +void VU_MERGE13b(int dest, int src) { // 1011s + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0x27); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x27); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); +} +void VU_MERGE14(int dest, int src) { // 0111 + SSE_MOVHLPS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, dest, 0xc4); + SSE_MOVAPS_XMM_to_XMM(dest, src); +} +void VU_MERGE14b(int dest, int src) { // 0111s + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xE1); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xE1); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); + SSE_MOVSS_XMM_to_XMM(dest, src); + SSE_SHUFPS_XMM_to_XMM(src, src, 0xC6); + SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xC6); +} +void VU_MERGE15(int dest, int src) { // 1111s + SSE_MOVAPS_XMM_to_XMM(dest, src); +} + +typedef void (*VUMERGEFN)(int dest, int src); + +static VUMERGEFN s_VuMerge[16] = { + VU_MERGE0, VU_MERGE1, VU_MERGE2, VU_MERGE3, + VU_MERGE4, VU_MERGE5, VU_MERGE6, VU_MERGE7, + VU_MERGE8, VU_MERGE9, VU_MERGE10, VU_MERGE11, + VU_MERGE12, VU_MERGE13, VU_MERGE14, VU_MERGE15 }; + +static VUMERGEFN s_VuMerge2[16] = { + VU_MERGE0, VU_MERGE1b, VU_MERGE2b, VU_MERGE3, + VU_MERGE4b, VU_MERGE5b, VU_MERGE6b, VU_MERGE7b, + VU_MERGE8, VU_MERGE9b, VU_MERGE10b, VU_MERGE11, + VU_MERGE12, VU_MERGE13b, VU_MERGE14b, VU_MERGE15 }; + +// Modifies the Source Reg! +void VU_MERGE_REGS_CUSTOM(int dest, int src, int xyzw) { + xyzw &= 0xf; + if ( (dest != src) && (xyzw != 0) ) { + if ( cpucaps.hasStreamingSIMD4Extensions && (xyzw != 0x8) && (xyzw != 0xf) ) { + xyzw = ((xyzw & 1) << 3) | ((xyzw & 2) << 1) | ((xyzw & 4) >> 1) | ((xyzw & 8) >> 3); + SSE4_BLENDPS_XMM_to_XMM(dest, src, xyzw); + } + else s_VuMerge[xyzw](dest, src); + } +} +// Doesn't Modify the Source Reg! (ToDo: s_VuMerge2() has room for optimization) +void VU_MERGE_REGS_SAFE(int dest, int src, int xyzw) { + xyzw &= 0xf; + if ( (dest != src) && (xyzw != 0) ) { + if ( cpucaps.hasStreamingSIMD4Extensions && (xyzw != 0x8) && (xyzw != 0xf) ) { + xyzw = ((xyzw & 1) << 3) | ((xyzw & 2) << 1) | ((xyzw & 4) >> 1) | ((xyzw & 8) >> 3); + SSE4_BLENDPS_XMM_to_XMM(dest, src, xyzw); + } + else s_VuMerge2[xyzw](dest, src); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// Misc VU Reg Clamping/Overflow Functions +//------------------------------------------------------------------ +#define CLAMP_NORMAL_SSE4(n) \ + SSE_MOVAPS_XMM_to_XMM(regTemp, regd);\ + SSE4_PMINUD_M128_to_XMM(regd, (uptr)&g_minvals_XYZW[n][0]);\ + SSE2_PSUBD_XMM_to_XMM(regTemp, regd);\ + SSE2_PCMPGTD_M128_to_XMM(regTemp, (uptr)&g_ones[0]);\ + SSE4_PMINSD_M128_to_XMM(regd, (uptr)&g_maxvals_XYZW[n][0]);\ + SSE2_PSLLD_I8_to_XMM(regTemp, 31);\ + SSE_XORPS_XMM_to_XMM(regd, regTemp); + +#define CLAMP_SIGN_SSE4(n) \ + SSE4_PMINSD_M128_to_XMM(regd, (uptr)&g_maxvals_XYZW[n][0]);\ + SSE4_PMINUD_M128_to_XMM(regd, (uptr)&g_minvals_XYZW[n][0]); + +void vFloat0(int regd, int regTemp) { } //0000 +void vFloat1(int regd, int regTemp) { //1000 + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); +} +void vFloat1c(int regd, int regTemp) { //1000 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(1); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat2(int regd, int regTemp) { //0100 + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); +} +void vFloat2c(int regd, int regTemp) { //0100 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(2); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat3(int regd, int regTemp) { //1100 + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x36); +} +void vFloat3b(int regd, int regTemp) { //1100 //regTemp is Modified + SSE2_MOVSD_XMM_to_XMM(regTemp, regd); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + SSE2_MOVSD_XMM_to_XMM(regd, regTemp); +} +void vFloat3c(int regd, int regTemp) { //1100 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(3); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x36); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat4(int regd, int regTemp) { //0010 + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); +} +void vFloat4c(int regd, int regTemp) { //0010 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(4); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat5(int regd, int regTemp) { //1010 + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x2d); +} +void vFloat5b(int regd, int regTemp) { //1010 //regTemp is Modified + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_NORMAL_SSE4(5); + } + else { + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x2d); + } +} +void vFloat5c(int regd, int regTemp) { //1010 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(5); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x2d); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat6(int regd, int regTemp) { //0110 + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc9); +} +void vFloat6b(int regd, int regTemp) { //0110 //regTemp is Modified + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_NORMAL_SSE4(6); + } + else { + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc9); + } +} +void vFloat6c(int regd, int regTemp) { //0110 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(6); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc9); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat7(int regd, int regTemp) { //1110 + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x39); +} +void vFloat7_useEAX(int regd, int regTemp) { //1110 //EAX is Modified + SSE2_MOVD_XMM_to_R(EAX, regd); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + if ( cpucaps.hasStreamingSIMD4Extensions ) + SSE4_PINSRD_R32_to_XMM(regd, EAX, 0x00); + else { + SSE_PINSRW_R32_to_XMM(regd, EAX, 0); + SHR32ItoR(EAX, 16); + SSE_PINSRW_R32_to_XMM(regd, EAX, 1); + } +} +void vFloat7b(int regd, int regTemp) { //1110 //regTemp is Modified + SSE_MOVSS_XMM_to_XMM(regTemp, regd); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + SSE_MOVSS_XMM_to_XMM(regd, regTemp); +} +void vFloat7c(int regd, int regTemp) { //1110 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(7); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x39); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat7c_useEAX(int regd, int regTemp) { //1110 //EAX is Modified + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(7); + } + else { + SSE2_MOVD_XMM_to_R(EAX, regd); + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + SSE2_MOVD_R_to_XMM(regTemp, EAX); + SSE_MOVSS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat8(int regd, int regTemp) { //0001 + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); +} +void vFloat8c(int regd, int regTemp) { //0001 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(8); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat9(int regd, int regTemp) { //1001 + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); +} +void vFloat9b(int regd, int regTemp) { //1001 //regTemp is Modified + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_NORMAL_SSE4(9); + } + else { + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + } +} +void vFloat9c(int regd, int regTemp) { //1001 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(9); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat10(int regd, int regTemp) { //0101 + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); +} +void vFloat10b(int regd, int regTemp) { //0101 //regTemp is Modified + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_NORMAL_SSE4(10); + } + else { + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + } +} +void vFloat10c(int regd, int regTemp) { //0101 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(10); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat11(int regd, int regTemp) { //1101 + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x36); +} +void vFloat11_useEAX(int regd, int regTemp) { //1101 //EAX is Modified + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE2_MOVD_XMM_to_R(EAX, regd); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + if ( cpucaps.hasStreamingSIMD4Extensions ) + SSE4_PINSRD_R32_to_XMM(regd, EAX, 0x00); + else { + SSE_PINSRW_R32_to_XMM(regd, EAX, 0); + SHR32ItoR(EAX, 16); + SSE_PINSRW_R32_to_XMM(regd, EAX, 1); + } + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); +} +void vFloat11b(int regd, int regTemp) { //1101 //regTemp is Modified + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + SSE_MOVSS_XMM_to_XMM(regTemp, regd); + SSE2_MOVSD_XMM_to_XMM(regd, regTemp); +} +void vFloat11c(int regd, int regTemp) { //1101 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(11); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x36); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat11c_useEAX(int regd, int regTemp) { //1101 // EAX is modified + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(11); + } + else { + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE2_MOVD_XMM_to_R(EAX, regd); + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + SSE2_MOVD_R_to_XMM(regTemp, EAX); + SSE_MOVSS_XMM_to_XMM(regd, regTemp); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + } +} +void vFloat12(int regd, int regTemp) { //0011 + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); +} +void vFloat12b(int regd, int regTemp) { //0011 //regTemp is Modified + SSE_MOVHLPS_XMM_to_XMM(regTemp, regd); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + SSE2_PUNPCKLQDQ_XMM_to_XMM(regd, regTemp); +} +void vFloat12c(int regd, int regTemp) { //0011 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(12); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat13(int regd, int regTemp) { //1011 + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x2d); +} +void vFloat13_useEAX(int regd, int regTemp) { //1011 // EAX is modified + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE2_MOVD_XMM_to_R(EAX, regd); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + if ( cpucaps.hasStreamingSIMD4Extensions ) + SSE4_PINSRD_R32_to_XMM(regd, EAX, 0x00); + else { + SSE_PINSRW_R32_to_XMM(regd, EAX, 0); + SHR32ItoR(EAX, 16); + SSE_PINSRW_R32_to_XMM(regd, EAX, 1); + } + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); +} +void vFloat13b(int regd, int regTemp) { //1011 //regTemp is Modified + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + SSE_MOVHLPS_XMM_to_XMM(regTemp, regd); + SSE_SHUFPS_XMM_to_XMM(regd, regTemp, 0x64); +} +void vFloat13c(int regd, int regTemp) { //1011 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(13); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x2d); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat13c_useEAX(int regd, int regTemp) { //1011 // EAX is modified + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(13); + } + else { + SSE2_PSHUFD_XMM_to_XMM(regd, regd, 0xc6); + SSE2_MOVD_XMM_to_R(EAX, regd); + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + SSE2_MOVD_R_to_XMM(regTemp, EAX); + SSE_MOVSS_XMM_to_XMM(regd, regTemp); + SSE2_PSHUFD_XMM_to_XMM(regd, regd, 0xc6); + } +} +void vFloat14(int regd, int regTemp) { //0111 + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc9); +} +void vFloat14_useEAX(int regd, int regTemp) { //0111 // EAX is modified + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); + SSE2_MOVD_XMM_to_R(EAX, regd); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + if ( cpucaps.hasStreamingSIMD4Extensions ) + SSE4_PINSRD_R32_to_XMM(regd, EAX, 0x00); + else { + SSE_PINSRW_R32_to_XMM(regd, EAX, 0); + SHR32ItoR(EAX, 16); + SSE_PINSRW_R32_to_XMM(regd, EAX, 1); + } + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x27); +} +void vFloat14b(int regd, int regTemp) { //0111 //regTemp is Modified + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + SSE_MOVHLPS_XMM_to_XMM(regTemp, regd); + SSE_SHUFPS_XMM_to_XMM(regd, regTemp, 0xc4); +} +void vFloat14c(int regd, int regTemp) { //0111 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(14); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE2_PSHUFLW_XMM_to_XMM(regd, regd, 0x4e); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc6); + SSE_MINSS_M32_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXSS_M32_to_XMM(regd, (uptr)g_minvals); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0xc9); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} +void vFloat14c_useEAX(int regd, int regTemp) { //0111 // EAX is modified + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(14); + } + else { + SSE2_PSHUFD_XMM_to_XMM(regd, regd, 0x27); + SSE2_MOVD_XMM_to_R(EAX, regd); + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + SSE2_MOVD_R_to_XMM(regTemp, EAX); + SSE_MOVSS_XMM_to_XMM(regd, regTemp); + SSE2_PSHUFD_XMM_to_XMM(regd, regd, 0x27); + } +} +void vFloat15(int regd, int regTemp) { //1111 + SSE_MINPS_M128_to_XMM(regd, (uptr)g_maxvals); + SSE_MAXPS_M128_to_XMM(regd, (uptr)g_minvals); +} +void vFloat15c(int regd, int regTemp) { //1111 + if ( cpucaps.hasStreamingSIMD4Extensions ) { + CLAMP_SIGN_SSE4(15); + } + else { + SSE_MOVAPS_XMM_to_XMM(regTemp, regd); + SSE_ANDPS_M128_to_XMM(regTemp, (uptr)&const_clip[4]); + SSE_MINPS_M128_to_XMM(regd, (uptr)&g_maxvals[0]); + SSE_MAXPS_M128_to_XMM(regd, (uptr)&g_minvals[0]); + SSE_ORPS_XMM_to_XMM(regd, regTemp); + } +} + +vFloat vFloats1[16] = { //regTemp is not modified + vFloat0, vFloat1, vFloat2, vFloat3, + vFloat4, vFloat5, vFloat6, vFloat7, + vFloat8, vFloat9, vFloat10, vFloat11, + vFloat12, vFloat13, vFloat14, vFloat15 }; + +vFloat vFloats1_useEAX[16] = { //regTemp is not modified but EAX is used + vFloat0, vFloat1, vFloat2, vFloat3, + vFloat4, vFloat5, vFloat6, vFloat7_useEAX, + vFloat8, vFloat9, vFloat10, vFloat11_useEAX, + vFloat12, vFloat13_useEAX, vFloat14_useEAX, vFloat15 }; + +vFloat vFloats2[16] = { //regTemp is modified + vFloat0, vFloat1, vFloat2, vFloat3b, + vFloat4, vFloat5b, vFloat6b, vFloat7b, + vFloat8, vFloat9b, vFloat10b, vFloat11b, + vFloat12b, vFloat13b, vFloat14b, vFloat15 }; + +vFloat vFloats4[16] = { //regTemp is modified + vFloat0, vFloat1c, vFloat2c, vFloat3c, + vFloat4c, vFloat5c, vFloat6c, vFloat7c, + vFloat8c, vFloat9c, vFloat10c, vFloat11c, + vFloat12c, vFloat13c, vFloat14c, vFloat15c }; + +vFloat vFloats4_useEAX[16] = { //regTemp is modified and EAX is used + vFloat0, vFloat1c, vFloat2c, vFloat3c, + vFloat4c, vFloat5c, vFloat6c, vFloat7c_useEAX, + vFloat8c, vFloat9c, vFloat10c, vFloat11c_useEAX, + vFloat12c, vFloat13c_useEAX, vFloat14c_useEAX, vFloat15c }; + +//------------------------------------------------------------------ +// Clamping Functions (wrapper for vFloat* functions) +// vuFloat : "normal" clamping +// vuFloat_useEAX : "normal" clamping (faster but EAX is modified) +// vuFloat2 : "normal" clamping (fastest but regTemp is modified) +// vuFloat3 : "preserve sign" clamping for pointer +// vuFloat4 : "preserve sign" clamping (regTemp is modified; *FASTEST* on SSE4 CPUs) +// vuFloat4_useEAX : "preserve sign" clamping (faster but regTemp and EAX are modified) +// vuFloat5 : wrapper function for vuFloat2 and vuFloat4 +// vuFloat5_useEAX : wrapper function for vuFloat2 and vuFloat4_useEAX +// vuFloatExtra : for debugging +// +// Notice 1: vuFloat*_useEAX may be slower on AMD CPUs, which have independent execution pipeline for +// vector and scalar instructions (need checks) +// Notice 2: recVUMI_MUL_xyzw_toD and recVUMI_MADD_xyzw_toD use vFloats directly! +//------------------------------------------------------------------ + +// Clamps +/-NaN to +fMax and +/-Inf to +/-fMax (doesn't use any temp regs) +void vuFloat( int info, int regd, int XYZW) { + if( CHECK_VU_OVERFLOW ) { + /*if ( (XYZW != 0) && (XYZW != 8) && (XYZW != 0xF) ) { + int t1reg = _vuGetTempXMMreg(info); + if (t1reg >= 0) { + vuFloat2( regd, t1reg, XYZW ); + _freeXMMreg( t1reg ); + return; + } + }*/ + //vuFloatExtra(regd, XYZW); + vFloats1[XYZW](regd, regd); + } +} + +// Clamps +/-NaN to +fMax and +/-Inf to +/-fMax (uses EAX as a temp register; faster but **destroys EAX**) +void vuFloat_useEAX( int info, int regd, int XYZW) { + if( CHECK_VU_OVERFLOW ) { + vFloats1_useEAX[XYZW](regd, regd); + } +} + +// Clamps +/-NaN to +fMax and +/-Inf to +/-fMax (uses a temp reg) +void vuFloat2(int regd, int regTemp, int XYZW) { + if( CHECK_VU_OVERFLOW ) { + //vuFloatExtra(regd, XYZW); + vFloats2[XYZW](regd, regTemp); + } +} + +// Clamps +/-NaN and +/-Inf to +/-fMax (uses a temp reg) +void vuFloat4(int regd, int regTemp, int XYZW) { + if( CHECK_VU_OVERFLOW ) { + vFloats4[XYZW](regd, regTemp); + } +} + +// Clamps +/-NaN and +/-Inf to +/-fMax (uses a temp reg, and uses EAX as a temp register; faster but **destroys EAX**) +void vuFloat4_useEAX(int regd, int regTemp, int XYZW) { + if( CHECK_VU_OVERFLOW ) { + vFloats4_useEAX[XYZW](regd, regTemp); + } +} + +// Uses vuFloat4 or vuFloat2 depending on the CHECK_VU_SIGN_OVERFLOW setting +void vuFloat5(int regd, int regTemp, int XYZW) { + if (CHECK_VU_SIGN_OVERFLOW) { + vuFloat4(regd, regTemp, XYZW); + } + else vuFloat2(regd, regTemp, XYZW); +} + +// Uses vuFloat4_useEAX or vuFloat2 depending on the CHECK_VU_SIGN_OVERFLOW setting (uses EAX as a temp register; faster but **destoroyes EAX**) +void vuFloat5_useEAX(int regd, int regTemp, int XYZW) { + if (CHECK_VU_SIGN_OVERFLOW) { + vuFloat4_useEAX(regd, regTemp, XYZW); + } + else vuFloat2(regd, regTemp, XYZW); +} + +// Clamps +/-infs to +/-fMax, and +/-NaNs to +/-fMax +void vuFloat3(uptr x86ptr) { + u8* pjmp; + + if( CHECK_VU_OVERFLOW ) { + CMP32ItoM(x86ptr, 0x7f800000 ); + pjmp = JL8(0); // Signed Comparison + MOV32ItoM(x86ptr, 0x7f7fffff ); + x86SetJ8(pjmp); + + CMP32ItoM(x86ptr, 0xff800000 ); + pjmp = JB8(0); // Unsigned Comparison + MOV32ItoM(x86ptr, 0xff7fffff ); + x86SetJ8(pjmp); + } +} + +PCSX2_ALIGNED16(u64 vuFloatData[2]); +PCSX2_ALIGNED16(u64 vuFloatData2[2]); +// Makes NaN == 0, Infinities stay the same; Very Slow - Use only for debugging +void vuFloatExtra( int regd, int XYZW) { + int t1reg = (regd == 0) ? (regd + 1) : (regd - 1); + int t2reg = (regd <= 1) ? (regd + 2) : (regd - 2); + SSE_MOVAPS_XMM_to_M128( (uptr)vuFloatData, t1reg ); + SSE_MOVAPS_XMM_to_M128( (uptr)vuFloatData2, t2reg ); + + SSE_XORPS_XMM_to_XMM(t1reg, t1reg); + SSE_CMPORDPS_XMM_to_XMM(t1reg, regd); + SSE_MOVAPS_XMM_to_XMM(t2reg, regd); + SSE_ANDPS_XMM_to_XMM(t2reg, t1reg); + VU_MERGE_REGS_CUSTOM(regd, t2reg, XYZW); + + SSE_MOVAPS_M128_to_XMM( t1reg, (uptr)vuFloatData ); + SSE_MOVAPS_M128_to_XMM( t2reg, (uptr)vuFloatData2 ); +} + +static PCSX2_ALIGNED16(u32 tempRegX[]) = {0x00000000, 0x00000000, 0x00000000, 0x00000000}; + +// Called by testWhenOverflow() function +void testPrintOverflow() { + tempRegX[0] &= 0xff800000; + tempRegX[1] &= 0xff800000; + tempRegX[2] &= 0xff800000; + tempRegX[3] &= 0xff800000; + if ( (tempRegX[0] == 0x7f800000) || (tempRegX[1] == 0x7f800000) || (tempRegX[2] == 0x7f800000) || (tempRegX[3] == 0x7f800000) ) + Console::Notice( "VU OVERFLOW!: Changing to +Fmax!!!!!!!!!!!!" ); + if ( (tempRegX[0] == 0xff800000) || (tempRegX[1] == 0xff800000) || (tempRegX[2] == 0xff800000) || (tempRegX[3] == 0xff800000) ) + Console::Notice( "VU OVERFLOW!: Changing to -Fmax!!!!!!!!!!!!" ); +} + +// Outputs to the console when overflow has occured. +void testWhenOverflow(int info, int regd, int t0reg) { + SSE_MOVAPS_XMM_to_M128((uptr)tempRegX, regd); + CALLFunc((uptr)testPrintOverflow); +} diff --git a/pcsx2/x86/iVUmicro.h b/pcsx2/x86/sVU_Micro.h similarity index 97% rename from pcsx2/x86/iVUmicro.h rename to pcsx2/x86/sVU_Micro.h index 777a7dc063..214a1c425c 100644 --- a/pcsx2/x86/iVUmicro.h +++ b/pcsx2/x86/sVU_Micro.h @@ -1,288 +1,286 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __IVUMICRO_H__ -#define __IVUMICRO_H__ - -#include "VUmicro.h" - -extern u32 vudump; - -#define VU0_MEMSIZE 0x1000 -#define VU1_MEMSIZE 0x4000 - -void recResetVU0(); -void recExecuteVU0Block(); -void recClearVU0( u32 Addr, u32 Size ); - -void recVU1Init(); -void recVU1Shutdown(); -void recResetVU1(); -void recExecuteVU1Block(); -void recClearVU1( u32 Addr, u32 Size ); - - -u32 GetVIAddr(VURegs * VU, int reg, int read, int info); // returns the correct VI addr -void recUpdateFlags(VURegs * VU, int reg, int info); - -void _recvuTestPipes(VURegs * VU); -void _recvuFlushFDIV(VURegs * VU); -void _recvuTestUpperStalls(VURegs * VU, _VURegsNum *VUregsn); -void _recvuTestLowerStalls(VURegs * VU, _VURegsNum *VUregsn); -void _recvuAddUpperStalls(VURegs * VU, _VURegsNum *VUregsn); -void _recvuAddLowerStalls(VURegs * VU, _VURegsNum *VUregsn); - -#define VUOP_READ 2 -#define VUOP_WRITE 4 - -// save on mem -struct _vuopinfo { - int cycle; - int cycles; - u8 statusflag; - u8 macflag; - u8 clipflag; - u8 dummy; - u8 q; - u8 p; - u16 pqinst; // bit of instruction specifying index (srec only) -}; - -void SuperVUAnalyzeOp(VURegs *VU, _vuopinfo *info, _VURegsNum* pCodeRegs); -int eeVURecompileCode(VURegs *VU, _VURegsNum* regs); // allocates all the necessary regs and returns the indices -void VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr); // used for MTGS in XGKICK - -extern int vucycle; -typedef void (*vFloat)(int regd, int regTemp); -extern vFloat vFloats1[16]; -extern vFloat vFloats1_useEAX[16]; -extern vFloat vFloats2[16]; -extern vFloat vFloats4[16]; -extern vFloat vFloats4_useEAX[16]; -PCSX2_ALIGNED16_EXTERN(const float s_fones[8]); -PCSX2_ALIGNED16_EXTERN(const u32 s_mask[4]); -PCSX2_ALIGNED16_EXTERN(const u32 s_expmask[4]); -PCSX2_ALIGNED16_EXTERN(const u32 g_minvals[4]); -PCSX2_ALIGNED16_EXTERN(const u32 g_maxvals[4]); -PCSX2_ALIGNED16_EXTERN(const u32 const_clip[8]); - -u32 GetVIAddr(VURegs * VU, int reg, int read, int info); -int _vuGetTempXMMreg(int info); -void vuFloat(int info, int regd, int XYZW); -void vuFloat_useEAX(int regd, int regTemp, int XYZW); -void vuFloat2(int regd, int regTemp, int XYZW); -void vuFloat3(uptr x86ptr); -void vuFloat4(int regd, int regTemp, int XYZW); -void vuFloat4_useEAX(int regd, int regTemp, int XYZW); -void vuFloat5(int regd, int regTemp, int XYZW); -void vuFloat5_useEAX(int regd, int regTemp, int XYZW); -void _vuFlipRegSS(VURegs * VU, int reg); -void _vuFlipRegSS_xyzw(int reg, int xyzw); -void _vuMoveSS(VURegs * VU, int dstreg, int srcreg); -void _unpackVF_xyzw(int dstreg, int srcreg, int xyzw); -void _unpackVFSS_xyzw(int dstreg, int srcreg, int xyzw); -void VU_MERGE_REGS_CUSTOM(int dest, int src, int xyzw); -void VU_MERGE_REGS_SAFE(int dest, int src, int xyzw); -#define VU_MERGE_REGS(dest, src) { \ - VU_MERGE_REGS_CUSTOM(dest, src, _X_Y_Z_W); \ -} - -// use for allocating vi regs -#define ALLOCTEMPX86(mode) _allocX86reg(-1, X86TYPE_TEMP, 0, ((info&PROCESS_VU_SUPER)?0:MODE_NOFRAME)|mode) -#define ALLOCVI(vi, mode) _allocX86reg(-1, X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), vi, ((info&PROCESS_VU_SUPER)?0:MODE_NOFRAME)|mode) -#define ADD_VI_NEEDED(vi) _addNeededX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), vi); - -#define SWAP(x, y) *(u32*)&y ^= *(u32*)&x ^= *(u32*)&y ^= *(u32*)&x; - -/***************************************** - VU Micromode Upper instructions -*****************************************/ - -void recVUMI_ABS(VURegs *vuRegs, int info); -void recVUMI_ADD(VURegs *vuRegs, int info); -void recVUMI_ADDi(VURegs *vuRegs, int info); -void recVUMI_ADDq(VURegs *vuRegs, int info); -void recVUMI_ADDx(VURegs *vuRegs, int info); -void recVUMI_ADDy(VURegs *vuRegs, int info); -void recVUMI_ADDz(VURegs *vuRegs, int info); -void recVUMI_ADDw(VURegs *vuRegs, int info); -void recVUMI_ADDA(VURegs *vuRegs, int info); -void recVUMI_ADDAi(VURegs *vuRegs, int info); -void recVUMI_ADDAq(VURegs *vuRegs, int info); -void recVUMI_ADDAx(VURegs *vuRegs, int info); -void recVUMI_ADDAy(VURegs *vuRegs, int info); -void recVUMI_ADDAz(VURegs *vuRegs, int info); -void recVUMI_ADDAw(VURegs *vuRegs, int info); -void recVUMI_SUB(VURegs *vuRegs, int info); -void recVUMI_SUBi(VURegs *vuRegs, int info); -void recVUMI_SUBq(VURegs *vuRegs, int info); -void recVUMI_SUBx(VURegs *vuRegs, int info); -void recVUMI_SUBy(VURegs *vuRegs, int info); -void recVUMI_SUBz(VURegs *vuRegs, int info); -void recVUMI_SUBw(VURegs *vuRegs, int info); -void recVUMI_SUBA(VURegs *vuRegs, int info); -void recVUMI_SUBAi(VURegs *vuRegs, int info); -void recVUMI_SUBAq(VURegs *vuRegs, int info); -void recVUMI_SUBAx(VURegs *vuRegs, int info); -void recVUMI_SUBAy(VURegs *vuRegs, int info); -void recVUMI_SUBAz(VURegs *vuRegs, int info); -void recVUMI_SUBAw(VURegs *vuRegs, int info); -void recVUMI_MUL(VURegs *vuRegs, int info); -void recVUMI_MULi(VURegs *vuRegs, int info); -void recVUMI_MULq(VURegs *vuRegs, int info); -void recVUMI_MULx(VURegs *vuRegs, int info); -void recVUMI_MULy(VURegs *vuRegs, int info); -void recVUMI_MULz(VURegs *vuRegs, int info); -void recVUMI_MULw(VURegs *vuRegs, int info); -void recVUMI_MULA(VURegs *vuRegs, int info); -void recVUMI_MULAi(VURegs *vuRegs, int info); -void recVUMI_MULAq(VURegs *vuRegs, int info); -void recVUMI_MULAx(VURegs *vuRegs, int info); -void recVUMI_MULAy(VURegs *vuRegs, int info); -void recVUMI_MULAz(VURegs *vuRegs, int info); -void recVUMI_MULAw(VURegs *vuRegs, int info); -void recVUMI_MADD(VURegs *vuRegs, int info); -void recVUMI_MADDi(VURegs *vuRegs, int info); -void recVUMI_MADDq(VURegs *vuRegs, int info); -void recVUMI_MADDx(VURegs *vuRegs, int info); -void recVUMI_MADDy(VURegs *vuRegs, int info); -void recVUMI_MADDz(VURegs *vuRegs, int info); -void recVUMI_MADDw(VURegs *vuRegs, int info); -void recVUMI_MADDA(VURegs *vuRegs, int info); -void recVUMI_MADDAi(VURegs *vuRegs, int info); -void recVUMI_MADDAq(VURegs *vuRegs, int info); -void recVUMI_MADDAx(VURegs *vuRegs, int info); -void recVUMI_MADDAy(VURegs *vuRegs, int info); -void recVUMI_MADDAz(VURegs *vuRegs, int info); -void recVUMI_MADDAw(VURegs *vuRegs, int info); -void recVUMI_MSUB(VURegs *vuRegs, int info); -void recVUMI_MSUBi(VURegs *vuRegs, int info); -void recVUMI_MSUBq(VURegs *vuRegs, int info); -void recVUMI_MSUBx(VURegs *vuRegs, int info); -void recVUMI_MSUBy(VURegs *vuRegs, int info); -void recVUMI_MSUBz(VURegs *vuRegs, int info); -void recVUMI_MSUBw(VURegs *vuRegs, int info); -void recVUMI_MSUBA(VURegs *vuRegs, int info); -void recVUMI_MSUBAi(VURegs *vuRegs, int info); -void recVUMI_MSUBAq(VURegs *vuRegs, int info); -void recVUMI_MSUBAx(VURegs *vuRegs, int info); -void recVUMI_MSUBAy(VURegs *vuRegs, int info); -void recVUMI_MSUBAz(VURegs *vuRegs, int info); -void recVUMI_MSUBAw(VURegs *vuRegs, int info); -void recVUMI_MAX(VURegs *vuRegs, int info); -void recVUMI_MAXi(VURegs *vuRegs, int info); -void recVUMI_MAXx(VURegs *vuRegs, int info); -void recVUMI_MAXy(VURegs *vuRegs, int info); -void recVUMI_MAXz(VURegs *vuRegs, int info); -void recVUMI_MAXw(VURegs *vuRegs, int info); -void recVUMI_MINI(VURegs *vuRegs, int info); -void recVUMI_MINIi(VURegs *vuRegs, int info); -void recVUMI_MINIx(VURegs *vuRegs, int info); -void recVUMI_MINIy(VURegs *vuRegs, int info); -void recVUMI_MINIz(VURegs *vuRegs, int info); -void recVUMI_MINIw(VURegs *vuRegs, int info); -void recVUMI_OPMULA(VURegs *vuRegs, int info); -void recVUMI_OPMSUB(VURegs *vuRegs, int info); -void recVUMI_NOP(VURegs *vuRegs, int info); -void recVUMI_FTOI0(VURegs *vuRegs, int info); -void recVUMI_FTOI4(VURegs *vuRegs, int info); -void recVUMI_FTOI12(VURegs *vuRegs, int info); -void recVUMI_FTOI15(VURegs *vuRegs, int info); -void recVUMI_ITOF0(VURegs *vuRegs, int info); -void recVUMI_ITOF4(VURegs *vuRegs, int info); -void recVUMI_ITOF12(VURegs *vuRegs, int info); -void recVUMI_ITOF15(VURegs *vuRegs, int info); -void recVUMI_CLIP(VURegs *vuRegs, int info); - -/***************************************** - VU Micromode Lower instructions -*****************************************/ - -void recVUMI_DIV(VURegs *vuRegs, int info); -void recVUMI_SQRT(VURegs *vuRegs, int info); -void recVUMI_RSQRT(VURegs *vuRegs, int info); -void recVUMI_IADD(VURegs *vuRegs, int info); -void recVUMI_IADDI(VURegs *vuRegs, int info); -void recVUMI_IADDIU(VURegs *vuRegs, int info); -void recVUMI_IAND(VURegs *vuRegs, int info); -void recVUMI_IOR(VURegs *vuRegs, int info); -void recVUMI_ISUB(VURegs *vuRegs, int info); -void recVUMI_ISUBIU(VURegs *vuRegs, int info); -void recVUMI_MOVE(VURegs *vuRegs, int info); -void recVUMI_MFIR(VURegs *vuRegs, int info); -void recVUMI_MTIR(VURegs *vuRegs, int info); -void recVUMI_MR32(VURegs *vuRegs, int info); -void recVUMI_LQ(VURegs *vuRegs, int info); -void recVUMI_LQD(VURegs *vuRegs, int info); -void recVUMI_LQI(VURegs *vuRegs, int info); -void recVUMI_SQ(VURegs *vuRegs, int info); -void recVUMI_SQD(VURegs *vuRegs, int info); -void recVUMI_SQI(VURegs *vuRegs, int info); -void recVUMI_ILW(VURegs *vuRegs, int info); -void recVUMI_ISW(VURegs *vuRegs, int info); -void recVUMI_ILWR(VURegs *vuRegs, int info); -void recVUMI_ISWR(VURegs *vuRegs, int info); -void recVUMI_LOI(VURegs *vuRegs, int info); -void recVUMI_RINIT(VURegs *vuRegs, int info); -void recVUMI_RGET(VURegs *vuRegs, int info); -void recVUMI_RNEXT(VURegs *vuRegs, int info); -void recVUMI_RXOR(VURegs *vuRegs, int info); -void recVUMI_WAITQ(VURegs *vuRegs, int info); -void recVUMI_FSAND(VURegs *vuRegs, int info); -void recVUMI_FSEQ(VURegs *vuRegs, int info); -void recVUMI_FSOR(VURegs *vuRegs, int info); -void recVUMI_FSSET(VURegs *vuRegs, int info); -void recVUMI_FMAND(VURegs *vuRegs, int info); -void recVUMI_FMEQ(VURegs *vuRegs, int info); -void recVUMI_FMOR(VURegs *vuRegs, int info); -void recVUMI_FCAND(VURegs *vuRegs, int info); -void recVUMI_FCEQ(VURegs *vuRegs, int info); -void recVUMI_FCOR(VURegs *vuRegs, int info); -void recVUMI_FCSET(VURegs *vuRegs, int info); -void recVUMI_FCGET(VURegs *vuRegs, int info); -void recVUMI_IBEQ(VURegs *vuRegs, int info); -void recVUMI_IBGEZ(VURegs *vuRegs, int info); -void recVUMI_IBGTZ(VURegs *vuRegs, int info); -void recVUMI_IBLTZ(VURegs *vuRegs, int info); -void recVUMI_IBLEZ(VURegs *vuRegs, int info); -void recVUMI_IBNE(VURegs *vuRegs, int info); -void recVUMI_B(VURegs *vuRegs, int info); -void recVUMI_BAL(VURegs *vuRegs, int info); -void recVUMI_JR(VURegs *vuRegs, int info); -void recVUMI_JALR(VURegs *vuRegs, int info); -void recVUMI_MFP(VURegs *vuRegs, int info); -void recVUMI_WAITP(VURegs *vuRegs, int info); -void recVUMI_ESADD(VURegs *vuRegs, int info); -void recVUMI_ERSADD(VURegs *vuRegs, int info); -void recVUMI_ELENG(VURegs *vuRegs, int info); -void recVUMI_ERLENG(VURegs *vuRegs, int info); -void recVUMI_EATANxy(VURegs *vuRegs, int info); -void recVUMI_EATANxz(VURegs *vuRegs, int info); -void recVUMI_ESUM(VURegs *vuRegs, int info); -void recVUMI_ERCPR(VURegs *vuRegs, int info); -void recVUMI_ESQRT(VURegs *vuRegs, int info); -void recVUMI_ERSQRT(VURegs *vuRegs, int info); -void recVUMI_ESIN(VURegs *vuRegs, int info); -void recVUMI_EATAN(VURegs *vuRegs, int info); -void recVUMI_EEXP(VURegs *vuRegs, int info); -void recVUMI_XGKICK(VURegs *vuRegs, int info); -void recVUMI_XTOP(VURegs *vuRegs, int info); -void recVUMI_XITOP(VURegs *vuRegs, int info); -void recVUMI_XTOP( VURegs *VU , int info); - -#endif /* __IVUMICRO_H__ */ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2003 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#pragma once + +#include "VUmicro.h" + +extern u32 vudump; + +#define VU0_MEMSIZE 0x1000 +#define VU1_MEMSIZE 0x4000 + +void recResetVU0(); +void recExecuteVU0Block(); +void recClearVU0( u32 Addr, u32 Size ); + +void recVU1Init(); +void recVU1Shutdown(); +void recResetVU1(); +void recExecuteVU1Block(); +void recClearVU1( u32 Addr, u32 Size ); + + +u32 GetVIAddr(VURegs * VU, int reg, int read, int info); // returns the correct VI addr +void recUpdateFlags(VURegs * VU, int reg, int info); + +void _recvuTestPipes(VURegs * VU); +void _recvuFlushFDIV(VURegs * VU); +void _recvuTestUpperStalls(VURegs * VU, _VURegsNum *VUregsn); +void _recvuTestLowerStalls(VURegs * VU, _VURegsNum *VUregsn); +void _recvuAddUpperStalls(VURegs * VU, _VURegsNum *VUregsn); +void _recvuAddLowerStalls(VURegs * VU, _VURegsNum *VUregsn); + +#define VUOP_READ 2 +#define VUOP_WRITE 4 + +// save on mem +struct _vuopinfo { + int cycle; + int cycles; + u8 statusflag; + u8 macflag; + u8 clipflag; + u8 dummy; + u8 q; + u8 p; + u16 pqinst; // bit of instruction specifying index (srec only) +}; + +void SuperVUAnalyzeOp(VURegs *VU, _vuopinfo *info, _VURegsNum* pCodeRegs); +int eeVURecompileCode(VURegs *VU, _VURegsNum* regs); // allocates all the necessary regs and returns the indices +void VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr); // used for MTGS in XGKICK + +extern int vucycle; +typedef void (*vFloat)(int regd, int regTemp); +extern vFloat vFloats1[16]; +extern vFloat vFloats1_useEAX[16]; +extern vFloat vFloats2[16]; +extern vFloat vFloats4[16]; +extern vFloat vFloats4_useEAX[16]; +PCSX2_ALIGNED16_EXTERN(const float s_fones[8]); +PCSX2_ALIGNED16_EXTERN(const u32 s_mask[4]); +PCSX2_ALIGNED16_EXTERN(const u32 s_expmask[4]); +PCSX2_ALIGNED16_EXTERN(const u32 g_minvals[4]); +PCSX2_ALIGNED16_EXTERN(const u32 g_maxvals[4]); +PCSX2_ALIGNED16_EXTERN(const u32 const_clip[8]); + +u32 GetVIAddr(VURegs * VU, int reg, int read, int info); +int _vuGetTempXMMreg(int info); +void vuFloat(int info, int regd, int XYZW); +void vuFloat_useEAX(int regd, int regTemp, int XYZW); +void vuFloat2(int regd, int regTemp, int XYZW); +void vuFloat3(uptr x86ptr); +void vuFloat4(int regd, int regTemp, int XYZW); +void vuFloat4_useEAX(int regd, int regTemp, int XYZW); +void vuFloat5(int regd, int regTemp, int XYZW); +void vuFloat5_useEAX(int regd, int regTemp, int XYZW); +void _vuFlipRegSS(VURegs * VU, int reg); +void _vuFlipRegSS_xyzw(int reg, int xyzw); +void _vuMoveSS(VURegs * VU, int dstreg, int srcreg); +void _unpackVF_xyzw(int dstreg, int srcreg, int xyzw); +void _unpackVFSS_xyzw(int dstreg, int srcreg, int xyzw); +void VU_MERGE_REGS_CUSTOM(int dest, int src, int xyzw); +void VU_MERGE_REGS_SAFE(int dest, int src, int xyzw); +#define VU_MERGE_REGS(dest, src) { \ + VU_MERGE_REGS_CUSTOM(dest, src, _X_Y_Z_W); \ +} + +// use for allocating vi regs +#define ALLOCTEMPX86(mode) _allocX86reg(-1, X86TYPE_TEMP, 0, ((info&PROCESS_VU_SUPER)?0:MODE_NOFRAME)|mode) +#define ALLOCVI(vi, mode) _allocX86reg(-1, X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), vi, ((info&PROCESS_VU_SUPER)?0:MODE_NOFRAME)|mode) +#define ADD_VI_NEEDED(vi) _addNeededX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), vi); + +#define SWAP(x, y) *(u32*)&y ^= *(u32*)&x ^= *(u32*)&y ^= *(u32*)&x; + +/***************************************** + VU Micromode Upper instructions +*****************************************/ + +void recVUMI_ABS(VURegs *vuRegs, int info); +void recVUMI_ADD(VURegs *vuRegs, int info); +void recVUMI_ADDi(VURegs *vuRegs, int info); +void recVUMI_ADDq(VURegs *vuRegs, int info); +void recVUMI_ADDx(VURegs *vuRegs, int info); +void recVUMI_ADDy(VURegs *vuRegs, int info); +void recVUMI_ADDz(VURegs *vuRegs, int info); +void recVUMI_ADDw(VURegs *vuRegs, int info); +void recVUMI_ADDA(VURegs *vuRegs, int info); +void recVUMI_ADDAi(VURegs *vuRegs, int info); +void recVUMI_ADDAq(VURegs *vuRegs, int info); +void recVUMI_ADDAx(VURegs *vuRegs, int info); +void recVUMI_ADDAy(VURegs *vuRegs, int info); +void recVUMI_ADDAz(VURegs *vuRegs, int info); +void recVUMI_ADDAw(VURegs *vuRegs, int info); +void recVUMI_SUB(VURegs *vuRegs, int info); +void recVUMI_SUBi(VURegs *vuRegs, int info); +void recVUMI_SUBq(VURegs *vuRegs, int info); +void recVUMI_SUBx(VURegs *vuRegs, int info); +void recVUMI_SUBy(VURegs *vuRegs, int info); +void recVUMI_SUBz(VURegs *vuRegs, int info); +void recVUMI_SUBw(VURegs *vuRegs, int info); +void recVUMI_SUBA(VURegs *vuRegs, int info); +void recVUMI_SUBAi(VURegs *vuRegs, int info); +void recVUMI_SUBAq(VURegs *vuRegs, int info); +void recVUMI_SUBAx(VURegs *vuRegs, int info); +void recVUMI_SUBAy(VURegs *vuRegs, int info); +void recVUMI_SUBAz(VURegs *vuRegs, int info); +void recVUMI_SUBAw(VURegs *vuRegs, int info); +void recVUMI_MUL(VURegs *vuRegs, int info); +void recVUMI_MULi(VURegs *vuRegs, int info); +void recVUMI_MULq(VURegs *vuRegs, int info); +void recVUMI_MULx(VURegs *vuRegs, int info); +void recVUMI_MULy(VURegs *vuRegs, int info); +void recVUMI_MULz(VURegs *vuRegs, int info); +void recVUMI_MULw(VURegs *vuRegs, int info); +void recVUMI_MULA(VURegs *vuRegs, int info); +void recVUMI_MULAi(VURegs *vuRegs, int info); +void recVUMI_MULAq(VURegs *vuRegs, int info); +void recVUMI_MULAx(VURegs *vuRegs, int info); +void recVUMI_MULAy(VURegs *vuRegs, int info); +void recVUMI_MULAz(VURegs *vuRegs, int info); +void recVUMI_MULAw(VURegs *vuRegs, int info); +void recVUMI_MADD(VURegs *vuRegs, int info); +void recVUMI_MADDi(VURegs *vuRegs, int info); +void recVUMI_MADDq(VURegs *vuRegs, int info); +void recVUMI_MADDx(VURegs *vuRegs, int info); +void recVUMI_MADDy(VURegs *vuRegs, int info); +void recVUMI_MADDz(VURegs *vuRegs, int info); +void recVUMI_MADDw(VURegs *vuRegs, int info); +void recVUMI_MADDA(VURegs *vuRegs, int info); +void recVUMI_MADDAi(VURegs *vuRegs, int info); +void recVUMI_MADDAq(VURegs *vuRegs, int info); +void recVUMI_MADDAx(VURegs *vuRegs, int info); +void recVUMI_MADDAy(VURegs *vuRegs, int info); +void recVUMI_MADDAz(VURegs *vuRegs, int info); +void recVUMI_MADDAw(VURegs *vuRegs, int info); +void recVUMI_MSUB(VURegs *vuRegs, int info); +void recVUMI_MSUBi(VURegs *vuRegs, int info); +void recVUMI_MSUBq(VURegs *vuRegs, int info); +void recVUMI_MSUBx(VURegs *vuRegs, int info); +void recVUMI_MSUBy(VURegs *vuRegs, int info); +void recVUMI_MSUBz(VURegs *vuRegs, int info); +void recVUMI_MSUBw(VURegs *vuRegs, int info); +void recVUMI_MSUBA(VURegs *vuRegs, int info); +void recVUMI_MSUBAi(VURegs *vuRegs, int info); +void recVUMI_MSUBAq(VURegs *vuRegs, int info); +void recVUMI_MSUBAx(VURegs *vuRegs, int info); +void recVUMI_MSUBAy(VURegs *vuRegs, int info); +void recVUMI_MSUBAz(VURegs *vuRegs, int info); +void recVUMI_MSUBAw(VURegs *vuRegs, int info); +void recVUMI_MAX(VURegs *vuRegs, int info); +void recVUMI_MAXi(VURegs *vuRegs, int info); +void recVUMI_MAXx(VURegs *vuRegs, int info); +void recVUMI_MAXy(VURegs *vuRegs, int info); +void recVUMI_MAXz(VURegs *vuRegs, int info); +void recVUMI_MAXw(VURegs *vuRegs, int info); +void recVUMI_MINI(VURegs *vuRegs, int info); +void recVUMI_MINIi(VURegs *vuRegs, int info); +void recVUMI_MINIx(VURegs *vuRegs, int info); +void recVUMI_MINIy(VURegs *vuRegs, int info); +void recVUMI_MINIz(VURegs *vuRegs, int info); +void recVUMI_MINIw(VURegs *vuRegs, int info); +void recVUMI_OPMULA(VURegs *vuRegs, int info); +void recVUMI_OPMSUB(VURegs *vuRegs, int info); +void recVUMI_NOP(VURegs *vuRegs, int info); +void recVUMI_FTOI0(VURegs *vuRegs, int info); +void recVUMI_FTOI4(VURegs *vuRegs, int info); +void recVUMI_FTOI12(VURegs *vuRegs, int info); +void recVUMI_FTOI15(VURegs *vuRegs, int info); +void recVUMI_ITOF0(VURegs *vuRegs, int info); +void recVUMI_ITOF4(VURegs *vuRegs, int info); +void recVUMI_ITOF12(VURegs *vuRegs, int info); +void recVUMI_ITOF15(VURegs *vuRegs, int info); +void recVUMI_CLIP(VURegs *vuRegs, int info); + +/***************************************** + VU Micromode Lower instructions +*****************************************/ + +void recVUMI_DIV(VURegs *vuRegs, int info); +void recVUMI_SQRT(VURegs *vuRegs, int info); +void recVUMI_RSQRT(VURegs *vuRegs, int info); +void recVUMI_IADD(VURegs *vuRegs, int info); +void recVUMI_IADDI(VURegs *vuRegs, int info); +void recVUMI_IADDIU(VURegs *vuRegs, int info); +void recVUMI_IAND(VURegs *vuRegs, int info); +void recVUMI_IOR(VURegs *vuRegs, int info); +void recVUMI_ISUB(VURegs *vuRegs, int info); +void recVUMI_ISUBIU(VURegs *vuRegs, int info); +void recVUMI_MOVE(VURegs *vuRegs, int info); +void recVUMI_MFIR(VURegs *vuRegs, int info); +void recVUMI_MTIR(VURegs *vuRegs, int info); +void recVUMI_MR32(VURegs *vuRegs, int info); +void recVUMI_LQ(VURegs *vuRegs, int info); +void recVUMI_LQD(VURegs *vuRegs, int info); +void recVUMI_LQI(VURegs *vuRegs, int info); +void recVUMI_SQ(VURegs *vuRegs, int info); +void recVUMI_SQD(VURegs *vuRegs, int info); +void recVUMI_SQI(VURegs *vuRegs, int info); +void recVUMI_ILW(VURegs *vuRegs, int info); +void recVUMI_ISW(VURegs *vuRegs, int info); +void recVUMI_ILWR(VURegs *vuRegs, int info); +void recVUMI_ISWR(VURegs *vuRegs, int info); +void recVUMI_LOI(VURegs *vuRegs, int info); +void recVUMI_RINIT(VURegs *vuRegs, int info); +void recVUMI_RGET(VURegs *vuRegs, int info); +void recVUMI_RNEXT(VURegs *vuRegs, int info); +void recVUMI_RXOR(VURegs *vuRegs, int info); +void recVUMI_WAITQ(VURegs *vuRegs, int info); +void recVUMI_FSAND(VURegs *vuRegs, int info); +void recVUMI_FSEQ(VURegs *vuRegs, int info); +void recVUMI_FSOR(VURegs *vuRegs, int info); +void recVUMI_FSSET(VURegs *vuRegs, int info); +void recVUMI_FMAND(VURegs *vuRegs, int info); +void recVUMI_FMEQ(VURegs *vuRegs, int info); +void recVUMI_FMOR(VURegs *vuRegs, int info); +void recVUMI_FCAND(VURegs *vuRegs, int info); +void recVUMI_FCEQ(VURegs *vuRegs, int info); +void recVUMI_FCOR(VURegs *vuRegs, int info); +void recVUMI_FCSET(VURegs *vuRegs, int info); +void recVUMI_FCGET(VURegs *vuRegs, int info); +void recVUMI_IBEQ(VURegs *vuRegs, int info); +void recVUMI_IBGEZ(VURegs *vuRegs, int info); +void recVUMI_IBGTZ(VURegs *vuRegs, int info); +void recVUMI_IBLTZ(VURegs *vuRegs, int info); +void recVUMI_IBLEZ(VURegs *vuRegs, int info); +void recVUMI_IBNE(VURegs *vuRegs, int info); +void recVUMI_B(VURegs *vuRegs, int info); +void recVUMI_BAL(VURegs *vuRegs, int info); +void recVUMI_JR(VURegs *vuRegs, int info); +void recVUMI_JALR(VURegs *vuRegs, int info); +void recVUMI_MFP(VURegs *vuRegs, int info); +void recVUMI_WAITP(VURegs *vuRegs, int info); +void recVUMI_ESADD(VURegs *vuRegs, int info); +void recVUMI_ERSADD(VURegs *vuRegs, int info); +void recVUMI_ELENG(VURegs *vuRegs, int info); +void recVUMI_ERLENG(VURegs *vuRegs, int info); +void recVUMI_EATANxy(VURegs *vuRegs, int info); +void recVUMI_EATANxz(VURegs *vuRegs, int info); +void recVUMI_ESUM(VURegs *vuRegs, int info); +void recVUMI_ERCPR(VURegs *vuRegs, int info); +void recVUMI_ESQRT(VURegs *vuRegs, int info); +void recVUMI_ERSQRT(VURegs *vuRegs, int info); +void recVUMI_ESIN(VURegs *vuRegs, int info); +void recVUMI_EATAN(VURegs *vuRegs, int info); +void recVUMI_EEXP(VURegs *vuRegs, int info); +void recVUMI_XGKICK(VURegs *vuRegs, int info); +void recVUMI_XTOP(VURegs *vuRegs, int info); +void recVUMI_XITOP(VURegs *vuRegs, int info); +void recVUMI_XTOP( VURegs *VU , int info); + diff --git a/pcsx2/x86/iVUmicroUpper.cpp b/pcsx2/x86/sVU_Upper.cpp similarity index 97% rename from pcsx2/x86/iVUmicroUpper.cpp rename to pcsx2/x86/sVU_Upper.cpp index 61393c43fe..6e06ccdf08 100644 --- a/pcsx2/x86/iVUmicroUpper.cpp +++ b/pcsx2/x86/sVU_Upper.cpp @@ -1,3070 +1,3070 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "PrecompiledHeader.h" - -#include "Common.h" -#include "GS.h" -#include "R5900OpcodeTables.h" -#include "iR5900.h" -#include "iMMI.h" -#include "iFPU.h" -#include "iCOP0.h" -#include "VUmicro.h" -#include "VUflags.h" -#include "iVUmicro.h" -#include "iVUops.h" -#include "iVUzerorec.h" -//------------------------------------------------------------------ -#define MINMAXFIX 1 -//------------------------------------------------------------------ -// Helper Macros -//------------------------------------------------------------------ -#define _Ft_ (( VU->code >> 16) & 0x1F) // The rt part of the instruction register -#define _Fs_ (( VU->code >> 11) & 0x1F) // The rd part of the instruction register -#define _Fd_ (( VU->code >> 6) & 0x1F) // The sa part of the instruction register - -#define _X (( VU->code>>24) & 0x1) -#define _Y (( VU->code>>23) & 0x1) -#define _Z (( VU->code>>22) & 0x1) -#define _W (( VU->code>>21) & 0x1) - -#define _XYZW_SS (_X+_Y+_Z+_W==1) - -#define _Fsf_ (( VU->code >> 21) & 0x03) -#define _Ftf_ (( VU->code >> 23) & 0x03) - -#define _Imm11_ (s32)(VU->code & 0x400 ? 0xfffffc00 | (VU->code & 0x3ff) : VU->code & 0x3ff) -#define _UImm11_ (s32)(VU->code & 0x7ff) - -#define VU_VFx_ADDR(x) (uptr)&VU->VF[x].UL[0] -#define VU_VFy_ADDR(x) (uptr)&VU->VF[x].UL[1] -#define VU_VFz_ADDR(x) (uptr)&VU->VF[x].UL[2] -#define VU_VFw_ADDR(x) (uptr)&VU->VF[x].UL[3] - -#define VU_REGR_ADDR (uptr)&VU->VI[REG_R] -#define VU_REGQ_ADDR (uptr)&VU->VI[REG_Q] -#define VU_REGMAC_ADDR (uptr)&VU->VI[REG_MAC_FLAG] - -#define VU_VI_ADDR(x, read) GetVIAddr(VU, x, read, info) - -#define VU_ACCx_ADDR (uptr)&VU->ACC.UL[0] -#define VU_ACCy_ADDR (uptr)&VU->ACC.UL[1] -#define VU_ACCz_ADDR (uptr)&VU->ACC.UL[2] -#define VU_ACCw_ADDR (uptr)&VU->ACC.UL[3] - -#define _X_Y_Z_W ((( VU->code >> 21 ) & 0xF ) ) -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// Global Variables -//------------------------------------------------------------------ -static const PCSX2_ALIGNED16(int SSEmovMask[ 16 ][ 4 ]) = -{ - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF }, - { 0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000 }, - { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000 }, - { 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF }, - { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }, - { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }, - { 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000 }, - { 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 }, - { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }, - { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF } -}; - -static const PCSX2_ALIGNED16(u32 const_abs_table[16][4]) = -{ - { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }, //0000 - { 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff }, //0001 - { 0xffffffff, 0xffffffff, 0x7fffffff, 0xffffffff }, //0010 - { 0xffffffff, 0xffffffff, 0x7fffffff, 0x7fffffff }, //0011 - { 0xffffffff, 0x7fffffff, 0xffffffff, 0xffffffff }, //0100 - { 0xffffffff, 0x7fffffff, 0xffffffff, 0x7fffffff }, //0101 - { 0xffffffff, 0x7fffffff, 0x7fffffff, 0xffffffff }, //0110 - { 0xffffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff }, //0111 - { 0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff }, //1000 - { 0x7fffffff, 0xffffffff, 0xffffffff, 0x7fffffff }, //1001 - { 0x7fffffff, 0xffffffff, 0x7fffffff, 0xffffffff }, //1010 - { 0x7fffffff, 0xffffffff, 0x7fffffff, 0x7fffffff }, //1011 - { 0x7fffffff, 0x7fffffff, 0xffffffff, 0xffffffff }, //1100 - { 0x7fffffff, 0x7fffffff, 0xffffffff, 0x7fffffff }, //1101 - { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0xffffffff }, //1110 - { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff }, //1111 -}; - -static const PCSX2_ALIGNED16(float recMult_float_to_int4[4]) = { 16.0, 16.0, 16.0, 16.0 }; -static const PCSX2_ALIGNED16(float recMult_float_to_int12[4]) = { 4096.0, 4096.0, 4096.0, 4096.0 }; -static const PCSX2_ALIGNED16(float recMult_float_to_int15[4]) = { 32768.0, 32768.0, 32768.0, 32768.0 }; - -static const PCSX2_ALIGNED16(float recMult_int_to_float4[4]) = { 0.0625f, 0.0625f, 0.0625f, 0.0625f }; -static const PCSX2_ALIGNED16(float recMult_int_to_float12[4]) = { 0.000244140625, 0.000244140625, 0.000244140625, 0.000244140625 }; -static const PCSX2_ALIGNED16(float recMult_int_to_float15[4]) = { 0.000030517578125, 0.000030517578125, 0.000030517578125, 0.000030517578125 }; - -static const PCSX2_ALIGNED16(u32 VU_Underflow_Mask1[4]) = {0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000}; -static const PCSX2_ALIGNED16(u32 VU_Underflow_Mask2[4]) = {0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff}; -static const PCSX2_ALIGNED16(u32 VU_Zero_Mask[4]) = {0x00000000, 0x00000000, 0x00000000, 0x00000000}; -static const PCSX2_ALIGNED16(u32 VU_Zero_Helper_Mask[4]) = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; -static const PCSX2_ALIGNED16(u32 VU_Signed_Zero_Mask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000}; -static const PCSX2_ALIGNED16(u32 VU_Pos_Infinity[4]) = {0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000}; -static const PCSX2_ALIGNED16(u32 VU_Neg_Infinity[4]) = {0xff800000, 0xff800000, 0xff800000, 0xff800000}; -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// recUpdateFlags() - Computes the flags for the Upper Opcodes -// -// Note: Computes under/overflow flags if CHECK_VU_EXTRA_FLAGS is 1 -//------------------------------------------------------------------ -PCSX2_ALIGNED16(u64 TEMPXMMData[2]); -void recUpdateFlags(VURegs * VU, int reg, int info) -{ - static u8 *pjmp, *pjmp2; - static u32 *pjmp32; - static u32 macaddr, stataddr, prevstataddr; - static int x86macflag, x86statflag, x86temp; - static int t1reg, t1regBoolean; - static const int flipMask[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}; - - if( !(info & PROCESS_VU_UPDATEFLAGS) ) { - if (CHECK_VU_EXTRA_OVERFLOW) { - if (reg != EEREC_TEMP) vuFloat2(reg, EEREC_TEMP, _X_Y_Z_W); - else vuFloat_useEAX(info, reg, _X_Y_Z_W); - } - return; - } - - //Console::WriteLn ("recUpdateFlags"); - - macaddr = VU_VI_ADDR(REG_MAC_FLAG, 0); - stataddr = VU_VI_ADDR(REG_STATUS_FLAG, 0); // write address - prevstataddr = VU_VI_ADDR(REG_STATUS_FLAG, 2); // previous address - - if( stataddr == 0 ) stataddr = prevstataddr; - if( macaddr == 0 ) { - Console::WriteLn( "VU ALLOCATION WARNING: Using Mac Flag Previous Address!" ); - macaddr = VU_VI_ADDR(REG_MAC_FLAG, 2); - } - - x86macflag = ALLOCTEMPX86(0); - x86statflag = ALLOCTEMPX86(0); - - if (reg == EEREC_TEMP) { - t1reg = _vuGetTempXMMreg(info); - if (t1reg < 0) { - //Console::WriteLn( "VU ALLOCATION ERROR: Temp reg can't be allocated!!!!" ); - t1reg = (reg == 0) ? 1 : 0; // Make t1reg != reg - SSE_MOVAPS_XMM_to_M128( (uptr)TEMPXMMData, t1reg ); // Backup data to temp address - t1regBoolean = 1; - } - else t1regBoolean = 0; - } - else { - t1reg = EEREC_TEMP; - t1regBoolean = 2; - } - - SSE_SHUFPS_XMM_to_XMM(reg, reg, 0x1B); // Flip wzyx to xyzw - MOV32MtoR(x86statflag, prevstataddr); // Load the previous status in to x86statflag - AND16ItoR(x86statflag, 0xff0); // Keep Sticky and D/I flags - - - if (CHECK_VU_EXTRA_FLAGS) { // Checks all flags - - x86temp = ALLOCTEMPX86(0); - - //-------------------------Check for Overflow flags------------------------------ - - //SSE_XORPS_XMM_to_XMM(t1reg, t1reg); // Clear t1reg - //SSE_CMPUNORDPS_XMM_to_XMM(t1reg, reg); // If reg == NaN then set Vector to 0xFFFFFFFF - - //SSE_MOVAPS_XMM_to_XMM(t1reg, reg); - //SSE_MINPS_M128_to_XMM(t1reg, (uptr)g_maxvals); - //SSE_MAXPS_M128_to_XMM(t1reg, (uptr)g_minvals); - //SSE_CMPNEPS_XMM_to_XMM(t1reg, reg); // If they're not equal, then overflow has occured - - SSE_MOVAPS_XMM_to_XMM(t1reg, reg); - SSE_ANDPS_M128_to_XMM(t1reg, (uptr)VU_Zero_Helper_Mask); - SSE_CMPEQPS_M128_to_XMM(t1reg, (uptr)VU_Pos_Infinity); // If infinity, then overflow has occured (NaN's don't report as overflow) - - SSE_MOVMSKPS_XMM_to_R32(x86macflag, t1reg); // Move the sign bits of the previous calculation - - AND16ItoR(x86macflag, _X_Y_Z_W ); // Grab "Has Overflowed" bits from the previous calculation (also make sure we're only grabbing from the XYZW being modified) - pjmp = JZ8(0); // Skip if none are - OR16ItoR(x86statflag, 0x208); // OS, O flags - SHL16ItoR(x86macflag, 12); - if (_XYZW_SS) pjmp32 = JMP32(0); // Skip Underflow Check - x86SetJ8(pjmp); - - //-------------------------Check for Underflow flags------------------------------ - - SSE_MOVAPS_XMM_to_XMM(t1reg, reg); // t1reg <- reg - - SSE_ANDPS_M128_to_XMM(t1reg, (uptr)&VU_Underflow_Mask1[ 0 ]); - SSE_CMPEQPS_M128_to_XMM(t1reg, (uptr)&VU_Zero_Mask[ 0 ]); // If (t1reg == zero exponent) then set Vector to 0xFFFFFFFF - - SSE_ANDPS_XMM_to_XMM(t1reg, reg); - SSE_ANDPS_M128_to_XMM(t1reg, (uptr)&VU_Underflow_Mask2[ 0 ]); - SSE_CMPNEPS_M128_to_XMM(t1reg, (uptr)&VU_Zero_Mask[ 0 ]); // If (t1reg != zero mantisa) then set Vector to 0xFFFFFFFF - - SSE_MOVMSKPS_XMM_to_R32(EAX, t1reg); // Move the sign bits of the previous calculation - - AND16ItoR(EAX, _X_Y_Z_W ); // Grab "Has Underflowed" bits from the previous calculation - pjmp = JZ8(0); // Skip if none are - OR16ItoR(x86statflag, 0x104); // US, U flags - SHL16ItoR(EAX, 8); - OR32RtoR(x86macflag, EAX); - x86SetJ8(pjmp); - - //-------------------------Optional Code: Denormals Are Zero------------------------------ - if (CHECK_VU_UNDERFLOW) { // Sets underflow/denormals to zero - SSE_ANDNPS_XMM_to_XMM(t1reg, reg); // t1reg = !t1reg & reg (t1reg = denormals are positive zero) - VU_MERGE_REGS_SAFE(t1reg, reg, (15 - flipMask[_X_Y_Z_W])); // Send t1reg the vectors that shouldn't be modified (since reg was flipped, we need a mask to get the unmodified vectors) - // Now we have Denormals are Positive Zero in t1reg; the next two lines take Signed Zero into account - SSE_ANDPS_M128_to_XMM(reg, (uptr)&VU_Signed_Zero_Mask[ 0 ]); // Only keep the sign bit for each vector - SSE_ORPS_XMM_to_XMM(reg, t1reg); // Denormals are Signed Zero, and unmodified vectors stay the same! - } - - if (_XYZW_SS) x86SetJ32(pjmp32); // If we skipped the Underflow Flag Checking (when we had an Overflow), return here - - vuFloat2(reg, t1reg, flipMask[_X_Y_Z_W]); // Clamp overflowed vectors that were modified (remember reg's vectors have been flipped, so have to use a flipmask) - - //-------------------------Check for Signed flags------------------------------ - - // The following code makes sure the Signed Bit isn't set with Negative Zero - SSE_XORPS_XMM_to_XMM(t1reg, t1reg); // Clear t1reg - SSE_CMPEQPS_XMM_to_XMM(t1reg, reg); // Set all F's if each vector is zero - SSE_MOVMSKPS_XMM_to_R32(x86temp, t1reg); // Used for Zero Flag Calculation - SSE_ANDNPS_XMM_to_XMM(t1reg, reg); - - SSE_MOVMSKPS_XMM_to_R32(EAX, t1reg); // Move the sign bits of the t1reg - - AND16ItoR(EAX, _X_Y_Z_W ); // Grab "Is Signed" bits from the previous calculation - pjmp = JZ8(0); // Skip if none are - OR16ItoR(x86statflag, 0x82); // SS, S flags - SHL16ItoR(EAX, 4); - OR32RtoR(x86macflag, EAX); - if (_XYZW_SS) pjmp2 = JMP8(0); // If negative and not Zero, we can skip the Zero Flag checking - x86SetJ8(pjmp); - - //-------------------------Check for Zero flags------------------------------ - - AND16ItoR(x86temp, _X_Y_Z_W ); // Grab "Is Zero" bits from the previous calculation - pjmp = JZ8(0); // Skip if none are - OR16ItoR(x86statflag, 0x41); // ZS, Z flags - OR32RtoR(x86macflag, x86temp); - x86SetJ8(pjmp); - - _freeX86reg(x86temp); - } - else { // Only Checks for Sign and Zero Flags - - vuFloat2(reg, t1reg, flipMask[_X_Y_Z_W]); // Clamp overflowed vectors that were modified (remember reg's vectors have been flipped, so have to use a flipmask) - - //-------------------------Check for Signed flags------------------------------ - - // The following code makes sure the Signed Bit isn't set with Negative Zero - SSE_XORPS_XMM_to_XMM(t1reg, t1reg); // Clear t1reg - SSE_CMPEQPS_XMM_to_XMM(t1reg, reg); // Set all F's if each vector is zero - SSE_MOVMSKPS_XMM_to_R32(EAX, t1reg); // Used for Zero Flag Calculation - SSE_ANDNPS_XMM_to_XMM(t1reg, reg); - - SSE_MOVMSKPS_XMM_to_R32(x86macflag, t1reg); // Move the sign bits of the t1reg - - AND16ItoR(x86macflag, _X_Y_Z_W ); // Grab "Is Signed" bits from the previous calculation - pjmp = JZ8(0); // Skip if none are - OR16ItoR(x86statflag, 0x82); // SS, S flags - SHL16ItoR(x86macflag, 4); - if (_XYZW_SS) pjmp2 = JMP8(0); // If negative and not Zero, we can skip the Zero Flag checking - x86SetJ8(pjmp); - - //-------------------------Check for Zero flags------------------------------ - - AND16ItoR(EAX, _X_Y_Z_W ); // Grab "Is Zero" bits from the previous calculation - pjmp = JZ8(0); // Skip if none are - OR16ItoR(x86statflag, 0x41); // ZS, Z flags - OR32RtoR(x86macflag, EAX); - x86SetJ8(pjmp); - } - //-------------------------Finally: Send the Flags to the Mac Flag Address------------------------------ - - if (_XYZW_SS) x86SetJ8(pjmp2); // If we skipped the Zero Flag Checking, return here - - if (t1regBoolean == 2) SSE_SHUFPS_XMM_to_XMM(reg, reg, 0x1B); // Flip back reg to wzyx (have to do this because reg != EEREC_TEMP) - else if (t1regBoolean == 1) SSE_MOVAPS_M128_to_XMM( t1reg, (uptr)TEMPXMMData ); // Restore data from temo address - else _freeXMMreg(t1reg); // Free temp reg - - MOV16RtoM(macaddr, x86macflag); - MOV16RtoM(stataddr, x86statflag); - - _freeX86reg(x86macflag); - _freeX86reg(x86statflag); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// Custom VU ADD/SUB routines by Nneeve -// -// Note: See FPU_ADD_SUB() for more info on what this is doing. -//------------------------------------------------------------------ -static PCSX2_ALIGNED16(u32 VU_addsuband[2][4]); -static PCSX2_ALIGNED16(u32 VU_addsub_reg[2][4]); - -static u32 tempECX; - -void VU_ADD_SUB(u32 regd, u32 regt, int is_sub, int info) -{ - u8 *localptr[4][8]; - - MOV32RtoM((uptr)&tempECX, ECX); - - int temp1 = ECX; //receives regd - int temp2 = ALLOCTEMPX86(0); - - if (temp2 == ECX) - { - temp2 = ALLOCTEMPX86(0); - _freeX86reg(ECX); - } - - SSE_MOVAPS_XMM_to_M128((uptr)&VU_addsub_reg[0][0], regd); - SSE_MOVAPS_XMM_to_M128((uptr)&VU_addsub_reg[1][0], regt); - - SSE2_PCMPEQB_XMM_to_XMM(regd, regd); - SSE_MOVAPS_XMM_to_M128((uptr)&VU_addsuband[0][0], regd); - SSE_MOVAPS_XMM_to_M128((uptr)&VU_addsuband[1][0], regd); - SSE_MOVAPS_M128_to_XMM(regd, (uptr)&VU_addsub_reg[0][0]); - - SSE2_PSLLD_I8_to_XMM(regd, 1); - SSE2_PSLLD_I8_to_XMM(regt, 1); - - SSE2_PSRLD_I8_to_XMM(regd, 24); - SSE2_PSRLD_I8_to_XMM(regt, 24); - - SSE2_PSUBD_XMM_to_XMM(regd, regt); - -#define PERFORM(i) \ - \ - SSE_PEXTRW_XMM_to_R32(temp1, regd, i*2); \ - MOVSX32R16toR(temp1, temp1); \ - CMP32ItoR(temp1, 25);\ - localptr[i][0] = JGE8(0);\ - CMP32ItoR(temp1, 0);\ - localptr[i][1] = JG8(0);\ - localptr[i][2] = JE8(0);\ - CMP32ItoR(temp1, -25);\ - localptr[i][3] = JLE8(0);\ - \ - NEG32R(temp1); \ - DEC32R(temp1);\ - MOV32ItoR(temp2, 0xffffffff); \ - SHL32CLtoR(temp2); \ - MOV32RtoM((uptr)&VU_addsuband[0][i], temp2);\ - localptr[i][4] = JMP8(0);\ - \ - x86SetJ8(localptr[i][0]);\ - MOV32ItoM((uptr)&VU_addsuband[1][i], 0x80000000);\ - localptr[i][5] = JMP8(0);\ - \ - x86SetJ8(localptr[i][1]);\ - DEC32R(temp1);\ - MOV32ItoR(temp2, 0xffffffff);\ - SHL32CLtoR(temp2); \ - MOV32RtoM((uptr)&VU_addsuband[1][i], temp2);\ - localptr[i][6] = JMP8(0);\ - \ - x86SetJ8(localptr[i][3]);\ - MOV32ItoM((uptr)&VU_addsuband[0][i], 0x80000000);\ - localptr[i][7] = JMP8(0);\ - \ - x86SetJ8(localptr[i][2]);\ - \ - x86SetJ8(localptr[i][4]);\ - x86SetJ8(localptr[i][5]);\ - x86SetJ8(localptr[i][6]);\ - x86SetJ8(localptr[i][7]); - - PERFORM(0); - PERFORM(1); - PERFORM(2); - PERFORM(3); -#undef PERFORM - - SSE_MOVAPS_M128_to_XMM(regd, (uptr)&VU_addsub_reg[0][0]); - SSE_MOVAPS_M128_to_XMM(regt, (uptr)&VU_addsub_reg[1][0]); - - SSE_ANDPS_M128_to_XMM(regd, (uptr)&VU_addsuband[0][0]); - SSE_ANDPS_M128_to_XMM(regt, (uptr)&VU_addsuband[1][0]); - - if (is_sub) SSE_SUBPS_XMM_to_XMM(regd, regt); - else SSE_ADDPS_XMM_to_XMM(regd, regt); - - SSE_MOVAPS_M128_to_XMM(regt, (uptr)&VU_addsub_reg[1][0]); - - _freeX86reg(temp2); - - MOV32MtoR(ECX, (uptr)&tempECX); -} - -void VU_ADD_SUB_SS(u32 regd, u32 regt, int is_sub, int is_mem, int info) -{ - u8 *localptr[8]; - u32 addrt = regt; //for case is_mem - - MOV32RtoM((uptr)&tempECX, ECX); - - int temp1 = ECX; //receives regd - int temp2 = ALLOCTEMPX86(0); - - if (temp2 == ECX) - { - temp2 = ALLOCTEMPX86(0); - _freeX86reg(ECX); - } - - SSE_MOVAPS_XMM_to_M128((uptr)&VU_addsub_reg[0][0], regd); - if (!is_mem) SSE_MOVAPS_XMM_to_M128((uptr)&VU_addsub_reg[1][0], regt); - - SSE2_MOVD_XMM_to_R(temp1, regd); - SHR32ItoR(temp1, 23); - - if (is_mem) { - MOV32MtoR(temp2, addrt); - MOV32RtoM((uptr)&VU_addsub_reg[1][0], temp2); - SHR32ItoR(temp2, 23); - } - else { - SSE2_MOVD_XMM_to_R(temp2, regt); - SHR32ItoR(temp2, 23); - } - - AND32ItoR(temp1, 0xff); - AND32ItoR(temp2, 0xff); - - SUB32RtoR(temp1, temp2); //temp1 = exponent difference - - CMP32ItoR(temp1, 25); - localptr[0] = JGE8(0); - CMP32ItoR(temp1, 0); - localptr[1] = JG8(0); - localptr[2] = JE8(0); - CMP32ItoR(temp1, -25); - localptr[3] = JLE8(0); - - NEG32R(temp1); - DEC32R(temp1); - MOV32ItoR(temp2, 0xffffffff); - SHL32CLtoR(temp2); - SSE2_PCMPEQB_XMM_to_XMM(regd, regd); - if (is_mem) { - SSE_PINSRW_R32_to_XMM(regd, temp2, 0); - SHR32ItoR(temp2, 16); - SSE_PINSRW_R32_to_XMM(regd, temp2, 1); - } - else { - SSE2_MOVD_R_to_XMM(regt, temp2); - SSE_MOVSS_XMM_to_XMM(regd, regt); - SSE2_PCMPEQB_XMM_to_XMM(regt, regt); - } - localptr[4] = JMP8(0); - - x86SetJ8(localptr[0]); - MOV32ItoR(temp2, 0x80000000); - if (is_mem) - AND32RtoM((uptr)&VU_addsub_reg[1][0], temp2); - else { - SSE2_PCMPEQB_XMM_to_XMM(regt, regt); - SSE2_MOVD_R_to_XMM(regd, temp2); - SSE_MOVSS_XMM_to_XMM(regt, regd); - } - SSE2_PCMPEQB_XMM_to_XMM(regd, regd); - localptr[5] = JMP8(0); - - x86SetJ8(localptr[1]); - DEC32R(temp1); - MOV32ItoR(temp2, 0xffffffff); - SHL32CLtoR(temp2); - if (is_mem) - AND32RtoM((uptr)&VU_addsub_reg[1][0], temp2); - else { - SSE2_PCMPEQB_XMM_to_XMM(regt, regt); - SSE2_MOVD_R_to_XMM(regd, temp2); - SSE_MOVSS_XMM_to_XMM(regt, regd); - } - SSE2_PCMPEQB_XMM_to_XMM(regd, regd); - localptr[6] = JMP8(0); - - x86SetJ8(localptr[3]); - MOV32ItoR(temp2, 0x80000000); - SSE2_PCMPEQB_XMM_to_XMM(regd, regd); - if (is_mem) { - SSE_PINSRW_R32_to_XMM(regd, temp2, 0); - SHR32ItoR(temp2, 16); - SSE_PINSRW_R32_to_XMM(regd, temp2, 1); - } - else { - SSE2_MOVD_R_to_XMM(regt, temp2); - SSE_MOVSS_XMM_to_XMM(regd, regt); - SSE2_PCMPEQB_XMM_to_XMM(regt, regt); - } - localptr[7] = JMP8(0); - - x86SetJ8(localptr[2]); - x86SetJ8(localptr[4]); - x86SetJ8(localptr[5]); - x86SetJ8(localptr[6]); - x86SetJ8(localptr[7]); - - if (is_mem) - { - SSE_ANDPS_M128_to_XMM(regd, (uptr)&VU_addsub_reg[0][0]); //regd contains mask - - if (is_sub) SSE_SUBSS_M32_to_XMM(regd, (uptr)&VU_addsub_reg[1][0]); - else SSE_ADDSS_M32_to_XMM(regd, (uptr)&VU_addsub_reg[1][0]); - } - else - { - SSE_ANDPS_M128_to_XMM(regd, (uptr)&VU_addsub_reg[0][0]); //regd contains mask - SSE_ANDPS_M128_to_XMM(regt, (uptr)&VU_addsub_reg[1][0]); //regt contains mask - - if (is_sub) SSE_SUBSS_XMM_to_XMM(regd, regt); - else SSE_ADDSS_XMM_to_XMM(regd, regt); - - SSE_MOVAPS_M128_to_XMM(regt, (uptr)&VU_addsub_reg[1][0]); - } - - _freeX86reg(temp2); - - MOV32MtoR(ECX, (uptr)&tempECX); -} - -void SSE_ADDPS_XMM_to_XMM_custom(int info, int regd, int regt) { - if (CHECK_VUADDSUBHACK) { - VU_ADD_SUB(regd, regt, 0, info); - } - else SSE_ADDPS_XMM_to_XMM(regd, regt); -} -void SSE_SUBPS_XMM_to_XMM_custom(int info, int regd, int regt) { - if (CHECK_VUADDSUBHACK) { - VU_ADD_SUB(regd, regt, 1, info); - } - else SSE_SUBPS_XMM_to_XMM(regd, regt); -} -void SSE_ADDSS_XMM_to_XMM_custom(int info, int regd, int regt) { - if (CHECK_VUADDSUBHACK) { - VU_ADD_SUB_SS(regd, regt, 0, 0, info); - } - else SSE_ADDSS_XMM_to_XMM(regd, regt); -} -void SSE_SUBSS_XMM_to_XMM_custom(int info, int regd, int regt) { - if (CHECK_VUADDSUBHACK) { - VU_ADD_SUB_SS(regd, regt, 1, 0, info); - } - else SSE_SUBSS_XMM_to_XMM(regd, regt); -} -void SSE_ADDSS_M32_to_XMM_custom(int info, int regd, int regt) { - if (CHECK_VUADDSUBHACK) { - VU_ADD_SUB_SS(regd, regt, 0, 1, info); - } - else SSE_ADDSS_M32_to_XMM(regd, regt); -} -void SSE_SUBSS_M32_to_XMM_custom(int info, int regd, int regt) { - if (CHECK_VUADDSUBHACK) { - VU_ADD_SUB_SS(regd, regt, 1, 1, info); - } - else SSE_SUBSS_M32_to_XMM(regd, regt); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// *VU Upper Instructions!* -// -// Note: * = Checked for errors by cottonvibes -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ABS* -//------------------------------------------------------------------ -void recVUMI_ABS(VURegs *VU, int info) -{ - //Console::WriteLn("recVUMI_ABS()"); - if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; - - if ((_X_Y_Z_W == 0x8) || (_X_Y_Z_W == 0xf)) { - VU_MERGE_REGS(EEREC_T, EEREC_S); - SSE_ANDPS_M128_to_XMM(EEREC_T, (uptr)&const_abs_table[ _X_Y_Z_W ][ 0 ] ); - } - else { // Use a temp reg because VU_MERGE_REGS() modifies source reg! - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_abs_table[ _X_Y_Z_W ][ 0 ] ); - VU_MERGE_REGS(EEREC_T, EEREC_TEMP); - } -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ADD*, ADD_iq*, ADD_xyzw* -//------------------------------------------------------------------ -PCSX2_ALIGNED16(float s_two[4]) = {0,0,0,2}; -void recVUMI_ADD(VURegs *VU, int info) -{ - //Console::WriteLn("recVUMI_ADD()"); - if ( _X_Y_Z_W == 0 ) goto flagUpdate; // Don't do anything and just clear flags - if ( !_Fd_ ) info = (info & ~PROCESS_EE_SET_D(0xf)) | PROCESS_EE_SET_D(EEREC_TEMP); - - if ( _Fs_ == 0 && _Ft_ == 0 ) { // if adding VF00 with VF00, then the result is always 0,0,0,2 - if ( _X_Y_Z_W != 0xf ) { - SSE_MOVAPS_M128_to_XMM(EEREC_TEMP, (uptr)s_two); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else SSE_MOVAPS_M128_to_XMM(EEREC_D, (uptr)s_two); - } - else { - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); - } - if( _X_Y_Z_W == 8 ) { // If only adding x, then we can do a Scalar Add - if (EEREC_D == EEREC_S) SSE_ADDSS_XMM_to_XMM(EEREC_D, EEREC_T); - else if (EEREC_D == EEREC_T) SSE_ADDSS_XMM_to_XMM(EEREC_D, EEREC_S); - else { - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_ADDSS_XMM_to_XMM(EEREC_D, EEREC_T); - } - } - else if (_X_Y_Z_W != 0xf) { // If xyzw != 1111, then we have to use a temp reg - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else { // All xyzw being modified (xyzw == 1111) - if (EEREC_D == EEREC_S) SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_T); - else if (EEREC_D == EEREC_T) SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_T); - } - } - } -flagUpdate: - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_ADD_iq(VURegs *VU, uptr addr, int info) -{ - //Console::WriteLn("recVUMI_ADD_iq()"); - if ( _X_Y_Z_W == 0 ) goto flagUpdate; - if ( !_Fd_ ) info = (info & ~PROCESS_EE_SET_D(0xf)) | PROCESS_EE_SET_D(EEREC_TEMP); - if (CHECK_VU_EXTRA_OVERFLOW) { - vuFloat3(addr); - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - } - - if ( _XYZW_SS ) { - if ( EEREC_D == EEREC_TEMP ) { - _vuFlipRegSS(VU, EEREC_S); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_ADDSS_M32_to_XMM(EEREC_D, addr); - _vuFlipRegSS(VU, EEREC_S); - _vuFlipRegSS(VU, EEREC_D); // have to flip over EEREC_D for computing flags! - } - else if ( EEREC_D == EEREC_S ) { - _vuFlipRegSS(VU, EEREC_D); - SSE_ADDSS_M32_to_XMM(EEREC_D, addr); - _vuFlipRegSS(VU, EEREC_D); - } - else { - if ( _X ) { - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_ADDSS_M32_to_XMM_custom(info, EEREC_D, addr); - } - else { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - SSE_ADDPS_XMM_to_XMM_custom(info, EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - } - } - else { - if ( (_X_Y_Z_W != 0xf) || (EEREC_D == EEREC_S) || (EEREC_D == EEREC_TEMP) ) { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - } - - if (_X_Y_Z_W != 0xf) { - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else { - if ( EEREC_D == EEREC_TEMP ) SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); - else if ( EEREC_D == EEREC_S ) SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - else { - SSE_MOVSS_M32_to_XMM(EEREC_D, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_D, EEREC_D, 0x00); - SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); - } - } - } -flagUpdate: - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_ADD_xyzw(VURegs *VU, int xyzw, int info) -{ - //Console::WriteLn("recVUMI_ADD_xyzw()"); - if ( _X_Y_Z_W == 0 ) goto flagUpdate; - if ( !_Fd_ ) info = (info & ~PROCESS_EE_SET_D(0xf)) | PROCESS_EE_SET_D(EEREC_TEMP); - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); - } - - if ( _Ft_ == 0 && xyzw < 3 ) { // just move since adding zero - if ( _X_Y_Z_W == 0x8 ) { VU_MERGE_REGS(EEREC_D, EEREC_S); } - else if ( _X_Y_Z_W != 0xf ) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); - } - else if ( _X_Y_Z_W == 8 && (EEREC_D != EEREC_TEMP) ) { - if ( xyzw == 0 ) { - if ( EEREC_D == EEREC_T ) SSE_ADDSS_XMM_to_XMM(EEREC_D, EEREC_S); - else { - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_ADDSS_XMM_to_XMM(EEREC_D, EEREC_T); - } - } - else { - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_ADDSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - } - else if( _Fs_ == 0 && !_W ) { // just move - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else { - if ( _X_Y_Z_W != 0xf ) { - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else { - if( EEREC_D == EEREC_TEMP ) { _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); } - else if( EEREC_D == EEREC_S ) { _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); } - else { _unpackVF_xyzw(EEREC_D, EEREC_T, xyzw); SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); } - } - } -flagUpdate: - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_ADDi(VURegs *VU, int info) { recVUMI_ADD_iq(VU, VU_VI_ADDR(REG_I, 1), info); } -void recVUMI_ADDq(VURegs *VU, int info) { recVUMI_ADD_iq(VU, VU_REGQ_ADDR, info); } -void recVUMI_ADDx(VURegs *VU, int info) { recVUMI_ADD_xyzw(VU, 0, info); } -void recVUMI_ADDy(VURegs *VU, int info) { recVUMI_ADD_xyzw(VU, 1, info); } -void recVUMI_ADDz(VURegs *VU, int info) { recVUMI_ADD_xyzw(VU, 2, info); } -void recVUMI_ADDw(VURegs *VU, int info) { recVUMI_ADD_xyzw(VU, 3, info); } -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ADDA*, ADDA_iq*, ADDA_xyzw* -//------------------------------------------------------------------ -void recVUMI_ADDA(VURegs *VU, int info) -{ - //Console::WriteLn("recVUMI_ADDA()"); - if ( _X_Y_Z_W == 0 ) goto flagUpdate; - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); - } - - if( _X_Y_Z_W == 8 ) { - if (EEREC_ACC == EEREC_S) SSE_ADDSS_XMM_to_XMM(EEREC_ACC, EEREC_T); // Can this case happen? (cottonvibes) - else if (EEREC_ACC == EEREC_T) SSE_ADDSS_XMM_to_XMM(EEREC_ACC, EEREC_S); // Can this case happen? - else { - SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); - SSE_ADDSS_XMM_to_XMM(EEREC_ACC, EEREC_T); - } - } - else if (_X_Y_Z_W != 0xf) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - - VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); - } - else { - if( EEREC_ACC == EEREC_S ) SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_T); // Can this case happen? - else if( EEREC_ACC == EEREC_T ) SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_S); // Can this case happen? - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_ACC, EEREC_S); - SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_T); - } - } -flagUpdate: - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_ADDA_iq(VURegs *VU, uptr addr, int info) -{ - //Console::WriteLn("recVUMI_ADDA_iq()"); - if ( _X_Y_Z_W == 0 ) goto flagUpdate; - if (CHECK_VU_EXTRA_OVERFLOW) { - vuFloat3(addr); - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - } - - if( _XYZW_SS ) { - assert( EEREC_ACC != EEREC_TEMP ); - if( EEREC_ACC == EEREC_S ) { - _vuFlipRegSS(VU, EEREC_ACC); - SSE_ADDSS_M32_to_XMM(EEREC_ACC, addr); - _vuFlipRegSS(VU, EEREC_ACC); - } - else { - if( _X ) { - SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); - SSE_ADDSS_M32_to_XMM(EEREC_ACC, addr); - } - else { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); - } - } - } - else { - if( _X_Y_Z_W != 0xf || EEREC_ACC == EEREC_S ) { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - } - - if (_X_Y_Z_W != 0xf) { - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); - } - else { - if( EEREC_ACC == EEREC_S ) SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); - else { - SSE_MOVSS_M32_to_XMM(EEREC_ACC, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_ACC, EEREC_ACC, 0x00); - SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_S); - } - } - } -flagUpdate: - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_ADDA_xyzw(VURegs *VU, int xyzw, int info) -{ - //Console::WriteLn("recVUMI_ADDA_xyzw()"); - if ( _X_Y_Z_W == 0 ) goto flagUpdate; - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); - } - - if( _X_Y_Z_W == 8 ) { - assert( EEREC_ACC != EEREC_T ); - if( xyzw == 0 ) { - SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); - SSE_ADDSS_XMM_to_XMM(EEREC_ACC, EEREC_T); - } - else { - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); - if( _Fs_ == 0 ) { - SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); - } - else { - SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); - SSE_ADDSS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); - } - } - } - else { - if( _X_Y_Z_W != 0xf || EEREC_ACC == EEREC_S ) - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); - - if (_X_Y_Z_W != 0xf) { - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); - } - else { - if( EEREC_ACC == EEREC_S ) SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); - else { - _unpackVF_xyzw(EEREC_ACC, EEREC_T, xyzw); - SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_S); - } - } - } -flagUpdate: - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_ADDAi(VURegs *VU, int info) { recVUMI_ADDA_iq(VU, VU_VI_ADDR(REG_I, 1), info); } -void recVUMI_ADDAq(VURegs *VU, int info) { recVUMI_ADDA_iq(VU, VU_REGQ_ADDR, info); } -void recVUMI_ADDAx(VURegs *VU, int info) { recVUMI_ADDA_xyzw(VU, 0, info); } -void recVUMI_ADDAy(VURegs *VU, int info) { recVUMI_ADDA_xyzw(VU, 1, info); } -void recVUMI_ADDAz(VURegs *VU, int info) { recVUMI_ADDA_xyzw(VU, 2, info); } -void recVUMI_ADDAw(VURegs *VU, int info) { recVUMI_ADDA_xyzw(VU, 3, info); } -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// SUB*, SUB_iq*, SUB_xyzw* -//------------------------------------------------------------------ -void recVUMI_SUB(VURegs *VU, int info) -{ - //Console::WriteLn("recVUMI_SUB()"); - if ( _X_Y_Z_W == 0 ) goto flagUpdate; - if ( !_Fd_ ) info = (info & ~PROCESS_EE_SET_D(0xf)) | PROCESS_EE_SET_D(EEREC_TEMP); - - if( EEREC_S == EEREC_T ) { - if (_X_Y_Z_W != 0xf) SSE_ANDPS_M128_to_XMM(EEREC_D, (uptr)&SSEmovMask[15-_X_Y_Z_W][0]); - else SSE_XORPS_XMM_to_XMM(EEREC_D, EEREC_D); - } - else if( _X_Y_Z_W == 8 ) { - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); - } - if (EEREC_D == EEREC_S) { - if (_Ft_) SSE_SUBSS_XMM_to_XMM(EEREC_D, EEREC_T); - } - else if (EEREC_D == EEREC_T) { - if (_Ft_) { - SSE_MOVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_SUBSS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - else SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - } - else { - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - if (_Ft_) SSE_SUBSS_XMM_to_XMM(EEREC_D, EEREC_T); - } - } - else { - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); - } - if (_X_Y_Z_W != 0xf) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if( ( _Ft_ > 0 ) || _W ) SSE_SUBPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else { - if (EEREC_D == EEREC_S) SSE_SUBPS_XMM_to_XMM(EEREC_D, EEREC_T); - else if (EEREC_D == EEREC_T) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_SUBPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_SUBPS_XMM_to_XMM(EEREC_D, EEREC_T); - } - } - } -flagUpdate: - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_SUB_iq(VURegs *VU, uptr addr, int info) -{ - //Console::WriteLn("recVUMI_SUB_iq()"); - if ( _X_Y_Z_W == 0 ) goto flagUpdate; - if (CHECK_VU_EXTRA_OVERFLOW) { - vuFloat3(addr); - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - } - if ( !_Fd_ ) info = (info & ~PROCESS_EE_SET_D(0xf)) | PROCESS_EE_SET_D(EEREC_TEMP); - - if( _XYZW_SS ) { - if( EEREC_D == EEREC_TEMP ) { - _vuFlipRegSS(VU, EEREC_S); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_SUBSS_M32_to_XMM(EEREC_D, addr); - _vuFlipRegSS(VU, EEREC_S); - _vuFlipRegSS(VU, EEREC_D); - } - else if( EEREC_D == EEREC_S ) { - _vuFlipRegSS(VU, EEREC_D); - SSE_SUBSS_M32_to_XMM(EEREC_D, addr); - _vuFlipRegSS(VU, EEREC_D); - } - else { - if( _X ) { - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_SUBSS_M32_to_XMM(EEREC_D, addr); - } - else { - _vuMoveSS(VU, EEREC_TEMP, EEREC_S); - _vuFlipRegSS(VU, EEREC_D); - SSE_SUBSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - _vuFlipRegSS(VU, EEREC_D); - } - } - } - else { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - - if (_X_Y_Z_W != 0xf) { - int t1reg = _vuGetTempXMMreg(info); - - if( t1reg >= 0 ) { - SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_S); - SSE_SUBPS_XMM_to_XMM(t1reg, EEREC_TEMP); - - VU_MERGE_REGS(EEREC_D, t1reg); - _freeXMMreg(t1reg); - } - else { - // negate - SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - } - else { - if( EEREC_D == EEREC_TEMP ) { - SSE_XORPS_M128_to_XMM(EEREC_D, (uptr)&const_clip[4]); - SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); - } - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_SUBPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - } - } -flagUpdate: - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_SUB_xyzw(VURegs *VU, int xyzw, int info) -{ - //Console::WriteLn("recVUMI_SUB_xyzw()"); - if ( _X_Y_Z_W == 0 ) goto flagUpdate; - if ( !_Fd_ ) info = (info & ~PROCESS_EE_SET_D(0xf)) | PROCESS_EE_SET_D(EEREC_TEMP); - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); - } - - if ( _X_Y_Z_W == 8 ) { - if ( (xyzw == 0) && (_Ft_ == _Fs_) ) { - SSE_ANDPS_M128_to_XMM(EEREC_D, (uptr)&SSEmovMask[7][0]); - } - else if ( EEREC_D == EEREC_TEMP ) { - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - if ( (_Ft_ > 0) || (xyzw == 3) ) { - _vuFlipRegSS_xyzw(EEREC_T, xyzw); - SSE_SUBSS_XMM_to_XMM(EEREC_D, EEREC_T); - _vuFlipRegSS_xyzw(EEREC_T, xyzw); - } - } - else { - if ( (_Ft_ > 0) || (xyzw == 3) ) { - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_SUBSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - else SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - } - } - else { - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); - - if (_X_Y_Z_W != 0xf) { - int t1reg = _vuGetTempXMMreg(info); - - if( t1reg >= 0 ) { - SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_S); - SSE_SUBPS_XMM_to_XMM(t1reg, EEREC_TEMP); - - VU_MERGE_REGS(EEREC_D, t1reg); - _freeXMMreg(t1reg); - } - else { - // negate - SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - } - else { - if( EEREC_D == EEREC_TEMP ) { - SSE_XORPS_M128_to_XMM(EEREC_D, (uptr)&const_clip[4]); - SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); - } - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_SUBPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - } - } -flagUpdate: - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_SUBi(VURegs *VU, int info) { recVUMI_SUB_iq(VU, VU_VI_ADDR(REG_I, 1), info); } -void recVUMI_SUBq(VURegs *VU, int info) { recVUMI_SUB_iq(VU, VU_REGQ_ADDR, info); } -void recVUMI_SUBx(VURegs *VU, int info) { recVUMI_SUB_xyzw(VU, 0, info); } -void recVUMI_SUBy(VURegs *VU, int info) { recVUMI_SUB_xyzw(VU, 1, info); } -void recVUMI_SUBz(VURegs *VU, int info) { recVUMI_SUB_xyzw(VU, 2, info); } -void recVUMI_SUBw(VURegs *VU, int info) { recVUMI_SUB_xyzw(VU, 3, info); } -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// SUBA*, SUBA_iq, SUBA_xyzw -//------------------------------------------------------------------ -void recVUMI_SUBA(VURegs *VU, int info) -{ - //Console::WriteLn("recVUMI_SUBA()"); - if ( _X_Y_Z_W == 0 ) goto flagUpdate; - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); - } - - if( EEREC_S == EEREC_T ) { - if (_X_Y_Z_W != 0xf) SSE_ANDPS_M128_to_XMM(EEREC_ACC, (uptr)&SSEmovMask[15-_X_Y_Z_W][0]); - else SSE_XORPS_XMM_to_XMM(EEREC_ACC, EEREC_ACC); - } - else if( _X_Y_Z_W == 8 ) { - if (EEREC_ACC == EEREC_S) SSE_SUBSS_XMM_to_XMM(EEREC_ACC, EEREC_T); - else if (EEREC_ACC == EEREC_T) { - SSE_MOVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_SUBSS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); - } - else { - SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); - SSE_SUBSS_XMM_to_XMM(EEREC_ACC, EEREC_T); - } - } - else if (_X_Y_Z_W != 0xf) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_SUBPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - - VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); - } - else { - if( EEREC_ACC == EEREC_S ) SSE_SUBPS_XMM_to_XMM(EEREC_ACC, EEREC_T); - else if( EEREC_ACC == EEREC_T ) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_SUBPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - SSE_MOVAPS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); - } - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_ACC, EEREC_S); - SSE_SUBPS_XMM_to_XMM(EEREC_ACC, EEREC_T); - } - } -flagUpdate: - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_SUBA_iq(VURegs *VU, uptr addr, int info) -{ - //Console::WriteLn ("recVUMI_SUBA_iq"); - if (CHECK_VU_EXTRA_OVERFLOW) { - vuFloat3(addr); - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - } - - if( _XYZW_SS ) { - if( EEREC_ACC == EEREC_S ) { - _vuFlipRegSS(VU, EEREC_ACC); - SSE_SUBSS_M32_to_XMM(EEREC_ACC, addr); - _vuFlipRegSS(VU, EEREC_ACC); - } - else { - if( _X ) { - SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); - SSE_SUBSS_M32_to_XMM(EEREC_ACC, addr); - } - else { - _vuMoveSS(VU, EEREC_TEMP, EEREC_S); - _vuFlipRegSS(VU, EEREC_ACC); - SSE_SUBSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); - _vuFlipRegSS(VU, EEREC_ACC); - } - } - } - else { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - - if (_X_Y_Z_W != 0xf) { - int t1reg = _vuGetTempXMMreg(info); - - if( t1reg >= 0 ) { - SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_S); - SSE_SUBPS_XMM_to_XMM(t1reg, EEREC_TEMP); - - VU_MERGE_REGS(EEREC_ACC, t1reg); - _freeXMMreg(t1reg); - } - else { - // negate - SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); - } - } - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_ACC, EEREC_S); - SSE_SUBPS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); - } - } - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_SUBA_xyzw(VURegs *VU, int xyzw, int info) -{ - //Console::WriteLn ("recVUMI_SUBA_xyzw"); - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); - } - - if( _X_Y_Z_W == 8 ) { - if( xyzw == 0 ) { - SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); - SSE_SUBSS_XMM_to_XMM(EEREC_ACC, EEREC_T); - } - else { - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); - SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); - SSE_SUBSS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); - } - } - else { - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); - - if (_X_Y_Z_W != 0xf) { - int t1reg = _vuGetTempXMMreg(info); - - if( t1reg >= 0 ) { - SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_S); - SSE_SUBPS_XMM_to_XMM(t1reg, EEREC_TEMP); - - VU_MERGE_REGS(EEREC_ACC, t1reg); - _freeXMMreg(t1reg); - } - else { - // negate - SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); - } - } - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_ACC, EEREC_S); - SSE_SUBPS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); - } - } - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_SUBAi(VURegs *VU, int info) { recVUMI_SUBA_iq(VU, VU_VI_ADDR(REG_I, 1), info); } -void recVUMI_SUBAq(VURegs *VU, int info) { recVUMI_SUBA_iq(VU, VU_REGQ_ADDR, info); } -void recVUMI_SUBAx(VURegs *VU, int info) { recVUMI_SUBA_xyzw(VU, 0, info); } -void recVUMI_SUBAy(VURegs *VU, int info) { recVUMI_SUBA_xyzw(VU, 1, info); } -void recVUMI_SUBAz(VURegs *VU, int info) { recVUMI_SUBA_xyzw(VU, 2, info); } -void recVUMI_SUBAw(VURegs *VU, int info) { recVUMI_SUBA_xyzw(VU, 3, info); } -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// MUL -//------------------------------------------------------------------ -void recVUMI_MUL_toD(VURegs *VU, int regd, int info) -{ - //Console::WriteLn ("recVUMI_MUL_toD"); - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); - } - - if (_X_Y_Z_W == 1 && (_Ft_ == 0 || _Fs_==0) ) { // W - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, _Ft_ ? EEREC_T : EEREC_S); - VU_MERGE_REGS(regd, EEREC_TEMP); - } - else if( _Fd_ == _Fs_ && _Fs_ == _Ft_ && _XYZW_SS ) { - _vuFlipRegSS(VU, EEREC_D); - SSE_MULSS_XMM_to_XMM(EEREC_D, EEREC_D); - _vuFlipRegSS(VU, EEREC_D); - } - else if( _X_Y_Z_W == 8 ) { - if (regd == EEREC_S) SSE_MULSS_XMM_to_XMM(regd, EEREC_T); - else if (regd == EEREC_T) SSE_MULSS_XMM_to_XMM(regd, EEREC_S); - else { - SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); - SSE_MULSS_XMM_to_XMM(regd, EEREC_T); - } - } - else if (_X_Y_Z_W != 0xf) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - - VU_MERGE_REGS(regd, EEREC_TEMP); - } - else { - if (regd == EEREC_S) SSE_MULPS_XMM_to_XMM(regd, EEREC_T); - else if (regd == EEREC_T) SSE_MULPS_XMM_to_XMM(regd, EEREC_S); - else { - SSE_MOVAPS_XMM_to_XMM(regd, EEREC_S); - SSE_MULPS_XMM_to_XMM(regd, EEREC_T); - } - } -} - -void recVUMI_MUL_iq_toD(VURegs *VU, uptr addr, int regd, int info) -{ - //Console::WriteLn ("recVUMI_MUL_iq_toD"); - if (CHECK_VU_EXTRA_OVERFLOW) { - vuFloat3(addr); - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - } - - if( _XYZW_SS ) { - if( regd == EEREC_TEMP ) { - _vuFlipRegSS(VU, EEREC_S); - SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); - SSE_MULSS_M32_to_XMM(regd, addr); - _vuFlipRegSS(VU, EEREC_S); - _vuFlipRegSS(VU, regd); - } - else if( regd == EEREC_S ) { - _vuFlipRegSS(VU, regd); - SSE_MULSS_M32_to_XMM(regd, addr); - _vuFlipRegSS(VU, regd); - } - else { - if( _X ) { - SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); - SSE_MULSS_M32_to_XMM(regd, addr); - } - else { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(regd, EEREC_TEMP); - } - } - } - else { - if( _X_Y_Z_W != 0xf || regd == EEREC_TEMP || regd == EEREC_S ) { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - } - - if (_X_Y_Z_W != 0xf) { - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(regd, EEREC_TEMP); - } - else { - if( regd == EEREC_TEMP ) SSE_MULPS_XMM_to_XMM(regd, EEREC_S); - else if (regd == EEREC_S) SSE_MULPS_XMM_to_XMM(regd, EEREC_TEMP); - else { - SSE_MOVSS_M32_to_XMM(regd, addr); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x00); - SSE_MULPS_XMM_to_XMM(regd, EEREC_S); - } - } - } -} - -void recVUMI_MUL_xyzw_toD(VURegs *VU, int xyzw, int regd, int info) -{ - //Console::WriteLn ("recVUMI_MUL_xyzw_toD"); - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); - } - if (_Fs_) { // This is needed for alot of games; so always clamp this operand - if (CHECK_VU_SIGN_OVERFLOW) vFloats4_useEAX[_X_Y_Z_W]( EEREC_S, EEREC_TEMP ); // Always clamp EEREC_S, regardless if CHECK_VU_OVERFLOW is set - else vFloats2[_X_Y_Z_W]( EEREC_S, EEREC_TEMP ); // Always clamp EEREC_S, regardless if CHECK_VU_OVERFLOW is set - } - if( _Ft_ == 0 ) { - if( xyzw < 3 ) { - if (_X_Y_Z_W != 0xf) { - SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); - VU_MERGE_REGS(regd, EEREC_TEMP); - } - else SSE_XORPS_XMM_to_XMM(regd, regd); - } - else { - assert(xyzw==3); - if (_X_Y_Z_W != 0xf) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(regd, EEREC_TEMP); - } - else SSE_MOVAPS_XMM_to_XMM(regd, EEREC_S); - } - } - else if( _X_Y_Z_W == 8 ) { - if( regd == EEREC_TEMP ) { - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); - SSE_MULSS_XMM_to_XMM(regd, EEREC_S); - } - else { - if( xyzw == 0 ) { - if( regd == EEREC_T ) { - SSE_MULSS_XMM_to_XMM(regd, EEREC_S); - } - else { - SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); - SSE_MULSS_XMM_to_XMM(regd, EEREC_T); - } - } - else { - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); - SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); - SSE_MULSS_XMM_to_XMM(regd, EEREC_TEMP); - } - } - } - else { - if( _X_Y_Z_W != 0xf || regd == EEREC_TEMP || regd == EEREC_S ) - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); - - if (_X_Y_Z_W != 0xf) { - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(regd, EEREC_TEMP); - } - else { - if( regd == EEREC_TEMP ) SSE_MULPS_XMM_to_XMM(regd, EEREC_S); - else if (regd == EEREC_S) SSE_MULPS_XMM_to_XMM(regd, EEREC_TEMP); - else { - _unpackVF_xyzw(regd, EEREC_T, xyzw); - SSE_MULPS_XMM_to_XMM(regd, EEREC_S); - } - } - } -} - -void recVUMI_MUL(VURegs *VU, int info) -{ - //Console::WriteLn ("recVUMI_MUL"); - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - recVUMI_MUL_toD(VU, EEREC_D, info); - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_MUL_iq(VURegs *VU, int addr, int info) -{ - //Console::WriteLn ("recVUMI_MUL_iq"); - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - recVUMI_MUL_iq_toD(VU, addr, EEREC_D, info); - recUpdateFlags(VU, EEREC_D, info); - // spacefisherman needs overflow checking on MULi.z -} - -void recVUMI_MUL_xyzw(VURegs *VU, int xyzw, int info) -{ - //Console::WriteLn ("recVUMI_MUL_xyzw"); - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - recVUMI_MUL_xyzw_toD(VU, xyzw, EEREC_D, info); - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_MULi(VURegs *VU, int info) { recVUMI_MUL_iq(VU, VU_VI_ADDR(REG_I, 1), info); } -void recVUMI_MULq(VURegs *VU, int info) { recVUMI_MUL_iq(VU, VU_REGQ_ADDR, info); } -void recVUMI_MULx(VURegs *VU, int info) { recVUMI_MUL_xyzw(VU, 0, info); } -void recVUMI_MULy(VURegs *VU, int info) { recVUMI_MUL_xyzw(VU, 1, info); } -void recVUMI_MULz(VURegs *VU, int info) { recVUMI_MUL_xyzw(VU, 2, info); } -void recVUMI_MULw(VURegs *VU, int info) { recVUMI_MUL_xyzw(VU, 3, info); } -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// MULA -//------------------------------------------------------------------ -void recVUMI_MULA( VURegs *VU, int info ) -{ - //Console::WriteLn ("recVUMI_MULA"); - recVUMI_MUL_toD(VU, EEREC_ACC, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MULA_iq(VURegs *VU, int addr, int info) -{ - //Console::WriteLn ("recVUMI_MULA_iq"); - recVUMI_MUL_iq_toD(VU, addr, EEREC_ACC, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MULA_xyzw(VURegs *VU, int xyzw, int info) -{ - //Console::WriteLn ("recVUMI_MULA_xyzw"); - recVUMI_MUL_xyzw_toD(VU, xyzw, EEREC_ACC, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MULAi(VURegs *VU, int info) { recVUMI_MULA_iq(VU, VU_VI_ADDR(REG_I, 1), info); } -void recVUMI_MULAq(VURegs *VU, int info) { recVUMI_MULA_iq(VU, VU_REGQ_ADDR, info); } -void recVUMI_MULAx(VURegs *VU, int info) { recVUMI_MULA_xyzw(VU, 0, info); } -void recVUMI_MULAy(VURegs *VU, int info) { recVUMI_MULA_xyzw(VU, 1, info); } -void recVUMI_MULAz(VURegs *VU, int info) { recVUMI_MULA_xyzw(VU, 2, info); } -void recVUMI_MULAw(VURegs *VU, int info) { recVUMI_MULA_xyzw(VU, 3, info); } -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// MADD -//------------------------------------------------------------------ -void recVUMI_MADD_toD(VURegs *VU, int regd, int info) -{ - //Console::WriteLn ("recVUMI_MADD_toD"); - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); - vuFloat5_useEAX( EEREC_ACC, EEREC_TEMP, _X_Y_Z_W ); - } - - - if( _X_Y_Z_W == 8 ) { - if( regd == EEREC_ACC ) { - SSE_MOVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_MULSS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, 8); } - SSE_ADDSS_XMM_to_XMM(regd, EEREC_TEMP); - } - else if (regd == EEREC_T) { - SSE_MULSS_XMM_to_XMM(regd, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, 8); } - SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); - } - else if (regd == EEREC_S) { - SSE_MULSS_XMM_to_XMM(regd, EEREC_T); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, 8); } - SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); - } - else { - SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); - SSE_MULSS_XMM_to_XMM(regd, EEREC_T); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, 8); } - SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); - } - } - else if (_X_Y_Z_W != 0xf) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); - - VU_MERGE_REGS(regd, EEREC_TEMP); - } - else { - if( regd == EEREC_ACC ) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_TEMP); - } - else if (regd == EEREC_T) { - SSE_MULPS_XMM_to_XMM(regd, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); - } - else if (regd == EEREC_S) { - SSE_MULPS_XMM_to_XMM(regd, EEREC_T); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); - } - else { - SSE_MOVAPS_XMM_to_XMM(regd, EEREC_S); - SSE_MULPS_XMM_to_XMM(regd, EEREC_T); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); - } - } -} - -void recVUMI_MADD_iq_toD(VURegs *VU, uptr addr, int regd, int info) -{ - //Console::WriteLn ("recVUMI_MADD_iq_toD"); - if (CHECK_VU_EXTRA_OVERFLOW) { - vuFloat3(addr); - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - vuFloat5_useEAX( EEREC_ACC, EEREC_TEMP, _X_Y_Z_W ); - } - - if( _X_Y_Z_W == 8 ) { - if( _Fs_ == 0 ) { - // do nothing if regd == ACC (ACCx <= ACCx + 0.0 * *addr) - if( regd != EEREC_ACC ) { - SSE_MOVSS_XMM_to_XMM(regd, EEREC_ACC); - } - return; - } - - if( regd == EEREC_ACC ) { - assert( EEREC_TEMP < iREGCNT_XMM ); - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_MULSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, 8); } - SSE_ADDSS_XMM_to_XMM(regd, EEREC_TEMP); - } - else if( regd == EEREC_S ) { - SSE_MULSS_M32_to_XMM(regd, addr); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); - } - else { - SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); - SSE_MULSS_M32_to_XMM(regd, addr); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); - } - } - else { - if( _Fs_ == 0 ) { - if( regd == EEREC_ACC ) { // ACCxyz is unchanged, ACCw <= ACCw + *addr - if( _W ) { // if _W is zero, do nothing - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); // { *addr, 0, 0, 0 } - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x27); // { 0, 0, 0, *addr } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_TEMP); // { ACCx, ACCy, ACCz, ACCw + *addr } - } - } - else { // DESTxyz <= ACCxyz, DESTw <= ACCw + *addr - if( _W ) { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); // { *addr, 0, 0, 0 } - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x27); // { 0, 0, 0, *addr } - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); // { ACCx, ACCy, ACCz, ACCw + *addr } - } - else SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); - VU_MERGE_REGS(regd, EEREC_TEMP); - } - - return; - } - - if( _X_Y_Z_W != 0xf || regd == EEREC_ACC || regd == EEREC_TEMP || regd == EEREC_S ) { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - } - - if (_X_Y_Z_W != 0xf) { - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); - - VU_MERGE_REGS(regd, EEREC_TEMP); - } - else { - if( regd == EEREC_ACC ) { - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_TEMP); - } - else if( regd == EEREC_S ) { - SSE_MULPS_XMM_to_XMM(regd, EEREC_TEMP); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); - } - else if( regd == EEREC_TEMP ) { - SSE_MULPS_XMM_to_XMM(regd, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); - } - else { - SSE_MOVSS_M32_to_XMM(regd, addr); - SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x00); - SSE_MULPS_XMM_to_XMM(regd, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); - } - } - } -} - -void recVUMI_MADD_xyzw_toD(VURegs *VU, int xyzw, int regd, int info) -{ - //Console::WriteLn ("recVUMI_MADD_xyzw_toD"); - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); - vuFloat5_useEAX( EEREC_ACC, EEREC_TEMP, _X_Y_Z_W ); - } - if (_Fs_) { // This is needed for alot of games; so always clamp this operand - if (CHECK_VU_SIGN_OVERFLOW) vFloats4_useEAX[_X_Y_Z_W]( EEREC_S, EEREC_TEMP ); // Always clamp EEREC_S, regardless if CHECK_VU_OVERFLOW is set - else vFloats2[_X_Y_Z_W]( EEREC_S, EEREC_TEMP ); // Always clamp EEREC_S, regardless if CHECK_VU_OVERFLOW is set - } - if( _Ft_ == 0 ) { - - if( xyzw == 3 ) { - // just add - if( _X_Y_Z_W == 8 ) { - if( regd == EEREC_S ) SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); - else { - SSE_MOVSS_XMM_to_XMM(regd, EEREC_ACC); - SSE_ADDSS_XMM_to_XMM(regd, EEREC_S); - } - } - else { - if( _X_Y_Z_W != 0xf ) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); - - VU_MERGE_REGS(regd, EEREC_TEMP); - } - else { - if( regd == EEREC_S ) SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); - else { - SSE_MOVAPS_XMM_to_XMM(regd, EEREC_ACC); - SSE_ADDPS_XMM_to_XMM(regd, EEREC_S); - } - } - } - } - else { - // just move acc to regd - if( _X_Y_Z_W != 0xf ) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); - VU_MERGE_REGS(regd, EEREC_TEMP); - } - else SSE_MOVAPS_XMM_to_XMM(regd, EEREC_ACC); - } - - return; - } - - if( _X_Y_Z_W == 8 ) { - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); - - if( regd == EEREC_ACC ) { - SSE_MULSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, 8); } - SSE_ADDSS_XMM_to_XMM(regd, EEREC_TEMP); - } - else if( regd == EEREC_S ) { - SSE_MULSS_XMM_to_XMM(regd, EEREC_TEMP); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, 8); } - SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); - } - else if( regd == EEREC_TEMP ) { - SSE_MULSS_XMM_to_XMM(regd, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, 8); } - SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); - } - else { - SSE_MOVSS_XMM_to_XMM(regd, EEREC_ACC); - SSE_MULSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, 8); } - SSE_ADDSS_XMM_to_XMM(regd, EEREC_TEMP); - } - } - else { - if( _X_Y_Z_W != 0xf || regd == EEREC_ACC || regd == EEREC_TEMP || regd == EEREC_S ) { - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); - } - - if (_X_Y_Z_W != 0xf) { - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); - - VU_MERGE_REGS(regd, EEREC_TEMP); - } - else { - if( regd == EEREC_ACC ) { - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_TEMP); - } - else if( regd == EEREC_S ) { - SSE_MULPS_XMM_to_XMM(regd, EEREC_TEMP); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); - } - else if( regd == EEREC_TEMP ) { - SSE_MULPS_XMM_to_XMM(regd, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); - } - else { - _unpackVF_xyzw(regd, EEREC_T, xyzw); - SSE_MULPS_XMM_to_XMM(regd, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); - } - } - } -} - -void recVUMI_MADD(VURegs *VU, int info) -{ - //Console::WriteLn ("recVUMI_MADD"); - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - recVUMI_MADD_toD(VU, EEREC_D, info); - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_MADD_iq(VURegs *VU, int addr, int info) -{ - //Console::WriteLn ("recVUMI_MADD_iq"); - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - recVUMI_MADD_iq_toD(VU, addr, EEREC_D, info); - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_MADD_xyzw(VURegs *VU, int xyzw, int info) -{ - //Console::WriteLn ("recVUMI_MADD_xyzw"); - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - recVUMI_MADD_xyzw_toD(VU, xyzw, EEREC_D, info); - recUpdateFlags(VU, EEREC_D, info); - // super bust-a-move arrows needs overflow clamping -} - -void recVUMI_MADDi(VURegs *VU, int info) { recVUMI_MADD_iq(VU, VU_VI_ADDR(REG_I, 1), info); } -void recVUMI_MADDq(VURegs *VU, int info) { recVUMI_MADD_iq(VU, VU_REGQ_ADDR, info); } -void recVUMI_MADDx(VURegs *VU, int info) { recVUMI_MADD_xyzw(VU, 0, info); } -void recVUMI_MADDy(VURegs *VU, int info) { recVUMI_MADD_xyzw(VU, 1, info); } -void recVUMI_MADDz(VURegs *VU, int info) { recVUMI_MADD_xyzw(VU, 2, info); } -void recVUMI_MADDw(VURegs *VU, int info) { recVUMI_MADD_xyzw(VU, 3, info); } -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// MADDA -//------------------------------------------------------------------ -void recVUMI_MADDA( VURegs *VU, int info ) -{ - //Console::WriteLn ("recVUMI_MADDA"); - recVUMI_MADD_toD(VU, EEREC_ACC, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MADDAi( VURegs *VU , int info) -{ - //Console::WriteLn ("recVUMI_MADDAi"); - recVUMI_MADD_iq_toD( VU, VU_VI_ADDR(REG_I, 1), EEREC_ACC, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MADDAq( VURegs *VU , int info) -{ - //Console::WriteLn ("recVUMI_MADDAq "); - recVUMI_MADD_iq_toD( VU, VU_REGQ_ADDR, EEREC_ACC, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MADDAx( VURegs *VU , int info) -{ - //Console::WriteLn ("recVUMI_MADDAx"); - recVUMI_MADD_xyzw_toD(VU, 0, EEREC_ACC, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MADDAy( VURegs *VU , int info) -{ - //Console::WriteLn ("recVUMI_MADDAy"); - recVUMI_MADD_xyzw_toD(VU, 1, EEREC_ACC, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MADDAz( VURegs *VU , int info) -{ - //Console::WriteLn ("recVUMI_MADDAz"); - recVUMI_MADD_xyzw_toD(VU, 2, EEREC_ACC, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MADDAw( VURegs *VU , int info) -{ - //Console::WriteLn ("recVUMI_MADDAw"); - recVUMI_MADD_xyzw_toD(VU, 3, EEREC_ACC, info); - recUpdateFlags(VU, EEREC_ACC, info); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// MSUB -//------------------------------------------------------------------ -void recVUMI_MSUB_toD(VURegs *VU, int regd, int info) -{ - //Console::WriteLn ("recVUMI_MSUB_toD"); - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); - vuFloat5_useEAX( EEREC_ACC, EEREC_TEMP, _X_Y_Z_W ); - } - - if (_X_Y_Z_W != 0xf) { - int t1reg = _vuGetTempXMMreg(info); - - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } - - if( t1reg >= 0 ) { - SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_ACC); - SSE_SUBPS_XMM_to_XMM(t1reg, EEREC_TEMP); - - VU_MERGE_REGS(regd, t1reg); - _freeXMMreg(t1reg); - } - else { - SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); - VU_MERGE_REGS(regd, EEREC_TEMP); - } - } - else { - if( regd == EEREC_S ) { - assert( regd != EEREC_ACC ); - SSE_MULPS_XMM_to_XMM(regd, EEREC_T); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_SUBPS_XMM_to_XMM(regd, EEREC_ACC); - SSE_XORPS_M128_to_XMM(regd, (uptr)&const_clip[4]); - } - else if( regd == EEREC_T ) { - assert( regd != EEREC_ACC ); - SSE_MULPS_XMM_to_XMM(regd, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_SUBPS_XMM_to_XMM(regd, EEREC_ACC); - SSE_XORPS_M128_to_XMM(regd, (uptr)&const_clip[4]); - } - else if( regd == EEREC_TEMP ) { - SSE_MOVAPS_XMM_to_XMM(regd, EEREC_S); - SSE_MULPS_XMM_to_XMM(regd, EEREC_T); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_SUBPS_XMM_to_XMM(regd, EEREC_ACC); - SSE_XORPS_M128_to_XMM(regd, (uptr)&const_clip[4]); - } - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_MOVAPS_XMM_to_XMM(regd, EEREC_ACC); - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } - SSE_SUBPS_XMM_to_XMM(regd, EEREC_TEMP); - } - } -} - -void recVUMI_MSUB_temp_toD(VURegs *VU, int regd, int info) -{ - //Console::WriteLn ("recVUMI_MSUB_temp_toD"); - - if (_X_Y_Z_W != 0xf) { - int t1reg = _vuGetTempXMMreg(info); - - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } - - if( t1reg >= 0 ) { - SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_ACC); - SSE_SUBPS_XMM_to_XMM(t1reg, EEREC_TEMP); - - if ( regd != EEREC_TEMP ) { VU_MERGE_REGS(regd, t1reg); } - else SSE_MOVAPS_XMM_to_XMM(regd, t1reg); - - _freeXMMreg(t1reg); - } - else { - SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); - VU_MERGE_REGS(regd, EEREC_TEMP); - } - } - else { - if( regd == EEREC_ACC ) { - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } - SSE_SUBPS_XMM_to_XMM(regd, EEREC_TEMP); - } - else if( regd == EEREC_S ) { - SSE_MULPS_XMM_to_XMM(regd, EEREC_TEMP); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_SUBPS_XMM_to_XMM(regd, EEREC_ACC); - SSE_XORPS_M128_to_XMM(regd, (uptr)&const_clip[4]); - } - else if( regd == EEREC_TEMP ) { - SSE_MULPS_XMM_to_XMM(regd, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } - SSE_SUBPS_XMM_to_XMM(regd, EEREC_ACC); - SSE_XORPS_M128_to_XMM(regd, (uptr)&const_clip[4]); - } - else { - SSE_MOVAPS_XMM_to_XMM(regd, EEREC_ACC); - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } - SSE_SUBPS_XMM_to_XMM(regd, EEREC_TEMP); - } - } -} - -void recVUMI_MSUB_iq_toD(VURegs *VU, int regd, int addr, int info) -{ - //Console::WriteLn ("recVUMI_MSUB_iq_toD"); - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - vuFloat5_useEAX( EEREC_ACC, EEREC_TEMP, _X_Y_Z_W ); - vuFloat3(addr); - } - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - recVUMI_MSUB_temp_toD(VU, regd, info); -} - -void recVUMI_MSUB_xyzw_toD(VURegs *VU, int regd, int xyzw, int info) -{ - //Console::WriteLn ("recVUMI_MSUB_xyzw_toD"); - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, 1 << (3 - xyzw)); - vuFloat5_useEAX( EEREC_ACC, EEREC_TEMP, _X_Y_Z_W ); - } - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); - recVUMI_MSUB_temp_toD(VU, regd, info); -} - -void recVUMI_MSUB(VURegs *VU, int info) -{ - //Console::WriteLn ("recVUMI_MSUB"); - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - recVUMI_MSUB_toD(VU, EEREC_D, info); - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_MSUB_iq(VURegs *VU, int addr, int info) -{ - //Console::WriteLn ("recVUMI_MSUB_iq"); - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - recVUMI_MSUB_iq_toD(VU, EEREC_D, addr, info); - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_MSUBi(VURegs *VU, int info) { recVUMI_MSUB_iq(VU, VU_VI_ADDR(REG_I, 1), info); } -void recVUMI_MSUBq(VURegs *VU, int info) { recVUMI_MSUB_iq(VU, VU_REGQ_ADDR, info); } -void recVUMI_MSUBx(VURegs *VU, int info) -{ - //Console::WriteLn ("recVUMI_MSUBx"); - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - recVUMI_MSUB_xyzw_toD(VU, EEREC_D, 0, info); - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_MSUBy(VURegs *VU, int info) -{ - //Console::WriteLn ("recVUMI_MSUBy"); - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - recVUMI_MSUB_xyzw_toD(VU, EEREC_D, 1, info); - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_MSUBz(VURegs *VU, int info) -{ - //Console::WriteLn ("recVUMI_MSUBz"); - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - recVUMI_MSUB_xyzw_toD(VU, EEREC_D, 2, info); - recUpdateFlags(VU, EEREC_D, info); -} - -void recVUMI_MSUBw(VURegs *VU, int info) -{ - //Console::WriteLn ("recVUMI_MSUBw"); - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - recVUMI_MSUB_xyzw_toD(VU, EEREC_D, 3, info); - recUpdateFlags(VU, EEREC_D, info); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// MSUBA -//------------------------------------------------------------------ -void recVUMI_MSUBA( VURegs *VU, int info ) -{ - //Console::WriteLn ("recVUMI_MSUBA"); - recVUMI_MSUB_toD(VU, EEREC_ACC, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MSUBAi( VURegs *VU, int info ) -{ - //Console::WriteLn ("recVUMI_MSUBAi "); - recVUMI_MSUB_iq_toD( VU, EEREC_ACC, VU_VI_ADDR(REG_I, 1), info ); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MSUBAq( VURegs *VU, int info ) -{ - //Console::WriteLn ("recVUMI_MSUBAq"); - recVUMI_MSUB_iq_toD( VU, EEREC_ACC, VU_REGQ_ADDR, info ); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MSUBAx( VURegs *VU, int info ) -{ - //Console::WriteLn ("recVUMI_MSUBAx"); - recVUMI_MSUB_xyzw_toD(VU, EEREC_ACC, 0, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MSUBAy( VURegs *VU, int info ) -{ - //Console::WriteLn ("recVUMI_MSUBAy"); - recVUMI_MSUB_xyzw_toD(VU, EEREC_ACC, 1, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MSUBAz( VURegs *VU, int info ) -{ - //Console::WriteLn ("recVUMI_MSUBAz "); - recVUMI_MSUB_xyzw_toD(VU, EEREC_ACC, 2, info); - recUpdateFlags(VU, EEREC_ACC, info); -} - -void recVUMI_MSUBAw( VURegs *VU, int info ) -{ - //Console::WriteLn ("recVUMI_MSUBAw"); - recVUMI_MSUB_xyzw_toD(VU, EEREC_ACC, 3, info); - recUpdateFlags(VU, EEREC_ACC, info); -} -//------------------------------------------------------------------ - - -static const u32 PCSX2_ALIGNED16(special_mask[4]) = {0xffffffff, 0x80000000, 0xffffffff, 0x80000000}; -static const u32 PCSX2_ALIGNED16(special_mask2[4]) = {0, 0x40000000, 0, 0x40000000}; - -u32 PCSX2_ALIGNED16(temp_loc[4]); -u32 PCSX2_ALIGNED16(temp_loc2[4]); - -//MAX/MINI are non-arithmetic operations that implicitly support numbers with the EXP field being 0 ("denormals"). -// -//As such, they are sometimes used for integer move and (positive!) integer max/min, knowing that integers that -//represent denormals will not be flushed to 0. -// -//As such, this implementation performs a non-arithmetic operation that supports "denormals" and "infs/nans". -//There might be an easier way to do it but here, MAX/MIN is performed with PMAXPD/PMINPD. -//Fake double-precision numbers are constructed by copying the sign of the original numbers, clearing the upper 32 bits, -//setting the 62nd bit to 1 (to ensure double-precision number is "normalized") and having the lower 32bits -//being the same as the original number. - -void MINMAXlogical(VURegs *VU, int info, int min, int mode, uptr addr = 0, int xyzw = 0) -//mode1 = iq, mode2 = xyzw, mode0 = normal -{ - int t1regbool = 0; - int t1reg = _vuGetTempXMMreg(info); - if (t1reg < 0) - { - t1regbool = 1; - for (t1reg = 0; ( (t1reg == EEREC_D) || (t1reg == EEREC_S) || (mode != 1 && t1reg == EEREC_T) - || (t1reg == EEREC_TEMP) ); t1reg++); // Find unused reg (For first temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)temp_loc, t1reg); // Backup t1reg XMM reg - } - int t2regbool = -1; - int t2reg = EEREC_TEMP; - if (EEREC_TEMP == EEREC_D || EEREC_TEMP == EEREC_S || (mode != 1 && EEREC_TEMP == EEREC_T)) - { - t2regbool = 0; - t2reg = _vuGetTempXMMreg(info); - if (t2reg < 0) - { - t2regbool = 1; - for (t2reg = 0; ( (t2reg == EEREC_D) || (t2reg == EEREC_S) || (mode != 1 && t2reg == EEREC_T) || - (t2reg == t1reg) || (t2reg == EEREC_TEMP) ); t2reg++); // Find unused reg (For second temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)temp_loc2, t2reg); // Backup t2reg XMM reg - } - } - - if (_X || _Y) - { - SSE2_PSHUFD_XMM_to_XMM(t1reg, EEREC_S, 0x50); - SSE2_PAND_M128_to_XMM(t1reg, (uptr)special_mask); - SSE2_POR_M128_to_XMM(t1reg, (uptr)special_mask2); - if (mode == 0) - SSE2_PSHUFD_XMM_to_XMM(t2reg, EEREC_T, 0x50); - else if (mode == 1) - { - SSE2_MOVD_M32_to_XMM(t2reg, addr); - SSE2_PSHUFD_XMM_to_XMM(t2reg, t2reg, 0x00); - } - else if (mode == 2) - _unpackVF_xyzw(t2reg, EEREC_T, xyzw); - SSE2_PAND_M128_to_XMM(t2reg, (uptr)special_mask); - SSE2_POR_M128_to_XMM(t2reg, (uptr)special_mask2); - if (min) - SSE2_MINPD_XMM_to_XMM(t1reg, t2reg); - else - SSE2_MAXPD_XMM_to_XMM(t1reg, t2reg); - SSE2_PSHUFD_XMM_to_XMM(t1reg, t1reg, 0x88); - VU_MERGE_REGS_CUSTOM(EEREC_D, t1reg, 0xc & _X_Y_Z_W); - } - - if (_Z || _W) - { - SSE2_PSHUFD_XMM_to_XMM(t1reg, EEREC_S, 0xfa); - SSE2_PAND_M128_to_XMM(t1reg, (uptr)special_mask); - SSE2_POR_M128_to_XMM(t1reg, (uptr)special_mask2); - if (mode == 0) - SSE2_PSHUFD_XMM_to_XMM(t2reg, EEREC_T, 0xfa); - else if (mode == 1) - { - SSE2_MOVD_M32_to_XMM(t2reg, addr); - SSE2_PSHUFD_XMM_to_XMM(t2reg, t2reg, 0x00); - } - else if (mode == 2) - _unpackVF_xyzw(t2reg, EEREC_T, xyzw); - SSE2_PAND_M128_to_XMM(t2reg, (uptr)special_mask); - SSE2_POR_M128_to_XMM(t2reg, (uptr)special_mask2); - if (min) - SSE2_MINPD_XMM_to_XMM(t1reg, t2reg); - else - SSE2_MAXPD_XMM_to_XMM(t1reg, t2reg); - SSE2_PSHUFD_XMM_to_XMM(t1reg, t1reg, 0x88); - VU_MERGE_REGS_CUSTOM(EEREC_D, t1reg, 0x3 & _X_Y_Z_W); - } - - if (t1regbool == 0) - _freeXMMreg(t1reg); - else if (t1regbool == 1) - SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)temp_loc); // Restore t1reg XMM reg - if (t2regbool == 0) - _freeXMMreg(t2reg); - else if (t2regbool == 1) - SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)temp_loc2); // Restore t2reg XMM reg -} - -//------------------------------------------------------------------ -// MAX -//------------------------------------------------------------------ - -void recVUMI_MAX(VURegs *VU, int info) -{ - if ( _Fd_ == 0 ) return; - //Console::WriteLn ("recVUMI_MAX"); - - if (MINMAXFIX) - MINMAXlogical(VU, info, 0, 0); - else - { - - if (_Fs_) vuFloat4_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); // Always do Preserved Sign Clamping - if (_Ft_) vuFloat4_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); - - if( _X_Y_Z_W == 8 ) { - if (EEREC_D == EEREC_S) SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_T); - else if (EEREC_D == EEREC_T) SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_S); - else { - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_T); - } - } - else if (_X_Y_Z_W != 0xf) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_MAXPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else { - if( EEREC_D == EEREC_S ) SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_T); - else if( EEREC_D == EEREC_T ) SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_S); - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_T); - } - } - } -} - -void recVUMI_MAX_iq(VURegs *VU, uptr addr, int info) -{ - if ( _Fd_ == 0 ) return; - //Console::WriteLn ("recVUMI_MAX_iq"); - - if (MINMAXFIX) - MINMAXlogical(VU, info, 0, 1, addr); - else - { - if (_Fs_) vuFloat4_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); // Always do Preserved Sign Clamping - vuFloat3(addr); - - if( _XYZW_SS ) { - if( EEREC_D == EEREC_TEMP ) { - _vuFlipRegSS(VU, EEREC_S); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_MAXSS_M32_to_XMM(EEREC_D, addr); - _vuFlipRegSS(VU, EEREC_S); - - // have to flip over EEREC_D if computing flags! - //if( (info & PROCESS_VU_UPDATEFLAGS) ) - _vuFlipRegSS(VU, EEREC_D); - } - else if( EEREC_D == EEREC_S ) { - _vuFlipRegSS(VU, EEREC_D); - SSE_MAXSS_M32_to_XMM(EEREC_D, addr); - _vuFlipRegSS(VU, EEREC_D); - } - else { - if( _X ) { - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_MAXSS_M32_to_XMM(EEREC_D, addr); - } - else { - _vuMoveSS(VU, EEREC_TEMP, EEREC_S); - _vuFlipRegSS(VU, EEREC_D); - SSE_MAXSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - _vuFlipRegSS(VU, EEREC_D); - } - } - } - else if (_X_Y_Z_W != 0xf) { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - SSE_MAXPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else { - if(EEREC_D == EEREC_S) { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - else { - SSE_MOVSS_M32_to_XMM(EEREC_D, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_D, EEREC_D, 0x00); - SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_S); - } - } - } -} - -void recVUMI_MAX_xyzw(VURegs *VU, int xyzw, int info) -{ - if ( _Fd_ == 0 ) return; - //Console::WriteLn ("recVUMI_MAX_xyzw"); - - if (_Fs_ == 0 && _Ft_ == 0) - { - if( _X_Y_Z_W == 8 && (EEREC_D != EEREC_TEMP)) { - if( xyzw < 3 ) { - SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - else { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)s_fones); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - } - else if (_X_Y_Z_W != 0xf) { - if( xyzw < 3 ) { - if( _X_Y_Z_W & 1 ) SSE_MOVAPS_M128_to_XMM(EEREC_TEMP, (uptr)&VU->VF[0].UL[0]); // w included, so insert the whole reg - else SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); // w not included, can zero out - } - else SSE_MOVAPS_M128_to_XMM(EEREC_TEMP, (uptr)s_fones); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else { - //If VF0.w isnt chosen as the constant, then its going to be MAX( 0, VF0 ), so the result is VF0 - if( xyzw < 3 ) { SSE_MOVAPS_M128_to_XMM(EEREC_D, (uptr)&VU->VF[0].UL[0]); } - else SSE_MOVAPS_M128_to_XMM(EEREC_D, (uptr)s_fones); - } - return; - } - - if (MINMAXFIX) - MINMAXlogical(VU, info, 0, 2, 0, xyzw); - else - { - if (_Fs_) vuFloat4_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); // Always do Preserved Sign Clamping - if (_Ft_) vuFloat4_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); - - if( _X_Y_Z_W == 8 && (EEREC_D != EEREC_TEMP)) { - if( xyzw == 0 ) { - if( EEREC_D == EEREC_S ) SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_T); - else if( EEREC_D == EEREC_T ) SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_S); - else { - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_T); - } - } - else { - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - } - else if (_X_Y_Z_W != 0xf) { - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); - SSE_MAXPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else { - if (EEREC_D == EEREC_S) { - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); - SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - else { - _unpackVF_xyzw(EEREC_D, EEREC_T, xyzw); - SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_S); - } - } - } -} - -void recVUMI_MAXi(VURegs *VU, int info) { recVUMI_MAX_iq(VU, VU_VI_ADDR(REG_I, 1), info); } -void recVUMI_MAXx(VURegs *VU, int info) { recVUMI_MAX_xyzw(VU, 0, info); } -void recVUMI_MAXy(VURegs *VU, int info) { recVUMI_MAX_xyzw(VU, 1, info); } -void recVUMI_MAXz(VURegs *VU, int info) { recVUMI_MAX_xyzw(VU, 2, info); } -void recVUMI_MAXw(VURegs *VU, int info) { recVUMI_MAX_xyzw(VU, 3, info); } -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// MINI -//------------------------------------------------------------------ -void recVUMI_MINI(VURegs *VU, int info) -{ - if ( _Fd_ == 0 ) return; - //Console::WriteLn ("recVUMI_MINI"); - - if (MINMAXFIX) - MINMAXlogical(VU, info, 1, 0); - else - { - - if (_Fs_) vuFloat4_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); // Always do Preserved Sign Clamping - if (_Ft_) vuFloat4_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); - - if( _X_Y_Z_W == 8 ) { - if (EEREC_D == EEREC_S) SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_T); - else if (EEREC_D == EEREC_T) SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_S); - else { - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_T); - } - } - else if (_X_Y_Z_W != 0xf) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_MINPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else { - if( EEREC_D == EEREC_S ) { - //ClampUnordered(EEREC_T, EEREC_TEMP, 0); // need for GT4 vu0rec - SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_T); - } - else if( EEREC_D == EEREC_T ) { - //ClampUnordered(EEREC_S, EEREC_TEMP, 0); // need for GT4 vu0rec - SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_S); - } - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_T); - } - } - } -} - -void recVUMI_MINI_iq(VURegs *VU, uptr addr, int info) -{ - if ( _Fd_ == 0 ) return; - //Console::WriteLn ("recVUMI_MINI_iq"); - - if (MINMAXFIX) - MINMAXlogical(VU, info, 1, 1, addr); - else - { - - if (_Fs_) vuFloat4_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); // Always do Preserved Sign Clamping - vuFloat3(addr); - - if( _XYZW_SS ) { - if( EEREC_D == EEREC_TEMP ) { - _vuFlipRegSS(VU, EEREC_S); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_MINSS_M32_to_XMM(EEREC_D, addr); - _vuFlipRegSS(VU, EEREC_S); - - // have to flip over EEREC_D if computing flags! - //if( (info & PROCESS_VU_UPDATEFLAGS) ) - _vuFlipRegSS(VU, EEREC_D); - } - else if( EEREC_D == EEREC_S ) { - _vuFlipRegSS(VU, EEREC_D); - SSE_MINSS_M32_to_XMM(EEREC_D, addr); - _vuFlipRegSS(VU, EEREC_D); - } - else { - if( _X ) { - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_MINSS_M32_to_XMM(EEREC_D, addr); - } - else { - _vuMoveSS(VU, EEREC_TEMP, EEREC_S); - _vuFlipRegSS(VU, EEREC_D); - SSE_MINSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - _vuFlipRegSS(VU, EEREC_D); - } - } - } - else if (_X_Y_Z_W != 0xf) { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - SSE_MINPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else { - if(EEREC_D == EEREC_S) { - SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); - SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - else { - SSE_MOVSS_M32_to_XMM(EEREC_D, addr); - SSE_SHUFPS_XMM_to_XMM(EEREC_D, EEREC_D, 0x00); - SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_S); - } - } - } -} - -void recVUMI_MINI_xyzw(VURegs *VU, int xyzw, int info) -{ - if ( _Fd_ == 0 ) return; - //Console::WriteLn ("recVUMI_MINI_xyzw"); - - if (_Fs_ == 0 && _Ft_ == 0) - { - if( _X_Y_Z_W == 0xf ) - { - //If VF0.w is the constant, the result will match VF0, else its all 0's - if(xyzw == 3) SSE_MOVAPS_M128_to_XMM(EEREC_D, (uptr)&VU->VF[0].UL[0]); - else SSE_XORPS_XMM_to_XMM(EEREC_D, EEREC_D); - } - else - { - //If VF0.w is the constant, the result will match VF0, else its all 0's - if(xyzw == 3) SSE_MOVAPS_M128_to_XMM(EEREC_TEMP, (uptr)&VU->VF[0].UL[0]); - else SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - return; - } - if (MINMAXFIX) - MINMAXlogical(VU, info, 1, 2, 0, xyzw); - else - { - if (_Fs_) vuFloat4_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); // Always do Preserved Sign Clamping - if (_Ft_) vuFloat4_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); - - if( _X_Y_Z_W == 8 && (EEREC_D != EEREC_TEMP)) { - if( xyzw == 0 ) { - if( EEREC_D == EEREC_S ) SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_T); - else if( EEREC_D == EEREC_T ) SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_S); - else { - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_T); - } - } - else { - _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); - SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); - SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - } - else if (_X_Y_Z_W != 0xf) { - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); - SSE_MINPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - VU_MERGE_REGS(EEREC_D, EEREC_TEMP); - } - else { - if (EEREC_D == EEREC_S) { - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); - SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); - } - else { - _unpackVF_xyzw(EEREC_D, EEREC_T, xyzw); - SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_S); - } - } - } -} - -void recVUMI_MINIi(VURegs *VU, int info) { recVUMI_MINI_iq(VU, VU_VI_ADDR(REG_I, 1), info); } -void recVUMI_MINIx(VURegs *VU, int info) { recVUMI_MINI_xyzw(VU, 0, info); } -void recVUMI_MINIy(VURegs *VU, int info) { recVUMI_MINI_xyzw(VU, 1, info); } -void recVUMI_MINIz(VURegs *VU, int info) { recVUMI_MINI_xyzw(VU, 2, info); } -void recVUMI_MINIw(VURegs *VU, int info) { recVUMI_MINI_xyzw(VU, 3, info); } -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// OPMULA -//------------------------------------------------------------------ -void recVUMI_OPMULA( VURegs *VU, int info ) -{ - //Console::WriteLn ("recVUMI_OPMULA"); - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, 0xE); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, 0xE); - } - - SSE_MOVAPS_XMM_to_XMM( EEREC_TEMP, EEREC_S ); - SSE_SHUFPS_XMM_to_XMM( EEREC_T, EEREC_T, 0xD2 ); // EEREC_T = WYXZ - SSE_SHUFPS_XMM_to_XMM( EEREC_TEMP, EEREC_TEMP, 0xC9 ); // EEREC_TEMP = WXZY - SSE_MULPS_XMM_to_XMM( EEREC_TEMP, EEREC_T ); - - VU_MERGE_REGS_CUSTOM(EEREC_ACC, EEREC_TEMP, 14); - - // revert EEREC_T - if( EEREC_T != EEREC_ACC ) - SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0xC9); - - recUpdateFlags(VU, EEREC_ACC, info); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// OPMSUB -//------------------------------------------------------------------ -void recVUMI_OPMSUB( VURegs *VU, int info ) -{ - //Console::WriteLn ("recVUMI_OPMSUB"); - if (CHECK_VU_EXTRA_OVERFLOW) { - if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, 0xE); - if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, 0xE); - } - - if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0xD2); // EEREC_T = WYXZ - SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0xC9); // EEREC_TEMP = WXZY - SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); - - // negate and add - SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); - SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); - VU_MERGE_REGS_CUSTOM(EEREC_D, EEREC_TEMP, 14); - - // revert EEREC_T - if( EEREC_T != EEREC_D ) SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0xC9); - - recUpdateFlags(VU, EEREC_D, info); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// NOP -//------------------------------------------------------------------ -void recVUMI_NOP( VURegs *VU, int info ) -{ - //Console::WriteLn ("recVUMI_NOP"); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// recVUMI_FTOI_Saturate() - Saturates result from FTOI Instructions -//------------------------------------------------------------------ -static const PCSX2_ALIGNED16(int rec_const_0x8000000[4]) = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; - -void recVUMI_FTOI_Saturate(int rec_s, int rec_t, int rec_tmp1, int rec_tmp2) -{ - //Console::WriteLn ("recVUMI_FTOI_Saturate"); - //Duplicate the xor'd sign bit to the whole value - //FFFF FFFF for positive, 0 for negative - SSE_MOVAPS_XMM_to_XMM(rec_tmp1, rec_s); - SSE2_PXOR_M128_to_XMM(rec_tmp1, (uptr)&const_clip[4]); - SSE2_PSRAD_I8_to_XMM(rec_tmp1, 31); - - //Create mask: 0 where !=8000 0000 - SSE_MOVAPS_XMM_to_XMM(rec_tmp2, rec_t); - SSE2_PCMPEQD_M128_to_XMM(rec_tmp2, (uptr)&const_clip[4]); - - //AND the mask w/ the edit values - SSE_ANDPS_XMM_to_XMM(rec_tmp1, rec_tmp2); - - //if v==8000 0000 && positive -> 8000 0000 + FFFF FFFF -> 7FFF FFFF - //if v==8000 0000 && negative -> 8000 0000 + 0 -> 8000 0000 - //if v!=8000 0000 -> v+0 (masked from the and) - - //Add the values as needed - SSE2_PADDD_XMM_to_XMM(rec_t, rec_tmp1); -} -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// FTOI 0/4/12/15 -//------------------------------------------------------------------ -static PCSX2_ALIGNED16(float FTIO_Temp1[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; -static PCSX2_ALIGNED16(float FTIO_Temp2[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; -void recVUMI_FTOI0(VURegs *VU, int info) -{ - int t1reg, t2reg; // Temp XMM regs - - if ( _Ft_ == 0 ) return; - - //Console::WriteLn ("recVUMI_FTOI0"); - - if (_X_Y_Z_W != 0xf) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - vuFloat_useEAX( info, EEREC_TEMP, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax) - SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); - - t1reg = _vuGetTempXMMreg(info); - - if( t1reg >= 0 ) { // If theres a temp XMM reg available - for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg) ); t2reg++) - ; // Find unused reg (For second temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t2reg); // Backup XMM reg - - recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result - - SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp1); // Restore XMM reg - _freeXMMreg(t1reg); // Free temp reg - } - else { // No temp reg available - for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++) - ; // Find unused reg (For first temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg - - for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg) ); t2reg++) - ; // Find unused reg (For second temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp2, t2reg); // Backup t2reg XMM reg - - recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result - - SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg - SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp2); // Restore t2reg XMM reg - } - - VU_MERGE_REGS(EEREC_T, EEREC_TEMP); - } - else { - if (EEREC_T != EEREC_S) { - SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_S); - vuFloat_useEAX( info, EEREC_T, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax) - SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_T, EEREC_T); - - t1reg = _vuGetTempXMMreg(info); - - if( t1reg >= 0 ) { // If theres a temp XMM reg available - recVUMI_FTOI_Saturate(EEREC_S, EEREC_T, EEREC_TEMP, t1reg); // Saturate if Float->Int conversion returned illegal result - _freeXMMreg(t1reg); // Free temp reg - } - else { // No temp reg available - for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++) - ; // Find unused reg - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg - - recVUMI_FTOI_Saturate(EEREC_S, EEREC_T, EEREC_TEMP, t1reg); // Saturate if Float->Int conversion returned illegal result - - SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg - } - } - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - vuFloat_useEAX( info, EEREC_TEMP, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax) - SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); - - t1reg = _vuGetTempXMMreg(info); - - if( t1reg >= 0 ) { // If theres a temp XMM reg available - for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg)); t2reg++) - ; // Find unused reg (For second temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t2reg); // Backup XMM reg - - recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result - - SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp1); // Restore XMM reg - _freeXMMreg(t1reg); // Free temp reg - } - else { // No temp reg available - for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++) - ; // Find unused reg (For first temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg - - for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg) ); t2reg++) - ; // Find unused reg (For second temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp2, t2reg); // Backup t2reg XMM reg - - recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result - - SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg - SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp2); // Restore t2reg XMM reg - } - - SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_TEMP); - } - } -} - -void recVUMI_FTOIX(VURegs *VU, int addr, int info) -{ - int t1reg, t2reg; // Temp XMM regs - - if ( _Ft_ == 0 ) return; - - //Console::WriteLn ("recVUMI_FTOIX"); - if (_X_Y_Z_W != 0xf) { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_MULPS_M128_to_XMM(EEREC_TEMP, addr); - vuFloat_useEAX( info, EEREC_TEMP, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax) - SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); - - t1reg = _vuGetTempXMMreg(info); - - if( t1reg >= 0 ) { // If theres a temp XMM reg available - for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg)); t2reg++) - ; // Find unused reg (For second temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t2reg); // Backup XMM reg - - recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result - - SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp1); // Restore XMM reg - _freeXMMreg(t1reg); // Free temp reg - } - else { // No temp reg available - for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++) - ; // Find unused reg (For first temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg - - for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg) ); t2reg++) - ; // Find unused reg (For second temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp2, t2reg); // Backup t2reg XMM reg - - recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result - - SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg - SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp2); // Restore t2reg XMM reg - } - - VU_MERGE_REGS(EEREC_T, EEREC_TEMP); - } - else { - if (EEREC_T != EEREC_S) { - SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_S); - SSE_MULPS_M128_to_XMM(EEREC_T, addr); - vuFloat_useEAX( info, EEREC_T, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax) - SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_T, EEREC_T); - - t1reg = _vuGetTempXMMreg(info); - - if( t1reg >= 0 ) { // If theres a temp XMM reg available - recVUMI_FTOI_Saturate(EEREC_S, EEREC_T, EEREC_TEMP, t1reg); // Saturate if Float->Int conversion returned illegal result - _freeXMMreg(t1reg); // Free temp reg - } - else { // No temp reg available - for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++) - ; // Find unused reg - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg - - recVUMI_FTOI_Saturate(EEREC_S, EEREC_T, EEREC_TEMP, t1reg); // Saturate if Float->Int conversion returned illegal result - - SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg - } - } - else { - SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_MULPS_M128_to_XMM(EEREC_TEMP, addr); - vuFloat_useEAX( info, EEREC_TEMP, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax) - SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); - - t1reg = _vuGetTempXMMreg(info); - - if( t1reg >= 0 ) { // If theres a temp XMM reg available - for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg)); t2reg++) - ; // Find unused reg (For second temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t2reg); // Backup XMM reg - - recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result - - SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp1); // Restore XMM reg - _freeXMMreg(t1reg); // Free temp reg - } - else { // No temp reg available - for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++) - ; // Find unused reg (For first temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg - - for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg) ); t2reg++) - ; // Find unused reg (For second temp reg) - SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp2, t2reg); // Backup t2reg XMM reg - - recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result - - SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg - SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp2); // Restore t2reg XMM reg - } - - SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_TEMP); - } - } -} - -void recVUMI_FTOI4( VURegs *VU, int info ) { recVUMI_FTOIX(VU, (uptr)&recMult_float_to_int4[0], info); } -void recVUMI_FTOI12( VURegs *VU, int info ) { recVUMI_FTOIX(VU, (uptr)&recMult_float_to_int12[0], info); } -void recVUMI_FTOI15( VURegs *VU, int info ) { recVUMI_FTOIX(VU, (uptr)&recMult_float_to_int15[0], info); } -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// ITOF 0/4/12/15 -//------------------------------------------------------------------ -void recVUMI_ITOF0( VURegs *VU, int info ) -{ - if ( _Ft_ == 0 ) return; - - //Console::WriteLn ("recVUMI_ITOF0"); - if (_X_Y_Z_W != 0xf) { - SSE2_CVTDQ2PS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - vuFloat_useEAX( info, EEREC_TEMP, 15); // Clamp infinities - VU_MERGE_REGS(EEREC_T, EEREC_TEMP); - xmmregs[EEREC_T].mode |= MODE_WRITE; - } - else { - SSE2_CVTDQ2PS_XMM_to_XMM(EEREC_T, EEREC_S); - vuFloat2(EEREC_T, EEREC_TEMP, 15); // Clamp infinities - } -} - -void recVUMI_ITOFX(VURegs *VU, int addr, int info) -{ - if ( _Ft_ == 0 ) return; - - //Console::WriteLn ("recVUMI_ITOFX"); - if (_X_Y_Z_W != 0xf) { - SSE2_CVTDQ2PS_XMM_to_XMM(EEREC_TEMP, EEREC_S); - SSE_MULPS_M128_to_XMM(EEREC_TEMP, addr); - vuFloat_useEAX( info, EEREC_TEMP, 15); // Clamp infinities - VU_MERGE_REGS(EEREC_T, EEREC_TEMP); - xmmregs[EEREC_T].mode |= MODE_WRITE; - } - else { - SSE2_CVTDQ2PS_XMM_to_XMM(EEREC_T, EEREC_S); - SSE_MULPS_M128_to_XMM(EEREC_T, addr); - vuFloat2(EEREC_T, EEREC_TEMP, 15); // Clamp infinities - } -} - -void recVUMI_ITOF4( VURegs *VU, int info ) { recVUMI_ITOFX(VU, (uptr)&recMult_int_to_float4[0], info); } -void recVUMI_ITOF12( VURegs *VU, int info ) { recVUMI_ITOFX(VU, (uptr)&recMult_int_to_float12[0], info); } -void recVUMI_ITOF15( VURegs *VU, int info ) { recVUMI_ITOFX(VU, (uptr)&recMult_int_to_float15[0], info); } -//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// CLIP -//------------------------------------------------------------------ -void recVUMI_CLIP(VURegs *VU, int info) -{ - int t1reg = EEREC_D; - int t2reg = EEREC_ACC; - int x86temp1, x86temp2; - - u32 clipaddr = VU_VI_ADDR(REG_CLIP_FLAG, 0); - u32 prevclipaddr = VU_VI_ADDR(REG_CLIP_FLAG, 2); - - if( clipaddr == 0 ) { // battle star has a clip right before fcset - Console::WriteLn("skipping vu clip"); - return; - } - - //Flush the clip flag before processing, incase of double clip commands (GoW) - - if( prevclipaddr != (uptr)&VU->VI[REG_CLIP_FLAG] ) { - MOV32MtoR(EAX, prevclipaddr); - MOV32RtoM((uptr)&VU->VI[REG_CLIP_FLAG], EAX); - } - - assert( clipaddr != 0 ); - assert( t1reg != t2reg && t1reg != EEREC_TEMP && t2reg != EEREC_TEMP ); - - x86temp1 = ALLOCTEMPX86(MODE_8BITREG); - x86temp2 = ALLOCTEMPX86(MODE_8BITREG); - - //if ( (x86temp1 == 0) || (x86temp2 == 0) ) Console::Error("VU CLIP Allocation Error: EAX being allocated!"); - - _freeXMMreg(t1reg); // These should have been freed at allocation in eeVURecompileCode() - _freeXMMreg(t2reg); // but if they've been used since then, then free them. (just doing this incase :p (cottonvibes)) - - if( _Ft_ == 0 ) { - SSE_MOVAPS_M128_to_XMM(EEREC_TEMP, (uptr)&s_fones[0]); // all 1s - SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)&s_fones[4]); - } - else { - _unpackVF_xyzw(EEREC_TEMP, EEREC_T, 3); - SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[0]); - SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_TEMP); - SSE_ORPS_M128_to_XMM(t1reg, (uptr)&const_clip[4]); - } - - MOV32MtoR(EAX, prevclipaddr); - - SSE_CMPNLEPS_XMM_to_XMM(t1reg, EEREC_S); //-w, -z, -y, -x - SSE_CMPLTPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); //+w, +z, +y, +x - - SHL32ItoR(EAX, 6); - - SSE_MOVAPS_XMM_to_XMM(t2reg, EEREC_TEMP); //t2 = +w, +z, +y, +x - SSE_UNPCKLPS_XMM_to_XMM(EEREC_TEMP, t1reg); //EEREC_TEMP = -y,+y,-x,+x - SSE_UNPCKHPS_XMM_to_XMM(t2reg, t1reg); //t2reg = -w,+w,-z,+z - SSE_MOVMSKPS_XMM_to_R32(x86temp2, EEREC_TEMP); // -y,+y,-x,+x - SSE_MOVMSKPS_XMM_to_R32(x86temp1, t2reg); // -w,+w,-z,+z - - AND8ItoR(x86temp1, 0x3); - SHL8ItoR(x86temp1, 4); - OR8RtoR(EAX, x86temp1); - AND8ItoR(x86temp2, 0xf); - OR8RtoR(EAX, x86temp2); - AND32ItoR(EAX, 0xffffff); - - MOV32RtoM(clipaddr, EAX); - - if (( !(info & (PROCESS_VU_SUPER|PROCESS_VU_COP2)) ) ) //Instantly update the flag if its called from elsewhere (unlikely, but ok) - MOV32RtoM((uptr)&VU->VI[REG_CLIP_FLAG], EAX); - - _freeX86reg(x86temp1); - _freeX86reg(x86temp2); -} +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "PrecompiledHeader.h" + +#include "Common.h" +#include "GS.h" +#include "R5900OpcodeTables.h" +#include "iR5900.h" +#include "iMMI.h" +#include "iFPU.h" +#include "iCOP0.h" +#include "VUmicro.h" +#include "VUflags.h" +#include "sVU_Micro.h" +#include "sVU_Debug.h" +#include "sVU_zerorec.h" +//------------------------------------------------------------------ +#define MINMAXFIX 1 +//------------------------------------------------------------------ +// Helper Macros +//------------------------------------------------------------------ +#define _Ft_ (( VU->code >> 16) & 0x1F) // The rt part of the instruction register +#define _Fs_ (( VU->code >> 11) & 0x1F) // The rd part of the instruction register +#define _Fd_ (( VU->code >> 6) & 0x1F) // The sa part of the instruction register + +#define _X (( VU->code>>24) & 0x1) +#define _Y (( VU->code>>23) & 0x1) +#define _Z (( VU->code>>22) & 0x1) +#define _W (( VU->code>>21) & 0x1) + +#define _XYZW_SS (_X+_Y+_Z+_W==1) + +#define _Fsf_ (( VU->code >> 21) & 0x03) +#define _Ftf_ (( VU->code >> 23) & 0x03) + +#define _Imm11_ (s32)(VU->code & 0x400 ? 0xfffffc00 | (VU->code & 0x3ff) : VU->code & 0x3ff) +#define _UImm11_ (s32)(VU->code & 0x7ff) + +#define VU_VFx_ADDR(x) (uptr)&VU->VF[x].UL[0] +#define VU_VFy_ADDR(x) (uptr)&VU->VF[x].UL[1] +#define VU_VFz_ADDR(x) (uptr)&VU->VF[x].UL[2] +#define VU_VFw_ADDR(x) (uptr)&VU->VF[x].UL[3] + +#define VU_REGR_ADDR (uptr)&VU->VI[REG_R] +#define VU_REGQ_ADDR (uptr)&VU->VI[REG_Q] +#define VU_REGMAC_ADDR (uptr)&VU->VI[REG_MAC_FLAG] + +#define VU_VI_ADDR(x, read) GetVIAddr(VU, x, read, info) + +#define VU_ACCx_ADDR (uptr)&VU->ACC.UL[0] +#define VU_ACCy_ADDR (uptr)&VU->ACC.UL[1] +#define VU_ACCz_ADDR (uptr)&VU->ACC.UL[2] +#define VU_ACCw_ADDR (uptr)&VU->ACC.UL[3] + +#define _X_Y_Z_W ((( VU->code >> 21 ) & 0xF ) ) +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// Global Variables +//------------------------------------------------------------------ +static const PCSX2_ALIGNED16(int SSEmovMask[ 16 ][ 4 ]) = +{ + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + { 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF }, + { 0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000 }, + { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }, + { 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000 }, + { 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF }, + { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }, + { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }, + { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }, + { 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF }, + { 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000 }, + { 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }, + { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 }, + { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF }, + { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }, + { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF } +}; + +static const PCSX2_ALIGNED16(u32 const_abs_table[16][4]) = +{ + { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }, //0000 + { 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff }, //0001 + { 0xffffffff, 0xffffffff, 0x7fffffff, 0xffffffff }, //0010 + { 0xffffffff, 0xffffffff, 0x7fffffff, 0x7fffffff }, //0011 + { 0xffffffff, 0x7fffffff, 0xffffffff, 0xffffffff }, //0100 + { 0xffffffff, 0x7fffffff, 0xffffffff, 0x7fffffff }, //0101 + { 0xffffffff, 0x7fffffff, 0x7fffffff, 0xffffffff }, //0110 + { 0xffffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff }, //0111 + { 0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff }, //1000 + { 0x7fffffff, 0xffffffff, 0xffffffff, 0x7fffffff }, //1001 + { 0x7fffffff, 0xffffffff, 0x7fffffff, 0xffffffff }, //1010 + { 0x7fffffff, 0xffffffff, 0x7fffffff, 0x7fffffff }, //1011 + { 0x7fffffff, 0x7fffffff, 0xffffffff, 0xffffffff }, //1100 + { 0x7fffffff, 0x7fffffff, 0xffffffff, 0x7fffffff }, //1101 + { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0xffffffff }, //1110 + { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff }, //1111 +}; + +static const PCSX2_ALIGNED16(float recMult_float_to_int4[4]) = { 16.0, 16.0, 16.0, 16.0 }; +static const PCSX2_ALIGNED16(float recMult_float_to_int12[4]) = { 4096.0, 4096.0, 4096.0, 4096.0 }; +static const PCSX2_ALIGNED16(float recMult_float_to_int15[4]) = { 32768.0, 32768.0, 32768.0, 32768.0 }; + +static const PCSX2_ALIGNED16(float recMult_int_to_float4[4]) = { 0.0625f, 0.0625f, 0.0625f, 0.0625f }; +static const PCSX2_ALIGNED16(float recMult_int_to_float12[4]) = { 0.000244140625, 0.000244140625, 0.000244140625, 0.000244140625 }; +static const PCSX2_ALIGNED16(float recMult_int_to_float15[4]) = { 0.000030517578125, 0.000030517578125, 0.000030517578125, 0.000030517578125 }; + +static const PCSX2_ALIGNED16(u32 VU_Underflow_Mask1[4]) = {0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000}; +static const PCSX2_ALIGNED16(u32 VU_Underflow_Mask2[4]) = {0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff}; +static const PCSX2_ALIGNED16(u32 VU_Zero_Mask[4]) = {0x00000000, 0x00000000, 0x00000000, 0x00000000}; +static const PCSX2_ALIGNED16(u32 VU_Zero_Helper_Mask[4]) = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; +static const PCSX2_ALIGNED16(u32 VU_Signed_Zero_Mask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000}; +static const PCSX2_ALIGNED16(u32 VU_Pos_Infinity[4]) = {0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000}; +static const PCSX2_ALIGNED16(u32 VU_Neg_Infinity[4]) = {0xff800000, 0xff800000, 0xff800000, 0xff800000}; +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// recUpdateFlags() - Computes the flags for the Upper Opcodes +// +// Note: Computes under/overflow flags if CHECK_VU_EXTRA_FLAGS is 1 +//------------------------------------------------------------------ +PCSX2_ALIGNED16(u64 TEMPXMMData[2]); +void recUpdateFlags(VURegs * VU, int reg, int info) +{ + static u8 *pjmp, *pjmp2; + static u32 *pjmp32; + static u32 macaddr, stataddr, prevstataddr; + static int x86macflag, x86statflag, x86temp; + static int t1reg, t1regBoolean; + static const int flipMask[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}; + + if( !(info & PROCESS_VU_UPDATEFLAGS) ) { + if (CHECK_VU_EXTRA_OVERFLOW) { + if (reg != EEREC_TEMP) vuFloat2(reg, EEREC_TEMP, _X_Y_Z_W); + else vuFloat_useEAX(info, reg, _X_Y_Z_W); + } + return; + } + + //Console::WriteLn ("recUpdateFlags"); + + macaddr = VU_VI_ADDR(REG_MAC_FLAG, 0); + stataddr = VU_VI_ADDR(REG_STATUS_FLAG, 0); // write address + prevstataddr = VU_VI_ADDR(REG_STATUS_FLAG, 2); // previous address + + if( stataddr == 0 ) stataddr = prevstataddr; + if( macaddr == 0 ) { + Console::WriteLn( "VU ALLOCATION WARNING: Using Mac Flag Previous Address!" ); + macaddr = VU_VI_ADDR(REG_MAC_FLAG, 2); + } + + x86macflag = ALLOCTEMPX86(0); + x86statflag = ALLOCTEMPX86(0); + + if (reg == EEREC_TEMP) { + t1reg = _vuGetTempXMMreg(info); + if (t1reg < 0) { + //Console::WriteLn( "VU ALLOCATION ERROR: Temp reg can't be allocated!!!!" ); + t1reg = (reg == 0) ? 1 : 0; // Make t1reg != reg + SSE_MOVAPS_XMM_to_M128( (uptr)TEMPXMMData, t1reg ); // Backup data to temp address + t1regBoolean = 1; + } + else t1regBoolean = 0; + } + else { + t1reg = EEREC_TEMP; + t1regBoolean = 2; + } + + SSE_SHUFPS_XMM_to_XMM(reg, reg, 0x1B); // Flip wzyx to xyzw + MOV32MtoR(x86statflag, prevstataddr); // Load the previous status in to x86statflag + AND16ItoR(x86statflag, 0xff0); // Keep Sticky and D/I flags + + + if (CHECK_VU_EXTRA_FLAGS) { // Checks all flags + + x86temp = ALLOCTEMPX86(0); + + //-------------------------Check for Overflow flags------------------------------ + + //SSE_XORPS_XMM_to_XMM(t1reg, t1reg); // Clear t1reg + //SSE_CMPUNORDPS_XMM_to_XMM(t1reg, reg); // If reg == NaN then set Vector to 0xFFFFFFFF + + //SSE_MOVAPS_XMM_to_XMM(t1reg, reg); + //SSE_MINPS_M128_to_XMM(t1reg, (uptr)g_maxvals); + //SSE_MAXPS_M128_to_XMM(t1reg, (uptr)g_minvals); + //SSE_CMPNEPS_XMM_to_XMM(t1reg, reg); // If they're not equal, then overflow has occured + + SSE_MOVAPS_XMM_to_XMM(t1reg, reg); + SSE_ANDPS_M128_to_XMM(t1reg, (uptr)VU_Zero_Helper_Mask); + SSE_CMPEQPS_M128_to_XMM(t1reg, (uptr)VU_Pos_Infinity); // If infinity, then overflow has occured (NaN's don't report as overflow) + + SSE_MOVMSKPS_XMM_to_R32(x86macflag, t1reg); // Move the sign bits of the previous calculation + + AND16ItoR(x86macflag, _X_Y_Z_W ); // Grab "Has Overflowed" bits from the previous calculation (also make sure we're only grabbing from the XYZW being modified) + pjmp = JZ8(0); // Skip if none are + OR16ItoR(x86statflag, 0x208); // OS, O flags + SHL16ItoR(x86macflag, 12); + if (_XYZW_SS) pjmp32 = JMP32(0); // Skip Underflow Check + x86SetJ8(pjmp); + + //-------------------------Check for Underflow flags------------------------------ + + SSE_MOVAPS_XMM_to_XMM(t1reg, reg); // t1reg <- reg + + SSE_ANDPS_M128_to_XMM(t1reg, (uptr)&VU_Underflow_Mask1[ 0 ]); + SSE_CMPEQPS_M128_to_XMM(t1reg, (uptr)&VU_Zero_Mask[ 0 ]); // If (t1reg == zero exponent) then set Vector to 0xFFFFFFFF + + SSE_ANDPS_XMM_to_XMM(t1reg, reg); + SSE_ANDPS_M128_to_XMM(t1reg, (uptr)&VU_Underflow_Mask2[ 0 ]); + SSE_CMPNEPS_M128_to_XMM(t1reg, (uptr)&VU_Zero_Mask[ 0 ]); // If (t1reg != zero mantisa) then set Vector to 0xFFFFFFFF + + SSE_MOVMSKPS_XMM_to_R32(EAX, t1reg); // Move the sign bits of the previous calculation + + AND16ItoR(EAX, _X_Y_Z_W ); // Grab "Has Underflowed" bits from the previous calculation + pjmp = JZ8(0); // Skip if none are + OR16ItoR(x86statflag, 0x104); // US, U flags + SHL16ItoR(EAX, 8); + OR32RtoR(x86macflag, EAX); + x86SetJ8(pjmp); + + //-------------------------Optional Code: Denormals Are Zero------------------------------ + if (CHECK_VU_UNDERFLOW) { // Sets underflow/denormals to zero + SSE_ANDNPS_XMM_to_XMM(t1reg, reg); // t1reg = !t1reg & reg (t1reg = denormals are positive zero) + VU_MERGE_REGS_SAFE(t1reg, reg, (15 - flipMask[_X_Y_Z_W])); // Send t1reg the vectors that shouldn't be modified (since reg was flipped, we need a mask to get the unmodified vectors) + // Now we have Denormals are Positive Zero in t1reg; the next two lines take Signed Zero into account + SSE_ANDPS_M128_to_XMM(reg, (uptr)&VU_Signed_Zero_Mask[ 0 ]); // Only keep the sign bit for each vector + SSE_ORPS_XMM_to_XMM(reg, t1reg); // Denormals are Signed Zero, and unmodified vectors stay the same! + } + + if (_XYZW_SS) x86SetJ32(pjmp32); // If we skipped the Underflow Flag Checking (when we had an Overflow), return here + + vuFloat2(reg, t1reg, flipMask[_X_Y_Z_W]); // Clamp overflowed vectors that were modified (remember reg's vectors have been flipped, so have to use a flipmask) + + //-------------------------Check for Signed flags------------------------------ + + // The following code makes sure the Signed Bit isn't set with Negative Zero + SSE_XORPS_XMM_to_XMM(t1reg, t1reg); // Clear t1reg + SSE_CMPEQPS_XMM_to_XMM(t1reg, reg); // Set all F's if each vector is zero + SSE_MOVMSKPS_XMM_to_R32(x86temp, t1reg); // Used for Zero Flag Calculation + SSE_ANDNPS_XMM_to_XMM(t1reg, reg); + + SSE_MOVMSKPS_XMM_to_R32(EAX, t1reg); // Move the sign bits of the t1reg + + AND16ItoR(EAX, _X_Y_Z_W ); // Grab "Is Signed" bits from the previous calculation + pjmp = JZ8(0); // Skip if none are + OR16ItoR(x86statflag, 0x82); // SS, S flags + SHL16ItoR(EAX, 4); + OR32RtoR(x86macflag, EAX); + if (_XYZW_SS) pjmp2 = JMP8(0); // If negative and not Zero, we can skip the Zero Flag checking + x86SetJ8(pjmp); + + //-------------------------Check for Zero flags------------------------------ + + AND16ItoR(x86temp, _X_Y_Z_W ); // Grab "Is Zero" bits from the previous calculation + pjmp = JZ8(0); // Skip if none are + OR16ItoR(x86statflag, 0x41); // ZS, Z flags + OR32RtoR(x86macflag, x86temp); + x86SetJ8(pjmp); + + _freeX86reg(x86temp); + } + else { // Only Checks for Sign and Zero Flags + + vuFloat2(reg, t1reg, flipMask[_X_Y_Z_W]); // Clamp overflowed vectors that were modified (remember reg's vectors have been flipped, so have to use a flipmask) + + //-------------------------Check for Signed flags------------------------------ + + // The following code makes sure the Signed Bit isn't set with Negative Zero + SSE_XORPS_XMM_to_XMM(t1reg, t1reg); // Clear t1reg + SSE_CMPEQPS_XMM_to_XMM(t1reg, reg); // Set all F's if each vector is zero + SSE_MOVMSKPS_XMM_to_R32(EAX, t1reg); // Used for Zero Flag Calculation + SSE_ANDNPS_XMM_to_XMM(t1reg, reg); + + SSE_MOVMSKPS_XMM_to_R32(x86macflag, t1reg); // Move the sign bits of the t1reg + + AND16ItoR(x86macflag, _X_Y_Z_W ); // Grab "Is Signed" bits from the previous calculation + pjmp = JZ8(0); // Skip if none are + OR16ItoR(x86statflag, 0x82); // SS, S flags + SHL16ItoR(x86macflag, 4); + if (_XYZW_SS) pjmp2 = JMP8(0); // If negative and not Zero, we can skip the Zero Flag checking + x86SetJ8(pjmp); + + //-------------------------Check for Zero flags------------------------------ + + AND16ItoR(EAX, _X_Y_Z_W ); // Grab "Is Zero" bits from the previous calculation + pjmp = JZ8(0); // Skip if none are + OR16ItoR(x86statflag, 0x41); // ZS, Z flags + OR32RtoR(x86macflag, EAX); + x86SetJ8(pjmp); + } + //-------------------------Finally: Send the Flags to the Mac Flag Address------------------------------ + + if (_XYZW_SS) x86SetJ8(pjmp2); // If we skipped the Zero Flag Checking, return here + + if (t1regBoolean == 2) SSE_SHUFPS_XMM_to_XMM(reg, reg, 0x1B); // Flip back reg to wzyx (have to do this because reg != EEREC_TEMP) + else if (t1regBoolean == 1) SSE_MOVAPS_M128_to_XMM( t1reg, (uptr)TEMPXMMData ); // Restore data from temo address + else _freeXMMreg(t1reg); // Free temp reg + + MOV16RtoM(macaddr, x86macflag); + MOV16RtoM(stataddr, x86statflag); + + _freeX86reg(x86macflag); + _freeX86reg(x86statflag); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// Custom VU ADD/SUB routines by Nneeve +// +// Note: See FPU_ADD_SUB() for more info on what this is doing. +//------------------------------------------------------------------ +static PCSX2_ALIGNED16(u32 VU_addsuband[2][4]); +static PCSX2_ALIGNED16(u32 VU_addsub_reg[2][4]); + +static u32 tempECX; + +void VU_ADD_SUB(u32 regd, u32 regt, int is_sub, int info) +{ + u8 *localptr[4][8]; + + MOV32RtoM((uptr)&tempECX, ECX); + + int temp1 = ECX; //receives regd + int temp2 = ALLOCTEMPX86(0); + + if (temp2 == ECX) + { + temp2 = ALLOCTEMPX86(0); + _freeX86reg(ECX); + } + + SSE_MOVAPS_XMM_to_M128((uptr)&VU_addsub_reg[0][0], regd); + SSE_MOVAPS_XMM_to_M128((uptr)&VU_addsub_reg[1][0], regt); + + SSE2_PCMPEQB_XMM_to_XMM(regd, regd); + SSE_MOVAPS_XMM_to_M128((uptr)&VU_addsuband[0][0], regd); + SSE_MOVAPS_XMM_to_M128((uptr)&VU_addsuband[1][0], regd); + SSE_MOVAPS_M128_to_XMM(regd, (uptr)&VU_addsub_reg[0][0]); + + SSE2_PSLLD_I8_to_XMM(regd, 1); + SSE2_PSLLD_I8_to_XMM(regt, 1); + + SSE2_PSRLD_I8_to_XMM(regd, 24); + SSE2_PSRLD_I8_to_XMM(regt, 24); + + SSE2_PSUBD_XMM_to_XMM(regd, regt); + +#define PERFORM(i) \ + \ + SSE_PEXTRW_XMM_to_R32(temp1, regd, i*2); \ + MOVSX32R16toR(temp1, temp1); \ + CMP32ItoR(temp1, 25);\ + localptr[i][0] = JGE8(0);\ + CMP32ItoR(temp1, 0);\ + localptr[i][1] = JG8(0);\ + localptr[i][2] = JE8(0);\ + CMP32ItoR(temp1, -25);\ + localptr[i][3] = JLE8(0);\ + \ + NEG32R(temp1); \ + DEC32R(temp1);\ + MOV32ItoR(temp2, 0xffffffff); \ + SHL32CLtoR(temp2); \ + MOV32RtoM((uptr)&VU_addsuband[0][i], temp2);\ + localptr[i][4] = JMP8(0);\ + \ + x86SetJ8(localptr[i][0]);\ + MOV32ItoM((uptr)&VU_addsuband[1][i], 0x80000000);\ + localptr[i][5] = JMP8(0);\ + \ + x86SetJ8(localptr[i][1]);\ + DEC32R(temp1);\ + MOV32ItoR(temp2, 0xffffffff);\ + SHL32CLtoR(temp2); \ + MOV32RtoM((uptr)&VU_addsuband[1][i], temp2);\ + localptr[i][6] = JMP8(0);\ + \ + x86SetJ8(localptr[i][3]);\ + MOV32ItoM((uptr)&VU_addsuband[0][i], 0x80000000);\ + localptr[i][7] = JMP8(0);\ + \ + x86SetJ8(localptr[i][2]);\ + \ + x86SetJ8(localptr[i][4]);\ + x86SetJ8(localptr[i][5]);\ + x86SetJ8(localptr[i][6]);\ + x86SetJ8(localptr[i][7]); + + PERFORM(0); + PERFORM(1); + PERFORM(2); + PERFORM(3); +#undef PERFORM + + SSE_MOVAPS_M128_to_XMM(regd, (uptr)&VU_addsub_reg[0][0]); + SSE_MOVAPS_M128_to_XMM(regt, (uptr)&VU_addsub_reg[1][0]); + + SSE_ANDPS_M128_to_XMM(regd, (uptr)&VU_addsuband[0][0]); + SSE_ANDPS_M128_to_XMM(regt, (uptr)&VU_addsuband[1][0]); + + if (is_sub) SSE_SUBPS_XMM_to_XMM(regd, regt); + else SSE_ADDPS_XMM_to_XMM(regd, regt); + + SSE_MOVAPS_M128_to_XMM(regt, (uptr)&VU_addsub_reg[1][0]); + + _freeX86reg(temp2); + + MOV32MtoR(ECX, (uptr)&tempECX); +} + +void VU_ADD_SUB_SS(u32 regd, u32 regt, int is_sub, int is_mem, int info) +{ + u8 *localptr[8]; + u32 addrt = regt; //for case is_mem + + MOV32RtoM((uptr)&tempECX, ECX); + + int temp1 = ECX; //receives regd + int temp2 = ALLOCTEMPX86(0); + + if (temp2 == ECX) + { + temp2 = ALLOCTEMPX86(0); + _freeX86reg(ECX); + } + + SSE_MOVAPS_XMM_to_M128((uptr)&VU_addsub_reg[0][0], regd); + if (!is_mem) SSE_MOVAPS_XMM_to_M128((uptr)&VU_addsub_reg[1][0], regt); + + SSE2_MOVD_XMM_to_R(temp1, regd); + SHR32ItoR(temp1, 23); + + if (is_mem) { + MOV32MtoR(temp2, addrt); + MOV32RtoM((uptr)&VU_addsub_reg[1][0], temp2); + SHR32ItoR(temp2, 23); + } + else { + SSE2_MOVD_XMM_to_R(temp2, regt); + SHR32ItoR(temp2, 23); + } + + AND32ItoR(temp1, 0xff); + AND32ItoR(temp2, 0xff); + + SUB32RtoR(temp1, temp2); //temp1 = exponent difference + + CMP32ItoR(temp1, 25); + localptr[0] = JGE8(0); + CMP32ItoR(temp1, 0); + localptr[1] = JG8(0); + localptr[2] = JE8(0); + CMP32ItoR(temp1, -25); + localptr[3] = JLE8(0); + + NEG32R(temp1); + DEC32R(temp1); + MOV32ItoR(temp2, 0xffffffff); + SHL32CLtoR(temp2); + SSE2_PCMPEQB_XMM_to_XMM(regd, regd); + if (is_mem) { + SSE_PINSRW_R32_to_XMM(regd, temp2, 0); + SHR32ItoR(temp2, 16); + SSE_PINSRW_R32_to_XMM(regd, temp2, 1); + } + else { + SSE2_MOVD_R_to_XMM(regt, temp2); + SSE_MOVSS_XMM_to_XMM(regd, regt); + SSE2_PCMPEQB_XMM_to_XMM(regt, regt); + } + localptr[4] = JMP8(0); + + x86SetJ8(localptr[0]); + MOV32ItoR(temp2, 0x80000000); + if (is_mem) + AND32RtoM((uptr)&VU_addsub_reg[1][0], temp2); + else { + SSE2_PCMPEQB_XMM_to_XMM(regt, regt); + SSE2_MOVD_R_to_XMM(regd, temp2); + SSE_MOVSS_XMM_to_XMM(regt, regd); + } + SSE2_PCMPEQB_XMM_to_XMM(regd, regd); + localptr[5] = JMP8(0); + + x86SetJ8(localptr[1]); + DEC32R(temp1); + MOV32ItoR(temp2, 0xffffffff); + SHL32CLtoR(temp2); + if (is_mem) + AND32RtoM((uptr)&VU_addsub_reg[1][0], temp2); + else { + SSE2_PCMPEQB_XMM_to_XMM(regt, regt); + SSE2_MOVD_R_to_XMM(regd, temp2); + SSE_MOVSS_XMM_to_XMM(regt, regd); + } + SSE2_PCMPEQB_XMM_to_XMM(regd, regd); + localptr[6] = JMP8(0); + + x86SetJ8(localptr[3]); + MOV32ItoR(temp2, 0x80000000); + SSE2_PCMPEQB_XMM_to_XMM(regd, regd); + if (is_mem) { + SSE_PINSRW_R32_to_XMM(regd, temp2, 0); + SHR32ItoR(temp2, 16); + SSE_PINSRW_R32_to_XMM(regd, temp2, 1); + } + else { + SSE2_MOVD_R_to_XMM(regt, temp2); + SSE_MOVSS_XMM_to_XMM(regd, regt); + SSE2_PCMPEQB_XMM_to_XMM(regt, regt); + } + localptr[7] = JMP8(0); + + x86SetJ8(localptr[2]); + x86SetJ8(localptr[4]); + x86SetJ8(localptr[5]); + x86SetJ8(localptr[6]); + x86SetJ8(localptr[7]); + + if (is_mem) + { + SSE_ANDPS_M128_to_XMM(regd, (uptr)&VU_addsub_reg[0][0]); //regd contains mask + + if (is_sub) SSE_SUBSS_M32_to_XMM(regd, (uptr)&VU_addsub_reg[1][0]); + else SSE_ADDSS_M32_to_XMM(regd, (uptr)&VU_addsub_reg[1][0]); + } + else + { + SSE_ANDPS_M128_to_XMM(regd, (uptr)&VU_addsub_reg[0][0]); //regd contains mask + SSE_ANDPS_M128_to_XMM(regt, (uptr)&VU_addsub_reg[1][0]); //regt contains mask + + if (is_sub) SSE_SUBSS_XMM_to_XMM(regd, regt); + else SSE_ADDSS_XMM_to_XMM(regd, regt); + + SSE_MOVAPS_M128_to_XMM(regt, (uptr)&VU_addsub_reg[1][0]); + } + + _freeX86reg(temp2); + + MOV32MtoR(ECX, (uptr)&tempECX); +} + +void SSE_ADDPS_XMM_to_XMM_custom(int info, int regd, int regt) { + if (CHECK_VUADDSUBHACK) { + VU_ADD_SUB(regd, regt, 0, info); + } + else SSE_ADDPS_XMM_to_XMM(regd, regt); +} +void SSE_SUBPS_XMM_to_XMM_custom(int info, int regd, int regt) { + if (CHECK_VUADDSUBHACK) { + VU_ADD_SUB(regd, regt, 1, info); + } + else SSE_SUBPS_XMM_to_XMM(regd, regt); +} +void SSE_ADDSS_XMM_to_XMM_custom(int info, int regd, int regt) { + if (CHECK_VUADDSUBHACK) { + VU_ADD_SUB_SS(regd, regt, 0, 0, info); + } + else SSE_ADDSS_XMM_to_XMM(regd, regt); +} +void SSE_SUBSS_XMM_to_XMM_custom(int info, int regd, int regt) { + if (CHECK_VUADDSUBHACK) { + VU_ADD_SUB_SS(regd, regt, 1, 0, info); + } + else SSE_SUBSS_XMM_to_XMM(regd, regt); +} +void SSE_ADDSS_M32_to_XMM_custom(int info, int regd, int regt) { + if (CHECK_VUADDSUBHACK) { + VU_ADD_SUB_SS(regd, regt, 0, 1, info); + } + else SSE_ADDSS_M32_to_XMM(regd, regt); +} +void SSE_SUBSS_M32_to_XMM_custom(int info, int regd, int regt) { + if (CHECK_VUADDSUBHACK) { + VU_ADD_SUB_SS(regd, regt, 1, 1, info); + } + else SSE_SUBSS_M32_to_XMM(regd, regt); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// *VU Upper Instructions!* +// +// Note: * = Checked for errors by cottonvibes +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ABS* +//------------------------------------------------------------------ +void recVUMI_ABS(VURegs *VU, int info) +{ + //Console::WriteLn("recVUMI_ABS()"); + if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; + + if ((_X_Y_Z_W == 0x8) || (_X_Y_Z_W == 0xf)) { + VU_MERGE_REGS(EEREC_T, EEREC_S); + SSE_ANDPS_M128_to_XMM(EEREC_T, (uptr)&const_abs_table[ _X_Y_Z_W ][ 0 ] ); + } + else { // Use a temp reg because VU_MERGE_REGS() modifies source reg! + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_abs_table[ _X_Y_Z_W ][ 0 ] ); + VU_MERGE_REGS(EEREC_T, EEREC_TEMP); + } +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ADD*, ADD_iq*, ADD_xyzw* +//------------------------------------------------------------------ +PCSX2_ALIGNED16(float s_two[4]) = {0,0,0,2}; +void recVUMI_ADD(VURegs *VU, int info) +{ + //Console::WriteLn("recVUMI_ADD()"); + if ( _X_Y_Z_W == 0 ) goto flagUpdate; // Don't do anything and just clear flags + if ( !_Fd_ ) info = (info & ~PROCESS_EE_SET_D(0xf)) | PROCESS_EE_SET_D(EEREC_TEMP); + + if ( _Fs_ == 0 && _Ft_ == 0 ) { // if adding VF00 with VF00, then the result is always 0,0,0,2 + if ( _X_Y_Z_W != 0xf ) { + SSE_MOVAPS_M128_to_XMM(EEREC_TEMP, (uptr)s_two); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else SSE_MOVAPS_M128_to_XMM(EEREC_D, (uptr)s_two); + } + else { + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); + } + if( _X_Y_Z_W == 8 ) { // If only adding x, then we can do a Scalar Add + if (EEREC_D == EEREC_S) SSE_ADDSS_XMM_to_XMM(EEREC_D, EEREC_T); + else if (EEREC_D == EEREC_T) SSE_ADDSS_XMM_to_XMM(EEREC_D, EEREC_S); + else { + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_ADDSS_XMM_to_XMM(EEREC_D, EEREC_T); + } + } + else if (_X_Y_Z_W != 0xf) { // If xyzw != 1111, then we have to use a temp reg + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else { // All xyzw being modified (xyzw == 1111) + if (EEREC_D == EEREC_S) SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_T); + else if (EEREC_D == EEREC_T) SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_T); + } + } + } +flagUpdate: + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_ADD_iq(VURegs *VU, uptr addr, int info) +{ + //Console::WriteLn("recVUMI_ADD_iq()"); + if ( _X_Y_Z_W == 0 ) goto flagUpdate; + if ( !_Fd_ ) info = (info & ~PROCESS_EE_SET_D(0xf)) | PROCESS_EE_SET_D(EEREC_TEMP); + if (CHECK_VU_EXTRA_OVERFLOW) { + vuFloat3(addr); + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + } + + if ( _XYZW_SS ) { + if ( EEREC_D == EEREC_TEMP ) { + _vuFlipRegSS(VU, EEREC_S); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_ADDSS_M32_to_XMM(EEREC_D, addr); + _vuFlipRegSS(VU, EEREC_S); + _vuFlipRegSS(VU, EEREC_D); // have to flip over EEREC_D for computing flags! + } + else if ( EEREC_D == EEREC_S ) { + _vuFlipRegSS(VU, EEREC_D); + SSE_ADDSS_M32_to_XMM(EEREC_D, addr); + _vuFlipRegSS(VU, EEREC_D); + } + else { + if ( _X ) { + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_ADDSS_M32_to_XMM_custom(info, EEREC_D, addr); + } + else { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + SSE_ADDPS_XMM_to_XMM_custom(info, EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + } + } + else { + if ( (_X_Y_Z_W != 0xf) || (EEREC_D == EEREC_S) || (EEREC_D == EEREC_TEMP) ) { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + } + + if (_X_Y_Z_W != 0xf) { + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else { + if ( EEREC_D == EEREC_TEMP ) SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); + else if ( EEREC_D == EEREC_S ) SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + else { + SSE_MOVSS_M32_to_XMM(EEREC_D, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_D, EEREC_D, 0x00); + SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); + } + } + } +flagUpdate: + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_ADD_xyzw(VURegs *VU, int xyzw, int info) +{ + //Console::WriteLn("recVUMI_ADD_xyzw()"); + if ( _X_Y_Z_W == 0 ) goto flagUpdate; + if ( !_Fd_ ) info = (info & ~PROCESS_EE_SET_D(0xf)) | PROCESS_EE_SET_D(EEREC_TEMP); + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); + } + + if ( _Ft_ == 0 && xyzw < 3 ) { // just move since adding zero + if ( _X_Y_Z_W == 0x8 ) { VU_MERGE_REGS(EEREC_D, EEREC_S); } + else if ( _X_Y_Z_W != 0xf ) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); + } + else if ( _X_Y_Z_W == 8 && (EEREC_D != EEREC_TEMP) ) { + if ( xyzw == 0 ) { + if ( EEREC_D == EEREC_T ) SSE_ADDSS_XMM_to_XMM(EEREC_D, EEREC_S); + else { + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_ADDSS_XMM_to_XMM(EEREC_D, EEREC_T); + } + } + else { + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_ADDSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + } + else if( _Fs_ == 0 && !_W ) { // just move + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else { + if ( _X_Y_Z_W != 0xf ) { + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else { + if( EEREC_D == EEREC_TEMP ) { _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); } + else if( EEREC_D == EEREC_S ) { _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); } + else { _unpackVF_xyzw(EEREC_D, EEREC_T, xyzw); SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); } + } + } +flagUpdate: + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_ADDi(VURegs *VU, int info) { recVUMI_ADD_iq(VU, VU_VI_ADDR(REG_I, 1), info); } +void recVUMI_ADDq(VURegs *VU, int info) { recVUMI_ADD_iq(VU, VU_REGQ_ADDR, info); } +void recVUMI_ADDx(VURegs *VU, int info) { recVUMI_ADD_xyzw(VU, 0, info); } +void recVUMI_ADDy(VURegs *VU, int info) { recVUMI_ADD_xyzw(VU, 1, info); } +void recVUMI_ADDz(VURegs *VU, int info) { recVUMI_ADD_xyzw(VU, 2, info); } +void recVUMI_ADDw(VURegs *VU, int info) { recVUMI_ADD_xyzw(VU, 3, info); } +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ADDA*, ADDA_iq*, ADDA_xyzw* +//------------------------------------------------------------------ +void recVUMI_ADDA(VURegs *VU, int info) +{ + //Console::WriteLn("recVUMI_ADDA()"); + if ( _X_Y_Z_W == 0 ) goto flagUpdate; + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); + } + + if( _X_Y_Z_W == 8 ) { + if (EEREC_ACC == EEREC_S) SSE_ADDSS_XMM_to_XMM(EEREC_ACC, EEREC_T); // Can this case happen? (cottonvibes) + else if (EEREC_ACC == EEREC_T) SSE_ADDSS_XMM_to_XMM(EEREC_ACC, EEREC_S); // Can this case happen? + else { + SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); + SSE_ADDSS_XMM_to_XMM(EEREC_ACC, EEREC_T); + } + } + else if (_X_Y_Z_W != 0xf) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + + VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); + } + else { + if( EEREC_ACC == EEREC_S ) SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_T); // Can this case happen? + else if( EEREC_ACC == EEREC_T ) SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_S); // Can this case happen? + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_ACC, EEREC_S); + SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_T); + } + } +flagUpdate: + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_ADDA_iq(VURegs *VU, uptr addr, int info) +{ + //Console::WriteLn("recVUMI_ADDA_iq()"); + if ( _X_Y_Z_W == 0 ) goto flagUpdate; + if (CHECK_VU_EXTRA_OVERFLOW) { + vuFloat3(addr); + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + } + + if( _XYZW_SS ) { + assert( EEREC_ACC != EEREC_TEMP ); + if( EEREC_ACC == EEREC_S ) { + _vuFlipRegSS(VU, EEREC_ACC); + SSE_ADDSS_M32_to_XMM(EEREC_ACC, addr); + _vuFlipRegSS(VU, EEREC_ACC); + } + else { + if( _X ) { + SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); + SSE_ADDSS_M32_to_XMM(EEREC_ACC, addr); + } + else { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); + } + } + } + else { + if( _X_Y_Z_W != 0xf || EEREC_ACC == EEREC_S ) { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + } + + if (_X_Y_Z_W != 0xf) { + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); + } + else { + if( EEREC_ACC == EEREC_S ) SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); + else { + SSE_MOVSS_M32_to_XMM(EEREC_ACC, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_ACC, EEREC_ACC, 0x00); + SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_S); + } + } + } +flagUpdate: + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_ADDA_xyzw(VURegs *VU, int xyzw, int info) +{ + //Console::WriteLn("recVUMI_ADDA_xyzw()"); + if ( _X_Y_Z_W == 0 ) goto flagUpdate; + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); + } + + if( _X_Y_Z_W == 8 ) { + assert( EEREC_ACC != EEREC_T ); + if( xyzw == 0 ) { + SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); + SSE_ADDSS_XMM_to_XMM(EEREC_ACC, EEREC_T); + } + else { + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); + if( _Fs_ == 0 ) { + SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); + } + else { + SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); + SSE_ADDSS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); + } + } + } + else { + if( _X_Y_Z_W != 0xf || EEREC_ACC == EEREC_S ) + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); + + if (_X_Y_Z_W != 0xf) { + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); + } + else { + if( EEREC_ACC == EEREC_S ) SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); + else { + _unpackVF_xyzw(EEREC_ACC, EEREC_T, xyzw); + SSE_ADDPS_XMM_to_XMM(EEREC_ACC, EEREC_S); + } + } + } +flagUpdate: + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_ADDAi(VURegs *VU, int info) { recVUMI_ADDA_iq(VU, VU_VI_ADDR(REG_I, 1), info); } +void recVUMI_ADDAq(VURegs *VU, int info) { recVUMI_ADDA_iq(VU, VU_REGQ_ADDR, info); } +void recVUMI_ADDAx(VURegs *VU, int info) { recVUMI_ADDA_xyzw(VU, 0, info); } +void recVUMI_ADDAy(VURegs *VU, int info) { recVUMI_ADDA_xyzw(VU, 1, info); } +void recVUMI_ADDAz(VURegs *VU, int info) { recVUMI_ADDA_xyzw(VU, 2, info); } +void recVUMI_ADDAw(VURegs *VU, int info) { recVUMI_ADDA_xyzw(VU, 3, info); } +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// SUB*, SUB_iq*, SUB_xyzw* +//------------------------------------------------------------------ +void recVUMI_SUB(VURegs *VU, int info) +{ + //Console::WriteLn("recVUMI_SUB()"); + if ( _X_Y_Z_W == 0 ) goto flagUpdate; + if ( !_Fd_ ) info = (info & ~PROCESS_EE_SET_D(0xf)) | PROCESS_EE_SET_D(EEREC_TEMP); + + if( EEREC_S == EEREC_T ) { + if (_X_Y_Z_W != 0xf) SSE_ANDPS_M128_to_XMM(EEREC_D, (uptr)&SSEmovMask[15-_X_Y_Z_W][0]); + else SSE_XORPS_XMM_to_XMM(EEREC_D, EEREC_D); + } + else if( _X_Y_Z_W == 8 ) { + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); + } + if (EEREC_D == EEREC_S) { + if (_Ft_) SSE_SUBSS_XMM_to_XMM(EEREC_D, EEREC_T); + } + else if (EEREC_D == EEREC_T) { + if (_Ft_) { + SSE_MOVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_SUBSS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + else SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + } + else { + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + if (_Ft_) SSE_SUBSS_XMM_to_XMM(EEREC_D, EEREC_T); + } + } + else { + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); + } + if (_X_Y_Z_W != 0xf) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if( ( _Ft_ > 0 ) || _W ) SSE_SUBPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else { + if (EEREC_D == EEREC_S) SSE_SUBPS_XMM_to_XMM(EEREC_D, EEREC_T); + else if (EEREC_D == EEREC_T) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_SUBPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_SUBPS_XMM_to_XMM(EEREC_D, EEREC_T); + } + } + } +flagUpdate: + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_SUB_iq(VURegs *VU, uptr addr, int info) +{ + //Console::WriteLn("recVUMI_SUB_iq()"); + if ( _X_Y_Z_W == 0 ) goto flagUpdate; + if (CHECK_VU_EXTRA_OVERFLOW) { + vuFloat3(addr); + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + } + if ( !_Fd_ ) info = (info & ~PROCESS_EE_SET_D(0xf)) | PROCESS_EE_SET_D(EEREC_TEMP); + + if( _XYZW_SS ) { + if( EEREC_D == EEREC_TEMP ) { + _vuFlipRegSS(VU, EEREC_S); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_SUBSS_M32_to_XMM(EEREC_D, addr); + _vuFlipRegSS(VU, EEREC_S); + _vuFlipRegSS(VU, EEREC_D); + } + else if( EEREC_D == EEREC_S ) { + _vuFlipRegSS(VU, EEREC_D); + SSE_SUBSS_M32_to_XMM(EEREC_D, addr); + _vuFlipRegSS(VU, EEREC_D); + } + else { + if( _X ) { + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_SUBSS_M32_to_XMM(EEREC_D, addr); + } + else { + _vuMoveSS(VU, EEREC_TEMP, EEREC_S); + _vuFlipRegSS(VU, EEREC_D); + SSE_SUBSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + _vuFlipRegSS(VU, EEREC_D); + } + } + } + else { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + + if (_X_Y_Z_W != 0xf) { + int t1reg = _vuGetTempXMMreg(info); + + if( t1reg >= 0 ) { + SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_S); + SSE_SUBPS_XMM_to_XMM(t1reg, EEREC_TEMP); + + VU_MERGE_REGS(EEREC_D, t1reg); + _freeXMMreg(t1reg); + } + else { + // negate + SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + } + else { + if( EEREC_D == EEREC_TEMP ) { + SSE_XORPS_M128_to_XMM(EEREC_D, (uptr)&const_clip[4]); + SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); + } + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_SUBPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + } + } +flagUpdate: + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_SUB_xyzw(VURegs *VU, int xyzw, int info) +{ + //Console::WriteLn("recVUMI_SUB_xyzw()"); + if ( _X_Y_Z_W == 0 ) goto flagUpdate; + if ( !_Fd_ ) info = (info & ~PROCESS_EE_SET_D(0xf)) | PROCESS_EE_SET_D(EEREC_TEMP); + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); + } + + if ( _X_Y_Z_W == 8 ) { + if ( (xyzw == 0) && (_Ft_ == _Fs_) ) { + SSE_ANDPS_M128_to_XMM(EEREC_D, (uptr)&SSEmovMask[7][0]); + } + else if ( EEREC_D == EEREC_TEMP ) { + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + if ( (_Ft_ > 0) || (xyzw == 3) ) { + _vuFlipRegSS_xyzw(EEREC_T, xyzw); + SSE_SUBSS_XMM_to_XMM(EEREC_D, EEREC_T); + _vuFlipRegSS_xyzw(EEREC_T, xyzw); + } + } + else { + if ( (_Ft_ > 0) || (xyzw == 3) ) { + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_SUBSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + else SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + } + } + else { + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); + + if (_X_Y_Z_W != 0xf) { + int t1reg = _vuGetTempXMMreg(info); + + if( t1reg >= 0 ) { + SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_S); + SSE_SUBPS_XMM_to_XMM(t1reg, EEREC_TEMP); + + VU_MERGE_REGS(EEREC_D, t1reg); + _freeXMMreg(t1reg); + } + else { + // negate + SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + } + else { + if( EEREC_D == EEREC_TEMP ) { + SSE_XORPS_M128_to_XMM(EEREC_D, (uptr)&const_clip[4]); + SSE_ADDPS_XMM_to_XMM(EEREC_D, EEREC_S); + } + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_SUBPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + } + } +flagUpdate: + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_SUBi(VURegs *VU, int info) { recVUMI_SUB_iq(VU, VU_VI_ADDR(REG_I, 1), info); } +void recVUMI_SUBq(VURegs *VU, int info) { recVUMI_SUB_iq(VU, VU_REGQ_ADDR, info); } +void recVUMI_SUBx(VURegs *VU, int info) { recVUMI_SUB_xyzw(VU, 0, info); } +void recVUMI_SUBy(VURegs *VU, int info) { recVUMI_SUB_xyzw(VU, 1, info); } +void recVUMI_SUBz(VURegs *VU, int info) { recVUMI_SUB_xyzw(VU, 2, info); } +void recVUMI_SUBw(VURegs *VU, int info) { recVUMI_SUB_xyzw(VU, 3, info); } +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// SUBA*, SUBA_iq, SUBA_xyzw +//------------------------------------------------------------------ +void recVUMI_SUBA(VURegs *VU, int info) +{ + //Console::WriteLn("recVUMI_SUBA()"); + if ( _X_Y_Z_W == 0 ) goto flagUpdate; + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); + } + + if( EEREC_S == EEREC_T ) { + if (_X_Y_Z_W != 0xf) SSE_ANDPS_M128_to_XMM(EEREC_ACC, (uptr)&SSEmovMask[15-_X_Y_Z_W][0]); + else SSE_XORPS_XMM_to_XMM(EEREC_ACC, EEREC_ACC); + } + else if( _X_Y_Z_W == 8 ) { + if (EEREC_ACC == EEREC_S) SSE_SUBSS_XMM_to_XMM(EEREC_ACC, EEREC_T); + else if (EEREC_ACC == EEREC_T) { + SSE_MOVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_SUBSS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); + } + else { + SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); + SSE_SUBSS_XMM_to_XMM(EEREC_ACC, EEREC_T); + } + } + else if (_X_Y_Z_W != 0xf) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_SUBPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + + VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); + } + else { + if( EEREC_ACC == EEREC_S ) SSE_SUBPS_XMM_to_XMM(EEREC_ACC, EEREC_T); + else if( EEREC_ACC == EEREC_T ) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_SUBPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + SSE_MOVAPS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); + } + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_ACC, EEREC_S); + SSE_SUBPS_XMM_to_XMM(EEREC_ACC, EEREC_T); + } + } +flagUpdate: + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_SUBA_iq(VURegs *VU, uptr addr, int info) +{ + //Console::WriteLn ("recVUMI_SUBA_iq"); + if (CHECK_VU_EXTRA_OVERFLOW) { + vuFloat3(addr); + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + } + + if( _XYZW_SS ) { + if( EEREC_ACC == EEREC_S ) { + _vuFlipRegSS(VU, EEREC_ACC); + SSE_SUBSS_M32_to_XMM(EEREC_ACC, addr); + _vuFlipRegSS(VU, EEREC_ACC); + } + else { + if( _X ) { + SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); + SSE_SUBSS_M32_to_XMM(EEREC_ACC, addr); + } + else { + _vuMoveSS(VU, EEREC_TEMP, EEREC_S); + _vuFlipRegSS(VU, EEREC_ACC); + SSE_SUBSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); + _vuFlipRegSS(VU, EEREC_ACC); + } + } + } + else { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + + if (_X_Y_Z_W != 0xf) { + int t1reg = _vuGetTempXMMreg(info); + + if( t1reg >= 0 ) { + SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_S); + SSE_SUBPS_XMM_to_XMM(t1reg, EEREC_TEMP); + + VU_MERGE_REGS(EEREC_ACC, t1reg); + _freeXMMreg(t1reg); + } + else { + // negate + SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); + } + } + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_ACC, EEREC_S); + SSE_SUBPS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); + } + } + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_SUBA_xyzw(VURegs *VU, int xyzw, int info) +{ + //Console::WriteLn ("recVUMI_SUBA_xyzw"); + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); + } + + if( _X_Y_Z_W == 8 ) { + if( xyzw == 0 ) { + SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); + SSE_SUBSS_XMM_to_XMM(EEREC_ACC, EEREC_T); + } + else { + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); + SSE_MOVSS_XMM_to_XMM(EEREC_ACC, EEREC_S); + SSE_SUBSS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); + } + } + else { + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); + + if (_X_Y_Z_W != 0xf) { + int t1reg = _vuGetTempXMMreg(info); + + if( t1reg >= 0 ) { + SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_S); + SSE_SUBPS_XMM_to_XMM(t1reg, EEREC_TEMP); + + VU_MERGE_REGS(EEREC_ACC, t1reg); + _freeXMMreg(t1reg); + } + else { + // negate + SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_ACC, EEREC_TEMP); + } + } + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_ACC, EEREC_S); + SSE_SUBPS_XMM_to_XMM(EEREC_ACC, EEREC_TEMP); + } + } + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_SUBAi(VURegs *VU, int info) { recVUMI_SUBA_iq(VU, VU_VI_ADDR(REG_I, 1), info); } +void recVUMI_SUBAq(VURegs *VU, int info) { recVUMI_SUBA_iq(VU, VU_REGQ_ADDR, info); } +void recVUMI_SUBAx(VURegs *VU, int info) { recVUMI_SUBA_xyzw(VU, 0, info); } +void recVUMI_SUBAy(VURegs *VU, int info) { recVUMI_SUBA_xyzw(VU, 1, info); } +void recVUMI_SUBAz(VURegs *VU, int info) { recVUMI_SUBA_xyzw(VU, 2, info); } +void recVUMI_SUBAw(VURegs *VU, int info) { recVUMI_SUBA_xyzw(VU, 3, info); } +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// MUL +//------------------------------------------------------------------ +void recVUMI_MUL_toD(VURegs *VU, int regd, int info) +{ + //Console::WriteLn ("recVUMI_MUL_toD"); + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); + } + + if (_X_Y_Z_W == 1 && (_Ft_ == 0 || _Fs_==0) ) { // W + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, _Ft_ ? EEREC_T : EEREC_S); + VU_MERGE_REGS(regd, EEREC_TEMP); + } + else if( _Fd_ == _Fs_ && _Fs_ == _Ft_ && _XYZW_SS ) { + _vuFlipRegSS(VU, EEREC_D); + SSE_MULSS_XMM_to_XMM(EEREC_D, EEREC_D); + _vuFlipRegSS(VU, EEREC_D); + } + else if( _X_Y_Z_W == 8 ) { + if (regd == EEREC_S) SSE_MULSS_XMM_to_XMM(regd, EEREC_T); + else if (regd == EEREC_T) SSE_MULSS_XMM_to_XMM(regd, EEREC_S); + else { + SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); + SSE_MULSS_XMM_to_XMM(regd, EEREC_T); + } + } + else if (_X_Y_Z_W != 0xf) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + + VU_MERGE_REGS(regd, EEREC_TEMP); + } + else { + if (regd == EEREC_S) SSE_MULPS_XMM_to_XMM(regd, EEREC_T); + else if (regd == EEREC_T) SSE_MULPS_XMM_to_XMM(regd, EEREC_S); + else { + SSE_MOVAPS_XMM_to_XMM(regd, EEREC_S); + SSE_MULPS_XMM_to_XMM(regd, EEREC_T); + } + } +} + +void recVUMI_MUL_iq_toD(VURegs *VU, uptr addr, int regd, int info) +{ + //Console::WriteLn ("recVUMI_MUL_iq_toD"); + if (CHECK_VU_EXTRA_OVERFLOW) { + vuFloat3(addr); + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + } + + if( _XYZW_SS ) { + if( regd == EEREC_TEMP ) { + _vuFlipRegSS(VU, EEREC_S); + SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); + SSE_MULSS_M32_to_XMM(regd, addr); + _vuFlipRegSS(VU, EEREC_S); + _vuFlipRegSS(VU, regd); + } + else if( regd == EEREC_S ) { + _vuFlipRegSS(VU, regd); + SSE_MULSS_M32_to_XMM(regd, addr); + _vuFlipRegSS(VU, regd); + } + else { + if( _X ) { + SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); + SSE_MULSS_M32_to_XMM(regd, addr); + } + else { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(regd, EEREC_TEMP); + } + } + } + else { + if( _X_Y_Z_W != 0xf || regd == EEREC_TEMP || regd == EEREC_S ) { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + } + + if (_X_Y_Z_W != 0xf) { + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(regd, EEREC_TEMP); + } + else { + if( regd == EEREC_TEMP ) SSE_MULPS_XMM_to_XMM(regd, EEREC_S); + else if (regd == EEREC_S) SSE_MULPS_XMM_to_XMM(regd, EEREC_TEMP); + else { + SSE_MOVSS_M32_to_XMM(regd, addr); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x00); + SSE_MULPS_XMM_to_XMM(regd, EEREC_S); + } + } + } +} + +void recVUMI_MUL_xyzw_toD(VURegs *VU, int xyzw, int regd, int info) +{ + //Console::WriteLn ("recVUMI_MUL_xyzw_toD"); + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); + } + if (_Fs_) { // This is needed for alot of games; so always clamp this operand + if (CHECK_VU_SIGN_OVERFLOW) vFloats4_useEAX[_X_Y_Z_W]( EEREC_S, EEREC_TEMP ); // Always clamp EEREC_S, regardless if CHECK_VU_OVERFLOW is set + else vFloats2[_X_Y_Z_W]( EEREC_S, EEREC_TEMP ); // Always clamp EEREC_S, regardless if CHECK_VU_OVERFLOW is set + } + if( _Ft_ == 0 ) { + if( xyzw < 3 ) { + if (_X_Y_Z_W != 0xf) { + SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); + VU_MERGE_REGS(regd, EEREC_TEMP); + } + else SSE_XORPS_XMM_to_XMM(regd, regd); + } + else { + assert(xyzw==3); + if (_X_Y_Z_W != 0xf) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(regd, EEREC_TEMP); + } + else SSE_MOVAPS_XMM_to_XMM(regd, EEREC_S); + } + } + else if( _X_Y_Z_W == 8 ) { + if( regd == EEREC_TEMP ) { + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); + SSE_MULSS_XMM_to_XMM(regd, EEREC_S); + } + else { + if( xyzw == 0 ) { + if( regd == EEREC_T ) { + SSE_MULSS_XMM_to_XMM(regd, EEREC_S); + } + else { + SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); + SSE_MULSS_XMM_to_XMM(regd, EEREC_T); + } + } + else { + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); + SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); + SSE_MULSS_XMM_to_XMM(regd, EEREC_TEMP); + } + } + } + else { + if( _X_Y_Z_W != 0xf || regd == EEREC_TEMP || regd == EEREC_S ) + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); + + if (_X_Y_Z_W != 0xf) { + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(regd, EEREC_TEMP); + } + else { + if( regd == EEREC_TEMP ) SSE_MULPS_XMM_to_XMM(regd, EEREC_S); + else if (regd == EEREC_S) SSE_MULPS_XMM_to_XMM(regd, EEREC_TEMP); + else { + _unpackVF_xyzw(regd, EEREC_T, xyzw); + SSE_MULPS_XMM_to_XMM(regd, EEREC_S); + } + } + } +} + +void recVUMI_MUL(VURegs *VU, int info) +{ + //Console::WriteLn ("recVUMI_MUL"); + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + recVUMI_MUL_toD(VU, EEREC_D, info); + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_MUL_iq(VURegs *VU, int addr, int info) +{ + //Console::WriteLn ("recVUMI_MUL_iq"); + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + recVUMI_MUL_iq_toD(VU, addr, EEREC_D, info); + recUpdateFlags(VU, EEREC_D, info); + // spacefisherman needs overflow checking on MULi.z +} + +void recVUMI_MUL_xyzw(VURegs *VU, int xyzw, int info) +{ + //Console::WriteLn ("recVUMI_MUL_xyzw"); + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + recVUMI_MUL_xyzw_toD(VU, xyzw, EEREC_D, info); + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_MULi(VURegs *VU, int info) { recVUMI_MUL_iq(VU, VU_VI_ADDR(REG_I, 1), info); } +void recVUMI_MULq(VURegs *VU, int info) { recVUMI_MUL_iq(VU, VU_REGQ_ADDR, info); } +void recVUMI_MULx(VURegs *VU, int info) { recVUMI_MUL_xyzw(VU, 0, info); } +void recVUMI_MULy(VURegs *VU, int info) { recVUMI_MUL_xyzw(VU, 1, info); } +void recVUMI_MULz(VURegs *VU, int info) { recVUMI_MUL_xyzw(VU, 2, info); } +void recVUMI_MULw(VURegs *VU, int info) { recVUMI_MUL_xyzw(VU, 3, info); } +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// MULA +//------------------------------------------------------------------ +void recVUMI_MULA( VURegs *VU, int info ) +{ + //Console::WriteLn ("recVUMI_MULA"); + recVUMI_MUL_toD(VU, EEREC_ACC, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MULA_iq(VURegs *VU, int addr, int info) +{ + //Console::WriteLn ("recVUMI_MULA_iq"); + recVUMI_MUL_iq_toD(VU, addr, EEREC_ACC, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MULA_xyzw(VURegs *VU, int xyzw, int info) +{ + //Console::WriteLn ("recVUMI_MULA_xyzw"); + recVUMI_MUL_xyzw_toD(VU, xyzw, EEREC_ACC, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MULAi(VURegs *VU, int info) { recVUMI_MULA_iq(VU, VU_VI_ADDR(REG_I, 1), info); } +void recVUMI_MULAq(VURegs *VU, int info) { recVUMI_MULA_iq(VU, VU_REGQ_ADDR, info); } +void recVUMI_MULAx(VURegs *VU, int info) { recVUMI_MULA_xyzw(VU, 0, info); } +void recVUMI_MULAy(VURegs *VU, int info) { recVUMI_MULA_xyzw(VU, 1, info); } +void recVUMI_MULAz(VURegs *VU, int info) { recVUMI_MULA_xyzw(VU, 2, info); } +void recVUMI_MULAw(VURegs *VU, int info) { recVUMI_MULA_xyzw(VU, 3, info); } +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// MADD +//------------------------------------------------------------------ +void recVUMI_MADD_toD(VURegs *VU, int regd, int info) +{ + //Console::WriteLn ("recVUMI_MADD_toD"); + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); + vuFloat5_useEAX( EEREC_ACC, EEREC_TEMP, _X_Y_Z_W ); + } + + + if( _X_Y_Z_W == 8 ) { + if( regd == EEREC_ACC ) { + SSE_MOVSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_MULSS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, 8); } + SSE_ADDSS_XMM_to_XMM(regd, EEREC_TEMP); + } + else if (regd == EEREC_T) { + SSE_MULSS_XMM_to_XMM(regd, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, 8); } + SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); + } + else if (regd == EEREC_S) { + SSE_MULSS_XMM_to_XMM(regd, EEREC_T); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, 8); } + SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); + } + else { + SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); + SSE_MULSS_XMM_to_XMM(regd, EEREC_T); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, 8); } + SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); + } + } + else if (_X_Y_Z_W != 0xf) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); + + VU_MERGE_REGS(regd, EEREC_TEMP); + } + else { + if( regd == EEREC_ACC ) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_TEMP); + } + else if (regd == EEREC_T) { + SSE_MULPS_XMM_to_XMM(regd, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); + } + else if (regd == EEREC_S) { + SSE_MULPS_XMM_to_XMM(regd, EEREC_T); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); + } + else { + SSE_MOVAPS_XMM_to_XMM(regd, EEREC_S); + SSE_MULPS_XMM_to_XMM(regd, EEREC_T); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); + } + } +} + +void recVUMI_MADD_iq_toD(VURegs *VU, uptr addr, int regd, int info) +{ + //Console::WriteLn ("recVUMI_MADD_iq_toD"); + if (CHECK_VU_EXTRA_OVERFLOW) { + vuFloat3(addr); + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + vuFloat5_useEAX( EEREC_ACC, EEREC_TEMP, _X_Y_Z_W ); + } + + if( _X_Y_Z_W == 8 ) { + if( _Fs_ == 0 ) { + // do nothing if regd == ACC (ACCx <= ACCx + 0.0 * *addr) + if( regd != EEREC_ACC ) { + SSE_MOVSS_XMM_to_XMM(regd, EEREC_ACC); + } + return; + } + + if( regd == EEREC_ACC ) { + assert( EEREC_TEMP < iREGCNT_XMM ); + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_MULSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, 8); } + SSE_ADDSS_XMM_to_XMM(regd, EEREC_TEMP); + } + else if( regd == EEREC_S ) { + SSE_MULSS_M32_to_XMM(regd, addr); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); + } + else { + SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); + SSE_MULSS_M32_to_XMM(regd, addr); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); + } + } + else { + if( _Fs_ == 0 ) { + if( regd == EEREC_ACC ) { // ACCxyz is unchanged, ACCw <= ACCw + *addr + if( _W ) { // if _W is zero, do nothing + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); // { *addr, 0, 0, 0 } + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x27); // { 0, 0, 0, *addr } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_TEMP); // { ACCx, ACCy, ACCz, ACCw + *addr } + } + } + else { // DESTxyz <= ACCxyz, DESTw <= ACCw + *addr + if( _W ) { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); // { *addr, 0, 0, 0 } + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x27); // { 0, 0, 0, *addr } + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); // { ACCx, ACCy, ACCz, ACCw + *addr } + } + else SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); + VU_MERGE_REGS(regd, EEREC_TEMP); + } + + return; + } + + if( _X_Y_Z_W != 0xf || regd == EEREC_ACC || regd == EEREC_TEMP || regd == EEREC_S ) { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + } + + if (_X_Y_Z_W != 0xf) { + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); + + VU_MERGE_REGS(regd, EEREC_TEMP); + } + else { + if( regd == EEREC_ACC ) { + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_TEMP); + } + else if( regd == EEREC_S ) { + SSE_MULPS_XMM_to_XMM(regd, EEREC_TEMP); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); + } + else if( regd == EEREC_TEMP ) { + SSE_MULPS_XMM_to_XMM(regd, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); + } + else { + SSE_MOVSS_M32_to_XMM(regd, addr); + SSE_SHUFPS_XMM_to_XMM(regd, regd, 0x00); + SSE_MULPS_XMM_to_XMM(regd, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); + } + } + } +} + +void recVUMI_MADD_xyzw_toD(VURegs *VU, int xyzw, int regd, int info) +{ + //Console::WriteLn ("recVUMI_MADD_xyzw_toD"); + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); + vuFloat5_useEAX( EEREC_ACC, EEREC_TEMP, _X_Y_Z_W ); + } + if (_Fs_) { // This is needed for alot of games; so always clamp this operand + if (CHECK_VU_SIGN_OVERFLOW) vFloats4_useEAX[_X_Y_Z_W]( EEREC_S, EEREC_TEMP ); // Always clamp EEREC_S, regardless if CHECK_VU_OVERFLOW is set + else vFloats2[_X_Y_Z_W]( EEREC_S, EEREC_TEMP ); // Always clamp EEREC_S, regardless if CHECK_VU_OVERFLOW is set + } + if( _Ft_ == 0 ) { + + if( xyzw == 3 ) { + // just add + if( _X_Y_Z_W == 8 ) { + if( regd == EEREC_S ) SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); + else { + SSE_MOVSS_XMM_to_XMM(regd, EEREC_ACC); + SSE_ADDSS_XMM_to_XMM(regd, EEREC_S); + } + } + else { + if( _X_Y_Z_W != 0xf ) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); + + VU_MERGE_REGS(regd, EEREC_TEMP); + } + else { + if( regd == EEREC_S ) SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); + else { + SSE_MOVAPS_XMM_to_XMM(regd, EEREC_ACC); + SSE_ADDPS_XMM_to_XMM(regd, EEREC_S); + } + } + } + } + else { + // just move acc to regd + if( _X_Y_Z_W != 0xf ) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); + VU_MERGE_REGS(regd, EEREC_TEMP); + } + else SSE_MOVAPS_XMM_to_XMM(regd, EEREC_ACC); + } + + return; + } + + if( _X_Y_Z_W == 8 ) { + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); + + if( regd == EEREC_ACC ) { + SSE_MULSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, 8); } + SSE_ADDSS_XMM_to_XMM(regd, EEREC_TEMP); + } + else if( regd == EEREC_S ) { + SSE_MULSS_XMM_to_XMM(regd, EEREC_TEMP); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, 8); } + SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); + } + else if( regd == EEREC_TEMP ) { + SSE_MULSS_XMM_to_XMM(regd, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, 8); } + SSE_ADDSS_XMM_to_XMM(regd, EEREC_ACC); + } + else { + SSE_MOVSS_XMM_to_XMM(regd, EEREC_ACC); + SSE_MULSS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, 8); } + SSE_ADDSS_XMM_to_XMM(regd, EEREC_TEMP); + } + } + else { + if( _X_Y_Z_W != 0xf || regd == EEREC_ACC || regd == EEREC_TEMP || regd == EEREC_S ) { + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); + } + + if (_X_Y_Z_W != 0xf) { + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); + + VU_MERGE_REGS(regd, EEREC_TEMP); + } + else { + if( regd == EEREC_ACC ) { + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_TEMP); + } + else if( regd == EEREC_S ) { + SSE_MULPS_XMM_to_XMM(regd, EEREC_TEMP); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); + } + else if( regd == EEREC_TEMP ) { + SSE_MULPS_XMM_to_XMM(regd, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); + } + else { + _unpackVF_xyzw(regd, EEREC_T, xyzw); + SSE_MULPS_XMM_to_XMM(regd, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_ADDPS_XMM_to_XMM(regd, EEREC_ACC); + } + } + } +} + +void recVUMI_MADD(VURegs *VU, int info) +{ + //Console::WriteLn ("recVUMI_MADD"); + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + recVUMI_MADD_toD(VU, EEREC_D, info); + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_MADD_iq(VURegs *VU, int addr, int info) +{ + //Console::WriteLn ("recVUMI_MADD_iq"); + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + recVUMI_MADD_iq_toD(VU, addr, EEREC_D, info); + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_MADD_xyzw(VURegs *VU, int xyzw, int info) +{ + //Console::WriteLn ("recVUMI_MADD_xyzw"); + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + recVUMI_MADD_xyzw_toD(VU, xyzw, EEREC_D, info); + recUpdateFlags(VU, EEREC_D, info); + // super bust-a-move arrows needs overflow clamping +} + +void recVUMI_MADDi(VURegs *VU, int info) { recVUMI_MADD_iq(VU, VU_VI_ADDR(REG_I, 1), info); } +void recVUMI_MADDq(VURegs *VU, int info) { recVUMI_MADD_iq(VU, VU_REGQ_ADDR, info); } +void recVUMI_MADDx(VURegs *VU, int info) { recVUMI_MADD_xyzw(VU, 0, info); } +void recVUMI_MADDy(VURegs *VU, int info) { recVUMI_MADD_xyzw(VU, 1, info); } +void recVUMI_MADDz(VURegs *VU, int info) { recVUMI_MADD_xyzw(VU, 2, info); } +void recVUMI_MADDw(VURegs *VU, int info) { recVUMI_MADD_xyzw(VU, 3, info); } +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// MADDA +//------------------------------------------------------------------ +void recVUMI_MADDA( VURegs *VU, int info ) +{ + //Console::WriteLn ("recVUMI_MADDA"); + recVUMI_MADD_toD(VU, EEREC_ACC, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MADDAi( VURegs *VU , int info) +{ + //Console::WriteLn ("recVUMI_MADDAi"); + recVUMI_MADD_iq_toD( VU, VU_VI_ADDR(REG_I, 1), EEREC_ACC, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MADDAq( VURegs *VU , int info) +{ + //Console::WriteLn ("recVUMI_MADDAq "); + recVUMI_MADD_iq_toD( VU, VU_REGQ_ADDR, EEREC_ACC, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MADDAx( VURegs *VU , int info) +{ + //Console::WriteLn ("recVUMI_MADDAx"); + recVUMI_MADD_xyzw_toD(VU, 0, EEREC_ACC, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MADDAy( VURegs *VU , int info) +{ + //Console::WriteLn ("recVUMI_MADDAy"); + recVUMI_MADD_xyzw_toD(VU, 1, EEREC_ACC, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MADDAz( VURegs *VU , int info) +{ + //Console::WriteLn ("recVUMI_MADDAz"); + recVUMI_MADD_xyzw_toD(VU, 2, EEREC_ACC, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MADDAw( VURegs *VU , int info) +{ + //Console::WriteLn ("recVUMI_MADDAw"); + recVUMI_MADD_xyzw_toD(VU, 3, EEREC_ACC, info); + recUpdateFlags(VU, EEREC_ACC, info); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// MSUB +//------------------------------------------------------------------ +void recVUMI_MSUB_toD(VURegs *VU, int regd, int info) +{ + //Console::WriteLn ("recVUMI_MSUB_toD"); + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); + vuFloat5_useEAX( EEREC_ACC, EEREC_TEMP, _X_Y_Z_W ); + } + + if (_X_Y_Z_W != 0xf) { + int t1reg = _vuGetTempXMMreg(info); + + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } + + if( t1reg >= 0 ) { + SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_ACC); + SSE_SUBPS_XMM_to_XMM(t1reg, EEREC_TEMP); + + VU_MERGE_REGS(regd, t1reg); + _freeXMMreg(t1reg); + } + else { + SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); + VU_MERGE_REGS(regd, EEREC_TEMP); + } + } + else { + if( regd == EEREC_S ) { + assert( regd != EEREC_ACC ); + SSE_MULPS_XMM_to_XMM(regd, EEREC_T); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_SUBPS_XMM_to_XMM(regd, EEREC_ACC); + SSE_XORPS_M128_to_XMM(regd, (uptr)&const_clip[4]); + } + else if( regd == EEREC_T ) { + assert( regd != EEREC_ACC ); + SSE_MULPS_XMM_to_XMM(regd, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_SUBPS_XMM_to_XMM(regd, EEREC_ACC); + SSE_XORPS_M128_to_XMM(regd, (uptr)&const_clip[4]); + } + else if( regd == EEREC_TEMP ) { + SSE_MOVAPS_XMM_to_XMM(regd, EEREC_S); + SSE_MULPS_XMM_to_XMM(regd, EEREC_T); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_SUBPS_XMM_to_XMM(regd, EEREC_ACC); + SSE_XORPS_M128_to_XMM(regd, (uptr)&const_clip[4]); + } + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_MOVAPS_XMM_to_XMM(regd, EEREC_ACC); + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } + SSE_SUBPS_XMM_to_XMM(regd, EEREC_TEMP); + } + } +} + +void recVUMI_MSUB_temp_toD(VURegs *VU, int regd, int info) +{ + //Console::WriteLn ("recVUMI_MSUB_temp_toD"); + + if (_X_Y_Z_W != 0xf) { + int t1reg = _vuGetTempXMMreg(info); + + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } + + if( t1reg >= 0 ) { + SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_ACC); + SSE_SUBPS_XMM_to_XMM(t1reg, EEREC_TEMP); + + if ( regd != EEREC_TEMP ) { VU_MERGE_REGS(regd, t1reg); } + else SSE_MOVAPS_XMM_to_XMM(regd, t1reg); + + _freeXMMreg(t1reg); + } + else { + SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); + VU_MERGE_REGS(regd, EEREC_TEMP); + } + } + else { + if( regd == EEREC_ACC ) { + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } + SSE_SUBPS_XMM_to_XMM(regd, EEREC_TEMP); + } + else if( regd == EEREC_S ) { + SSE_MULPS_XMM_to_XMM(regd, EEREC_TEMP); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_SUBPS_XMM_to_XMM(regd, EEREC_ACC); + SSE_XORPS_M128_to_XMM(regd, (uptr)&const_clip[4]); + } + else if( regd == EEREC_TEMP ) { + SSE_MULPS_XMM_to_XMM(regd, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, regd, _X_Y_Z_W ); } + SSE_SUBPS_XMM_to_XMM(regd, EEREC_ACC); + SSE_XORPS_M128_to_XMM(regd, (uptr)&const_clip[4]); + } + else { + SSE_MOVAPS_XMM_to_XMM(regd, EEREC_ACC); + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + if (CHECK_VU_EXTRA_OVERFLOW) { vuFloat_useEAX( info, EEREC_TEMP, _X_Y_Z_W ); } + SSE_SUBPS_XMM_to_XMM(regd, EEREC_TEMP); + } + } +} + +void recVUMI_MSUB_iq_toD(VURegs *VU, int regd, int addr, int info) +{ + //Console::WriteLn ("recVUMI_MSUB_iq_toD"); + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + vuFloat5_useEAX( EEREC_ACC, EEREC_TEMP, _X_Y_Z_W ); + vuFloat3(addr); + } + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + recVUMI_MSUB_temp_toD(VU, regd, info); +} + +void recVUMI_MSUB_xyzw_toD(VURegs *VU, int regd, int xyzw, int info) +{ + //Console::WriteLn ("recVUMI_MSUB_xyzw_toD"); + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, 1 << (3 - xyzw)); + vuFloat5_useEAX( EEREC_ACC, EEREC_TEMP, _X_Y_Z_W ); + } + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); + recVUMI_MSUB_temp_toD(VU, regd, info); +} + +void recVUMI_MSUB(VURegs *VU, int info) +{ + //Console::WriteLn ("recVUMI_MSUB"); + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + recVUMI_MSUB_toD(VU, EEREC_D, info); + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_MSUB_iq(VURegs *VU, int addr, int info) +{ + //Console::WriteLn ("recVUMI_MSUB_iq"); + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + recVUMI_MSUB_iq_toD(VU, EEREC_D, addr, info); + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_MSUBi(VURegs *VU, int info) { recVUMI_MSUB_iq(VU, VU_VI_ADDR(REG_I, 1), info); } +void recVUMI_MSUBq(VURegs *VU, int info) { recVUMI_MSUB_iq(VU, VU_REGQ_ADDR, info); } +void recVUMI_MSUBx(VURegs *VU, int info) +{ + //Console::WriteLn ("recVUMI_MSUBx"); + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + recVUMI_MSUB_xyzw_toD(VU, EEREC_D, 0, info); + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_MSUBy(VURegs *VU, int info) +{ + //Console::WriteLn ("recVUMI_MSUBy"); + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + recVUMI_MSUB_xyzw_toD(VU, EEREC_D, 1, info); + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_MSUBz(VURegs *VU, int info) +{ + //Console::WriteLn ("recVUMI_MSUBz"); + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + recVUMI_MSUB_xyzw_toD(VU, EEREC_D, 2, info); + recUpdateFlags(VU, EEREC_D, info); +} + +void recVUMI_MSUBw(VURegs *VU, int info) +{ + //Console::WriteLn ("recVUMI_MSUBw"); + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + recVUMI_MSUB_xyzw_toD(VU, EEREC_D, 3, info); + recUpdateFlags(VU, EEREC_D, info); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// MSUBA +//------------------------------------------------------------------ +void recVUMI_MSUBA( VURegs *VU, int info ) +{ + //Console::WriteLn ("recVUMI_MSUBA"); + recVUMI_MSUB_toD(VU, EEREC_ACC, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MSUBAi( VURegs *VU, int info ) +{ + //Console::WriteLn ("recVUMI_MSUBAi "); + recVUMI_MSUB_iq_toD( VU, EEREC_ACC, VU_VI_ADDR(REG_I, 1), info ); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MSUBAq( VURegs *VU, int info ) +{ + //Console::WriteLn ("recVUMI_MSUBAq"); + recVUMI_MSUB_iq_toD( VU, EEREC_ACC, VU_REGQ_ADDR, info ); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MSUBAx( VURegs *VU, int info ) +{ + //Console::WriteLn ("recVUMI_MSUBAx"); + recVUMI_MSUB_xyzw_toD(VU, EEREC_ACC, 0, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MSUBAy( VURegs *VU, int info ) +{ + //Console::WriteLn ("recVUMI_MSUBAy"); + recVUMI_MSUB_xyzw_toD(VU, EEREC_ACC, 1, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MSUBAz( VURegs *VU, int info ) +{ + //Console::WriteLn ("recVUMI_MSUBAz "); + recVUMI_MSUB_xyzw_toD(VU, EEREC_ACC, 2, info); + recUpdateFlags(VU, EEREC_ACC, info); +} + +void recVUMI_MSUBAw( VURegs *VU, int info ) +{ + //Console::WriteLn ("recVUMI_MSUBAw"); + recVUMI_MSUB_xyzw_toD(VU, EEREC_ACC, 3, info); + recUpdateFlags(VU, EEREC_ACC, info); +} +//------------------------------------------------------------------ + + +static const u32 PCSX2_ALIGNED16(special_mask[4]) = {0xffffffff, 0x80000000, 0xffffffff, 0x80000000}; +static const u32 PCSX2_ALIGNED16(special_mask2[4]) = {0, 0x40000000, 0, 0x40000000}; + +u32 PCSX2_ALIGNED16(temp_loc[4]); +u32 PCSX2_ALIGNED16(temp_loc2[4]); + +//MAX/MINI are non-arithmetic operations that implicitly support numbers with the EXP field being 0 ("denormals"). +// +//As such, they are sometimes used for integer move and (positive!) integer max/min, knowing that integers that +//represent denormals will not be flushed to 0. +// +//As such, this implementation performs a non-arithmetic operation that supports "denormals" and "infs/nans". +//There might be an easier way to do it but here, MAX/MIN is performed with PMAXPD/PMINPD. +//Fake double-precision numbers are constructed by copying the sign of the original numbers, clearing the upper 32 bits, +//setting the 62nd bit to 1 (to ensure double-precision number is "normalized") and having the lower 32bits +//being the same as the original number. + +void MINMAXlogical(VURegs *VU, int info, int min, int mode, uptr addr = 0, int xyzw = 0) +//mode1 = iq, mode2 = xyzw, mode0 = normal +{ + int t1regbool = 0; + int t1reg = _vuGetTempXMMreg(info); + if (t1reg < 0) + { + t1regbool = 1; + for (t1reg = 0; ( (t1reg == EEREC_D) || (t1reg == EEREC_S) || (mode != 1 && t1reg == EEREC_T) + || (t1reg == EEREC_TEMP) ); t1reg++); // Find unused reg (For first temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)temp_loc, t1reg); // Backup t1reg XMM reg + } + int t2regbool = -1; + int t2reg = EEREC_TEMP; + if (EEREC_TEMP == EEREC_D || EEREC_TEMP == EEREC_S || (mode != 1 && EEREC_TEMP == EEREC_T)) + { + t2regbool = 0; + t2reg = _vuGetTempXMMreg(info); + if (t2reg < 0) + { + t2regbool = 1; + for (t2reg = 0; ( (t2reg == EEREC_D) || (t2reg == EEREC_S) || (mode != 1 && t2reg == EEREC_T) || + (t2reg == t1reg) || (t2reg == EEREC_TEMP) ); t2reg++); // Find unused reg (For second temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)temp_loc2, t2reg); // Backup t2reg XMM reg + } + } + + if (_X || _Y) + { + SSE2_PSHUFD_XMM_to_XMM(t1reg, EEREC_S, 0x50); + SSE2_PAND_M128_to_XMM(t1reg, (uptr)special_mask); + SSE2_POR_M128_to_XMM(t1reg, (uptr)special_mask2); + if (mode == 0) + SSE2_PSHUFD_XMM_to_XMM(t2reg, EEREC_T, 0x50); + else if (mode == 1) + { + SSE2_MOVD_M32_to_XMM(t2reg, addr); + SSE2_PSHUFD_XMM_to_XMM(t2reg, t2reg, 0x00); + } + else if (mode == 2) + _unpackVF_xyzw(t2reg, EEREC_T, xyzw); + SSE2_PAND_M128_to_XMM(t2reg, (uptr)special_mask); + SSE2_POR_M128_to_XMM(t2reg, (uptr)special_mask2); + if (min) + SSE2_MINPD_XMM_to_XMM(t1reg, t2reg); + else + SSE2_MAXPD_XMM_to_XMM(t1reg, t2reg); + SSE2_PSHUFD_XMM_to_XMM(t1reg, t1reg, 0x88); + VU_MERGE_REGS_CUSTOM(EEREC_D, t1reg, 0xc & _X_Y_Z_W); + } + + if (_Z || _W) + { + SSE2_PSHUFD_XMM_to_XMM(t1reg, EEREC_S, 0xfa); + SSE2_PAND_M128_to_XMM(t1reg, (uptr)special_mask); + SSE2_POR_M128_to_XMM(t1reg, (uptr)special_mask2); + if (mode == 0) + SSE2_PSHUFD_XMM_to_XMM(t2reg, EEREC_T, 0xfa); + else if (mode == 1) + { + SSE2_MOVD_M32_to_XMM(t2reg, addr); + SSE2_PSHUFD_XMM_to_XMM(t2reg, t2reg, 0x00); + } + else if (mode == 2) + _unpackVF_xyzw(t2reg, EEREC_T, xyzw); + SSE2_PAND_M128_to_XMM(t2reg, (uptr)special_mask); + SSE2_POR_M128_to_XMM(t2reg, (uptr)special_mask2); + if (min) + SSE2_MINPD_XMM_to_XMM(t1reg, t2reg); + else + SSE2_MAXPD_XMM_to_XMM(t1reg, t2reg); + SSE2_PSHUFD_XMM_to_XMM(t1reg, t1reg, 0x88); + VU_MERGE_REGS_CUSTOM(EEREC_D, t1reg, 0x3 & _X_Y_Z_W); + } + + if (t1regbool == 0) + _freeXMMreg(t1reg); + else if (t1regbool == 1) + SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)temp_loc); // Restore t1reg XMM reg + if (t2regbool == 0) + _freeXMMreg(t2reg); + else if (t2regbool == 1) + SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)temp_loc2); // Restore t2reg XMM reg +} + +//------------------------------------------------------------------ +// MAX +//------------------------------------------------------------------ + +void recVUMI_MAX(VURegs *VU, int info) +{ + if ( _Fd_ == 0 ) return; + //Console::WriteLn ("recVUMI_MAX"); + + if (MINMAXFIX) + MINMAXlogical(VU, info, 0, 0); + else + { + + if (_Fs_) vuFloat4_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); // Always do Preserved Sign Clamping + if (_Ft_) vuFloat4_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); + + if( _X_Y_Z_W == 8 ) { + if (EEREC_D == EEREC_S) SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_T); + else if (EEREC_D == EEREC_T) SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_S); + else { + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_T); + } + } + else if (_X_Y_Z_W != 0xf) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_MAXPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else { + if( EEREC_D == EEREC_S ) SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_T); + else if( EEREC_D == EEREC_T ) SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_S); + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_T); + } + } + } +} + +void recVUMI_MAX_iq(VURegs *VU, uptr addr, int info) +{ + if ( _Fd_ == 0 ) return; + //Console::WriteLn ("recVUMI_MAX_iq"); + + if (MINMAXFIX) + MINMAXlogical(VU, info, 0, 1, addr); + else + { + if (_Fs_) vuFloat4_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); // Always do Preserved Sign Clamping + vuFloat3(addr); + + if( _XYZW_SS ) { + if( EEREC_D == EEREC_TEMP ) { + _vuFlipRegSS(VU, EEREC_S); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_MAXSS_M32_to_XMM(EEREC_D, addr); + _vuFlipRegSS(VU, EEREC_S); + + // have to flip over EEREC_D if computing flags! + //if( (info & PROCESS_VU_UPDATEFLAGS) ) + _vuFlipRegSS(VU, EEREC_D); + } + else if( EEREC_D == EEREC_S ) { + _vuFlipRegSS(VU, EEREC_D); + SSE_MAXSS_M32_to_XMM(EEREC_D, addr); + _vuFlipRegSS(VU, EEREC_D); + } + else { + if( _X ) { + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_MAXSS_M32_to_XMM(EEREC_D, addr); + } + else { + _vuMoveSS(VU, EEREC_TEMP, EEREC_S); + _vuFlipRegSS(VU, EEREC_D); + SSE_MAXSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + _vuFlipRegSS(VU, EEREC_D); + } + } + } + else if (_X_Y_Z_W != 0xf) { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + SSE_MAXPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else { + if(EEREC_D == EEREC_S) { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + else { + SSE_MOVSS_M32_to_XMM(EEREC_D, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_D, EEREC_D, 0x00); + SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_S); + } + } + } +} + +void recVUMI_MAX_xyzw(VURegs *VU, int xyzw, int info) +{ + if ( _Fd_ == 0 ) return; + //Console::WriteLn ("recVUMI_MAX_xyzw"); + + if (_Fs_ == 0 && _Ft_ == 0) + { + if( _X_Y_Z_W == 8 && (EEREC_D != EEREC_TEMP)) { + if( xyzw < 3 ) { + SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + else { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)s_fones); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + } + else if (_X_Y_Z_W != 0xf) { + if( xyzw < 3 ) { + if( _X_Y_Z_W & 1 ) SSE_MOVAPS_M128_to_XMM(EEREC_TEMP, (uptr)&VU->VF[0].UL[0]); // w included, so insert the whole reg + else SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); // w not included, can zero out + } + else SSE_MOVAPS_M128_to_XMM(EEREC_TEMP, (uptr)s_fones); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else { + //If VF0.w isnt chosen as the constant, then its going to be MAX( 0, VF0 ), so the result is VF0 + if( xyzw < 3 ) { SSE_MOVAPS_M128_to_XMM(EEREC_D, (uptr)&VU->VF[0].UL[0]); } + else SSE_MOVAPS_M128_to_XMM(EEREC_D, (uptr)s_fones); + } + return; + } + + if (MINMAXFIX) + MINMAXlogical(VU, info, 0, 2, 0, xyzw); + else + { + if (_Fs_) vuFloat4_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); // Always do Preserved Sign Clamping + if (_Ft_) vuFloat4_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); + + if( _X_Y_Z_W == 8 && (EEREC_D != EEREC_TEMP)) { + if( xyzw == 0 ) { + if( EEREC_D == EEREC_S ) SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_T); + else if( EEREC_D == EEREC_T ) SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_S); + else { + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_T); + } + } + else { + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_MAXSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + } + else if (_X_Y_Z_W != 0xf) { + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); + SSE_MAXPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else { + if (EEREC_D == EEREC_S) { + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); + SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + else { + _unpackVF_xyzw(EEREC_D, EEREC_T, xyzw); + SSE_MAXPS_XMM_to_XMM(EEREC_D, EEREC_S); + } + } + } +} + +void recVUMI_MAXi(VURegs *VU, int info) { recVUMI_MAX_iq(VU, VU_VI_ADDR(REG_I, 1), info); } +void recVUMI_MAXx(VURegs *VU, int info) { recVUMI_MAX_xyzw(VU, 0, info); } +void recVUMI_MAXy(VURegs *VU, int info) { recVUMI_MAX_xyzw(VU, 1, info); } +void recVUMI_MAXz(VURegs *VU, int info) { recVUMI_MAX_xyzw(VU, 2, info); } +void recVUMI_MAXw(VURegs *VU, int info) { recVUMI_MAX_xyzw(VU, 3, info); } +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// MINI +//------------------------------------------------------------------ +void recVUMI_MINI(VURegs *VU, int info) +{ + if ( _Fd_ == 0 ) return; + //Console::WriteLn ("recVUMI_MINI"); + + if (MINMAXFIX) + MINMAXlogical(VU, info, 1, 0); + else + { + + if (_Fs_) vuFloat4_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); // Always do Preserved Sign Clamping + if (_Ft_) vuFloat4_useEAX( EEREC_T, EEREC_TEMP, _X_Y_Z_W ); + + if( _X_Y_Z_W == 8 ) { + if (EEREC_D == EEREC_S) SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_T); + else if (EEREC_D == EEREC_T) SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_S); + else { + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_T); + } + } + else if (_X_Y_Z_W != 0xf) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_MINPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else { + if( EEREC_D == EEREC_S ) { + //ClampUnordered(EEREC_T, EEREC_TEMP, 0); // need for GT4 vu0rec + SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_T); + } + else if( EEREC_D == EEREC_T ) { + //ClampUnordered(EEREC_S, EEREC_TEMP, 0); // need for GT4 vu0rec + SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_S); + } + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_T); + } + } + } +} + +void recVUMI_MINI_iq(VURegs *VU, uptr addr, int info) +{ + if ( _Fd_ == 0 ) return; + //Console::WriteLn ("recVUMI_MINI_iq"); + + if (MINMAXFIX) + MINMAXlogical(VU, info, 1, 1, addr); + else + { + + if (_Fs_) vuFloat4_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); // Always do Preserved Sign Clamping + vuFloat3(addr); + + if( _XYZW_SS ) { + if( EEREC_D == EEREC_TEMP ) { + _vuFlipRegSS(VU, EEREC_S); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_MINSS_M32_to_XMM(EEREC_D, addr); + _vuFlipRegSS(VU, EEREC_S); + + // have to flip over EEREC_D if computing flags! + //if( (info & PROCESS_VU_UPDATEFLAGS) ) + _vuFlipRegSS(VU, EEREC_D); + } + else if( EEREC_D == EEREC_S ) { + _vuFlipRegSS(VU, EEREC_D); + SSE_MINSS_M32_to_XMM(EEREC_D, addr); + _vuFlipRegSS(VU, EEREC_D); + } + else { + if( _X ) { + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_MINSS_M32_to_XMM(EEREC_D, addr); + } + else { + _vuMoveSS(VU, EEREC_TEMP, EEREC_S); + _vuFlipRegSS(VU, EEREC_D); + SSE_MINSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + _vuFlipRegSS(VU, EEREC_D); + } + } + } + else if (_X_Y_Z_W != 0xf) { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + SSE_MINPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else { + if(EEREC_D == EEREC_S) { + SSE_MOVSS_M32_to_XMM(EEREC_TEMP, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x00); + SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + else { + SSE_MOVSS_M32_to_XMM(EEREC_D, addr); + SSE_SHUFPS_XMM_to_XMM(EEREC_D, EEREC_D, 0x00); + SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_S); + } + } + } +} + +void recVUMI_MINI_xyzw(VURegs *VU, int xyzw, int info) +{ + if ( _Fd_ == 0 ) return; + //Console::WriteLn ("recVUMI_MINI_xyzw"); + + if (_Fs_ == 0 && _Ft_ == 0) + { + if( _X_Y_Z_W == 0xf ) + { + //If VF0.w is the constant, the result will match VF0, else its all 0's + if(xyzw == 3) SSE_MOVAPS_M128_to_XMM(EEREC_D, (uptr)&VU->VF[0].UL[0]); + else SSE_XORPS_XMM_to_XMM(EEREC_D, EEREC_D); + } + else + { + //If VF0.w is the constant, the result will match VF0, else its all 0's + if(xyzw == 3) SSE_MOVAPS_M128_to_XMM(EEREC_TEMP, (uptr)&VU->VF[0].UL[0]); + else SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + return; + } + if (MINMAXFIX) + MINMAXlogical(VU, info, 1, 2, 0, xyzw); + else + { + if (_Fs_) vuFloat4_useEAX( EEREC_S, EEREC_TEMP, _X_Y_Z_W ); // Always do Preserved Sign Clamping + if (_Ft_) vuFloat4_useEAX( EEREC_T, EEREC_TEMP, ( 1 << (3 - xyzw) ) ); + + if( _X_Y_Z_W == 8 && (EEREC_D != EEREC_TEMP)) { + if( xyzw == 0 ) { + if( EEREC_D == EEREC_S ) SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_T); + else if( EEREC_D == EEREC_T ) SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_S); + else { + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_T); + } + } + else { + _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, xyzw); + SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); + SSE_MINSS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + } + else if (_X_Y_Z_W != 0xf) { + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); + SSE_MINPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + VU_MERGE_REGS(EEREC_D, EEREC_TEMP); + } + else { + if (EEREC_D == EEREC_S) { + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, xyzw); + SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_TEMP); + } + else { + _unpackVF_xyzw(EEREC_D, EEREC_T, xyzw); + SSE_MINPS_XMM_to_XMM(EEREC_D, EEREC_S); + } + } + } +} + +void recVUMI_MINIi(VURegs *VU, int info) { recVUMI_MINI_iq(VU, VU_VI_ADDR(REG_I, 1), info); } +void recVUMI_MINIx(VURegs *VU, int info) { recVUMI_MINI_xyzw(VU, 0, info); } +void recVUMI_MINIy(VURegs *VU, int info) { recVUMI_MINI_xyzw(VU, 1, info); } +void recVUMI_MINIz(VURegs *VU, int info) { recVUMI_MINI_xyzw(VU, 2, info); } +void recVUMI_MINIw(VURegs *VU, int info) { recVUMI_MINI_xyzw(VU, 3, info); } +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// OPMULA +//------------------------------------------------------------------ +void recVUMI_OPMULA( VURegs *VU, int info ) +{ + //Console::WriteLn ("recVUMI_OPMULA"); + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, 0xE); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, 0xE); + } + + SSE_MOVAPS_XMM_to_XMM( EEREC_TEMP, EEREC_S ); + SSE_SHUFPS_XMM_to_XMM( EEREC_T, EEREC_T, 0xD2 ); // EEREC_T = WYXZ + SSE_SHUFPS_XMM_to_XMM( EEREC_TEMP, EEREC_TEMP, 0xC9 ); // EEREC_TEMP = WXZY + SSE_MULPS_XMM_to_XMM( EEREC_TEMP, EEREC_T ); + + VU_MERGE_REGS_CUSTOM(EEREC_ACC, EEREC_TEMP, 14); + + // revert EEREC_T + if( EEREC_T != EEREC_ACC ) + SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0xC9); + + recUpdateFlags(VU, EEREC_ACC, info); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// OPMSUB +//------------------------------------------------------------------ +void recVUMI_OPMSUB( VURegs *VU, int info ) +{ + //Console::WriteLn ("recVUMI_OPMSUB"); + if (CHECK_VU_EXTRA_OVERFLOW) { + if (_Fs_) vuFloat5_useEAX( EEREC_S, EEREC_TEMP, 0xE); + if (_Ft_) vuFloat5_useEAX( EEREC_T, EEREC_TEMP, 0xE); + } + + if( !_Fd_ ) info |= PROCESS_EE_SET_D(EEREC_TEMP); + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0xD2); // EEREC_T = WYXZ + SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0xC9); // EEREC_TEMP = WXZY + SSE_MULPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); + + // negate and add + SSE_XORPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); + SSE_ADDPS_XMM_to_XMM(EEREC_TEMP, EEREC_ACC); + VU_MERGE_REGS_CUSTOM(EEREC_D, EEREC_TEMP, 14); + + // revert EEREC_T + if( EEREC_T != EEREC_D ) SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, 0xC9); + + recUpdateFlags(VU, EEREC_D, info); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// NOP +//------------------------------------------------------------------ +void recVUMI_NOP( VURegs *VU, int info ) +{ + //Console::WriteLn ("recVUMI_NOP"); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// recVUMI_FTOI_Saturate() - Saturates result from FTOI Instructions +//------------------------------------------------------------------ +static const PCSX2_ALIGNED16(int rec_const_0x8000000[4]) = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; + +void recVUMI_FTOI_Saturate(int rec_s, int rec_t, int rec_tmp1, int rec_tmp2) +{ + //Console::WriteLn ("recVUMI_FTOI_Saturate"); + //Duplicate the xor'd sign bit to the whole value + //FFFF FFFF for positive, 0 for negative + SSE_MOVAPS_XMM_to_XMM(rec_tmp1, rec_s); + SSE2_PXOR_M128_to_XMM(rec_tmp1, (uptr)&const_clip[4]); + SSE2_PSRAD_I8_to_XMM(rec_tmp1, 31); + + //Create mask: 0 where !=8000 0000 + SSE_MOVAPS_XMM_to_XMM(rec_tmp2, rec_t); + SSE2_PCMPEQD_M128_to_XMM(rec_tmp2, (uptr)&const_clip[4]); + + //AND the mask w/ the edit values + SSE_ANDPS_XMM_to_XMM(rec_tmp1, rec_tmp2); + + //if v==8000 0000 && positive -> 8000 0000 + FFFF FFFF -> 7FFF FFFF + //if v==8000 0000 && negative -> 8000 0000 + 0 -> 8000 0000 + //if v!=8000 0000 -> v+0 (masked from the and) + + //Add the values as needed + SSE2_PADDD_XMM_to_XMM(rec_t, rec_tmp1); +} +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// FTOI 0/4/12/15 +//------------------------------------------------------------------ +static PCSX2_ALIGNED16(float FTIO_Temp1[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; +static PCSX2_ALIGNED16(float FTIO_Temp2[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; +void recVUMI_FTOI0(VURegs *VU, int info) +{ + int t1reg, t2reg; // Temp XMM regs + + if ( _Ft_ == 0 ) return; + + //Console::WriteLn ("recVUMI_FTOI0"); + + if (_X_Y_Z_W != 0xf) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + vuFloat_useEAX( info, EEREC_TEMP, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax) + SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); + + t1reg = _vuGetTempXMMreg(info); + + if( t1reg >= 0 ) { // If theres a temp XMM reg available + for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg) ); t2reg++) + ; // Find unused reg (For second temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t2reg); // Backup XMM reg + + recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result + + SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp1); // Restore XMM reg + _freeXMMreg(t1reg); // Free temp reg + } + else { // No temp reg available + for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++) + ; // Find unused reg (For first temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg + + for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg) ); t2reg++) + ; // Find unused reg (For second temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp2, t2reg); // Backup t2reg XMM reg + + recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result + + SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg + SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp2); // Restore t2reg XMM reg + } + + VU_MERGE_REGS(EEREC_T, EEREC_TEMP); + } + else { + if (EEREC_T != EEREC_S) { + SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_S); + vuFloat_useEAX( info, EEREC_T, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax) + SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_T, EEREC_T); + + t1reg = _vuGetTempXMMreg(info); + + if( t1reg >= 0 ) { // If theres a temp XMM reg available + recVUMI_FTOI_Saturate(EEREC_S, EEREC_T, EEREC_TEMP, t1reg); // Saturate if Float->Int conversion returned illegal result + _freeXMMreg(t1reg); // Free temp reg + } + else { // No temp reg available + for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++) + ; // Find unused reg + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg + + recVUMI_FTOI_Saturate(EEREC_S, EEREC_T, EEREC_TEMP, t1reg); // Saturate if Float->Int conversion returned illegal result + + SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg + } + } + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + vuFloat_useEAX( info, EEREC_TEMP, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax) + SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); + + t1reg = _vuGetTempXMMreg(info); + + if( t1reg >= 0 ) { // If theres a temp XMM reg available + for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg)); t2reg++) + ; // Find unused reg (For second temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t2reg); // Backup XMM reg + + recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result + + SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp1); // Restore XMM reg + _freeXMMreg(t1reg); // Free temp reg + } + else { // No temp reg available + for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++) + ; // Find unused reg (For first temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg + + for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg) ); t2reg++) + ; // Find unused reg (For second temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp2, t2reg); // Backup t2reg XMM reg + + recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result + + SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg + SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp2); // Restore t2reg XMM reg + } + + SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_TEMP); + } + } +} + +void recVUMI_FTOIX(VURegs *VU, int addr, int info) +{ + int t1reg, t2reg; // Temp XMM regs + + if ( _Ft_ == 0 ) return; + + //Console::WriteLn ("recVUMI_FTOIX"); + if (_X_Y_Z_W != 0xf) { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_MULPS_M128_to_XMM(EEREC_TEMP, addr); + vuFloat_useEAX( info, EEREC_TEMP, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax) + SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); + + t1reg = _vuGetTempXMMreg(info); + + if( t1reg >= 0 ) { // If theres a temp XMM reg available + for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg)); t2reg++) + ; // Find unused reg (For second temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t2reg); // Backup XMM reg + + recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result + + SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp1); // Restore XMM reg + _freeXMMreg(t1reg); // Free temp reg + } + else { // No temp reg available + for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++) + ; // Find unused reg (For first temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg + + for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg) ); t2reg++) + ; // Find unused reg (For second temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp2, t2reg); // Backup t2reg XMM reg + + recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result + + SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg + SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp2); // Restore t2reg XMM reg + } + + VU_MERGE_REGS(EEREC_T, EEREC_TEMP); + } + else { + if (EEREC_T != EEREC_S) { + SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_S); + SSE_MULPS_M128_to_XMM(EEREC_T, addr); + vuFloat_useEAX( info, EEREC_T, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax) + SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_T, EEREC_T); + + t1reg = _vuGetTempXMMreg(info); + + if( t1reg >= 0 ) { // If theres a temp XMM reg available + recVUMI_FTOI_Saturate(EEREC_S, EEREC_T, EEREC_TEMP, t1reg); // Saturate if Float->Int conversion returned illegal result + _freeXMMreg(t1reg); // Free temp reg + } + else { // No temp reg available + for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++) + ; // Find unused reg + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg + + recVUMI_FTOI_Saturate(EEREC_S, EEREC_T, EEREC_TEMP, t1reg); // Saturate if Float->Int conversion returned illegal result + + SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg + } + } + else { + SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_MULPS_M128_to_XMM(EEREC_TEMP, addr); + vuFloat_useEAX( info, EEREC_TEMP, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax) + SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); + + t1reg = _vuGetTempXMMreg(info); + + if( t1reg >= 0 ) { // If theres a temp XMM reg available + for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg)); t2reg++) + ; // Find unused reg (For second temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t2reg); // Backup XMM reg + + recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result + + SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp1); // Restore XMM reg + _freeXMMreg(t1reg); // Free temp reg + } + else { // No temp reg available + for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++) + ; // Find unused reg (For first temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg + + for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg) ); t2reg++) + ; // Find unused reg (For second temp reg) + SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp2, t2reg); // Backup t2reg XMM reg + + recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result + + SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg + SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp2); // Restore t2reg XMM reg + } + + SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_TEMP); + } + } +} + +void recVUMI_FTOI4( VURegs *VU, int info ) { recVUMI_FTOIX(VU, (uptr)&recMult_float_to_int4[0], info); } +void recVUMI_FTOI12( VURegs *VU, int info ) { recVUMI_FTOIX(VU, (uptr)&recMult_float_to_int12[0], info); } +void recVUMI_FTOI15( VURegs *VU, int info ) { recVUMI_FTOIX(VU, (uptr)&recMult_float_to_int15[0], info); } +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// ITOF 0/4/12/15 +//------------------------------------------------------------------ +void recVUMI_ITOF0( VURegs *VU, int info ) +{ + if ( _Ft_ == 0 ) return; + + //Console::WriteLn ("recVUMI_ITOF0"); + if (_X_Y_Z_W != 0xf) { + SSE2_CVTDQ2PS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + vuFloat_useEAX( info, EEREC_TEMP, 15); // Clamp infinities + VU_MERGE_REGS(EEREC_T, EEREC_TEMP); + xmmregs[EEREC_T].mode |= MODE_WRITE; + } + else { + SSE2_CVTDQ2PS_XMM_to_XMM(EEREC_T, EEREC_S); + vuFloat2(EEREC_T, EEREC_TEMP, 15); // Clamp infinities + } +} + +void recVUMI_ITOFX(VURegs *VU, int addr, int info) +{ + if ( _Ft_ == 0 ) return; + + //Console::WriteLn ("recVUMI_ITOFX"); + if (_X_Y_Z_W != 0xf) { + SSE2_CVTDQ2PS_XMM_to_XMM(EEREC_TEMP, EEREC_S); + SSE_MULPS_M128_to_XMM(EEREC_TEMP, addr); + vuFloat_useEAX( info, EEREC_TEMP, 15); // Clamp infinities + VU_MERGE_REGS(EEREC_T, EEREC_TEMP); + xmmregs[EEREC_T].mode |= MODE_WRITE; + } + else { + SSE2_CVTDQ2PS_XMM_to_XMM(EEREC_T, EEREC_S); + SSE_MULPS_M128_to_XMM(EEREC_T, addr); + vuFloat2(EEREC_T, EEREC_TEMP, 15); // Clamp infinities + } +} + +void recVUMI_ITOF4( VURegs *VU, int info ) { recVUMI_ITOFX(VU, (uptr)&recMult_int_to_float4[0], info); } +void recVUMI_ITOF12( VURegs *VU, int info ) { recVUMI_ITOFX(VU, (uptr)&recMult_int_to_float12[0], info); } +void recVUMI_ITOF15( VURegs *VU, int info ) { recVUMI_ITOFX(VU, (uptr)&recMult_int_to_float15[0], info); } +//------------------------------------------------------------------ + + +//------------------------------------------------------------------ +// CLIP +//------------------------------------------------------------------ +void recVUMI_CLIP(VURegs *VU, int info) +{ + int t1reg = EEREC_D; + int t2reg = EEREC_ACC; + int x86temp1, x86temp2; + + u32 clipaddr = VU_VI_ADDR(REG_CLIP_FLAG, 0); + u32 prevclipaddr = VU_VI_ADDR(REG_CLIP_FLAG, 2); + + if( clipaddr == 0 ) { // battle star has a clip right before fcset + Console::WriteLn("skipping vu clip"); + return; + } + + //Flush the clip flag before processing, incase of double clip commands (GoW) + + if( prevclipaddr != (uptr)&VU->VI[REG_CLIP_FLAG] ) { + MOV32MtoR(EAX, prevclipaddr); + MOV32RtoM((uptr)&VU->VI[REG_CLIP_FLAG], EAX); + } + + assert( clipaddr != 0 ); + assert( t1reg != t2reg && t1reg != EEREC_TEMP && t2reg != EEREC_TEMP ); + + x86temp1 = ALLOCTEMPX86(MODE_8BITREG); + x86temp2 = ALLOCTEMPX86(MODE_8BITREG); + + //if ( (x86temp1 == 0) || (x86temp2 == 0) ) Console::Error("VU CLIP Allocation Error: EAX being allocated!"); + + _freeXMMreg(t1reg); // These should have been freed at allocation in eeVURecompileCode() + _freeXMMreg(t2reg); // but if they've been used since then, then free them. (just doing this incase :p (cottonvibes)) + + if( _Ft_ == 0 ) { + SSE_MOVAPS_M128_to_XMM(EEREC_TEMP, (uptr)&s_fones[0]); // all 1s + SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)&s_fones[4]); + } + else { + _unpackVF_xyzw(EEREC_TEMP, EEREC_T, 3); + SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[0]); + SSE_MOVAPS_XMM_to_XMM(t1reg, EEREC_TEMP); + SSE_ORPS_M128_to_XMM(t1reg, (uptr)&const_clip[4]); + } + + MOV32MtoR(EAX, prevclipaddr); + + SSE_CMPNLEPS_XMM_to_XMM(t1reg, EEREC_S); //-w, -z, -y, -x + SSE_CMPLTPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); //+w, +z, +y, +x + + SHL32ItoR(EAX, 6); + + SSE_MOVAPS_XMM_to_XMM(t2reg, EEREC_TEMP); //t2 = +w, +z, +y, +x + SSE_UNPCKLPS_XMM_to_XMM(EEREC_TEMP, t1reg); //EEREC_TEMP = -y,+y,-x,+x + SSE_UNPCKHPS_XMM_to_XMM(t2reg, t1reg); //t2reg = -w,+w,-z,+z + SSE_MOVMSKPS_XMM_to_R32(x86temp2, EEREC_TEMP); // -y,+y,-x,+x + SSE_MOVMSKPS_XMM_to_R32(x86temp1, t2reg); // -w,+w,-z,+z + + AND8ItoR(x86temp1, 0x3); + SHL8ItoR(x86temp1, 4); + OR8RtoR(EAX, x86temp1); + AND8ItoR(x86temp2, 0xf); + OR8RtoR(EAX, x86temp2); + AND32ItoR(EAX, 0xffffff); + + MOV32RtoM(clipaddr, EAX); + + if (( !(info & (PROCESS_VU_SUPER|PROCESS_VU_COP2)) ) ) //Instantly update the flag if its called from elsewhere (unlikely, but ok) + MOV32RtoM((uptr)&VU->VI[REG_CLIP_FLAG], EAX); + + _freeX86reg(x86temp1); + _freeX86reg(x86temp2); +} diff --git a/pcsx2/x86/sVU_zerorec.cpp b/pcsx2/x86/sVU_zerorec.cpp new file mode 100644 index 0000000000..7693387d28 --- /dev/null +++ b/pcsx2/x86/sVU_zerorec.cpp @@ -0,0 +1,4656 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +// Super VU recompiler - author: zerofrog(@gmail.com) + +#include "PrecompiledHeader.h" + +#include +#include +#include +#include + +#include "Utilities/AsciiFile.h" + +#ifndef _WIN32 +#include +#endif + +#include "Common.h" + +#include "GS.h" +#include "R5900.h" +#include "VU.h" +#include "iR5900.h" + +#include "sVU_zerorec.h" +#include "SamplProf.h" +#include "NakedAsm.h" + +using namespace std; + +// temporary externs +extern void iDumpVU0Registers(); +extern void iDumpVU1Registers(); + +// SuperVURec optimization options, uncomment only for debugging purposes +#define SUPERVU_CACHING // vu programs are saved and queried via memcompare (should be no reason to disable this) +#define SUPERVU_WRITEBACKS // don't flush the writebacks after every block +#define SUPERVU_X86CACHING // use x86reg caching (faster) (not really. rather lots slower :p (rama) ) +#define SUPERVU_VIBRANCHDELAY // when integers are modified right before a branch that uses the integer, + // the old integer value is used in the branch, fixes kh2 + +#define SUPERVU_PROPAGATEFLAGS // the correct behavior of VUs, for some reason superman breaks gfx with it on... + +// registers won't be flushed at block boundaries (faster) (nothing noticable speed-wise, causes SPS in Ratchet and clank (Nneeve) ) +#ifndef PCSX2_DEBUG +//#define SUPERVU_INTERCACHING +#endif + +#define SUPERVU_CHECKCONDITION 0 // has to be 0!! + +#define VU_EXESIZE 0x00800000 + +#define _Imm11_ (s32)( (vucode & 0x400) ? (0xfffffc00 | (vucode & 0x3ff)) : (vucode & 0x3ff) ) +#define _UImm11_ (s32)(vucode & 0x7ff) + +#define _Ft_ ((VU->code >> 16) & 0x1F) // The rt part of the instruction register +#define _Fs_ ((VU->code >> 11) & 0x1F) // The rd part of the instruction register +#define _Fd_ ((VU->code >> 6) & 0x1F) // The sa part of the instruction register +#define _It_ (_Ft_ & 15) +#define _Is_ (_Fs_ & 15) +#define _Id_ (_Fd_ & 15) + +static const u32 QWaitTimes[] = { 6, 12 }; +static const u32 PWaitTimes[] = { 53, 43, 28, 23, 17, 11, 10 }; + +static u32 s_vuInfo; // info passed into rec insts + +static const u32 s_MemSize[2] = {VU0_MEMSIZE, VU1_MEMSIZE}; +static u8* s_recVUMem = NULL, *s_recVUPtr = NULL; + +// tables which are defined at the bottom of this massive file. +extern void (*recVU_UPPER_OPCODE[64])(VURegs* VU, s32 info); +extern void (*recVU_LOWER_OPCODE[128])(VURegs* VU, s32 info); + +#define INST_Q_READ 0x0001 // flush Q +#define INST_P_READ 0x0002 // flush P +#define INST_BRANCH_DELAY 0x0004 +#define INST_CLIP_WRITE 0x0040 // inst writes CLIP in the future +#define INST_STATUS_WRITE 0x0080 +#define INST_MAC_WRITE 0x0100 +#define INST_Q_WRITE 0x0200 +#define INST_CACHE_VI 0x0400 // write old vi value to s_VIBranchDelay + +// Let's tempt fate by defining two different constants with almost identical names +#define INST_DUMMY_ 0x8000 +#define INST_DUMMY 0x83c0 + +#define VFFREE_INVALID0 0x80000000 // (vffree[i]&0xf) is invalid + +//#define FORIT(it, v) for(it = (v).begin(); it != (v).end(); ++(it)) + +#ifdef PCSX2_DEBUG +u32 s_vucount = 0; + +static u32 g_vu1lastrec = 0, skipparent = -1; +static u32 s_svulast = 0, s_vufnheader; +static u32 badaddrs[][2] = {0, 0xffff}; +#endif + +union VURecRegs +{ + struct + { + u16 reg; + u16 type; + }; + u32 id; +}; + +#define SUPERVU_XGKICKDELAY 1 // yes this is needed as default (wipeout) + +class VuBaseBlock; + +struct VuFunctionHeader +{ + struct RANGE + { + RANGE() : pmem(NULL) {} + + u16 start, size; + void* pmem; // all the mem + }; + + VuFunctionHeader() : pprogfunc(NULL), startpc(0xffffffff) {} + ~VuFunctionHeader() + { + for (vector::iterator it = ranges.begin(); it != ranges.end(); ++it) + { + free(it->pmem); + } + } + + // returns true if the checksum for the current mem is the same as this fn + bool IsSame(void* pmem); + + u32 startpc; + void* pprogfunc; + + vector ranges; +}; + +struct VuBlockHeader +{ + VuBaseBlock* pblock; + u32 delay; +}; + +// one vu inst (lower and upper) +class VuInstruction +{ + public: + VuInstruction() + { + memzero_obj(*this); + nParentPc = -1; + vicached = -1; + } + + int nParentPc; // used for syncing with flag writes, -1 for no parent + + _vuopinfo info; + + _VURegsNum regs[2]; // [0] - lower, [1] - upper + u32 livevars[2]; // live variables right before this inst, [0] - inst, [1] - float + u32 addvars[2]; // live variables to add + u32 usedvars[2]; // set if var is used in the future including vars used in this inst + u32 keepvars[2]; + u16 pqcycles; // the number of cycles to stall if function writes to the regs + u16 type; // INST_ + + u32 pClipWrite, pMACWrite, pStatusWrite; // addrs to write the flags + u32 vffree[2]; + s8 vfwrite[2], vfread0[2], vfread1[2], vfacc[2]; + s8 vfflush[2]; // extra flush regs + s8 vicached; // if >= 0, then use the cached integer s_VIBranchDelay + VuInstruction *pPrevInst; + + int SetCachedRegs(int upper, u32 vuxyz); + void Recompile(list::iterator& itinst, u32 vuxyz); +}; + +enum BlockType +{ + BLOCKTYPE_EOP = 0x01, // at least one of the children of the block contains eop (or the block itself) + BLOCKTYPE_FUNCTION = 0x02, + BLOCKTYPE_HASEOP = 0x04, // last inst of block is an eop + BLOCKTYPE_MACFLAGS = 0x08, + BLOCKTYPE_ANALYZED = 0x40, + BLOCKTYPE_IGNORE = 0x80, // special for recursive fns + BLOCKTYPE_ANALYZEDPARENT = 0x100 +}; + +// base block used when recompiling +class VuBaseBlock +{ + public: + typedef list LISTBLOCKS; + + VuBaseBlock(); + + // returns true if the leads to a EOP (ALL VU blocks must ret true) + void AssignVFRegs(); + void AssignVIRegs(int parent); + + list::iterator GetInstIterAtPc(int instpc); + void GetInstsAtPc(int instpc, list& listinsts); + + void Recompile(); + + u16 type; // BLOCKTYPE_ + u16 id; + u16 startpc; + u16 endpc; // first inst not in block + void* pcode; // x86 code pointer + void* pendcode; // end of the x86 code pointer + int cycles; + list insts; + list parents; + LISTBLOCKS blocks; // blocks branches to + u32* pChildJumps[4]; // addrs that need to be filled with the children's start addrs + // if highest bit is set, addr needs to be relational + u32 vuxyz; // corresponding bit is set if reg's xyz channels are used only + u32 vuxy; // corresponding bit is set if reg's xyz channels are used only + + _xmmregs startregs[iREGCNT_XMM], endregs[iREGCNT_XMM]; + int nStartx86, nEndx86; // indices into s_vecRegArray + + int allocX86Regs; + int prevFlagsOutOfBlock; +}; + +struct WRITEBACK +{ + WRITEBACK() : nParentPc(0), cycle(0) //, pStatusWrite(NULL), pMACWrite(NULL) + { + viwrite[0] = viwrite[1] = 0; + viread[0] = viread[1] = 0; + } + + void InitInst(VuInstruction* pinst, int cycle) const + { + u32 write = viwrite[0] | viwrite[1]; + pinst->type = ((write & (1 << REG_CLIP_FLAG)) ? INST_CLIP_WRITE : 0) | + ((write & (1 << REG_MAC_FLAG)) ? INST_MAC_WRITE : 0) | + ((write & (1 << REG_STATUS_FLAG)) ? INST_STATUS_WRITE : 0) | + ((write & (1 << REG_Q)) ? INST_Q_WRITE : 0); + pinst->nParentPc = nParentPc; + pinst->info.cycle = cycle; + for (int i = 0; i < 2; ++i) + { + pinst->regs[i].VIwrite = viwrite[i]; + pinst->regs[i].VIread = viread[i]; + } + } + + static int SortWritebacks(const WRITEBACK& w1, const WRITEBACK& w2) + { + return w1.cycle < w2.cycle; + } + + int nParentPc; + int cycle; + u32 viwrite[2]; + u32 viread[2]; +}; + +struct VUPIPELINES +{ + fmacPipe fmac[8]; + fdivPipe fdiv; + efuPipe efu; + ialuPipe ialu[8]; + list< WRITEBACK > listWritebacks; +}; + +VuBaseBlock::VuBaseBlock() +{ + type = 0; + endpc = 0; + cycles = 0; + pcode = NULL; + id = 0; + memzero_obj(pChildJumps); + memzero_obj(startregs); + memzero_obj(endregs); + allocX86Regs = nStartx86 = nEndx86 = -1; + prevFlagsOutOfBlock = 0; +} + +#define SUPERVU_STACKSIZE 0x1000 + +static list s_listVUHeaders[2]; +static list* s_plistCachedHeaders[2] = {NULL, NULL}; +static VuFunctionHeader** recVUHeaders[2] = {NULL, NULL}; +static VuBlockHeader* recVUBlocks[2] = {NULL, NULL}; +static u8* recVUStack = NULL, *recVUStackPtr = NULL; +static vector<_x86regs> s_vecRegArray(128); + +static VURegs* VU = NULL; +static list s_listBlocks; +static u32 s_vu = 0; +static u32 s_UnconditionalDelay = 0; // 1 if there are two sequential branches and the last is unconditional +static u32 g_nLastBlockExecuted = 0; + +static VuFunctionHeader* SuperVURecompileProgram(u32 startpc, int vuindex); +static VuBaseBlock* SuperVUBuildBlocks(VuBaseBlock* parent, u32 startpc, const VUPIPELINES& pipes); +static void SuperVUInitLiveness(VuBaseBlock* pblock); +static void SuperVULivenessAnalysis(); +static void SuperVUEliminateDeadCode(); +static void SuperVUAssignRegs(); + +//void SuperVUFreeXMMreg(int xmmreg, int xmmtype, int reg); +#define SuperVUFreeXMMreg 0&& +void SuperVUFreeXMMregs(u32* livevars); + +static u32* SuperVUStaticAlloc(u32 size); +static void SuperVURecompile(); + +// allocate VU resources +void SuperVUAlloc(int vuindex) +{ + // The old -1 crap has been depreciated on this function. Please + // specify either 0 or 1, thanks. + jASSUME(vuindex >= 0); + + // upper 4 bits must be zero! + if (s_recVUMem == NULL) + { + // upper 4 bits must be zero! + // Changed "first try base" to 0xf1e0000, since 0x0c000000 liked to fail a lot. (cottonvibes) + s_recVUMem = SysMmapEx(0xf1e0000, VU_EXESIZE, 0x10000000, "SuperVUAlloc"); + + if (s_recVUMem == NULL) + { + throw Exception::OutOfMemory( + // untranslated diagnostic msg, use exception's default for translation + wxsFormat( L"Error > SuperVU failed to allocate recompiler memory (addr: 0x%x)", (u32)s_recVUMem ) + ); + } + + ProfilerRegisterSource("VURec", s_recVUMem, VU_EXESIZE); + + if (recVUStack == NULL) recVUStack = new u8[SUPERVU_STACKSIZE * 4]; + } + + if (vuindex >= 0) + { + jASSUME(s_recVUMem != NULL); + + if (recVUHeaders[vuindex] == NULL) + recVUHeaders[vuindex] = new VuFunctionHeader* [s_MemSize[vuindex] / 8]; + if (recVUBlocks[vuindex] == NULL) + recVUBlocks[vuindex] = new VuBlockHeader[s_MemSize[vuindex] / 8]; + if (s_plistCachedHeaders[vuindex] == NULL) + s_plistCachedHeaders[vuindex] = new list[s_MemSize[vuindex] / 8]; + } +} + +void DestroyCachedHeaders(int vuindex, int j) +{ + list::iterator it = s_plistCachedHeaders[vuindex][j].begin(); + + while (it != s_plistCachedHeaders[vuindex][j].end()) + { + delete *it; + it++; + } + + s_plistCachedHeaders[vuindex][j].clear(); +} + +void DestroyVUHeaders(int vuindex) +{ + list::iterator it = s_listVUHeaders[vuindex].begin(); + + while (it != s_listVUHeaders[vuindex].end()) + { + delete *it; + it++; + } + + s_listVUHeaders[vuindex].clear(); +} + +// destroy VU resources +void SuperVUDestroy(int vuindex) +{ + list::iterator it; + + if (vuindex < 0) + { + SuperVUDestroy(0); + SuperVUDestroy(1); + ProfilerTerminateSource("VURec"); + SafeSysMunmap(s_recVUMem, VU_EXESIZE); + safe_delete_array(recVUStack); + } + else + { + safe_delete_array(recVUHeaders[vuindex]); + safe_delete_array(recVUBlocks[vuindex]); + + if (s_plistCachedHeaders[vuindex] != NULL) + { + for (u32 j = 0; j < s_MemSize[vuindex] / 8; ++j) + { + DestroyCachedHeaders(vuindex, j); + } + safe_delete_array(s_plistCachedHeaders[vuindex]); + } + DestroyVUHeaders(vuindex); + } +} + +// reset VU +void SuperVUReset(int vuindex) +{ +#ifdef PCSX2_DEBUG + s_vucount = 0; +#endif + + if (s_recVUMem == NULL) + return; + + //jASSUME( s_recVUMem != NULL ); + + if (vuindex < 0) + { + DbgCon::Status("SuperVU reset > Resetting recompiler memory and structures."); + + // Does this cause problems on VU recompiler resets? It could, if the VU works like + // the EE used to, and actually tries to re-enter the recBlock after issuing a clear. (air) + + //memset_8<0xcd, VU_EXESIZE>(s_recVUMem); + memzero_ptr(recVUStack); + + s_recVUPtr = s_recVUMem; + } + else + { + DbgCon::Status("SuperVU reset [VU%d] > Resetting the recs and junk", params vuindex); + list::iterator it; + if (recVUHeaders[vuindex]) memset(recVUHeaders[vuindex], 0, sizeof(VuFunctionHeader*) * (s_MemSize[vuindex] / 8)); + if (recVUBlocks[vuindex]) memset(recVUBlocks[vuindex], 0, sizeof(VuBlockHeader) * (s_MemSize[vuindex] / 8)); + + if (s_plistCachedHeaders[vuindex] != NULL) + { + for (u32 j = 0; j < s_MemSize[vuindex] / 8; ++j) + { + DestroyCachedHeaders(vuindex, j); + } + } + DestroyVUHeaders(vuindex); + } +} + +// clear the block and any joining blocks +void __fastcall SuperVUClear(u32 startpc, u32 size, int vuindex) +{ + vector::iterator itrange; + list::iterator it = s_listVUHeaders[vuindex].begin(); + u32 endpc = startpc + (size + (8 - (size & 7))); // Adding this code to ensure size is always a multiple of 8, it can be simplified to startpc+size if size is always a multiple of 8 (cottonvibes) + while (it != s_listVUHeaders[vuindex].end()) + { + + // for every fn, check if it has code in the range + for(itrange = (*it)->ranges.begin(); itrange != (*it)->ranges.end(); itrange++) + { + if (startpc < (u32)itrange->start + itrange->size && itrange->start < endpc) + break; + } + + if (itrange != (*it)->ranges.end()) + { + recVUHeaders[vuindex][(*it)->startpc/8] = NULL; +#ifdef SUPERVU_CACHING + list* plist = &s_plistCachedHeaders[vuindex][(*it)->startpc/8]; + plist->push_back(*it); + if (plist->size() > 30) + { + // list is too big, delete + //Console::Notice("Performance warning: deleting cached VU program!"); + delete plist->front(); + plist->pop_front(); + } + it = s_listVUHeaders[vuindex].erase(it); +#else + delete *it; + it = s_listVUHeaders[vuindex].erase(it); +#endif + } + else ++it; + } +} + +static VuFunctionHeader* s_pFnHeader = NULL; +static VuBaseBlock* s_pCurBlock = NULL; +static VuInstruction* s_pCurInst = NULL; +static u32 s_StatusRead = 0, s_MACRead = 0, s_ClipRead = 0; // read addrs +static u32 s_PrevStatusWrite = 0, s_PrevMACWrite = 0, s_PrevClipWrite = 0, s_PrevIWrite = 0; +static u32 s_WriteToReadQ = 0; + +static u32 s_VIBranchDelay = 0; //Value of register to use in a vi branch delayed situation + + +u32 s_TotalVUCycles; // total cycles since start of program execution + + +u32 SuperVUGetVIAddr(int reg, int read) +{ + assert(s_pCurInst != NULL); + + switch (reg) + { + case REG_STATUS_FLAG: + { + u32 addr = (read == 2) ? s_PrevStatusWrite : (read ? s_StatusRead : s_pCurInst->pStatusWrite); + assert(!read || addr != 0); + return addr; + } + case REG_MAC_FLAG: + { + u32 addr = (read == 2) ? s_PrevMACWrite : (read ? s_MACRead : s_pCurInst->pMACWrite); + return addr; + } + case REG_CLIP_FLAG: + { + u32 addr = (read == 2) ? s_PrevClipWrite : (read ? s_ClipRead : s_pCurInst->pClipWrite); + assert(!read || addr != 0); + return addr; + } + case REG_Q: + return (read || s_WriteToReadQ) ? (uptr)&VU->VI[REG_Q] : (uptr)&VU->q; + case REG_P: + return read ? (uptr)&VU->VI[REG_P] : (uptr)&VU->p; + case REG_I: + return s_PrevIWrite; + } + +#ifdef SUPERVU_VIBRANCHDELAY + if ((read != 0) && (s_pCurInst->regs[0].pipe == VUPIPE_BRANCH) && (s_pCurInst->vicached >= 0) && (s_pCurInst->vicached == reg)) + { + return (uptr)&s_VIBranchDelay; // test for branch delays + } +#endif + + return (uptr)&VU->VI[reg]; +} + +void SuperVUDumpBlock(list& blocks, int vuindex) +{ + u32 *mem; + u32 i; + + g_Conf.Folders.Dumps.Mkdir(); + AsciiFile eff( + Path::Combine( g_Conf.Folders.Dumps, wxsFormat(L"svu%cdump%.4X.txt", s_vu?L'0':L'1', s_pFnHeader->startpc) ), + wxFile::write + ); + + eff.Printf("Format: upper_inst lower_inst\ntype f:vf_live_vars vf_used_vars i:vi_live_vars vi_used_vars inst_cycle pq_inst\n"); + eff.Printf("Type: %.2x - qread, %.2x - pread, %.2x - clip_write, %.2x - status_write\n" + "%.2x - mac_write, %.2x -qflush\n", + INST_Q_READ, INST_P_READ, INST_CLIP_WRITE, INST_STATUS_WRITE, INST_MAC_WRITE, INST_Q_WRITE); + eff.Printf("XMM: Upper: read0 read1 write acc temp; Lower: read0 read1 write acc temp\n\n"); + + list::iterator itblock; + list::iterator itinst; + VuBaseBlock::LISTBLOCKS::iterator itchild; + + for(itblock = blocks.begin(); itblock != blocks.end(); itblock++) + { + eff.Printf( "block:%c %x-%x; children: ", ((*itblock)->type&BLOCKTYPE_HASEOP) ? '*' : ' ', + (*itblock)->startpc, (*itblock)->endpc - 8); + + for(itchild = (*itblock)->blocks.begin(); itchild != (*itblock)->blocks.end(); itchild++) + { + eff.Printf("%x ", (*itchild)->startpc); + } + eff.Printf("; vuxyz = %x, vuxy = %x\n", (*itblock)->vuxyz&(*itblock)->insts.front().usedvars[1], + (*itblock)->vuxy&(*itblock)->insts.front().usedvars[1]); + + itinst = (*itblock)->insts.begin(); + i = (*itblock)->startpc; + while (itinst != (*itblock)->insts.end()) + { + assert(i <= (*itblock)->endpc); + if (itinst->type & INST_DUMMY) + { + if (itinst->nParentPc >= 0 && !(itinst->type&INST_DUMMY_)) + { + // search for the parent + eff.Printf("writeback 0x%x (%x)\n", itinst->type, itinst->nParentPc); + } + } + else + { + mem = (u32*) & VU->Micro[i]; + char* pstr = disVU1MicroUF(mem[1], i + 4); + eff.Printf( "%.4x: %-40s", i, pstr); + if (mem[1] & 0x80000000) eff.Printf( " I=%f(%.8x)\n", *(float*)mem, mem[0]); + else eff.Printf( "%s\n", disVU1MicroLF(mem[0], i)); + i += 8; + } + + ++itinst; + } + + eff.Printf("\n"); + + _x86regs* pregs; + if ((*itblock)->nStartx86 >= 0 || (*itblock)->nEndx86 >= 0) + { + eff.Printf( "X86: AX CX DX BX SP BP SI DI\n"); + } + + if ((*itblock)->nStartx86 >= 0) + { + pregs = &s_vecRegArray[(*itblock)->nStartx86]; + eff.Printf( "STR: "); + for (i = 0; i < iREGCNT_GPR; ++i) + { + if (pregs[i].inuse) + eff.Printf( "%.2d ", pregs[i].reg); + else + eff.Printf( "-1 "); + } + eff.Printf( "\n"); + } + + if ((*itblock)->nEndx86 >= 0) + { + eff.Printf( "END: "); + pregs = &s_vecRegArray[(*itblock)->nEndx86]; + for (i = 0; i < iREGCNT_GPR; ++i) + { + if (pregs[i].inuse) + eff.Printf( "%.2d ", pregs[i].reg); + else + eff.Printf( "-1 "); + } + eff.Printf( "\n"); + } + + itinst = (*itblock)->insts.begin(); + for (i = (*itblock)->startpc; i < (*itblock)->endpc; ++itinst) + { + + if (itinst->type & INST_DUMMY) + { + } + else + { + char str[256]; + sprintf(str, "%.4x:%x f:%.8x_%.8x", i, itinst->type, itinst->livevars[1], itinst->usedvars[1]); + eff.Printf( "%-46s i:%.8x_%.8x c:%d pq:%d\n", str, + itinst->livevars[0], itinst->usedvars[0], (int)itinst->info.cycle, (int)itinst->pqcycles); + + sprintf(str, "XMM r0:%d r1:%d w:%d a:%d t:%x;", + itinst->vfread0[1], itinst->vfread1[1], itinst->vfwrite[1], itinst->vfacc[1], itinst->vffree[1]); + eff.Printf( "%-46s r0:%d r1:%d w:%d a:%d t:%x\n", str, + itinst->vfread0[0], itinst->vfread1[0], itinst->vfwrite[0], itinst->vfacc[0], itinst->vffree[0]); + i += 8; + } + } + +// +#if 0 // __LINUX__ + + // dump the asm + if ((*itblock)->pcode != NULL) + { + char command[255]; + FILE* fasm = fopen("mydump1", "wb"); + //Console::WriteLn("writing: %x, %x", params (*itblock)->startpc, (uptr)(*itblock)->pendcode - (uptr)(*itblock)->pcode); + fwrite((*itblock)->pcode, 1, (uptr)(*itblock)->pendcode - (uptr)(*itblock)->pcode, fasm); + fclose(fasm); + sprintf(command, "objdump -D --target=binary --architecture=i386 -M intel mydump1 > tempdump"); + system(command); + fasm = fopen("tempdump", "r"); + // read all of it and write it to f + fseek(fasm, 0, SEEK_END); + vector vbuffer(ftell(fasm)); + fseek(fasm, 0, SEEK_SET); + fread(&vbuffer[0], vbuffer.size(), 1, fasm); + + fprintf(f, "\n\n"); + fwrite(&vbuffer[0], vbuffer.size(), 1, f); + fclose(fasm); + } +#endif + + eff.Printf("\n---------------\n"); + } +} + +// uncomment to count svu exec time +//#define SUPERVU_COUNT + +// Private methods +void* SuperVUGetProgram(u32 startpc, int vuindex) +{ + assert(startpc < s_MemSize[vuindex]); + assert((startpc % 8) == 0); + assert(recVUHeaders[vuindex] != NULL); + VuFunctionHeader** pheader = &recVUHeaders[vuindex][startpc/8]; + + if (*pheader == NULL) + { + +#ifdef SUPERVU_CACHING + void* pmem = (vuindex & 1) ? VU1.Micro : VU0.Micro; + // check if program exists in cache + list::iterator it; + for(it = s_plistCachedHeaders[vuindex][startpc/8].begin(); it != s_plistCachedHeaders[vuindex][startpc/8].end(); it++) + { + if ((*it)->IsSame(pmem)) + { + // found, transfer to regular lists + void* pfn = (*it)->pprogfunc; + recVUHeaders[vuindex][startpc/8] = *it; + s_listVUHeaders[vuindex].push_back(*it); + s_plistCachedHeaders[vuindex][startpc/8].erase(it); + return pfn; + } + } +#endif + + *pheader = SuperVURecompileProgram(startpc, vuindex); + + if (*pheader == NULL) + { + assert(s_TotalVUCycles > 0); + if (vuindex) + VU1.VI[REG_TPC].UL = startpc; + else + VU0.VI[REG_TPC].UL = startpc; + + return (void*)SuperVUEndProgram; + } + + assert((*pheader)->pprogfunc != NULL); + } + //else assert( (*pheader)->IsSame((vuindex&1) ? VU1.Micro : VU0.Micro) ); + + assert((*pheader)->startpc == startpc); + + return (*pheader)->pprogfunc; +} + +bool VuFunctionHeader::IsSame(void* pmem) +{ +#ifdef SUPERVU_CACHING + vector::iterator it; + for(it = ranges.begin(); it != ranges.end(); it++) + { + if (memcmp_mmx((u8*)pmem + it->start, it->pmem, it->size)) + return false; + } +#endif + return true; +} + +list::iterator VuBaseBlock::GetInstIterAtPc(int instpc) +{ + assert(instpc >= 0); + + u32 curpc = startpc; + list::iterator it; + for (it = insts.begin(); it != insts.end(); ++it) + { + if (it->type & INST_DUMMY) continue; + if (curpc == instpc) break; + curpc += 8; + } + + if (it != insts.end()) return it; + + assert(0); + return insts.begin(); +} + +void VuBaseBlock::GetInstsAtPc(int instpc, list& listinsts) +{ + assert(instpc >= 0); + + listinsts.clear(); + + u32 curpc = startpc; + list::iterator it; + for (it = insts.begin(); it != insts.end(); ++it) + { + if (it->type & INST_DUMMY) continue; + if (curpc == instpc) break; + curpc += 8; + } + + if (it != insts.end()) + { + listinsts.push_back(&(*it)); + return; + } + + // look for the pc in other blocks + for (list::iterator itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); ++itblock) + { + if (*itblock == this) continue; + + if (instpc >= (*itblock)->startpc && instpc < (*itblock)->endpc) + { + listinsts.push_back(&(*(*itblock)->GetInstIterAtPc(instpc))); + } + } + + assert(listinsts.size() > 0); +} + +static VuFunctionHeader* SuperVURecompileProgram(u32 startpc, int vuindex) +{ + assert(vuindex < 2); + assert(s_recVUPtr != NULL); + //Console::WriteLn("svu%c rec: %x", params '0'+vuindex, startpc); + + // if recPtr reached the mem limit reset whole mem + if (((uptr)s_recVUPtr - (uptr)s_recVUMem) >= VU_EXESIZE - 0x40000) + { + //Console::WriteLn("SuperVU reset mem"); + SuperVUReset(0); + SuperVUReset(1); + SuperVUReset(-1); + if (s_TotalVUCycles > 0) + { + // already executing, so return NULL + return NULL; + } + } + + list::iterator itblock; + + s_vu = vuindex; + VU = s_vu ? &VU1 : &VU0; + s_pFnHeader = new VuFunctionHeader(); + s_listVUHeaders[vuindex].push_back(s_pFnHeader); + s_pFnHeader->startpc = startpc; + + memset(recVUBlocks[s_vu], 0, sizeof(VuBlockHeader) * (s_MemSize[s_vu] / 8)); + + // analyze the global graph + s_listBlocks.clear(); + VUPIPELINES pipes; + memzero_obj(pipes.fmac); + memzero_obj(pipes.fdiv); + memzero_obj(pipes.efu); + memzero_obj(pipes.ialu); + SuperVUBuildBlocks(NULL, startpc, pipes); + + // fill parents + VuBaseBlock::LISTBLOCKS::iterator itchild; + for(itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); itblock++) + { + for(itchild = (*itblock)->blocks.begin(); itchild != (*itblock)->blocks.end(); itchild++) + { + (*itchild)->parents.push_back(*itblock); + } + + //(*itblock)->type &= ~(BLOCKTYPE_IGNORE|BLOCKTYPE_ANALYZED); + } + + assert(s_listBlocks.front()->startpc == startpc); + s_listBlocks.front()->type |= BLOCKTYPE_FUNCTION; + + for(itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); itblock++) + { + SuperVUInitLiveness(*itblock); + } + + SuperVULivenessAnalysis(); + SuperVUEliminateDeadCode(); + SuperVUAssignRegs(); + +#ifdef PCSX2_DEBUG + if ((s_vu && (vudump&1)) || (!s_vu && (vudump&16))) SuperVUDumpBlock(s_listBlocks, s_vu); +#endif + + // code generation + x86SetPtr(s_recVUPtr); + branch = 0; + + SuperVURecompile(); + + s_recVUPtr = x86Ptr; + + // set the function's range + VuFunctionHeader::RANGE r; + s_pFnHeader->ranges.reserve(s_listBlocks.size()); + + for(itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); itblock++) + { + r.start = (*itblock)->startpc; + r.size = (*itblock)->endpc - (*itblock)->startpc; +#ifdef SUPERVU_CACHING + //memxor_mmx(r.checksum, &VU->Micro[r.start], r.size); + r.pmem = malloc(r.size); + memcpy_fast(r.pmem, &VU->Micro[r.start], r.size); +#endif + s_pFnHeader->ranges.push_back(r); + } + +#if defined(PCSX2_DEBUG) && defined(__LINUX__) + // dump at the end to capture the actual code + if ((s_vu && (vudump&1)) || (!s_vu && (vudump&16))) SuperVUDumpBlock(s_listBlocks, s_vu); +#endif + + // destroy + for (list::iterator itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); ++itblock) + { + delete *itblock; + } + s_listBlocks.clear(); + + assert(s_recVUPtr < s_recVUMem + VU_EXESIZE); + + return s_pFnHeader; +} + +static int _recbranchAddr(u32 vucode) +{ + s32 bpc = pc + (_Imm11_ << 3); + /* + if ( bpc < 0 ) { + Console::WriteLn("zerorec branch warning: bpc < 0 ( %x ); Using unsigned imm11", params bpc); + bpc = pc + (_UImm11_ << 3); + }*/ + bpc &= (s_MemSize[s_vu] - 1); + + return bpc; +} + +// return inst that flushes everything +static VuInstruction SuperVUFlushInst() +{ + VuInstruction inst; + // don't need to read q/p + inst.type = INST_DUMMY_;//|INST_Q_READ|INST_P_READ; + return inst; +} + +void SuperVUAddWritebacks(VuBaseBlock* pblock, const list& listWritebacks) +{ +#ifdef SUPERVU_WRITEBACKS + // regardless of repetition, add the pipes (for selfloops) + list::const_iterator itwriteback = listWritebacks.begin(); + list::iterator itinst = pblock->insts.begin(), itinst2; + + while (itwriteback != listWritebacks.end()) + { + if (itinst != pblock->insts.end() && (itinst->info.cycle < itwriteback->cycle || (itinst->type&INST_DUMMY))) + { + ++itinst; + continue; + } + + itinst2 = pblock->insts.insert(itinst, VuInstruction()); + itwriteback->InitInst(&(*itinst2), vucycle); + ++itwriteback; + } +#endif +} + +#ifdef SUPERVU_VIBRANCHDELAY +static VuInstruction* getDelayInst(VuInstruction* pInst) +{ + // check for the N cycle branch delay + // example of 2 cycles delay (monster house) : + // sqi vi05 + // sqi vi05 + // ibeq vi05, vi03 + // The ibeq should read the vi05 before the first sqi + + //more info: + + // iaddiu vi01, 0, 1 + // ibeq vi01, 0 <- reads vi01 before the iaddiu + + // iaddiu vi01, 0, 1 + // iaddiu vi01, vi01, 1 + // iaddiu vi01, vi01, 1 + // ibeq vi01, 0 <- reads vi01 before the last two iaddiu's (so the value read is 1) + + // ilw vi02, addr + // iaddiu vi01, 0, 1 + // ibeq vi01, vi02 <- reads current values of both vi01 and vi02 because the branch instruction stalls + + int delay = 1; + VuInstruction* pDelayInst = NULL; + VuInstruction* pTargetInst = pInst->pPrevInst; + while (1) + { + if (pTargetInst != NULL + && pTargetInst->info.cycle + delay == pInst->info.cycle + && (pTargetInst->regs[0].pipe == VUPIPE_IALU || pTargetInst->regs[0].pipe == VUPIPE_FMAC) + && ((pTargetInst->regs[0].VIwrite & pInst->regs[0].VIread) & 0xffff) + && (delay == 1 || ((pTargetInst->regs[0].VIwrite & pInst->regs[0].VIread) & 0xffff) == ((pTargetInst->regs[0].VIwrite & pInst->pPrevInst->regs[0].VIread) & 0xffff)) + && !(pTargetInst->regs[0].VIread&((1 << REG_STATUS_FLAG) | (1 << REG_MAC_FLAG) | (1 << REG_CLIP_FLAG)))) + { + pDelayInst = pTargetInst; + pTargetInst = pTargetInst->pPrevInst; + delay++; + if (delay == 5) //maximum delay is 4 (length of the pipeline) + { + DevCon::WriteLn("supervu: cycle branch delay maximum (4) is reached"); + break; + } + } + else break; + } + if (delay > 1) DevCon::WriteLn("supervu: %d cycle branch delay detected: %x %x", params delay - 1, pc, s_pFnHeader->startpc); + return pDelayInst; +} +#endif + +static VuBaseBlock* SuperVUBuildBlocks(VuBaseBlock* parent, u32 startpc, const VUPIPELINES& pipes) +{ + // check if block already exists + //Console::WriteLn("startpc %x", params startpc); + startpc &= (s_vu ? 0x3fff : 0xfff); + VuBlockHeader* pbh = &recVUBlocks[s_vu][startpc/8]; + + if (pbh->pblock != NULL) + { + + VuBaseBlock* pblock = pbh->pblock; + list::iterator itinst; + + if (pblock->startpc == startpc) + { + SuperVUAddWritebacks(pblock, pipes.listWritebacks); + return pblock; + } + + // have to divide the blocks, pnewblock is first block + assert(startpc > pblock->startpc); + assert(startpc < pblock->endpc); + + u32 dummyinst = (startpc - pblock->startpc) >> 3; + + // count inst non-dummy insts + itinst = pblock->insts.begin(); + int cycleoff = 0; + + while (dummyinst > 0) + { + if (itinst->type & INST_DUMMY) + ++itinst; + else + { + cycleoff = itinst->info.cycle; + ++itinst; + --dummyinst; + } + } + + // NOTE: still leaves insts with their writebacks in different blocks + while (itinst->type & INST_DUMMY) + ++itinst; + + // the difference in cycles between dummy insts (naruto utlimate ninja) + int cyclediff = 0; + if (parent == pblock) + cyclediff = itinst->info.cycle - cycleoff; + cycleoff = itinst->info.cycle; + + // new block + VuBaseBlock* pnewblock = new VuBaseBlock(); + s_listBlocks.push_back(pnewblock); + + pnewblock->startpc = startpc; + pnewblock->endpc = pblock->endpc; + pnewblock->cycles = pblock->cycles - cycleoff + cyclediff; + + pnewblock->blocks.splice(pnewblock->blocks.end(), pblock->blocks); + pnewblock->insts.splice(pnewblock->insts.end(), pblock->insts, itinst, pblock->insts.end()); + pnewblock->type = pblock->type; + + // any writebacks in the next 3 cycles also belong to original block +// for(itinst = pnewblock->insts.begin(); itinst != pnewblock->insts.end(); ) { +// if( (itinst->type & INST_DUMMY) && itinst->nParentPc >= 0 && itinst->nParentPc < (int)startpc ) { +// +// if( !(itinst->type & INST_Q_WRITE) ) +// pblock->insts.push_back(*itinst); +// itinst = pnewblock->insts.erase(itinst); +// continue; +// } +// +// ++itinst; +// } + + pbh = &recVUBlocks[s_vu][startpc/8]; + for (u32 inst = startpc; inst < pblock->endpc; inst += 8) + { + if (pbh->pblock == pblock) + pbh->pblock = pnewblock; + ++pbh; + } + + for(itinst = pnewblock->insts.begin(); itinst != pnewblock->insts.end(); itinst++) + { + itinst->info.cycle -= cycleoff; + } + + SuperVUAddWritebacks(pnewblock, pipes.listWritebacks); + + // old block + pblock->blocks.push_back(pnewblock); + pblock->endpc = startpc; + pblock->cycles = cycleoff; + pblock->type &= BLOCKTYPE_MACFLAGS; + //pblock->insts.push_back(SuperVUFlushInst()); //don't need + + return pnewblock; + } + + VuBaseBlock* pblock = new VuBaseBlock(); + s_listBlocks.push_back(pblock); + + int i = 0; + branch = 0; + pc = startpc; + pblock->startpc = startpc; + + // clear stalls (might be a prob) + memcpy(VU->fmac, pipes.fmac, sizeof(pipes.fmac)); + memcpy(&VU->fdiv, &pipes.fdiv, sizeof(pipes.fdiv)); + memcpy(&VU->efu, &pipes.efu, sizeof(pipes.efu)); + memcpy(VU->ialu, pipes.ialu, sizeof(pipes.ialu)); +// memset(VU->fmac, 0, sizeof(VU->fmac)); +// memset(&VU->fdiv, 0, sizeof(VU->fdiv)); +// memset(&VU->efu, 0, sizeof(VU->efu)); + + vucycle = 0; + + u8 macflags = 0; + + list< WRITEBACK > listWritebacks; + list< WRITEBACK >::iterator itwriteback; + list::iterator itinst; + u32 hasSecondBranch = 0; + u32 needFullStatusFlag = 0; + +#ifdef SUPERVU_WRITEBACKS + listWritebacks = pipes.listWritebacks; +#endif + + // first analysis pass for status flags + while (1) + { + u32* ptr = (u32*) & VU->Micro[pc]; + pc += 8; + int prevbranch = branch; + + if (ptr[1] & 0x40000000) + branch = 1; + + if (!(ptr[1] & 0x80000000)) // not I + { + switch (ptr[0] >> 25) + { + case 0x24: // jr + case 0x25: // jalr + case 0x20: // B + case 0x21: // BAL + case 0x28: // IBEQ + case 0x2f: // IBGEZ + case 0x2d: // IBGTZ + case 0x2e: // IBLEZ + case 0x2c: // IBLTZ + case 0x29: // IBNE + branch = 1; + break; + + case 0x14: // fseq + case 0x17: // fsor + //needFullStatusFlag = 2; + break; + + case 0x16: // fsand + if ((ptr[0]&0xc0)) + { + // sometimes full sticky bits are needed (simple series 2000 - oane chapara) + //Console::WriteLn("needSticky: %x-%x", params s_pFnHeader->startpc, startpc); + needFullStatusFlag = 2; + } + break; + } + } + + if (prevbranch) + break; + + if (pc >= s_MemSize[s_vu]) + { + Console::Error("inf vu0 prog %x", params startpc); + break; + } + } + + // second full pass + pc = startpc; + branch = 0; + VuInstruction* pprevinst = NULL, *pinst = NULL; + + while (1) + { + + if (pc == s_MemSize[s_vu]) + { + branch |= 8; + break; + } + + if (!branch && pbh->pblock != NULL) + { + pblock->blocks.push_back(pbh->pblock); + break; + } + + int prevbranch = branch; + + if (!prevbranch) + { + pbh->pblock = pblock; + } + else assert(prevbranch || pbh->pblock == NULL); + + pblock->insts.push_back(VuInstruction()); + + pprevinst = pinst; + pinst = &pblock->insts.back(); + pinst->pPrevInst = pprevinst; + SuperVUAnalyzeOp(VU, &pinst->info, pinst->regs); + +#ifdef SUPERVU_VIBRANCHDELAY + if (pinst->regs[0].pipe == VUPIPE_BRANCH && pblock->insts.size() > 1) + { + + VuInstruction* pdelayinst = getDelayInst(pinst); + if (pdelayinst) + { + pdelayinst->type |= INST_CACHE_VI; + + // find the correct register + u32 mask = pdelayinst->regs[0].VIwrite & pinst->regs[0].VIread; + for (int i = 0; i < 16; ++i) + { + if (mask & (1 << i)) + { + pdelayinst->vicached = i; + break; + } + } + + pinst->vicached = pdelayinst->vicached; + } + } +#endif + + if (prevbranch) + { + if (pinst->regs[0].pipe == VUPIPE_BRANCH) + hasSecondBranch = 1; + pinst->type |= INST_BRANCH_DELAY; + } + + // check write back + for (itwriteback = listWritebacks.begin(); itwriteback != listWritebacks.end();) + { + if (pinst->info.cycle >= itwriteback->cycle) + { + itinst = pblock->insts.insert(--pblock->insts.end(), VuInstruction()); + itwriteback->InitInst(&(*itinst), pinst->info.cycle); + itwriteback = listWritebacks.erase(itwriteback); + } + else ++itwriteback; + } + + // add new writebacks + WRITEBACK w; + const u32 allflags = (1 << REG_CLIP_FLAG) | (1 << REG_MAC_FLAG) | (1 << REG_STATUS_FLAG); + for (int j = 0; j < 2; ++j) w.viwrite[j] = pinst->regs[j].VIwrite & allflags; + + if (pinst->info.macflag & VUOP_WRITE) w.viwrite[1] |= (1 << REG_MAC_FLAG); + if (pinst->info.statusflag & VUOP_WRITE) w.viwrite[1] |= (1 << REG_STATUS_FLAG); + + if ((pinst->info.macflag | pinst->info.statusflag) & VUOP_READ) + macflags = 1; + if (pinst->regs[0].VIread & ((1 << REG_MAC_FLAG) | (1 << REG_STATUS_FLAG))) + macflags = 1; + +// if( pinst->regs[1].pipe == VUPIPE_FMAC && (pinst->regs[1].VFwrite==0&&!(pinst->regs[1].VIwrite&(1<regs[0].VIread |= (1<VIwrite |= lregs->VIwrite & (1<info.statusflag&VUOP_WRITE) && !(pinst->regs[0].VIwrite&(1 << REG_STATUS_FLAG))) && needFullStatusFlag) + { + // don't read if first inst + if (needFullStatusFlag == 1) + w.viread[1] |= (1 << REG_STATUS_FLAG); + else --needFullStatusFlag; + } + + for (int j = 0; j < 2; ++j) + { + w.viread[j] |= pinst->regs[j].VIread & allflags; + + if ((pinst->regs[j].VIread&(1 << REG_STATUS_FLAG)) && (pinst->regs[j].VIwrite&(1 << REG_STATUS_FLAG))) + { + // don't need the read anymore + pinst->regs[j].VIread &= ~(1 << REG_STATUS_FLAG); + } + if ((pinst->regs[j].VIread&(1 << REG_MAC_FLAG)) && (pinst->regs[j].VIwrite&(1 << REG_MAC_FLAG))) + { + // don't need the read anymore + pinst->regs[j].VIread &= ~(1 << REG_MAC_FLAG); + } + + pinst->regs[j].VIwrite &= ~allflags; + } + + if (pinst->info.macflag & VUOP_READ) w.viread[1] |= 1 << REG_MAC_FLAG; + if (pinst->info.statusflag & VUOP_READ) w.viread[1] |= 1 << REG_STATUS_FLAG; + + w.nParentPc = pc - 8; + w.cycle = pinst->info.cycle + 4; + listWritebacks.push_back(w); + } + + if (pinst->info.q&VUOP_READ) pinst->type |= INST_Q_READ; + if (pinst->info.p&VUOP_READ) pinst->type |= INST_P_READ; + + if (pinst->info.q&VUOP_WRITE) + { + pinst->pqcycles = QWaitTimes[pinst->info.pqinst] + 1; + + memset(&w, 0, sizeof(w)); + w.nParentPc = pc - 8; + w.cycle = pinst->info.cycle + pinst->pqcycles; + w.viwrite[0] = 1 << REG_Q; + listWritebacks.push_back(w); + } + if (pinst->info.p&VUOP_WRITE) + pinst->pqcycles = PWaitTimes[pinst->info.pqinst] + 1; + + if (prevbranch) + { + break; + } + + // make sure there is always a branch + // sensible soccer overflows on vu0, so increase the limit... + if ((s_vu == 1 && i >= 0x799) || (s_vu == 0 && i >= 0x201)) + { + Console::Error("VuRec base block doesn't terminate!"); + assert(0); + break; + } + + i++; + pbh++; + } + + if (macflags) + pblock->type |= BLOCKTYPE_MACFLAGS; + + pblock->endpc = pc; + u32 lastpc = pc; + + pblock->cycles = vucycle; + +#ifdef SUPERVU_WRITEBACKS + if (!branch || (branch&8)) +#endif + { + // flush writebacks + if (listWritebacks.size() > 0) + { + listWritebacks.sort(WRITEBACK::SortWritebacks); + for (itwriteback = listWritebacks.begin(); itwriteback != listWritebacks.end(); ++itwriteback) + { + if (itwriteback->viwrite[0] & (1 << REG_Q)) + { + // ignore all Q writebacks + continue; + } + + pblock->insts.push_back(VuInstruction()); + itwriteback->InitInst(&pblock->insts.back(), vucycle); + } + + listWritebacks.clear(); + } + } + + if (!branch) return pblock; + + if (branch & 8) + { + // what if also a jump? + pblock->type |= BLOCKTYPE_EOP | BLOCKTYPE_HASEOP; + + // add an instruction to flush p and q (if written) + pblock->insts.push_back(SuperVUFlushInst()); + return pblock; + } + + // it is a (cond) branch or a jump + u32 vucode = *(u32*)(VU->Micro + lastpc - 16); + int bpc = _recbranchAddr(vucode) - 8; + + VUPIPELINES newpipes; + memcpy(newpipes.fmac, VU->fmac, sizeof(newpipes.fmac)); + memcpy(&newpipes.fdiv, &VU->fdiv, sizeof(newpipes.fdiv)); + memcpy(&newpipes.efu, &VU->efu, sizeof(newpipes.efu)); + memcpy(newpipes.ialu, VU->ialu, sizeof(newpipes.ialu)); + + for (i = 0; i < 8; ++i) newpipes.fmac[i].sCycle -= vucycle; + newpipes.fdiv.sCycle -= vucycle; + newpipes.efu.sCycle -= vucycle; + for (i = 0; i < 8; ++i) newpipes.ialu[i].sCycle -= vucycle; + + if (listWritebacks.size() > 0) + { + // flush all when jumping, send down the pipe when in branching + bool bFlushWritebacks = (vucode >> 25) == 0x24 || (vucode >> 25) == 0x25;//||(vucode>>25)==0x20||(vucode>>25)==0x21; + + listWritebacks.sort(WRITEBACK::SortWritebacks); + for (itwriteback = listWritebacks.begin(); itwriteback != listWritebacks.end(); ++itwriteback) + { + if (itwriteback->viwrite[0] & (1 << REG_Q)) + { + // ignore all Q writebacks + continue; + } + + if (itwriteback->cycle < vucycle || bFlushWritebacks) + { + pblock->insts.push_back(VuInstruction()); + itwriteback->InitInst(&pblock->insts.back(), vucycle); + } + else + { + newpipes.listWritebacks.push_back(*itwriteback); + newpipes.listWritebacks.back().cycle -= vucycle; + } + } + } + + if (newpipes.listWritebacks.size() > 0) // other blocks might read the mac flags + pblock->type |= BLOCKTYPE_MACFLAGS; + + u32 firstbranch = vucode >> 25; + switch (firstbranch) + { + case 0x24: // jr + pblock->type |= BLOCKTYPE_EOP; // jump out of procedure, since not returning, set EOP + pblock->insts.push_back(SuperVUFlushInst()); + firstbranch = 0xff; //Non-Conditional Jump + break; + + case 0x25: // jalr + { + // linking, so will return to procedure + pblock->insts.push_back(SuperVUFlushInst()); + + VuBaseBlock* pjumpblock = SuperVUBuildBlocks(pblock, lastpc, newpipes); + + // update pblock since could have changed + pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; + assert(pblock != NULL); + + pblock->blocks.push_back(pjumpblock); + firstbranch = 0xff; //Non-Conditional Jump + break; + } + case 0x20: // B + { + VuBaseBlock* pbranchblock = SuperVUBuildBlocks(pblock, bpc, newpipes); + + // update pblock since could have changed + pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; + assert(pblock != NULL); + + pblock->blocks.push_back(pbranchblock); + firstbranch = 0xff; //Non-Conditional Jump + break; + } + case 0x21: // BAL + { + VuBaseBlock* pbranchblock = SuperVUBuildBlocks(pblock, bpc, newpipes); + + // update pblock since could have changed + pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; + assert(pblock != NULL); + pblock->blocks.push_back(pbranchblock); + firstbranch = 0xff; //Non-Conditional Jump + break; + } + case 0x28: // IBEQ + case 0x2f: // IBGEZ + case 0x2d: // IBGTZ + case 0x2e: // IBLEZ + case 0x2c: // IBLTZ + case 0x29: // IBNE + { + VuBaseBlock* pbranchblock = SuperVUBuildBlocks(pblock, bpc, newpipes); + + // update pblock since could have changed + pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; + assert(pblock != NULL); + pblock->blocks.push_back(pbranchblock); + + // if has a second branch that is B or BAL, skip this + u32 secondbranch = (*(u32*)(VU->Micro + lastpc - 8)) >> 25; + if (!hasSecondBranch || (secondbranch != 0x21 && secondbranch != 0x20)) + { + pbranchblock = SuperVUBuildBlocks(pblock, lastpc, newpipes); + + pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; + pblock->blocks.push_back(pbranchblock); + } + + break; + } + default: + assert(pblock->blocks.size() == 1); + break; + } + + pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; + +#ifdef SUPERVU_VIBRANCHDELAY +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +///// NOTE! This could still be a hack for KH2/GoW, but until we know how it properly works, this will do for now./// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + if (hasSecondBranch && firstbranch != 0xff) //check the previous jump was conditional and there is a second branch + { +#else + if (hasSecondBranch) + { +#endif + + u32 vucode = *(u32*)(VU->Micro + lastpc - 8); + pc = lastpc; + int bpc = _recbranchAddr(vucode); + + switch (vucode >> 25) + { + case 0x24: // jr + Console::Error("svurec bad jr jump!"); + assert(0); + break; + + case 0x25: // jalr + { + Console::Error("svurec bad jalr jump!"); + assert(0); + break; + } + case 0x20: // B + { + VuBaseBlock* pbranchblock = SuperVUBuildBlocks(pblock, bpc, newpipes); + + // update pblock since could have changed + pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; + + pblock->blocks.push_back(pbranchblock); + break; + } + case 0x21: // BAL + { + VuBaseBlock* pbranchblock = SuperVUBuildBlocks(pblock, bpc, newpipes); + + // replace instead of pushing a new block + pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; + pblock->blocks.push_back(pbranchblock); + break; + } + case 0x28: // IBEQ + case 0x2f: // IBGEZ + case 0x2d: // IBGTZ + case 0x2e: // IBLEZ + case 0x2c: // IBLTZ + case 0x29: // IBNE + { + VuBaseBlock* pbranchblock = SuperVUBuildBlocks(pblock, bpc, newpipes); + + // update pblock since could have changed + pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; + pblock->blocks.push_back(pbranchblock); + + // only add the block if the previous branch doesn't include the next instruction (ie, if a direct jump) + if (firstbranch == 0x24 || firstbranch == 0x25 || firstbranch == 0x20 || firstbranch == 0x21) + { + pbranchblock = SuperVUBuildBlocks(pblock, lastpc, newpipes); + + pblock = recVUBlocks[s_vu][lastpc/8-2].pblock; + pblock->blocks.push_back(pbranchblock); + } + + break; + } + + jNO_DEFAULT; + } + } + + return recVUBlocks[s_vu][startpc/8].pblock; +} + +static void SuperVUInitLiveness(VuBaseBlock* pblock) +{ + list::iterator itinst, itnext; + + assert(pblock->insts.size() > 0); + + for (itinst = pblock->insts.begin(); itinst != pblock->insts.end(); ++itinst) + { + + if (itinst->type & INST_DUMMY_) + { + itinst->addvars[0] = itinst->addvars[1] = 0xffffffff; + itinst->livevars[0] = itinst->livevars[1] = 0xffffffff; + itinst->keepvars[0] = itinst->keepvars[1] = 0xffffffff; + itinst->usedvars[0] = itinst->usedvars[1] = 0; + } + else + { + itinst->addvars[0] = itinst->regs[0].VIread | itinst->regs[1].VIread; + itinst->addvars[1] = (itinst->regs[0].VFread0 ? (1 << itinst->regs[0].VFread0) : 0) | + (itinst->regs[0].VFread1 ? (1 << itinst->regs[0].VFread1) : 0) | + (itinst->regs[1].VFread0 ? (1 << itinst->regs[1].VFread0) : 0) | + (itinst->regs[1].VFread1 ? (1 << itinst->regs[1].VFread1) : 0); + + // vf0 is not handled by VFread + if (!itinst->regs[0].VFread0 && (itinst->regs[0].VIread & (1 << REG_VF0_FLAG))) itinst->addvars[1] |= 1; + if (!itinst->regs[1].VFread0 && (itinst->regs[1].VIread & (1 << REG_VF0_FLAG))) itinst->addvars[1] |= 1; + if (!itinst->regs[0].VFread1 && (itinst->regs[0].VIread & (1 << REG_VF0_FLAG)) && itinst->regs[0].VFr1xyzw != 0xff) itinst->addvars[1] |= 1; + if (!itinst->regs[1].VFread1 && (itinst->regs[1].VIread & (1 << REG_VF0_FLAG)) && itinst->regs[1].VFr1xyzw != 0xff) itinst->addvars[1] |= 1; + + + u32 vfwrite = 0; + if (itinst->regs[0].VFwrite != 0) + { + if (itinst->regs[0].VFwxyzw != 0xf) itinst->addvars[1] |= 1 << itinst->regs[0].VFwrite; + else vfwrite |= 1 << itinst->regs[0].VFwrite; + } + if (itinst->regs[1].VFwrite != 0) + { + if (itinst->regs[1].VFwxyzw != 0xf) itinst->addvars[1] |= 1 << itinst->regs[1].VFwrite; + else vfwrite |= 1 << itinst->regs[1].VFwrite; + } + if ((itinst->regs[1].VIwrite & (1 << REG_ACC_FLAG)) && itinst->regs[1].VFwxyzw != 0xf) + itinst->addvars[1] |= 1 << REG_ACC_FLAG; + + u32 viwrite = (itinst->regs[0].VIwrite | itinst->regs[1].VIwrite); + + itinst->usedvars[0] = itinst->addvars[0] | viwrite; + itinst->usedvars[1] = itinst->addvars[1] | vfwrite; + +// itinst->addvars[0] &= ~viwrite; +// itinst->addvars[1] &= ~vfwrite; + itinst->keepvars[0] = ~viwrite; + itinst->keepvars[1] = ~vfwrite; + } + } + + itinst = --pblock->insts.end(); + while (itinst != pblock->insts.begin()) + { + itnext = itinst; + --itnext; + + itnext->usedvars[0] |= itinst->usedvars[0]; + itnext->usedvars[1] |= itinst->usedvars[1]; + + itinst = itnext; + } +} + +u32 COMPUTE_LIVE(u32 R, u32 K, u32 L) +{ + u32 live = R | ((L) & (K)); + // special process mac and status flags + // only propagate liveness if doesn't write to the flag + if (!(L&(1 << REG_STATUS_FLAG)) && !(K&(1 << REG_STATUS_FLAG))) + live &= ~(1 << REG_STATUS_FLAG); + if (!(L&(1 << REG_MAC_FLAG)) && !(K&(1 << REG_MAC_FLAG))) + live &= ~(1 << REG_MAC_FLAG); + return live;//|(1<::reverse_iterator itblock; + list::iterator itinst, itnext; + VuBaseBlock::LISTBLOCKS::iterator itchild; + + u32 livevars[2]; + + do + { + changed = FALSE; + for (itblock = s_listBlocks.rbegin(); itblock != s_listBlocks.rend(); ++itblock) + { + + u32 newlive; + VuBaseBlock* pb = *itblock; + + // the last inst relies on the neighbor's insts + itinst = --pb->insts.end(); + + if (pb->blocks.size() > 0) + { + livevars[0] = 0; + livevars[1] = 0; + for (itchild = pb->blocks.begin(); itchild != pb->blocks.end(); ++itchild) + { + VuInstruction& front = (*itchild)->insts.front(); + livevars[0] |= front.livevars[0]; + livevars[1] |= front.livevars[1]; + } + + newlive = COMPUTE_LIVE(itinst->addvars[0], itinst->keepvars[0], livevars[0]); + + // should propagate status flags whose parent insts are not in this block +// if( itinst->nParentPc >= 0 && (itinst->type & (INST_STATUS_WRITE|INST_MAC_WRITE)) ) +// newlive |= livevars[0]&((1<livevars[0] != newlive) + { + changed = TRUE; + itinst->livevars[0] = newlive; + } + + newlive = COMPUTE_LIVE(itinst->addvars[1], itinst->keepvars[1], livevars[1]); + if (itinst->livevars[1] != newlive) + { + changed = TRUE; + itinst->livevars[1] = newlive; + } + } + + while (itinst != pb->insts.begin()) + { + + itnext = itinst; + --itnext; + + newlive = COMPUTE_LIVE(itnext->addvars[0], itnext->keepvars[0], itinst->livevars[0]); + + // should propagate status flags whose parent insts are not in this block +// if( itnext->nParentPc >= 0 && (itnext->type & (INST_STATUS_WRITE|INST_MAC_WRITE)) && !(itinst->type & (INST_STATUS_WRITE|INST_MAC_WRITE)) ) +// newlive |= itinst->livevars[0]&((1<livevars[0] != newlive) + { + changed = TRUE; + itnext->livevars[0] = newlive; + itnext->livevars[1] = COMPUTE_LIVE(itnext->addvars[1], itnext->keepvars[1], itinst->livevars[1]); + } + else + { + newlive = COMPUTE_LIVE(itnext->addvars[1], itnext->keepvars[1], itinst->livevars[1]); + if (itnext->livevars[1] != newlive) + { + changed = TRUE; + itnext->livevars[1] = newlive; + } + } + + itinst = itnext; + } + +// if( (livevars[0] | itinst->livevars[0]) != itinst->livevars[0] ) { +// changed = TRUE; +// itinst->livevars[0] |= livevars[0]; +// } +// if( (livevars[1] | itinst->livevars[1]) != itinst->livevars[1] ) { +// changed = TRUE; +// itinst->livevars[1] |= livevars[1]; +// } +// +// while( itinst != pb->insts.begin() ) { +// +// itnext = itinst; --itnext; +// if( (itnext->livevars[0] | (itinst->livevars[0] & itnext->keepvars[0])) != itnext->livevars[0] ) { +// changed = TRUE; +// itnext->livevars[0] |= itinst->livevars[0] & itnext->keepvars[0]; +// itnext->livevars[1] |= itinst->livevars[1] & itnext->keepvars[1]; +// } +// else if( (itnext->livevars[1] | (itinst->livevars[1] & itnext->keepvars[1])) != itnext->livevars[1] ) { +// changed = TRUE; +// itnext->livevars[1] |= itinst->livevars[1] & itnext->keepvars[1]; +// } +// +// itinst = itnext; +// } + } + + } + while (changed); +} + +static void SuperVUEliminateDeadCode() +{ + list::iterator itblock; + VuBaseBlock::LISTBLOCKS::iterator itchild; + list::iterator itinst, itnext; + list listParents; + list::iterator itparent; + + for(itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); itblock++) + { + +#ifdef PCSX2_DEBUG + u32 startpc = (*itblock)->startpc; + u32 curpc = startpc; +#endif + + itnext = (*itblock)->insts.begin(); + itinst = itnext++; + while (itnext != (*itblock)->insts.end()) + { + if (itinst->type & (INST_CLIP_WRITE | INST_MAC_WRITE | INST_STATUS_WRITE)) + { + u32 live0 = itnext->livevars[0]; + if (itinst->nParentPc >= 0 && itnext->nParentPc >= 0 && itinst->nParentPc != itnext->nParentPc) // superman returns + { + // take the live vars from the next next inst + list::iterator itnextnext = itnext; + ++itnextnext; + if (itnextnext != (*itblock)->insts.end()) + { + live0 = itnextnext->livevars[0]; + } + } + + itinst->regs[0].VIwrite &= live0; + itinst->regs[1].VIwrite &= live0; + + u32 viwrite = itinst->regs[0].VIwrite | itinst->regs[1].VIwrite; + + (*itblock)->GetInstsAtPc(itinst->nParentPc, listParents); + int removetype = 0; + + for(itparent = listParents.begin(); itparent != listParents.end(); itparent++) + { + VuInstruction* parent = *itparent; + + if (viwrite & (1 << REG_CLIP_FLAG)) + { + parent->regs[0].VIwrite |= (itinst->regs[0].VIwrite & (1 << REG_CLIP_FLAG)); + parent->regs[1].VIwrite |= (itinst->regs[1].VIwrite & (1 << REG_CLIP_FLAG)); + } + else + removetype |= INST_CLIP_WRITE; + + if (parent->info.macflag && (itinst->type & INST_MAC_WRITE)) + { + if (!(viwrite&(1 << REG_MAC_FLAG))) + { + //parent->info.macflag = 0; + // parent->regs[0].VIwrite &= ~(1<regs[1].VIwrite &= ~(1<regs[0].VIwrite & (1 << REG_MAC_FLAG)) && !(parent->regs[1].VIwrite & (1 << REG_MAC_FLAG))); +#endif + // if VUPIPE_FMAC and destination is vf00, probably need to keep the mac flag + if (parent->regs[1].pipe == VUPIPE_FMAC && (parent->regs[1].VFwrite == 0 && !(parent->regs[1].VIwrite&(1 << REG_ACC_FLAG)))) + { + parent->regs[0].VIwrite |= ((1 << REG_MAC_FLAG)); + parent->regs[1].VIwrite |= ((1 << REG_MAC_FLAG)); + } + else + removetype |= INST_MAC_WRITE; + } + else + { + parent->regs[0].VIwrite |= (itinst->regs[0].VIwrite & (1 << REG_MAC_FLAG)); + parent->regs[1].VIwrite |= (itinst->regs[1].VIwrite & (1 << REG_MAC_FLAG)); + } + } + else removetype |= INST_MAC_WRITE; + + if (parent->info.statusflag && (itinst->type & INST_STATUS_WRITE)) + { + if (!(viwrite&(1 << REG_STATUS_FLAG))) + { + //parent->info.statusflag = 0; + // parent->regs[0].VIwrite &= ~(1<regs[1].VIwrite &= ~(1<regs[0].VIwrite & (1 << REG_STATUS_FLAG)) && !(parent->regs[1].VIwrite & (1 << REG_STATUS_FLAG))); +#endif + if (parent->regs[1].pipe == VUPIPE_FMAC && (parent->regs[1].VFwrite == 0 && !(parent->regs[1].VIwrite&(1 << REG_ACC_FLAG)))) + { + parent->regs[0].VIwrite |= ((1 << REG_STATUS_FLAG)); + parent->regs[1].VIwrite |= ((1 << REG_STATUS_FLAG)); + } + else + removetype |= INST_STATUS_WRITE; + } + else + { + parent->regs[0].VIwrite |= (itinst->regs[0].VIwrite & (1 << REG_STATUS_FLAG)); + parent->regs[1].VIwrite |= (itinst->regs[1].VIwrite & (1 << REG_STATUS_FLAG)); + } + } + else removetype |= INST_STATUS_WRITE; + } + + itinst->type &= ~removetype; + if (itinst->type == 0) + { + itnext = (*itblock)->insts.erase(itinst); + itinst = itnext++; + continue; + } + } +#ifdef PCSX2_DEBUG + else + { + curpc += 8; + } +#endif + itinst = itnext; + ++itnext; + } + + if (itinst->type & INST_DUMMY) + { + // last inst with the children + u32 mask = 0; + for (itchild = (*itblock)->blocks.begin(); itchild != (*itblock)->blocks.end(); ++itchild) + { + mask |= (*itchild)->insts.front().livevars[0]; + } + itinst->regs[0].VIwrite &= mask; + itinst->regs[1].VIwrite &= mask; + u32 viwrite = itinst->regs[0].VIwrite | itinst->regs[1].VIwrite; + + if (itinst->nParentPc >= 0) + { + + (*itblock)->GetInstsAtPc(itinst->nParentPc, listParents); + int removetype = 0; + + for(itparent = listParents.begin(); itparent != listParents.end(); itparent++) + { + VuInstruction* parent = *itparent; + + if (viwrite & (1 << REG_CLIP_FLAG)) + { + parent->regs[0].VIwrite |= (itinst->regs[0].VIwrite & (1 << REG_CLIP_FLAG)); + parent->regs[1].VIwrite |= (itinst->regs[1].VIwrite & (1 << REG_CLIP_FLAG)); + } + else removetype |= INST_CLIP_WRITE; + + if (parent->info.macflag && (itinst->type & INST_MAC_WRITE)) + { + if (!(viwrite&(1 << REG_MAC_FLAG))) + { + //parent->info.macflag = 0; +#ifndef SUPERVU_WRITEBACKS + assert(!(parent->regs[0].VIwrite & (1 << REG_MAC_FLAG)) && !(parent->regs[1].VIwrite & (1 << REG_MAC_FLAG))); +#endif + removetype |= INST_MAC_WRITE; + } + else + { + parent->regs[0].VIwrite |= (itinst->regs[0].VIwrite & (1 << REG_MAC_FLAG)); + parent->regs[1].VIwrite |= (itinst->regs[1].VIwrite & (1 << REG_MAC_FLAG)); + } + } + else removetype |= INST_MAC_WRITE; + + if (parent->info.statusflag && (itinst->type & INST_STATUS_WRITE)) + { + if (!(viwrite&(1 << REG_STATUS_FLAG))) + { + //parent->info.statusflag = 0; +#ifndef SUPERVU_WRITEBACKS + assert(!(parent->regs[0].VIwrite & (1 << REG_STATUS_FLAG)) && !(parent->regs[1].VIwrite & (1 << REG_STATUS_FLAG))); +#endif + removetype |= INST_STATUS_WRITE; + } + else + { + parent->regs[0].VIwrite |= (itinst->regs[0].VIwrite & (1 << REG_STATUS_FLAG)); + parent->regs[1].VIwrite |= (itinst->regs[1].VIwrite & (1 << REG_STATUS_FLAG)); + } + } + else removetype |= INST_STATUS_WRITE; + } + + itinst->type &= ~removetype; + if (itinst->type == 0) + { + (*itblock)->insts.erase(itinst); + } + } + } + } +} + +void VuBaseBlock::AssignVFRegs() +{ + int i; + VuBaseBlock::LISTBLOCKS::iterator itchild; + list::iterator itblock; + list::iterator itinst, itnext, itinst2; + + // init the start regs + if (type & BLOCKTYPE_ANALYZED) return; // nothing changed + memcpy(xmmregs, startregs, sizeof(xmmregs)); + + if (type & BLOCKTYPE_ANALYZED) + { + // check if changed + for (i = 0; i < iREGCNT_XMM; ++i) + { + if (xmmregs[i].inuse != startregs[i].inuse) + break; + if (xmmregs[i].inuse && (xmmregs[i].reg != startregs[i].reg || xmmregs[i].type != startregs[i].type)) + break; + } + + if (i == iREGCNT_XMM) return; // nothing changed + } + + u8* oldX86 = x86Ptr; + + for(itinst = insts.begin(); itinst != insts.end(); itinst++) + { + + if (itinst->type & INST_DUMMY) continue; + + // reserve, go from upper to lower + int lastwrite = -1; + + for (i = 1; i >= 0; --i) + { + _VURegsNum* regs = itinst->regs + i; + + + // redo the counters so that the proper regs are released + for (int j = 0; j < iREGCNT_XMM; ++j) + { + if (xmmregs[j].inuse) + { + if (xmmregs[j].type == XMMTYPE_VFREG) + { + int count = 0; + itinst2 = itinst; + + if (i) + { + if (itinst2->regs[0].VFread0 == xmmregs[j].reg || itinst2->regs[0].VFread1 == xmmregs[j].reg || itinst2->regs[0].VFwrite == xmmregs[j].reg) + { + itinst2 = insts.end(); + break; + } + else + { + ++count; + ++itinst2; + } + } + + while (itinst2 != insts.end()) + { + if (itinst2->regs[0].VFread0 == xmmregs[j].reg || itinst2->regs[0].VFread1 == xmmregs[j].reg || itinst2->regs[0].VFwrite == xmmregs[j].reg || + itinst2->regs[1].VFread0 == xmmregs[j].reg || itinst2->regs[1].VFread1 == xmmregs[j].reg || itinst2->regs[1].VFwrite == xmmregs[j].reg) + break; + + ++count; + ++itinst2; + } + xmmregs[j].counter = 1000 - count; + } + else + { + assert(xmmregs[j].type == XMMTYPE_ACC); + + int count = 0; + itinst2 = itinst; + + if (i) ++itinst2; // acc isn't used in lower insts + + while (itinst2 != insts.end()) + { + assert(!((itinst2->regs[0].VIread | itinst2->regs[0].VIwrite) & (1 << REG_ACC_FLAG))); + + if ((itinst2->regs[1].VIread | itinst2->regs[1].VIwrite) & (1 << REG_ACC_FLAG)) + break; + + ++count; + ++itinst2; + } + + xmmregs[j].counter = 1000 - count; + } + } + } + + if (regs->VFread0) _addNeededVFtoXMMreg(regs->VFread0); + if (regs->VFread1) _addNeededVFtoXMMreg(regs->VFread1); + if (regs->VFwrite) _addNeededVFtoXMMreg(regs->VFwrite); + if (regs->VIread & (1 << REG_ACC_FLAG)) _addNeededACCtoXMMreg(); + if (regs->VIread & (1 << REG_VF0_FLAG)) _addNeededVFtoXMMreg(0); + + // alloc + itinst->vfread0[i] = itinst->vfread1[i] = itinst->vfwrite[i] = itinst->vfacc[i] = -1; + itinst->vfflush[i] = -1; + + if (regs->VFread0) + itinst->vfread0[i] = _allocVFtoXMMreg(VU, -1, regs->VFread0, 0); + else if (regs->VIread & (1 << REG_VF0_FLAG)) + itinst->vfread0[i] = _allocVFtoXMMreg(VU, -1, 0, 0); + + if (regs->VFread1) + itinst->vfread1[i] = _allocVFtoXMMreg(VU, -1, regs->VFread1, 0); + else if ((regs->VIread & (1 << REG_VF0_FLAG)) && regs->VFr1xyzw != 0xff) + itinst->vfread1[i] = _allocVFtoXMMreg(VU, -1, 0, 0); + + if (regs->VIread & (1 << REG_ACC_FLAG)) itinst->vfacc[i] = _allocACCtoXMMreg(VU, -1, 0); + + int reusereg = -1; // 0 - VFwrite, 1 - VFAcc + + if (regs->VFwrite) + { + assert(!(regs->VIwrite&(1 << REG_ACC_FLAG))); + + if (regs->VFwxyzw == 0xf) + { + itinst->vfwrite[i] = _checkXMMreg(XMMTYPE_VFREG, regs->VFwrite, 0); + if (itinst->vfwrite[i] < 0) reusereg = 0; + } + else + { + itinst->vfwrite[i] = _allocVFtoXMMreg(VU, -1, regs->VFwrite, 0); + } + } + else if (regs->VIwrite & (1 << REG_ACC_FLAG)) + { + + if (regs->VFwxyzw == 0xf) + { + itinst->vfacc[i] = _checkXMMreg(XMMTYPE_ACC, 0, 0); + if (itinst->vfacc[i] < 0) reusereg = 1; + } + else + { + itinst->vfacc[i] = _allocACCtoXMMreg(VU, -1, 0); + } + } + + if (reusereg >= 0) + { + // reuse + itnext = itinst; + itnext++; + + u8 type = reusereg ? XMMTYPE_ACC : XMMTYPE_VFREG; + u8 reg = reusereg ? 0 : regs->VFwrite; + + if (itinst->vfacc[i] >= 0 && lastwrite != itinst->vfacc[i] && + (itnext == insts.end() || ((regs->VIread&(1 << REG_ACC_FLAG)) && (!(itnext->usedvars[0]&(1 << REG_ACC_FLAG)) || !(itnext->livevars[0]&(1 << REG_ACC_FLAG)))))) + { + + assert(reusereg == 0); + if (itnext == insts.end() || (itnext->livevars[0]&(1 << REG_ACC_FLAG))) _freeXMMreg(itinst->vfacc[i]); + xmmregs[itinst->vfacc[i]].inuse = 1; + xmmregs[itinst->vfacc[i]].reg = reg; + xmmregs[itinst->vfacc[i]].type = type; + xmmregs[itinst->vfacc[i]].mode = 0; + itinst->vfwrite[i] = itinst->vfacc[i]; + } + else if (itinst->vfread0[i] >= 0 && lastwrite != itinst->vfread0[i] && + (itnext == insts.end() || (regs->VFread0 > 0 && (!(itnext->usedvars[1]&(1 << regs->VFread0)) || !(itnext->livevars[1]&(1 << regs->VFread0)))))) + { + + if (itnext == insts.end() || (itnext->livevars[1]®s->VFread0)) _freeXMMreg(itinst->vfread0[i]); + + xmmregs[itinst->vfread0[i]].inuse = 1; + xmmregs[itinst->vfread0[i]].reg = reg; + xmmregs[itinst->vfread0[i]].type = type; + xmmregs[itinst->vfread0[i]].mode = 0; + + if (reusereg) + itinst->vfacc[i] = itinst->vfread0[i]; + else + itinst->vfwrite[i] = itinst->vfread0[i]; + } + else if (itinst->vfread1[i] >= 0 && lastwrite != itinst->vfread1[i] && + (itnext == insts.end() || (regs->VFread1 > 0 && (!(itnext->usedvars[1]&(1 << regs->VFread1)) || !(itnext->livevars[1]&(1 << regs->VFread1)))))) + { + + if (itnext == insts.end() || (itnext->livevars[1]®s->VFread1)) _freeXMMreg(itinst->vfread1[i]); + + xmmregs[itinst->vfread1[i]].inuse = 1; + xmmregs[itinst->vfread1[i]].reg = reg; + xmmregs[itinst->vfread1[i]].type = type; + xmmregs[itinst->vfread1[i]].mode = 0; + if (reusereg) + itinst->vfacc[i] = itinst->vfread1[i]; + else + itinst->vfwrite[i] = itinst->vfread1[i]; + } + else + { + if (reusereg) + itinst->vfacc[i] = _allocACCtoXMMreg(VU, -1, 0); + else + itinst->vfwrite[i] = _allocVFtoXMMreg(VU, -1, regs->VFwrite, 0); + } + } + + if (itinst->vfwrite[i] >= 0) lastwrite = itinst->vfwrite[i]; + else if (itinst->vfacc[i] >= 0) lastwrite = itinst->vfacc[i]; + + // always alloc at least 1 temp reg + int free0 = (i || regs->VFwrite || regs->VFread0 || regs->VFread1 || (regs->VIwrite & (1 << REG_ACC_FLAG)) || (regs->VIread & (1 << REG_VF0_FLAG))) + ? _allocTempXMMreg(XMMT_FPS, -1) : -1; + int free1 = 0, free2 = 0; + + if (i == 0 && itinst->vfwrite[1] >= 0 && (itinst->vfread0[0] == itinst->vfwrite[1] || itinst->vfread1[0] == itinst->vfwrite[1])) + { + itinst->vfflush[i] = _allocTempXMMreg(XMMT_FPS, -1); + } + + if (i == 1 && (regs->VIwrite & (1 << REG_CLIP_FLAG))) + { + // CLIP inst, need two extra regs + if (free0 < 0) free0 = _allocTempXMMreg(XMMT_FPS, -1); + + free1 = _allocTempXMMreg(XMMT_FPS, -1); + free2 = _allocTempXMMreg(XMMT_FPS, -1); + _freeXMMreg(free1); + _freeXMMreg(free2); + } + else if (regs->VIwrite & (1 << REG_P)) + { + // EFU inst, need extra reg + free1 = _allocTempXMMreg(XMMT_FPS, -1); + if (free0 == -1) free0 = free1; + _freeXMMreg(free1); + } + + if (itinst->vfflush[i] >= 0) _freeXMMreg(itinst->vfflush[i]); + if (free0 >= 0) _freeXMMreg(free0); + + itinst->vffree[i] = (free0 & 0xf) | (free1 << 8) | (free2 << 16); + if (free0 == -1) itinst->vffree[i] |= VFFREE_INVALID0; + + _clearNeededXMMregs(); + } + } + + assert(x86Ptr == oldX86); + u32 analyzechildren = !(type & BLOCKTYPE_ANALYZED); + type |= BLOCKTYPE_ANALYZED; + + //memset(endregs, 0, sizeof(endregs)); + + if (analyzechildren) + { + for(itchild = blocks.begin(); itchild != blocks.end(); itchild++) + { + (*itchild)->AssignVFRegs(); + } + } +} + +struct MARKOVBLANKET +{ + list parents; + list children; +}; + +static MARKOVBLANKET s_markov; + +void VuBaseBlock::AssignVIRegs(int parent) +{ + const int maxregs = 6; + + if (parent) + { + if ((type&BLOCKTYPE_ANALYZEDPARENT)) + return; + + type |= BLOCKTYPE_ANALYZEDPARENT; + s_markov.parents.push_back(this); + for (LISTBLOCKS::iterator it = blocks.begin(); it != blocks.end(); ++it) + { + (*it)->AssignVIRegs(0); + } + return; + } + + if ((type&BLOCKTYPE_ANALYZED)) + return; + + // child + assert(allocX86Regs == -1); + allocX86Regs = s_vecRegArray.size(); + s_vecRegArray.resize(allocX86Regs + iREGCNT_GPR); + + _x86regs* pregs = &s_vecRegArray[allocX86Regs]; + memset(pregs, 0, sizeof(_x86regs)*iREGCNT_GPR); + + assert(parents.size() > 0); + + list::iterator itparent; + u32 usedvars = insts.front().usedvars[0]; + u32 livevars = insts.front().livevars[0]; + + if (parents.size() > 0) + { + u32 usedvars2 = 0xffffffff; + + for(itparent = parents.begin(); itparent != parents.end(); itparent++) + { + usedvars2 &= (*itparent)->insts.front().usedvars[0]; + } + + usedvars |= usedvars2; + } + + usedvars &= livevars; + + // currently order doesn't matter + int num = 0; + + if (usedvars) + { + for (int i = 1; i < 16; ++i) + { + if (usedvars & (1 << i)) + { + pregs[num].inuse = 1; + pregs[num].reg = i; + + livevars &= ~(1 << i); + + if (++num >= maxregs) break; + } + } + } + + if (num < maxregs) + { + livevars &= ~usedvars; + livevars &= insts.back().usedvars[0]; + + if (livevars) + { + for (int i = 1; i < 16; ++i) + { + if (livevars & (1 << i)) + { + pregs[num].inuse = 1; + pregs[num].reg = i; + + if (++num >= maxregs) break; + } + } + } + } + + s_markov.children.push_back(this); + type |= BLOCKTYPE_ANALYZED; + + for(itparent = parents.begin(); itparent != parents.end(); itparent++) + { + (*itparent)->AssignVIRegs(1); + } +} + +static void SuperVUAssignRegs() +{ + list::iterator itblock, itblock2; + + for(itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); itblock++) + { + (*itblock)->type &= ~BLOCKTYPE_ANALYZED; + } + s_listBlocks.front()->AssignVFRegs(); + + // VI assignments, find markov blanket for each node in the graph + // then allocate regs based on the commonly used ones +#ifdef SUPERVU_X86CACHING + for(itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); itblock++) + { + (*itblock)->type &= ~(BLOCKTYPE_ANALYZED | BLOCKTYPE_ANALYZEDPARENT); + } + s_vecRegArray.resize(0); + u8 usedregs[16]; + + // note: first block always has to start with no alloc regs + bool bfirst = true; + + for(itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); itblock++) + { + + if (!((*itblock)->type & BLOCKTYPE_ANALYZED)) + { + + if ((*itblock)->parents.size() == 0) + { + (*itblock)->type |= BLOCKTYPE_ANALYZED; + bfirst = false; + continue; + } + + s_markov.children.clear(); + s_markov.parents.clear(); + (*itblock)->AssignVIRegs(0); + + // assign the regs + int regid = s_vecRegArray.size(); + s_vecRegArray.resize(regid + iREGCNT_GPR); + + _x86regs* mergedx86 = &s_vecRegArray[regid]; + memset(mergedx86, 0, sizeof(_x86regs)*iREGCNT_GPR); + + if (!bfirst) + { + *(u32*)usedregs = *((u32*)usedregs + 1) = *((u32*)usedregs + 2) = *((u32*)usedregs + 3) = 0; + + for(itblock2 = s_markov.children.begin(); itblock2 != s_markov.children.end(); itblock2++) + { + assert((*itblock2)->allocX86Regs >= 0); + _x86regs* pregs = &s_vecRegArray[(*itblock2)->allocX86Regs]; + for (int i = 0; i < iREGCNT_GPR; ++i) + { + if (pregs[i].inuse && pregs[i].reg < 16) + { + //assert( pregs[i].reg < 16); + usedregs[pregs[i].reg]++; + } + } + } + + int num = 1; + for (int i = 0; i < 16; ++i) + { + if (usedregs[i] == s_markov.children.size()) + { + // use + mergedx86[num].inuse = 1; + mergedx86[num].reg = i; + mergedx86[num].type = (s_vu ? X86TYPE_VU1 : 0) | X86TYPE_VI; + mergedx86[num].mode = MODE_READ; + if (++num >= iREGCNT_GPR) + break; + if (num == ESP) + ++num; + } + } + + for(itblock2 = s_markov.children.begin(); itblock2 != s_markov.children.end(); itblock2++) + { + assert((*itblock2)->nStartx86 == -1); + (*itblock2)->nStartx86 = regid; + } + + for(itblock2 = s_markov.parents.begin(); itblock2 != s_markov.parents.end(); itblock2++) + { + assert((*itblock2)->nEndx86 == -1); + (*itblock2)->nEndx86 = regid; + } + } + + bfirst = false; + } + } +#endif +} + +////////////////// +// Recompilation +////////////////// + +// cycles in which the last Q,P regs were finished (written to VU->VI[]) +// the write occurs before the instruction is executed at that cycle +// compare with s_TotalVUCycles +// if less than 0, already flushed +int s_writeQ, s_writeP; + +// declare the saved registers +uptr s_vu1esp, s_callstack;//, s_vu1esp +uptr s_vu1ebp, s_vuebx, s_vuedi, s_vu1esi; + +static int s_recWriteQ, s_recWriteP; // wait times during recompilation +static int s_needFlush; // first bit - Q, second bit - P, third bit - Q has been written, fourth bit - P has been written + +static int s_JumpX86; +static int s_ScheduleXGKICK = 0, s_XGKICKReg = -1; + +void recVUMI_XGKICK_(VURegs *VU); + +void SuperVUCleanupProgram(u32 startpc, int vuindex) +{ +#ifdef SUPERVU_COUNT + QueryPerformanceCounter(&svufinal); + svutime += (u32)(svufinal.QuadPart - svubase.QuadPart); +#endif + + assert(s_vu1esp == 0); + + VU = vuindex ? &VU1 : &VU0; + VU->cycle += s_TotalVUCycles; + + //VU cycle stealing hack, 3000 cycle maximum so it doesn't get out of hand + if (s_TotalVUCycles < 3000) + cpuRegs.cycle += s_TotalVUCycles * Config.Hacks.VUCycleSteal; + else + cpuRegs.cycle += 3000 * Config.Hacks.VUCycleSteal; + + if ((int)s_writeQ > 0) VU->VI[REG_Q] = VU->q; + if ((int)s_writeP > 0) + { + assert(VU == &VU1); + VU1.VI[REG_P] = VU1.p; // only VU1 + } + + //memset(recVUStack, 0, SUPERVU_STACKSIZE * 4); + + // Could clear allocation info to prevent possibly bad data being used in other parts of pcsx2; + // not doing this because it's slow and not needed (rama) + // _initXMMregs(); + // _initMMXregs(); + // _initX86regs(); +} + +#if defined(_MSC_VER) + +// entry point of all vu programs from emulator calls +__declspec(naked) void SuperVUExecuteProgram(u32 startpc, int vuindex) +{ + __asm + { + mov eax, dword ptr [esp] + mov s_TotalVUCycles, 0 // necessary to be here! + add esp, 4 + mov s_callstack, eax + call SuperVUGetProgram + + // save cpu state + mov s_vu1ebp, ebp + mov s_vu1esi, esi // have to save even in Release + mov s_vuedi, edi // have to save even in Release + mov s_vuebx, ebx + } +#ifdef PCSX2_DEBUG + __asm + { + mov s_vu1esp, esp + } +#endif + + __asm + { + //stmxcsr s_ssecsr + ldmxcsr g_sseVUMXCSR + + // init vars + mov s_writeQ, 0xffffffff + mov s_writeP, 0xffffffff + + jmp eax + } +} + +// exit point of all vu programs +__declspec(naked) static void SuperVUEndProgram() +{ + __asm + { + // restore cpu state + ldmxcsr g_sseMXCSR + + mov ebp, s_vu1ebp + mov esi, s_vu1esi + mov edi, s_vuedi + mov ebx, s_vuebx + } + +#ifdef PCSX2_DEBUG + __asm + { + sub s_vu1esp, esp + } +#endif + + __asm + { + call SuperVUCleanupProgram + jmp s_callstack // so returns correctly + } +} + +#endif + +// Flushes P/Q regs +void SuperVUFlush(int p, int wait) +{ + u8* pjmp[3]; + if (!(s_needFlush&(1 << p))) return; + + int recwait = p ? s_recWriteP : s_recWriteQ; + if (!wait && s_pCurInst->info.cycle < recwait) return; + + if (recwait == 0) + { + // write didn't happen this block + MOV32MtoR(EAX, p ? (uptr)&s_writeP : (uptr)&s_writeQ); + OR32RtoR(EAX, EAX); + pjmp[0] = JS8(0); + + if (s_pCurInst->info.cycle) SUB32ItoR(EAX, s_pCurInst->info.cycle); + + // if writeQ <= total+offset + if (!wait) // only write back if time is up + { + CMP32MtoR(EAX, (uptr)&s_TotalVUCycles); + pjmp[1] = JG8(0); + } + else + { + // add (writeQ-total-offset) to s_TotalVUCycles + // necessary? + CMP32MtoR(EAX, (uptr)&s_TotalVUCycles); + pjmp[2] = JLE8(0); + MOV32RtoM((uptr)&s_TotalVUCycles, EAX); + x86SetJ8(pjmp[2]); + } + } + else if (wait && s_pCurInst->info.cycle < recwait) + { + ADD32ItoM((uptr)&s_TotalVUCycles, recwait); + } + + MOV32MtoR(EAX, SuperVUGetVIAddr(p ? REG_P : REG_Q, 0)); + MOV32ItoM(p ? (uptr)&s_writeP : (uptr)&s_writeQ, 0x80000000); + MOV32RtoM(SuperVUGetVIAddr(p ? REG_P : REG_Q, 1), EAX); + + if (recwait == 0) + { + if (!wait) x86SetJ8(pjmp[1]); + x86SetJ8(pjmp[0]); + } + + if (wait || (!p && recwait == 0 && s_pCurInst->info.cycle >= 12) || (!p && recwait > 0 && s_pCurInst->info.cycle >= recwait)) + s_needFlush &= ~(1 << p); +} + +// executed only once per program +static u32* SuperVUStaticAlloc(u32 size) +{ + assert(recVUStackPtr + size <= recVUStack + SUPERVU_STACKSIZE); + // always zero + if (size == 4) *(u32*)recVUStackPtr = 0; + else memset(recVUStackPtr, 0, size); + recVUStackPtr += size; + return (u32*)(recVUStackPtr - size); +} + +static void SuperVURecompile() +{ + // save cpu state + recVUStackPtr = recVUStack; + + _initXMMregs(); + + list::iterator itblock; + + for(itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); itblock++) + { + (*itblock)->type &= ~BLOCKTYPE_ANALYZED; + } + + s_listBlocks.front()->Recompile(); + + // make sure everything compiled + for(itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); itblock++) + { + assert(((*itblock)->type & BLOCKTYPE_ANALYZED) && (*itblock)->pcode != NULL); + } + + // link all blocks + for(itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); itblock++) + { + VuBaseBlock::LISTBLOCKS::iterator itchild; + + assert((*itblock)->blocks.size() <= ArraySize((*itblock)->pChildJumps)); + + int i = 0; + for(itchild = (*itblock)->blocks.begin(); itchild != (*itblock)->blocks.end(); itchild++) + { + + if ((u32)(uptr)(*itblock)->pChildJumps[i] == 0xffffffff) + continue; + + if ((*itblock)->pChildJumps[i] == NULL) + { + VuBaseBlock* pchild = *itchild; + + if (pchild->type & BLOCKTYPE_HASEOP) + { + assert(pchild->blocks.size() == 0); + + AND32ItoM((uptr)&VU0.VI[ REG_VPU_STAT ].UL, s_vu ? ~0x100 : ~0x001); // E flag + AND32ItoM((uptr)&VU->vifRegs->stat, ~0x4); + + MOV32ItoM((uptr)&VU->VI[REG_TPC], pchild->endpc); + JMP32((uptr)SuperVUEndProgram - ((uptr)x86Ptr + 5)); + } + // only other case is when there are two branches + else + { + assert((*itblock)->insts.back().regs[0].pipe == VUPIPE_BRANCH); + } + + continue; + } + + if ((u32)(uptr)(*itblock)->pChildJumps[i] & 0x80000000) + { + // relative + assert((uptr)(*itblock)->pChildJumps[i] <= 0xffffffff); + (*itblock)->pChildJumps[i] = (u32*)((uptr)(*itblock)->pChildJumps[i] & 0x7fffffff); + *(*itblock)->pChildJumps[i] = (uptr)(*itchild)->pcode - ((uptr)(*itblock)->pChildJumps[i] + 4); + } + else + { + *(*itblock)->pChildJumps[i] = (uptr)(*itchild)->pcode; + } + + ++i; + } + } + + s_pFnHeader->pprogfunc = s_listBlocks.front()->pcode; +} + +// debug + + +u32 s_saveecx, s_saveedx, s_saveebx, s_saveesi, s_saveedi, s_saveebp; +u32 g_curdebugvu; + +//float vuDouble(u32 f); + +#if defined(_MSC_VER) +__declspec(naked) static void svudispfn() +{ + __asm + { + mov g_curdebugvu, eax + mov s_saveecx, ecx + mov s_saveedx, edx + mov s_saveebx, ebx + mov s_saveesi, esi + mov s_saveedi, edi + mov s_saveebp, ebp + } +#else + +void svudispfntemp() +{ +#endif + +#ifdef PCSX2_DEBUG + static u32 i; + + if (((vudump&8) && g_curdebugvu) || ((vudump&0x80) && !g_curdebugvu)) //&& g_vu1lastrec != g_vu1last ) { + { + + if (skipparent != g_vu1lastrec) + { + for (i = 0; i < ArraySize(badaddrs); ++i) + { + if (s_svulast == badaddrs[i][1] && g_vu1lastrec == badaddrs[i][0]) + break; + } + + if (i == ArraySize(badaddrs)) + { + //static int curesp; + //__asm mov curesp, esp + //Console::WriteLn("tVU: %x %x %x", s_svulast, s_vucount, s_vufnheader); + if (g_curdebugvu) iDumpVU1Registers(); + else iDumpVU0Registers(); + s_vucount++; + } + } + + g_vu1lastrec = s_svulast; + } +#endif + +#if defined(_MSC_VER) + __asm + { + mov ecx, s_saveecx + mov edx, s_saveedx + mov ebx, s_saveebx + mov esi, s_saveesi + mov edi, s_saveedi + mov ebp, s_saveebp + ret + } +#endif +} + +// frees all regs taking into account the livevars +void SuperVUFreeXMMregs(u32* livevars) +{ + for (int i = 0; i < iREGCNT_XMM; ++i) + { + if (xmmregs[i].inuse) + { + // same reg + if ((xmmregs[i].mode & MODE_WRITE)) + { + +#ifdef SUPERVU_INTERCACHING + if (xmmregs[i].type == XMMTYPE_VFREG) + { + if (!(livevars[1] & (1 << xmmregs[i].reg))) continue; + } + else if (xmmregs[i].type == XMMTYPE_ACC) + { + if (!(livevars[0] & (1 << REG_ACC_FLAG))) continue; + } +#endif + + if (xmmregs[i].mode & MODE_VUXYZ) + { + // ALWAYS update + u32 addr = xmmregs[i].type == XMMTYPE_VFREG ? (uptr) & VU->VF[xmmregs[i].reg] : (uptr) & VU->ACC; + + if (xmmregs[i].mode & MODE_VUZ) + { + SSE_MOVHPS_XMM_to_M64(addr, (x86SSERegType)i); + SSE_SHUFPS_M128_to_XMM((x86SSERegType)i, addr, 0xc4); + } + else + { + SSE_MOVHPS_M64_to_XMM((x86SSERegType)i, addr + 8); + } + + xmmregs[i].mode &= ~MODE_VUXYZ; + } + + _freeXMMreg(i); + } + } + } + + //_freeXMMregs(); +} + +void SuperVUTestVU0Condition(u32 incstack) +{ + if (s_vu && !SUPERVU_CHECKCONDITION) return; // vu0 only + + CMP32ItoM((uptr)&s_TotalVUCycles, 512); // sometimes games spin on vu0, so be careful with this value + // woody hangs if too high + + if (incstack) + { + u8* ptr = JB8(0); + + ADD32ItoR(ESP, incstack); + //CALLFunc((u32)timeout); + JMP32((uptr)SuperVUEndProgram - ((uptr)x86Ptr + 5)); + + x86SetJ8(ptr); + } + else JAE32((uptr)SuperVUEndProgram - ((uptr)x86Ptr + 6)); +} + +void VuBaseBlock::Recompile() +{ + if (type & BLOCKTYPE_ANALYZED) return; + + x86Align(16); + pcode = x86Ptr; + +#ifdef PCSX2_DEBUG + MOV32ItoM((uptr)&s_vufnheader, s_pFnHeader->startpc); + MOV32ItoM((uptr)&VU->VI[REG_TPC], startpc); + MOV32ItoM((uptr)&s_svulast, startpc); + + list::iterator itparent; + for (itparent = parents.begin(); itparent != parents.end(); ++itparent) + { + if ((*itparent)->blocks.size() == 1 && (*itparent)->blocks.front()->startpc == startpc && + ((*itparent)->insts.size() < 2 || (----(*itparent)->insts.end())->regs[0].pipe != VUPIPE_BRANCH)) + { + MOV32ItoM((uptr)&skipparent, (*itparent)->startpc); + break; + } + } + + if (itparent == parents.end()) MOV32ItoM((uptr)&skipparent, -1); + + MOV32ItoR(EAX, s_vu); + CALLFunc((uptr)svudispfn); +#endif + + s_pCurBlock = this; + s_needFlush = 3; + pc = startpc; + branch = 0; + s_recWriteQ = s_recWriteP = 0; + s_XGKICKReg = -1; + s_ScheduleXGKICK = 0; + + s_ClipRead = s_PrevClipWrite = (uptr) & VU->VI[REG_CLIP_FLAG]; + s_StatusRead = s_PrevStatusWrite = (uptr) & VU->VI[REG_STATUS_FLAG]; + s_MACRead = s_PrevMACWrite = (uptr) & VU->VI[REG_MAC_FLAG]; + s_PrevIWrite = (uptr) & VU->VI[REG_I]; + s_JumpX86 = 0; + s_UnconditionalDelay = 0; + + memcpy(xmmregs, startregs, sizeof(xmmregs)); +#ifdef SUPERVU_X86CACHING + if (nStartx86 >= 0) + memcpy(x86regs, &s_vecRegArray[nStartx86], sizeof(x86regs)); + else + _initX86regs(); +#else + _initX86regs(); +#endif + + list::iterator itinst; + for(itinst = insts.begin(); itinst != insts.end(); itinst++) + { + s_pCurInst = &(*itinst); + if (s_JumpX86 > 0) + { + if (!x86regs[s_JumpX86].inuse) + { + // load + s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_READ); + } + x86regs[s_JumpX86].needed = 1; + } + + if (s_ScheduleXGKICK && s_XGKICKReg > 0) + { + assert(x86regs[s_XGKICKReg].inuse); + x86regs[s_XGKICKReg].needed = 1; + } + itinst->Recompile(itinst, vuxyz); + + if (s_ScheduleXGKICK > 0) + { + if (s_ScheduleXGKICK-- == 1) + { + recVUMI_XGKICK_(VU); + } + } + } + assert(pc == endpc); + assert(s_ScheduleXGKICK == 0); + + // flush flags + if (s_PrevClipWrite != (uptr)&VU->VI[REG_CLIP_FLAG]) + { + MOV32MtoR(EAX, s_PrevClipWrite); + MOV32RtoM((uptr)&VU->VI[REG_CLIP_FLAG], EAX); + } + if (s_PrevStatusWrite != (uptr)&VU->VI[REG_STATUS_FLAG]) + { + MOV32MtoR(EAX, s_PrevStatusWrite); + MOV32RtoM((uptr)&VU->VI[REG_STATUS_FLAG], EAX); + } + if (s_PrevMACWrite != (uptr)&VU->VI[REG_MAC_FLAG]) + { + MOV32MtoR(EAX, s_PrevMACWrite); + MOV32RtoM((uptr)&VU->VI[REG_MAC_FLAG], EAX); + } +// if( s_StatusRead != (uptr)&VU->VI[REG_STATUS_FLAG] ) { +// // only lower 8 bits valid! +// MOVZX32M8toR(EAX, s_StatusRead); +// MOV32RtoM((uptr)&VU->VI[REG_STATUS_FLAG], EAX); +// } +// if( s_MACRead != (uptr)&VU->VI[REG_MAC_FLAG] ) { +// // only lower 8 bits valid! +// MOVZX32M8toR(EAX, s_MACRead); +// MOV32RtoM((uptr)&VU->VI[REG_MAC_FLAG], EAX); +// } + if (s_PrevIWrite != (uptr)&VU->VI[REG_I]) + { + MOV32ItoM((uptr)&VU->VI[REG_I], *(u32*)s_PrevIWrite); // never changes + } + + ADD32ItoM((uptr)&s_TotalVUCycles, cycles); + + // compute branches, jumps, eop + if (type & BLOCKTYPE_HASEOP) + { + // end + _freeXMMregs(); + _freeX86regs(); + AND32ItoM((uptr)&VU0.VI[ REG_VPU_STAT ].UL, s_vu ? ~0x100 : ~0x001); // E flag + AND32ItoM((uptr)&VU->vifRegs->stat, ~0x4); + + if (!branch) MOV32ItoM((uptr)&VU->VI[REG_TPC], endpc); + + JMP32((uptr)SuperVUEndProgram - ((uptr)x86Ptr + 5)); + } + else + { + + u32 livevars[2] = {0}; + + list::iterator lastinst = GetInstIterAtPc(endpc - 8); + lastinst++; + + if (lastinst != insts.end()) + { + livevars[0] = lastinst->livevars[0]; + livevars[1] = lastinst->livevars[1]; + } + else + { + // take from children + if (blocks.size() > 0) + { + LISTBLOCKS::iterator itchild; + for(itchild = blocks.begin(); itchild != blocks.end(); itchild++) + { + livevars[0] |= (*itchild)->insts.front().livevars[0]; + livevars[1] |= (*itchild)->insts.front().livevars[1]; + } + } + else + { + livevars[0] = ~0; + livevars[1] = ~0; + } + } + + SuperVUFreeXMMregs(livevars); + + // get rid of any writes, otherwise _freeX86regs will write + x86regs[s_JumpX86].mode &= ~MODE_WRITE; + + if (branch == 1) + { + if (!x86regs[s_JumpX86].inuse) + { + assert(x86regs[s_JumpX86].type == X86TYPE_VUJUMP); + s_JumpX86 = 0xffffffff; // notify to jump from g_recWriteback + } + } + + // align VI regs +#ifdef SUPERVU_X86CACHING + if (nEndx86 >= 0) + { + _x86regs* endx86 = &s_vecRegArray[nEndx86]; + for (int i = 0; i < iREGCNT_GPR; ++i) + { + if (endx86[i].inuse) + { + + if (s_JumpX86 == i && x86regs[s_JumpX86].inuse) + { + x86regs[s_JumpX86].inuse = 0; + x86regs[EAX].inuse = 1; + MOV32RtoR(EAX, s_JumpX86); + s_JumpX86 = EAX; + } + + if (x86regs[i].inuse) + { + if (x86regs[i].type == endx86[i].type && x86regs[i].reg == endx86[i].reg) + { + _freeX86reg(i); + // will continue to use it + continue; + } + +#ifdef SUPERVU_INTERCACHING + if (x86regs[i].type == (X86TYPE_VI | (s_vu ? X86TYPE_VU1 : 0))) + { + if (livevars[0] & (1 << x86regs[i].reg)) + _freeX86reg(i); + else + x86regs[i].inuse = 0; + } + else +#endif + { + _freeX86reg(i); + } + } + + // realloc + _allocX86reg(i, endx86[i].type, endx86[i].reg, MODE_READ); + if (x86regs[i].mode & MODE_WRITE) + { + _freeX86reg(i); + x86regs[i].inuse = 1; + } + } + else _freeX86reg(i); + } + } + else _freeX86regs(); +#else + _freeX86regs(); +#endif + + // store the last block executed + MOV32ItoM((uptr)&g_nLastBlockExecuted, s_pCurBlock->startpc); + + switch (branch) + { + case 1: // branch, esi has new prog + + SuperVUTestVU0Condition(0); + + if (s_JumpX86 == 0xffffffff) + JMP32M((uptr)&g_recWriteback); + else + JMPR(s_JumpX86); + + break; + case 4: // jalr + pChildJumps[0] = (u32*)0xffffffff; + // fall through + + case 0x10: // jump, esi has new vupc + { + _freeXMMregs(); + _freeX86regs(); + + SuperVUTestVU0Condition(8); + + // already onto stack + CALLFunc((uptr)SuperVUGetProgram); + ADD32ItoR(ESP, 8); + JMPR(EAX); + break; + } + + case 0x13: // jr with uncon branch, uncond branch takes precendence (dropship) + { +// s32 delta = (s32)(VU->code & 0x400 ? 0xfffffc00 | (VU->code & 0x3ff) : VU->code & 0x3ff) << 3; +// ADD32ItoRmOffset(ESP, delta, 0); + + ADD32ItoR(ESP, 8); // restore + pChildJumps[0] = (u32*)((uptr)JMP32(0) | 0x80000000); + break; + } + case 0: + case 3: // unconditional branch + pChildJumps[s_UnconditionalDelay] = (u32*)((uptr)JMP32(0) | 0x80000000); + break; + + default: + DevCon::Error("Bad branch %x\n", params branch); + assert(0); + break; + } + } + + pendcode = x86Ptr; + type |= BLOCKTYPE_ANALYZED; + + LISTBLOCKS::iterator itchild; + for(itchild = blocks.begin(); itchild != blocks.end(); itchild++) + { + (*itchild)->Recompile(); + } +} + +#define GET_VUXYZMODE(reg) 0//((vuxyz&(1<<(reg)))?MODE_VUXYZ:0) + +int VuInstruction::SetCachedRegs(int upper, u32 vuxyz) +{ + if (vfread0[upper] >= 0) + { + SuperVUFreeXMMreg(vfread0[upper], XMMTYPE_VFREG, regs[upper].VFread0); + _allocVFtoXMMreg(VU, vfread0[upper], regs[upper].VFread0, MODE_READ | GET_VUXYZMODE(regs[upper].VFread0)); + } + if (vfread1[upper] >= 0) + { + SuperVUFreeXMMreg(vfread1[upper], XMMTYPE_VFREG, regs[upper].VFread1); + _allocVFtoXMMreg(VU, vfread1[upper], regs[upper].VFread1, MODE_READ | GET_VUXYZMODE(regs[upper].VFread1)); + } + if (vfacc[upper] >= 0 && (regs[upper].VIread&(1 << REG_ACC_FLAG))) + { + SuperVUFreeXMMreg(vfacc[upper], XMMTYPE_ACC, 0); + _allocACCtoXMMreg(VU, vfacc[upper], MODE_READ); + } + if (vfwrite[upper] >= 0) + { + assert(regs[upper].VFwrite > 0); + SuperVUFreeXMMreg(vfwrite[upper], XMMTYPE_VFREG, regs[upper].VFwrite); + _allocVFtoXMMreg(VU, vfwrite[upper], regs[upper].VFwrite, + MODE_WRITE | (regs[upper].VFwxyzw != 0xf ? MODE_READ : 0) | GET_VUXYZMODE(regs[upper].VFwrite)); + } + if (vfacc[upper] >= 0 && (regs[upper].VIwrite&(1 << REG_ACC_FLAG))) + { + SuperVUFreeXMMreg(vfacc[upper], XMMTYPE_ACC, 0); + _allocACCtoXMMreg(VU, vfacc[upper], MODE_WRITE | (regs[upper].VFwxyzw != 0xf ? MODE_READ : 0)); + } + + int info = PROCESS_VU_SUPER; + if (vfread0[upper] >= 0) info |= PROCESS_EE_SET_S(vfread0[upper]); + if (vfread1[upper] >= 0) info |= PROCESS_EE_SET_T(vfread1[upper]); + if (vfacc[upper] >= 0) info |= PROCESS_VU_SET_ACC(vfacc[upper]); + if (vfwrite[upper] >= 0) + { + if (regs[upper].VFwrite == _Ft_ && vfread1[upper] < 0) + { + info |= PROCESS_EE_SET_T(vfwrite[upper]); + } + else + { + assert(regs[upper].VFwrite == _Fd_); + info |= PROCESS_EE_SET_D(vfwrite[upper]); + } + } + + if (!(vffree[upper]&VFFREE_INVALID0)) + { + SuperVUFreeXMMreg(vffree[upper]&0xf, XMMTYPE_TEMP, 0); + _allocTempXMMreg(XMMT_FPS, vffree[upper]&0xf); + } + info |= PROCESS_VU_SET_TEMP(vffree[upper] & 0xf); + + if (vfflush[upper] >= 0) + { + SuperVUFreeXMMreg(vfflush[upper], XMMTYPE_TEMP, 0); + _allocTempXMMreg(XMMT_FPS, vfflush[upper]); + } + + if (upper && (regs[upper].VIwrite & (1 << REG_CLIP_FLAG))) + { + // CLIP inst, need two extra temp registers, put it EEREC_D and EEREC_ACC + assert(vfwrite[upper] == -1); + SuperVUFreeXMMreg((vffree[upper] >> 8)&0xf, XMMTYPE_TEMP, 0); + _allocTempXMMreg(XMMT_FPS, (vffree[upper] >> 8)&0xf); + info |= PROCESS_EE_SET_D((vffree[upper] >> 8) & 0xf); + + SuperVUFreeXMMreg((vffree[upper] >> 16)&0xf, XMMTYPE_TEMP, 0); + _allocTempXMMreg(XMMT_FPS, (vffree[upper] >> 16)&0xf); + info |= PROCESS_EE_SET_ACC((vffree[upper] >> 16) & 0xf); + + _freeXMMreg((vffree[upper] >> 8)&0xf); // don't need anymore + _freeXMMreg((vffree[upper] >> 16)&0xf); // don't need anymore + } + else if (regs[upper].VIwrite & (1 << REG_P)) + { + SuperVUFreeXMMreg((vffree[upper] >> 8)&0xf, XMMTYPE_TEMP, 0); + _allocTempXMMreg(XMMT_FPS, (vffree[upper] >> 8)&0xf); + info |= PROCESS_EE_SET_D((vffree[upper] >> 8) & 0xf); + _freeXMMreg((vffree[upper] >> 8)&0xf); // don't need anymore + } + + if (vfflush[upper] >= 0) _freeXMMreg(vfflush[upper]); + if (!(vffree[upper]&VFFREE_INVALID0)) + _freeXMMreg(vffree[upper]&0xf); // don't need anymore + + if ((regs[0].VIwrite | regs[1].VIwrite) & ((1 << REG_STATUS_FLAG) | (1 << REG_MAC_FLAG))) + info |= PROCESS_VU_UPDATEFLAGS; + + return info; +} + +void VuInstruction::Recompile(list::iterator& itinst, u32 vuxyz) +{ + //static PCSX2_ALIGNED16(VECTOR _VF); + //static PCSX2_ALIGNED16(VECTOR _VFc); + u32 *ptr; + u8* pjmp; + int vfregstore = 0; + + assert(s_pCurInst == this); + s_WriteToReadQ = 0; + + ptr = (u32*) & VU->Micro[ pc ]; + + if (type & INST_Q_READ) + SuperVUFlush(0, (ptr[0] == 0x800003bf) || !!(regs[0].VIwrite & (1 << REG_Q))); + if (type & INST_P_READ) + SuperVUFlush(1, (ptr[0] == 0x800007bf) || !!(regs[0].VIwrite & (1 << REG_P))); + + if (type & INST_DUMMY) + { + + // find nParentPc + VuInstruction* pparentinst = NULL; + + // if true, will check if parent block was executed before getting the results of the flags (superman returns) + int nParentCheckForExecution = -1; + +// int badaddrs[] = { +// 0x60,0x68,0x70,0x60,0x68,0x70,0x88,0x90,0x98,0x98,0xa8,0xb8,0x88,0x90, +// 0x4a8,0x4a8,0x398,0x3a0,0x3a8,0xa0 +// }; + +#ifdef SUPERVU_PROPAGATEFLAGS + if (nParentPc != -1 && (nParentPc < s_pCurBlock->startpc || nParentPc >= (int)pc)) + { + +// if( !s_vu ) { +// for(int j = 0; j < ARRAYSIZE(badaddrs); ++j) { +// if( badaddrs[j] == nParentPc ) +// goto NoParent; +// } +// } + + list::iterator itblock; + for(itblock = s_listBlocks.begin(); itblock != s_listBlocks.end(); itblock++) + { + if (nParentPc >= (*itblock)->startpc && nParentPc < (*itblock)->endpc) + { + pparentinst = &(*(*itblock)->GetInstIterAtPc(nParentPc)); + //if( !s_vu ) SysPrintf("%x ", nParentPc); + if (find(s_pCurBlock->parents.begin(), s_pCurBlock->parents.end(), *itblock) != s_pCurBlock->parents.end()) + nParentCheckForExecution = (*itblock)->startpc; + break; + } + } + + assert(pparentinst != NULL); + } +#endif + + if (type & INST_CLIP_WRITE) + { + if (nParentPc < s_pCurBlock->startpc || nParentPc >= (int)pc) + { + + if (!CHECK_VUCLIPFLAGHACK && pparentinst != NULL) + { + + if (nParentCheckForExecution >= 0) + { + if (pparentinst->pClipWrite == 0) + pparentinst->pClipWrite = (uptr)SuperVUStaticAlloc(4); + + if (s_ClipRead == 0) + s_ClipRead = (uptr) & VU->VI[REG_CLIP_FLAG]; + + CMP32ItoM((uptr)&g_nLastBlockExecuted, nParentCheckForExecution); + u8* jptr = JNE8(0); + CMP32ItoM((uptr)&s_ClipRead, (uptr)&VU->VI[REG_CLIP_FLAG]); + u8* jptr2 = JE8(0); + MOV32MtoR(EAX, pparentinst->pClipWrite); + MOV32RtoM(s_ClipRead, EAX); + x86SetJ8(jptr); + x86SetJ8(jptr2); + } + } + else s_ClipRead = (uptr) & VU->VI[REG_CLIP_FLAG]; + } + else + { + s_ClipRead = s_pCurBlock->GetInstIterAtPc(nParentPc)->pClipWrite; + if (s_ClipRead == 0) Console::WriteLn("super ClipRead allocation error!"); + } + } + + // before modifying, check if they will ever be read + if (s_pCurBlock->type & BLOCKTYPE_MACFLAGS) + { + + u8 outofblock = 0; + if (type & INST_STATUS_WRITE) + { + + if (nParentPc < s_pCurBlock->startpc || nParentPc >= (int)pc) + { + + // reading from out of this block, so already flushed to mem + if (pparentinst != NULL) //&& pparentinst->pStatusWrite != NULL ) { + { + + // might not have processed it yet, so reserve a mem loc + if (pparentinst->pStatusWrite == 0) + { + pparentinst->pStatusWrite = (uptr)SuperVUStaticAlloc(4); + //MOV32ItoM(pparentinst->pStatusWrite, 0); + } + +// if( s_pCurBlock->prevFlagsOutOfBlock && s_StatusRead != NULL ) { +// // or instead since don't now which parent we came from +// MOV32MtoR(EAX, pparentinst->pStatusWrite); +// OR32RtoM(s_StatusRead, EAX); +// MOV32ItoM(pparentinst->pStatusWrite, 0); +// } + + if (nParentCheckForExecution >= 0) + { + + // don't now which parent we came from, so have to check +// uptr tempstatus = (uptr)SuperVUStaticAlloc(4); +// if( s_StatusRead != NULL ) +// MOV32MtoR(EAX, s_StatusRead); +// else +// MOV32MtoR(EAX, (uptr)&VU->VI[REG_STATUS_FLAG]); +// s_StatusRead = tempstatus; + + if (s_StatusRead == 0) + s_StatusRead = (uptr) & VU->VI[REG_STATUS_FLAG]; + + CMP32ItoM((uptr)&g_nLastBlockExecuted, nParentCheckForExecution); + u8* jptr = JNE8(0); + MOV32MtoR(EAX, pparentinst->pStatusWrite); + MOV32ItoM(pparentinst->pStatusWrite, 0); + MOV32RtoM(s_StatusRead, EAX); + x86SetJ8(jptr); + } + else + { + uptr tempstatus = (uptr)SuperVUStaticAlloc(4); + MOV32MtoR(EAX, pparentinst->pStatusWrite); + MOV32RtoM(tempstatus, EAX); + MOV32ItoM(pparentinst->pStatusWrite, 0); + s_StatusRead = tempstatus; + } + + outofblock = 2; + } + else + s_StatusRead = (uptr) & VU->VI[REG_STATUS_FLAG]; + } + else + { + s_StatusRead = s_pCurBlock->GetInstIterAtPc(nParentPc)->pStatusWrite; + if (s_StatusRead == 0) Console::WriteLn("super StatusRead allocation error!"); +// if( pc >= (u32)s_pCurBlock->endpc-8 ) { +// // towards the end, so variable might be leaded to another block (silent hill 4) +// uptr tempstatus = (uptr)SuperVUStaticAlloc(4); +// MOV32MtoR(EAX, s_StatusRead); +// MOV32RtoM(tempstatus, EAX); +// MOV32ItoM(s_StatusRead, 0); +// s_StatusRead = tempstatus; +// } + } + } + if (type & INST_MAC_WRITE) + { + + if (nParentPc < s_pCurBlock->startpc || nParentPc >= (int)pc) + { + // reading from out of this block, so already flushed to mem + + if (pparentinst != NULL) //&& pparentinst->pMACWrite != NULL ) { + { + // necessary for (katamari) + // towards the end, so variable might be leaked to another block (silent hill 4) + + // might not have processed it yet, so reserve a mem loc + if (pparentinst->pMACWrite == 0) + { + pparentinst->pMACWrite = (uptr)SuperVUStaticAlloc(4); + //MOV32ItoM(pparentinst->pMACWrite, 0); + } + +// if( s_pCurBlock->prevFlagsOutOfBlock && s_MACRead != NULL ) { +// // or instead since don't now which parent we came from +// MOV32MtoR(EAX, pparentinst->pMACWrite); +// OR32RtoM(s_MACRead, EAX); +// MOV32ItoM(pparentinst->pMACWrite, 0); +// } + if (nParentCheckForExecution >= 0) + { + + // don't now which parent we came from, so have to check +// uptr tempmac = (uptr)SuperVUStaticAlloc(4); +// if( s_MACRead != NULL ) +// MOV32MtoR(EAX, s_MACRead); +// else +// MOV32MtoR(EAX, (uptr)&VU->VI[REG_MAC_FLAG]); +// s_MACRead = tempmac; + + if (s_MACRead == 0) s_MACRead = (uptr) & VU->VI[REG_MAC_FLAG]; + + CMP32ItoM((uptr)&g_nLastBlockExecuted, nParentCheckForExecution); + u8* jptr = JNE8(0); + MOV32MtoR(EAX, pparentinst->pMACWrite); + MOV32ItoM(pparentinst->pMACWrite, 0); + MOV32RtoM(s_MACRead, EAX); + x86SetJ8(jptr); + } + else + { + uptr tempMAC = (uptr)SuperVUStaticAlloc(4); + MOV32MtoR(EAX, pparentinst->pMACWrite); + MOV32RtoM(tempMAC, EAX); + MOV32ItoM(pparentinst->pMACWrite, 0); + s_MACRead = tempMAC; + } + + outofblock = 2; + } + else + s_MACRead = (uptr) & VU->VI[REG_MAC_FLAG]; + +// if( pc >= (u32)s_pCurBlock->endpc-8 ) { +// // towards the end, so variable might be leaked to another block (silent hill 4) +// uptr tempMAC = (uptr)SuperVUStaticAlloc(4); +// MOV32MtoR(EAX, s_MACRead); +// MOV32RtoM(tempMAC, EAX); +// MOV32ItoM(s_MACRead, 0); +// s_MACRead = tempMAC; +// } + } + else + { + s_MACRead = s_pCurBlock->GetInstIterAtPc(nParentPc)->pMACWrite; + } + } + + s_pCurBlock->prevFlagsOutOfBlock = outofblock; + } + else if (pparentinst != NULL) + { + // make sure to reset the mac and status flags! (katamari) + if (pparentinst->pStatusWrite) + MOV32ItoM(pparentinst->pStatusWrite, 0); + if (pparentinst->pMACWrite) + MOV32ItoM(pparentinst->pMACWrite, 0); + } + + assert(s_ClipRead != 0); + assert(s_MACRead != 0); + assert(s_StatusRead != 0); + + return; + } + + s_pCurBlock->prevFlagsOutOfBlock = 0; + + if( IsDebugBuild ) + MOV32ItoR(EAX, pc); + + assert(!(type & (INST_CLIP_WRITE | INST_STATUS_WRITE | INST_MAC_WRITE))); + pc += 8; + + list::const_iterator itinst2; + + if ((regs[0].VIwrite | regs[1].VIwrite) & ((1 << REG_MAC_FLAG) | (1 << REG_STATUS_FLAG))) + { + if (s_pCurBlock->type & BLOCKTYPE_MACFLAGS) + { + if (pMACWrite == 0) + { + pMACWrite = (uptr)SuperVUStaticAlloc(4); + //MOV32ItoM(pMACWrite, 0); + } + if (pStatusWrite == 0) + { + pStatusWrite = (uptr)SuperVUStaticAlloc(4); + //MOV32ItoM(pStatusWrite, 0); + } + } + else + { + assert(s_StatusRead == (uptr)&VU->VI[REG_STATUS_FLAG]); + assert(s_MACRead == (uptr)&VU->VI[REG_MAC_FLAG]); + pMACWrite = s_MACRead; + pStatusWrite = s_StatusRead; + } + } + + if ((pClipWrite == 0) && ((regs[0].VIwrite | regs[1].VIwrite) & (1 << REG_CLIP_FLAG))) + { + pClipWrite = (uptr)SuperVUStaticAlloc(4); + //MOV32ItoM(pClipWrite, 0); + } + +#ifdef SUPERVU_X86CACHING + // redo the counters so that the proper regs are released + for (int j = 0; j < iREGCNT_GPR; ++j) + { + if (x86regs[j].inuse && X86_ISVI(x86regs[j].type)) + { + int count = 0; + itinst2 = itinst; + + while (itinst2 != s_pCurBlock->insts.end()) + { + if ((itinst2->regs[0].VIread | itinst2->regs[0].VIwrite | itinst2->regs[1].VIread | itinst2->regs[1].VIwrite) && (1 << x86regs[j].reg)) + break; + + ++count; + ++itinst2; + } + + x86regs[j].counter = 1000 - count; + } + } +#endif + + if (s_vu == 0 && (ptr[1] & 0x20000000)) // M flag + { + OR8ItoM((uptr)&VU->flags, VUFLAG_MFLAGSET); + } + if (ptr[1] & 0x10000000) // D flag + { + TEST32ItoM((uptr)&VU0.VI[REG_FBRST].UL, s_vu ? 0x400 : 0x004); + u8* ptr = JZ8(0); + OR32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, s_vu ? 0x200 : 0x002); + _callFunctionArg1((uptr)hwIntcIrq, MEM_CONSTTAG, s_vu ? INTC_VU1 : INTC_VU0); + x86SetJ8(ptr); + } + if (ptr[1] & 0x08000000) // T flag + { + TEST32ItoM((uptr)&VU0.VI[REG_FBRST].UL, s_vu ? 0x800 : 0x008); + u8* ptr = JZ8(0); + OR32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, s_vu ? 0x400 : 0x004); + _callFunctionArg1((uptr)hwIntcIrq, MEM_CONSTTAG, s_vu ? INTC_VU1 : INTC_VU0); + x86SetJ8(ptr); + } + + // check upper flags + if (ptr[1] & 0x80000000) // I flag + { + + assert(!(regs[0].VIwrite & ((1 << REG_Q) | (1 << REG_P)))); + + VU->code = ptr[1]; + s_vuInfo = SetCachedRegs(1, vuxyz); + if (s_JumpX86 > 0) x86regs[s_JumpX86].needed = 1; + if (s_ScheduleXGKICK && s_XGKICKReg > 0) x86regs[s_XGKICKReg].needed = 1; + + recVU_UPPER_OPCODE[ VU->code & 0x3f ](VU, s_vuInfo); + + s_PrevIWrite = (uptr)ptr; + _clearNeededXMMregs(); + _clearNeededX86regs(); + } + else + { + if (regs[0].VIwrite & (1 << REG_Q)) + { + + // search for all the insts between this inst and writeback + itinst2 = itinst; + ++itinst2; + u32 cacheq = (itinst2 == s_pCurBlock->insts.end()); + u32* codeptr2 = ptr + 2; + + while (itinst2 != s_pCurBlock->insts.end()) + { + if (!(itinst2->type & INST_DUMMY) && ((itinst2->regs[0].VIwrite&(1 << REG_Q)) || codeptr2[0] == 0x800003bf)) // waitq, or fdiv inst + { + break; + } + if ((itinst2->type & INST_Q_WRITE) && itinst2->nParentPc == pc - 8) + { + break; + } + if (itinst2->type & INST_Q_READ) + { + cacheq = 1; + break; + } + if (itinst2->type & INST_DUMMY) + { + ++itinst2; + continue; + } + codeptr2 += 2; + ++itinst2; + } + + if (itinst2 == s_pCurBlock->insts.end()) + cacheq = 1; + + int x86temp = -1; + if (cacheq) + x86temp = _allocX86reg(-1, X86TYPE_TEMP, 0, 0); + + // new is written so flush old + // if type & INST_Q_READ, already flushed + if (!(type & INST_Q_READ) && s_recWriteQ == 0) MOV32MtoR(EAX, (uptr)&s_writeQ); + + if (cacheq) + MOV32MtoR(x86temp, (uptr)&s_TotalVUCycles); + + if (!(type & INST_Q_READ)) + { + if (s_recWriteQ == 0) + { + OR32RtoR(EAX, EAX); + pjmp = JS8(0); + MOV32MtoR(EAX, SuperVUGetVIAddr(REG_Q, 0)); + MOV32RtoM(SuperVUGetVIAddr(REG_Q, 1), EAX); + x86SetJ8(pjmp); + } + else if (s_needFlush & 1) + { + MOV32MtoR(EAX, SuperVUGetVIAddr(REG_Q, 0)); + MOV32RtoM(SuperVUGetVIAddr(REG_Q, 1), EAX); + s_needFlush &= ~1; + } + } + + // write new Q + if (cacheq) + { + assert(s_pCurInst->pqcycles > 1); + ADD32ItoR(x86temp, s_pCurInst->info.cycle + s_pCurInst->pqcycles); + MOV32RtoM((uptr)&s_writeQ, x86temp); + s_needFlush |= 1; + } + else + { + // won't be writing back + s_WriteToReadQ = 1; + s_needFlush &= ~1; + MOV32ItoM((uptr)&s_writeQ, 0x80000001); + } + + s_recWriteQ = s_pCurInst->info.cycle + s_pCurInst->pqcycles; + + if (x86temp >= 0) + _freeX86reg(x86temp); + } + + if (regs[0].VIwrite & (1 << REG_P)) + { + int x86temp = _allocX86reg(-1, X86TYPE_TEMP, 0, 0); + + // new is written so flush old + if (!(type & INST_P_READ) && s_recWriteP == 0) + MOV32MtoR(EAX, (uptr)&s_writeP); + MOV32MtoR(x86temp, (uptr)&s_TotalVUCycles); + + if (!(type & INST_P_READ)) + { + if (s_recWriteP == 0) + { + OR32RtoR(EAX, EAX); + pjmp = JS8(0); + MOV32MtoR(EAX, SuperVUGetVIAddr(REG_P, 0)); + MOV32RtoM(SuperVUGetVIAddr(REG_P, 1), EAX); + x86SetJ8(pjmp); + } + else if (s_needFlush & 2) + { + MOV32MtoR(EAX, SuperVUGetVIAddr(REG_P, 0)); + MOV32RtoM(SuperVUGetVIAddr(REG_P, 1), EAX); + s_needFlush &= ~2; + } + } + + // write new P + assert(s_pCurInst->pqcycles > 1); + ADD32ItoR(x86temp, s_pCurInst->info.cycle + s_pCurInst->pqcycles); + MOV32RtoM((uptr)&s_writeP, x86temp); + s_needFlush |= 2; + + s_recWriteP = s_pCurInst->info.cycle + s_pCurInst->pqcycles; + + _freeX86reg(x86temp); + } + + // waitq + if (ptr[0] == 0x800003bf) SuperVUFlush(0, 1); + // waitp + if (ptr[0] == 0x800007bf) SuperVUFlush(1, 1); + +#ifdef PCSX2_DEVBUILD + if (regs[1].VIread & regs[0].VIwrite & ~((1 << REG_Q) | (1 << REG_P) | (1 << REG_VF0_FLAG) | (1 << REG_ACC_FLAG))) + { + Console::Notice("*PCSX2*: Warning, VI write to the same reg %x in both lower/upper cycle %x", params regs[1].VIread & regs[0].VIwrite, s_pCurBlock->startpc); + } +#endif + + u32 modewrite = 0; + if (vfwrite[1] >= 0 && xmmregs[vfwrite[1]].inuse && xmmregs[vfwrite[1]].type == XMMTYPE_VFREG && xmmregs[vfwrite[1]].reg == regs[1].VFwrite) + modewrite = xmmregs[vfwrite[1]].mode & MODE_WRITE; + + VU->code = ptr[1]; + s_vuInfo = SetCachedRegs(1, vuxyz); + + if (vfwrite[1] >= 0) + { + assert(regs[1].VFwrite > 0); + + if (vfwrite[0] == vfwrite[1]) + { + //Console::WriteLn("*PCSX2*: Warning, VF write to the same reg in both lower/upper cycle %x", params s_pCurBlock->startpc); + } + + if (vfread0[0] == vfwrite[1] || vfread1[0] == vfwrite[1]) + { + assert(regs[0].VFread0 == regs[1].VFwrite || regs[0].VFread1 == regs[1].VFwrite); + assert(vfflush[0] >= 0); + if (modewrite) + { + SSE_MOVAPS_XMM_to_M128((uptr)&VU->VF[regs[1].VFwrite], (x86SSERegType)vfwrite[1]); + } + vfregstore = 1; + } + } + + if (s_JumpX86 > 0) x86regs[s_JumpX86].needed = 1; + if (s_ScheduleXGKICK && s_XGKICKReg > 0) x86regs[s_XGKICKReg].needed = 1; + + recVU_UPPER_OPCODE[ VU->code & 0x3f ](VU, s_vuInfo); + _clearNeededXMMregs(); + _clearNeededX86regs(); + + // necessary because status can be set by both upper and lower + if (regs[1].VIwrite & (1 << REG_STATUS_FLAG)) + { + assert(pStatusWrite != 0); + s_PrevStatusWrite = pStatusWrite; + } + + VU->code = ptr[0]; + s_vuInfo = SetCachedRegs(0, vuxyz); + + if (vfregstore) + { + // load + SSE_MOVAPS_M128_to_XMM(vfflush[0], (uptr)&VU->VF[regs[1].VFwrite]); + + assert(xmmregs[vfwrite[1]].mode & MODE_WRITE); + + // replace with vfflush + if (_Fs_ == regs[1].VFwrite) + { + s_vuInfo &= ~PROCESS_EE_SET_S(0xf); + s_vuInfo |= PROCESS_EE_SET_S(vfflush[0]); + } + if (_Ft_ == regs[1].VFwrite) + { + s_vuInfo &= ~PROCESS_EE_SET_T(0xf); + s_vuInfo |= PROCESS_EE_SET_T(vfflush[0]); + } + + xmmregs[vfflush[0]].mode |= MODE_NOFLUSH | MODE_WRITE; // so that lower inst doesn't flush + } + + // notify vuinsts that upper inst is a fmac + if (regs[1].pipe == VUPIPE_FMAC) + s_vuInfo |= PROCESS_VU_SET_FMAC(); + + if (s_JumpX86 > 0) x86regs[s_JumpX86].needed = 1; + if (s_ScheduleXGKICK && s_XGKICKReg > 0) x86regs[s_XGKICKReg].needed = 1; + +#ifdef SUPERVU_VIBRANCHDELAY + if (type & INST_CACHE_VI) + { + assert(vicached >= 0); + int cachedreg = _allocX86reg(-1, X86TYPE_VI | (s_vu ? X86TYPE_VU1 : 0), vicached, MODE_READ); + MOV32RtoM((uptr)&s_VIBranchDelay, cachedreg); + } +#endif + + // check if inst before branch and the write is the same as the read in the branch (wipeout) +// int oldreg=0; +// if( pc == s_pCurBlock->endpc-16 ) { +// itinst2 = itinst; ++itinst2; +// if( itinst2->regs[0].pipe == VUPIPE_BRANCH && (itinst->regs[0].VIwrite&itinst2->regs[0].VIread) ) { +// +// CALLFunc((u32)branchfn); +// assert( itinst->regs[0].VIwrite & 0xffff ); +// Console::WriteLn("vi write before branch"); +// for(s_CacheVIReg = 0; s_CacheVIReg < 16; ++s_CacheVIReg) { +// if( itinst->regs[0].VIwrite & (1<endpc-8 && s_CacheVIReg >= 0 ) { +// assert( s_CacheVIX86 > 0 && x86regs[s_CacheVIX86].inuse && x86regs[s_CacheVIX86].reg == s_CacheVIReg && x86regs[s_CacheVIX86].type == X86TYPE_VITEMP ); +// +// oldreg = _allocX86reg(-1, X86TYPE_VI|(s_vu?X86TYPE_VU1:0), s_CacheVIReg, MODE_READ); +// x86regs[s_CacheVIX86].needed = 1; +// assert( x86regs[oldreg].mode & MODE_WRITE ); +// +// x86regs[s_CacheVIX86].type = X86TYPE_VI|(s_vu?X86TYPE_VU1:0); +// x86regs[oldreg].type = X86TYPE_VITEMP; +// } + + recVU_LOWER_OPCODE[ VU->code >> 25 ](VU, s_vuInfo); + +// if( pc == s_pCurBlock->endpc-8 && s_CacheVIReg >= 0 ) { +// // revert +// x86regs[s_CacheVIX86].inuse = 0; +// x86regs[oldreg].type = X86TYPE_VI|(s_vu?X86TYPE_VU1:0); +// } + + _clearNeededXMMregs(); + _clearNeededX86regs(); + } + + // clip is always written so ok + if ((regs[0].VIwrite | regs[1].VIwrite) & (1 << REG_CLIP_FLAG)) + { + assert(pClipWrite != 0); + s_PrevClipWrite = pClipWrite; + } + + if ((regs[0].VIwrite | regs[1].VIwrite) & (1 << REG_STATUS_FLAG)) + { + assert(pStatusWrite != 0); + s_PrevStatusWrite = pStatusWrite; + } + + if ((regs[0].VIwrite | regs[1].VIwrite) & (1 << REG_MAC_FLAG)) + { + assert(pMACWrite != 0); + s_PrevMACWrite = pMACWrite; + } +} + +/////////////////////////////////// +// Super VU Recompilation Tables // +/////////////////////////////////// + +void recVUMI_BranchHandle() +{ + int bpc = _recbranchAddr(VU->code); + int curjump = 0; + + if (s_pCurInst->type & INST_BRANCH_DELAY) + { + assert((branch&0x17) != 0x10 && (branch&0x17) != 4); // no jump handlig for now + + if ((branch & 0x7) == 3) + { + // previous was a direct jump + curjump = 1; + } + else if (branch & 1) curjump = 2; + } + + assert(s_JumpX86 > 0); + + if ((s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION) + MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), bpc); + MOV32ItoR(s_JumpX86, 1); // use 1 to disable optimization to XOR + s_pCurBlock->pChildJumps[curjump] = (u32*)x86Ptr - 1; + + if (!(s_pCurInst->type & INST_BRANCH_DELAY)) + { + j8Ptr[1] = JMP8(0); + x86SetJ8(j8Ptr[ 0 ]); + + if ((s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION) + MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), pc + 8); + MOV32ItoR(s_JumpX86, 1); // use 1 to disable optimization to XOR + s_pCurBlock->pChildJumps[curjump+1] = (u32*)x86Ptr - 1; + + x86SetJ8(j8Ptr[ 1 ]); + } + else + x86SetJ8(j8Ptr[ 0 ]); + + branch |= 1; +} + +// supervu specific insts +void recVUMI_IBQ_prep() +{ + int isreg, itreg; + + if (_Is_ == 0) + { +#ifdef SUPERVU_VIBRANCHDELAY + if (s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _It_) + { + itreg = -1; + } + else +#endif + { + itreg = _checkX86reg(X86TYPE_VI | (VU == &VU1 ? X86TYPE_VU1 : 0), _It_, MODE_READ); + } + + s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); + + if (itreg >= 0) + { + CMP16ItoR(itreg, 0); + } + else CMP16ItoM(SuperVUGetVIAddr(_It_, 1), 0); + } + else if (_It_ == 0) + { +#ifdef SUPERVU_VIBRANCHDELAY + if (s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Is_) + { + isreg = -1; + } + else +#endif + { + isreg = _checkX86reg(X86TYPE_VI | (VU == &VU1 ? X86TYPE_VU1 : 0), _Is_, MODE_READ); + } + + s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); + + if (isreg >= 0) + { + CMP16ItoR(isreg, 0); + } + else CMP16ItoM(SuperVUGetVIAddr(_Is_, 1), 0); + + } + else + { + _addNeededX86reg(X86TYPE_VI | (VU == &VU1 ? X86TYPE_VU1 : 0), _It_); + +#ifdef SUPERVU_VIBRANCHDELAY + if (s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Is_) + { + isreg = -1; + } + else +#endif + { + isreg = _checkX86reg(X86TYPE_VI | (VU == &VU1 ? X86TYPE_VU1 : 0), _Is_, MODE_READ); + } + +#ifdef SUPERVU_VIBRANCHDELAY + if (s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _It_) + { + itreg = -1; + + if (isreg <= 0) + { + // allocate fsreg + if (s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Is_) + { + isreg = _allocX86reg(-1, X86TYPE_TEMP, 0, MODE_READ | MODE_WRITE); + MOV32MtoR(isreg, SuperVUGetVIAddr(_Is_, 1)); + } + else + isreg = _allocX86reg(-1, X86TYPE_VI | (VU == &VU1 ? X86TYPE_VU1 : 0), _Is_, MODE_READ); + } + } + else +#endif + { + itreg = _checkX86reg(X86TYPE_VI | (VU == &VU1 ? X86TYPE_VU1 : 0), _It_, MODE_READ); + } + + s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); + + if (isreg >= 0) + { + if (itreg >= 0) + { + CMP16RtoR(isreg, itreg); + } + else CMP16MtoR(isreg, SuperVUGetVIAddr(_It_, 1)); + } + else if (itreg >= 0) + { + CMP16MtoR(itreg, SuperVUGetVIAddr(_Is_, 1)); + } + else + { + isreg = _allocX86reg(-1, X86TYPE_VI | (VU == &VU1 ? X86TYPE_VU1 : 0), _Is_, MODE_READ); + CMP16MtoR(isreg, SuperVUGetVIAddr(_It_, 1)); + } + } +} + +void recVUMI_IBEQ(VURegs* vuu, s32 info) +{ + recVUMI_IBQ_prep(); + j8Ptr[ 0 ] = JNE8(0); + recVUMI_BranchHandle(); +} + +void recVUMI_IBGEZ(VURegs* vuu, s32 info) +{ + int isreg; + s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); + +#ifdef SUPERVU_VIBRANCHDELAY + if (s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Is_) + { + isreg = -1; + } + else +#endif + { + isreg = _checkX86reg(X86TYPE_VI | (VU == &VU1 ? X86TYPE_VU1 : 0), _Is_, MODE_READ); + } + + if (isreg >= 0) + { + TEST16RtoR(isreg, isreg); + j8Ptr[ 0 ] = JS8(0); + } + else + { + CMP16ItoM(SuperVUGetVIAddr(_Is_, 1), 0x0); + j8Ptr[ 0 ] = JL8(0); + } + + recVUMI_BranchHandle(); +} + +void recVUMI_IBGTZ(VURegs* vuu, s32 info) +{ + int isreg; + s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); + +#ifdef SUPERVU_VIBRANCHDELAY + if (s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Is_) + { + isreg = -1; + } + else +#endif + { + isreg = _checkX86reg(X86TYPE_VI | (VU == &VU1 ? X86TYPE_VU1 : 0), _Is_, MODE_READ); + } + + if (isreg >= 0) + { + CMP16ItoR(isreg, 0); + j8Ptr[ 0 ] = JLE8(0); + } + else + { + CMP16ItoM(SuperVUGetVIAddr(_Is_, 1), 0x0); + j8Ptr[ 0 ] = JLE8(0); + } + recVUMI_BranchHandle(); +} + +void recVUMI_IBLEZ(VURegs* vuu, s32 info) +{ + int isreg; + s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); + +#ifdef SUPERVU_VIBRANCHDELAY + if (s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Is_) + { + isreg = -1; + } + else +#endif + { + isreg = _checkX86reg(X86TYPE_VI | (VU == &VU1 ? X86TYPE_VU1 : 0), _Is_, MODE_READ); + } + + if (isreg >= 0) + { + CMP16ItoR(isreg, 0); + j8Ptr[ 0 ] = JG8(0); + } + else + { + CMP16ItoM(SuperVUGetVIAddr(_Is_, 1), 0x0); + j8Ptr[ 0 ] = JG8(0); + } + recVUMI_BranchHandle(); +} + +void recVUMI_IBLTZ(VURegs* vuu, s32 info) +{ + int isreg; + s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); + +#ifdef SUPERVU_VIBRANCHDELAY + if (s_pCurInst->vicached >= 0 && s_pCurInst->vicached == _Is_) + { + isreg = -1; + } + else +#endif + { + isreg = _checkX86reg(X86TYPE_VI | (VU == &VU1 ? X86TYPE_VU1 : 0), _Is_, MODE_READ); + } + + if (isreg >= 0) + { + TEST16RtoR(isreg, isreg); + j8Ptr[ 0 ] = JNS8(0); + } + else + { + CMP16ItoM(SuperVUGetVIAddr(_Is_, 1), 0x0); + j8Ptr[ 0 ] = JGE8(0); + } + recVUMI_BranchHandle(); +} + +void recVUMI_IBNE(VURegs* vuu, s32 info) +{ + recVUMI_IBQ_prep(); + j8Ptr[ 0 ] = JE8(0); + recVUMI_BranchHandle(); +} + +void recVUMI_B(VURegs* vuu, s32 info) +{ + // supervu will take care of the rest + int bpc = _recbranchAddr(VU->code); + if ((s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION) + MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), bpc); + + // loops to self, so check condition + if (bpc == s_pCurBlock->startpc && (s_vu == 0 || SUPERVU_CHECKCONDITION)) + { + SuperVUTestVU0Condition(0); + } + + if (s_pCurBlock->blocks.size() > 1) + { + s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); + MOV32ItoR(s_JumpX86, 1); + s_pCurBlock->pChildJumps[(s_pCurInst->type & INST_BRANCH_DELAY)?1:0] = (u32*)x86Ptr - 1; + s_UnconditionalDelay = 1; + } + + branch |= 3; +} + +void recVUMI_BAL(VURegs* vuu, s32 info) +{ + int bpc = _recbranchAddr(VU->code); + if ((s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION) + MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), bpc); + + // loops to self, so check condition + if (bpc == s_pCurBlock->startpc && (s_vu == 0 || SUPERVU_CHECKCONDITION)) + { + SuperVUTestVU0Condition(0); + } + + if (_It_) + { + _deleteX86reg(X86TYPE_VI | (s_vu ? X86TYPE_VU1 : 0), _It_, 2); + MOV16ItoM(SuperVUGetVIAddr(_It_, 0), (pc + 8) >> 3); + } + + if (s_pCurBlock->blocks.size() > 1) + { + s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE); + MOV32ItoR(s_JumpX86, 1); + s_pCurBlock->pChildJumps[(s_pCurInst->type & INST_BRANCH_DELAY)?1:0] = (u32*)x86Ptr - 1; + s_UnconditionalDelay = 1; + } + + branch |= 3; +} + +void recVUMI_JR(VURegs* vuu, s32 info) +{ + int isreg = _allocX86reg(-1, X86TYPE_VI | (s_vu ? X86TYPE_VU1 : 0), _Is_, MODE_READ); + LEA32RStoR(EAX, isreg, 3); + + //Mask the address to something valid + if (vuu == &VU0) + AND32ItoR(EAX, 0xfff); + else + AND32ItoR(EAX, 0x3fff); + + if ((s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0) MOV32RtoM(SuperVUGetVIAddr(REG_TPC, 0), EAX); + + if (!(s_pCurBlock->type & BLOCKTYPE_HASEOP)) + { + PUSH32I(s_vu); + PUSH32R(EAX); + } + branch |= 0x10; // 0x08 is reserved +} + +void recVUMI_JALR(VURegs* vuu, s32 info) +{ + _addNeededX86reg(X86TYPE_VI | (s_vu ? X86TYPE_VU1 : 0), _It_); + + int isreg = _allocX86reg(-1, X86TYPE_VI | (s_vu ? X86TYPE_VU1 : 0), _Is_, MODE_READ); + LEA32RStoR(EAX, isreg, 3); + + //Mask the address to something valid + if (vuu == &VU0) + AND32ItoR(EAX, 0xfff); + else + AND32ItoR(EAX, 0x3fff); + + if (_It_) + { + _deleteX86reg(X86TYPE_VI | (s_vu ? X86TYPE_VU1 : 0), _It_, 2); + MOV16ItoM(SuperVUGetVIAddr(_It_, 0), (pc + 8) >> 3); + } + + if ((s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0) MOV32RtoM(SuperVUGetVIAddr(REG_TPC, 0), EAX); + + if (!(s_pCurBlock->type & BLOCKTYPE_HASEOP)) + { + PUSH32I(s_vu); + PUSH32R(EAX); + } + + branch |= 4; +} + +#ifdef PCSX2_DEVBUILD +void vu1xgkick(u32* pMem, u32 addr) +{ + assert(addr < 0x4000); +#ifdef SUPERVU_COUNT + StopSVUCounter(); +#endif + + GSGIFTRANSFER1(pMem, addr); + +#ifdef SUPERVU_COUNT + StartSVUCounter(); +#endif +} +#endif + +void recVUMI_XGKICK_(VURegs *VU) +{ + assert(s_XGKICKReg > 0 && x86regs[s_XGKICKReg].inuse && x86regs[s_XGKICKReg].type == X86TYPE_VITEMP); + + x86regs[s_XGKICKReg].inuse = 0; // so free doesn't flush + _freeX86regs(); + _freeXMMregs(); + + OR32ItoM((uptr)&psHu32(GIF_STAT), (GIF_STAT_APATH1 | GIF_STAT_OPH)); // Set PATH1 GIF Status Flags + PUSH32R(s_XGKICKReg); + PUSH32I((uptr)VU->Mem); + + if (mtgsThread) { + CALLFunc((uptr)VU1XGKICK_MTGSTransfer); + ADD32ItoR(ESP, 8); + } + else { +#ifdef PCSX2_DEVBUILD + CALLFunc((uptr)vu1xgkick); + ADD32ItoR(ESP, 8); +#else + CALLFunc((uptr)GSgifTransfer1); +#endif + } + AND32ItoM((uptr)&psHu32(GIF_STAT), ~(GIF_STAT_APATH1 | GIF_STAT_OPH)); // Clear PATH1 GIF Status Flags + s_ScheduleXGKICK = 0; +} + +void recVUMI_XGKICK(VURegs *VU, int info) +{ + if (s_ScheduleXGKICK) { + // second xgkick, so launch the first + recVUMI_XGKICK_(VU); + } + + int isreg = _allocX86reg(X86ARG2, X86TYPE_VI | (s_vu ? X86TYPE_VU1 : 0), _Is_, MODE_READ); + _freeX86reg(isreg); // flush + x86regs[isreg].inuse = 1; + x86regs[isreg].type = X86TYPE_VITEMP; + x86regs[isreg].needed = 1; + x86regs[isreg].mode = MODE_WRITE | MODE_READ; + SHL32ItoR(isreg, 4); + AND32ItoR(isreg, 0x3fff); + s_XGKICKReg = isreg; + + if (!SUPERVU_XGKICKDELAY || pc == s_pCurBlock->endpc) { + recVUMI_XGKICK_(VU); + } + else { + s_ScheduleXGKICK = (CHECK_XGKICKHACK) ? (min((u32)4, (s_pCurBlock->endpc-pc)/8)) : 2; + } +} + +void recVU_UPPER_FD_00(VURegs* VU, s32 info); +void recVU_UPPER_FD_01(VURegs* VU, s32 info); +void recVU_UPPER_FD_10(VURegs* VU, s32 info); +void recVU_UPPER_FD_11(VURegs* VU, s32 info); +void recVULowerOP(VURegs* VU, s32 info); +void recVULowerOP_T3_00(VURegs* VU, s32 info); +void recVULowerOP_T3_01(VURegs* VU, s32 info); +void recVULowerOP_T3_10(VURegs* VU, s32 info); +void recVULowerOP_T3_11(VURegs* VU, s32 info); +void recVUunknown(VURegs* VU, s32 info); + +void (*recVU_LOWER_OPCODE[128])(VURegs* VU, s32 info) = +{ + recVUMI_LQ , recVUMI_SQ , recVUunknown , recVUunknown, + recVUMI_ILW , recVUMI_ISW , recVUunknown , recVUunknown, + recVUMI_IADDIU, recVUMI_ISUBIU, recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUMI_FCEQ , recVUMI_FCSET , recVUMI_FCAND, recVUMI_FCOR, /* 0x10 */ + recVUMI_FSEQ , recVUMI_FSSET , recVUMI_FSAND, recVUMI_FSOR, + recVUMI_FMEQ , recVUunknown , recVUMI_FMAND, recVUMI_FMOR, + recVUMI_FCGET , recVUunknown , recVUunknown , recVUunknown, + recVUMI_B , recVUMI_BAL , recVUunknown , recVUunknown, /* 0x20 */ + recVUMI_JR , recVUMI_JALR , recVUunknown , recVUunknown, + recVUMI_IBEQ , recVUMI_IBNE , recVUunknown , recVUunknown, + recVUMI_IBLTZ , recVUMI_IBGTZ , recVUMI_IBLEZ, recVUMI_IBGEZ, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x30 */ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVULowerOP , recVUunknown , recVUunknown , recVUunknown, /* 0x40*/ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x50 */ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x60 */ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x70 */ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, +}; + +void (*recVULowerOP_T3_00_OPCODE[32])(VURegs* VU, s32 info) = +{ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUMI_MOVE , recVUMI_LQI , recVUMI_DIV , recVUMI_MTIR, + recVUMI_RNEXT , recVUunknown , recVUunknown , recVUunknown, /* 0x10 */ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUMI_MFP , recVUMI_XTOP , recVUMI_XGKICK, + recVUMI_ESADD , recVUMI_EATANxy, recVUMI_ESQRT, recVUMI_ESIN, +}; + +void (*recVULowerOP_T3_01_OPCODE[32])(VURegs* VU, s32 info) = +{ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUMI_MR32 , recVUMI_SQI , recVUMI_SQRT , recVUMI_MFIR, + recVUMI_RGET , recVUunknown , recVUunknown , recVUunknown, /* 0x10 */ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUMI_XITOP, recVUunknown, + recVUMI_ERSADD, recVUMI_EATANxz, recVUMI_ERSQRT, recVUMI_EATAN, +}; + +void (*recVULowerOP_T3_10_OPCODE[32])(VURegs* VU, s32 info) = +{ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUMI_LQD , recVUMI_RSQRT, recVUMI_ILWR, + recVUMI_RINIT , recVUunknown , recVUunknown , recVUunknown, /* 0x10 */ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUMI_ELENG , recVUMI_ESUM , recVUMI_ERCPR, recVUMI_EEXP, +}; + +void (*recVULowerOP_T3_11_OPCODE[32])(VURegs* VU, s32 info) = +{ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUMI_SQD , recVUMI_WAITQ, recVUMI_ISWR, + recVUMI_RXOR , recVUunknown , recVUunknown , recVUunknown, /* 0x10 */ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUMI_ERLENG, recVUunknown , recVUMI_WAITP, recVUunknown, +}; + +void (*recVULowerOP_OPCODE[64])(VURegs* VU, s32 info) = +{ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x10 */ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x20 */ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUMI_IADD , recVUMI_ISUB , recVUMI_IADDI, recVUunknown, /* 0x30 */ + recVUMI_IAND , recVUMI_IOR , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVULowerOP_T3_00, recVULowerOP_T3_01, recVULowerOP_T3_10, recVULowerOP_T3_11, +}; + +void (*recVU_UPPER_OPCODE[64])(VURegs* VU, s32 info) = +{ + recVUMI_ADDx , recVUMI_ADDy , recVUMI_ADDz , recVUMI_ADDw, + recVUMI_SUBx , recVUMI_SUBy , recVUMI_SUBz , recVUMI_SUBw, + recVUMI_MADDx , recVUMI_MADDy , recVUMI_MADDz , recVUMI_MADDw, + recVUMI_MSUBx , recVUMI_MSUBy , recVUMI_MSUBz , recVUMI_MSUBw, + recVUMI_MAXx , recVUMI_MAXy , recVUMI_MAXz , recVUMI_MAXw, /* 0x10 */ + recVUMI_MINIx , recVUMI_MINIy , recVUMI_MINIz , recVUMI_MINIw, + recVUMI_MULx , recVUMI_MULy , recVUMI_MULz , recVUMI_MULw, + recVUMI_MULq , recVUMI_MAXi , recVUMI_MULi , recVUMI_MINIi, + recVUMI_ADDq , recVUMI_MADDq , recVUMI_ADDi , recVUMI_MADDi, /* 0x20 */ + recVUMI_SUBq , recVUMI_MSUBq , recVUMI_SUBi , recVUMI_MSUBi, + recVUMI_ADD , recVUMI_MADD , recVUMI_MUL , recVUMI_MAX, + recVUMI_SUB , recVUMI_MSUB , recVUMI_OPMSUB, recVUMI_MINI, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, /* 0x30 */ + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVUunknown , recVUunknown , recVUunknown , recVUunknown, + recVU_UPPER_FD_00, recVU_UPPER_FD_01, recVU_UPPER_FD_10, recVU_UPPER_FD_11, +}; + +void (*recVU_UPPER_FD_00_TABLE[32])(VURegs* VU, s32 info) = +{ + recVUMI_ADDAx, recVUMI_SUBAx , recVUMI_MADDAx, recVUMI_MSUBAx, + recVUMI_ITOF0, recVUMI_FTOI0, recVUMI_MULAx , recVUMI_MULAq , + recVUMI_ADDAq, recVUMI_SUBAq, recVUMI_ADDA , recVUMI_SUBA , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , +}; + +void (*recVU_UPPER_FD_01_TABLE[32])(VURegs* VU, s32 info) = +{ + recVUMI_ADDAy , recVUMI_SUBAy , recVUMI_MADDAy, recVUMI_MSUBAy, + recVUMI_ITOF4 , recVUMI_FTOI4 , recVUMI_MULAy , recVUMI_ABS , + recVUMI_MADDAq, recVUMI_MSUBAq, recVUMI_MADDA , recVUMI_MSUBA , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , +}; + +void (*recVU_UPPER_FD_10_TABLE[32])(VURegs* VU, s32 info) = +{ + recVUMI_ADDAz , recVUMI_SUBAz , recVUMI_MADDAz, recVUMI_MSUBAz, + recVUMI_ITOF12, recVUMI_FTOI12, recVUMI_MULAz , recVUMI_MULAi , + recVUMI_ADDAi, recVUMI_SUBAi , recVUMI_MULA , recVUMI_OPMULA, + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , +}; + +void (*recVU_UPPER_FD_11_TABLE[32])(VURegs* VU, s32 info) = +{ + recVUMI_ADDAw , recVUMI_SUBAw , recVUMI_MADDAw, recVUMI_MSUBAw, + recVUMI_ITOF15, recVUMI_FTOI15, recVUMI_MULAw , recVUMI_CLIP , + recVUMI_MADDAi, recVUMI_MSUBAi, recVUunknown , recVUMI_NOP , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , + recVUunknown , recVUunknown , recVUunknown , recVUunknown , +}; + +void recVU_UPPER_FD_00(VURegs* VU, s32 info) +{ + recVU_UPPER_FD_00_TABLE[(VU->code >> 6) & 0x1f ](VU, info); +} + +void recVU_UPPER_FD_01(VURegs* VU, s32 info) +{ + recVU_UPPER_FD_01_TABLE[(VU->code >> 6) & 0x1f ](VU, info); +} + +void recVU_UPPER_FD_10(VURegs* VU, s32 info) +{ + recVU_UPPER_FD_10_TABLE[(VU->code >> 6) & 0x1f ](VU, info); +} + +void recVU_UPPER_FD_11(VURegs* VU, s32 info) +{ + recVU_UPPER_FD_11_TABLE[(VU->code >> 6) & 0x1f ](VU, info); +} + +void recVULowerOP(VURegs* VU, s32 info) +{ + recVULowerOP_OPCODE[ VU->code & 0x3f ](VU, info); +} + +void recVULowerOP_T3_00(VURegs* VU, s32 info) +{ + recVULowerOP_T3_00_OPCODE[(VU->code >> 6) & 0x1f ](VU, info); +} + +void recVULowerOP_T3_01(VURegs* VU, s32 info) +{ + recVULowerOP_T3_01_OPCODE[(VU->code >> 6) & 0x1f ](VU, info); +} + +void recVULowerOP_T3_10(VURegs* VU, s32 info) +{ + recVULowerOP_T3_10_OPCODE[(VU->code >> 6) & 0x1f ](VU, info); +} + +void recVULowerOP_T3_11(VURegs* VU, s32 info) +{ + recVULowerOP_T3_11_OPCODE[(VU->code >> 6) & 0x1f ](VU, info); +} + +void recVUunknown(VURegs* VU, s32 info) +{ + Console::Notice("Unknown SVU micromode opcode called"); +} diff --git a/pcsx2/x86/iVUzerorec.h b/pcsx2/x86/sVU_zerorec.h similarity index 85% rename from pcsx2/x86/iVUzerorec.h rename to pcsx2/x86/sVU_zerorec.h index f81ec8d7b1..060ef7d9ce 100644 --- a/pcsx2/x86/iVUzerorec.h +++ b/pcsx2/x86/sVU_zerorec.h @@ -1,50 +1,47 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -// Super VU recompiler - author: zerofrog(@gmail.com) - -#ifndef VU1_SUPER_RECOMPILER -#define VU1_SUPER_RECOMPILER - -#include "iVUmicro.h" - -extern void SuperVUAlloc(int vuindex); // global VU resources are automatically allocated if necessary. -extern void SuperVUDestroy(int vuindex); // if vuindex is -1, destroys everything -extern void SuperVUReset(int vuindex); // if vuindex is -1, resets everything - -//Using assembly code from an external file. -#ifdef __LINUX__ -extern "C" { -#endif -extern void SuperVUExecuteProgram(u32 startpc, int vuindex); -extern void SuperVUEndProgram(); -extern void svudispfntemp(); -#ifdef __LINUX__ -} -#endif -extern void __fastcall SuperVUClear(u32 startpc, u32 size, int vuindex); - -// read = 0, will write to reg -// read = 1, will read from reg -// read = 2, addr of previously written reg (used for status and clip flags) -extern u32 SuperVUGetVIAddr(int reg, int read); - -// if p == 0, flush q else flush p; if wait is != 0, waits for p/q -extern void SuperVUFlush(int p, int wait); - -#endif +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +// Super VU recompiler - author: zerofrog(@gmail.com) + +#pragma once + +#include "sVU_Micro.h" + +extern void SuperVUAlloc(int vuindex); // global VU resources are automatically allocated if necessary. +extern void SuperVUDestroy(int vuindex); // if vuindex is -1, destroys everything +extern void SuperVUReset(int vuindex); // if vuindex is -1, resets everything + +//Using assembly code from an external file. +#ifdef __LINUX__ +extern "C" { +#endif +extern void SuperVUExecuteProgram(u32 startpc, int vuindex); +extern void SuperVUEndProgram(); +extern void svudispfntemp(); +#ifdef __LINUX__ +} +#endif +extern void __fastcall SuperVUClear(u32 startpc, u32 size, int vuindex); + +// read = 0, will write to reg +// read = 1, will read from reg +// read = 2, addr of previously written reg (used for status and clip flags) +extern u32 SuperVUGetVIAddr(int reg, int read); + +// if p == 0, flush q else flush p; if wait is != 0, waits for p/q +extern void SuperVUFlush(int p, int wait); diff --git a/pcsx2_suite_2008.sln b/pcsx2_suite_2008.sln index 90fecc8295..155b292600 100644 --- a/pcsx2_suite_2008.sln +++ b/pcsx2_suite_2008.sln @@ -4,9 +4,11 @@ Microsoft Visual Studio Solution File, Format Version 10.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcsx2", "pcsx2\windows\VCprojects\pcsx2_2008.vcproj", "{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}" ProjectSection(ProjectDependencies) = postProject {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} + {4639972E-424E-4E13-8B07-CA403C481346} = {4639972E-424E-4E13-8B07-CA403C481346} {0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0} {26511268-2902-4997-8421-ECD7055F9E28} = {26511268-2902-4997-8421-ECD7055F9E28} {2F6C0388-20CB-4242-9F6C-A6EBB6A83F47} = {2F6C0388-20CB-4242-9F6C-A6EBB6A83F47} + {A51123F5-9505-4EAE-85E7-D320290A272C} = {A51123F5-9505-4EAE-85E7-D320290A272C} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZeroGS", "plugins\zerogs\dx\Windows\zerogs_2008.vcproj", "{5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}" @@ -22,6 +24,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CDVDiso", "plugins\CDVDiso\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SPU2-X", "plugins\spu2-x\src\Windows\Spu2-X_vs2008.vcproj", "{5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}" ProjectSection(ProjectDependencies) = postProject + {4639972E-424E-4E13-8B07-CA403C481346} = {4639972E-424E-4E13-8B07-CA403C481346} {E9B51944-7E6D-4BCD-83F2-7BBD5A46182D} = {E9B51944-7E6D-4BCD-83F2-7BBD5A46182D} EndProjectSection EndProject @@ -35,7 +38,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bzip2", "3rdparty\bzip2\bzi EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LilyPad", "plugins\LilyPad\LilyPad_VC2008.vcproj", "{E4081455-398C-4610-A87C-90A8A7D72DC3}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pthreads", "3rdparty\w32pthreads\pthreads_2008.vcproj", "{26511268-2902-4997-8421-ECD7055F9E28}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "w32pthreads", "3rdparty\w32pthreads\pthreads_2008.vcproj", "{26511268-2902-4997-8421-ECD7055F9E28}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZeroSPU2", "plugins\zerospu2\Windows\ZeroSPU2_2008.vcproj", "{7F059854-568D-4E08-9D00-1E78E203E4DC}" ProjectSection(ProjectDependencies) = postProject @@ -79,10 +82,17 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Include", "Include", "{0FADC26C-0E9D-4DD7-84B1-BF4F7754E90C}" ProjectSection(SolutionItems) = preProject common\include\afxresmw.h = common\include\afxresmw.h + common\include\intrin_x86.h = common\include\intrin_x86.h + common\include\Pcsx2Api.h = common\include\Pcsx2Api.h + common\include\Pcsx2Config.h = common\include\Pcsx2Config.h + common\include\Pcsx2Defs.h = common\include\Pcsx2Defs.h + common\include\Pcsx2Types.h = common\include\Pcsx2Types.h common\include\PS2Edefs.h = common\include\PS2Edefs.h common\include\PS2Etypes.h = common\include\PS2Etypes.h EndProjectSection EndProject +Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "setup", "setup\setup.vdproj", "{14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxBase28", "3rdparty\wxWidgets\build\msw\wx_base_2008.vcproj", "{48AD7E0A-25B1-4974-A1E3-03F8C438D34F}" ProjectSection(ProjectDependencies) = postProject {C34487AF-228A-4D11-8E50-27803DF76873} = {C34487AF-228A-4D11-8E50-27803DF76873} @@ -95,6 +105,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxCore28", "3rdparty\wxWidg EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxConfig28", "3rdparty\wxWidgets\build\msw\wx_config_2008.vcproj", "{C34487AF-228A-4D11-8E50-27803DF76873}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "x86emitter", "common\build\x86emitter\x86emitter.vcproj", "{A51123F5-9505-4EAE-85E7-D320290A272C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Utilities", "common\build\Utilities\utilities.vcproj", "{4639972E-424E-4E13-8B07-CA403C481346}" + ProjectSection(ProjectDependencies) = postProject + {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -456,6 +473,18 @@ Global {CDD9DB83-3BD9-4ED8-BB83-399A2F65F022}.Release|Win32.ActiveCfg = Release|Win32 {CDD9DB83-3BD9-4ED8-BB83-399A2F65F022}.Release|Win32.Build.0 = Release|Win32 {CDD9DB83-3BD9-4ED8-BB83-399A2F65F022}.Release|x64.ActiveCfg = Release|Win32 + {14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}.Debug|Win32.ActiveCfg = Release + {14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}.Debug|x64.ActiveCfg = Release + {14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}.Devel|Win32.ActiveCfg = Release + {14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}.Devel|x64.ActiveCfg = Release + {14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}.Release SSE2|Win32.ActiveCfg = Release + {14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}.Release SSE2|x64.ActiveCfg = Release + {14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}.Release SSE4|Win32.ActiveCfg = Release + {14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}.Release SSE4|x64.ActiveCfg = Release + {14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}.Release SSSE3|Win32.ActiveCfg = Release + {14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}.Release SSSE3|x64.ActiveCfg = Release + {14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}.Release|Win32.ActiveCfg = Release + {14259DC9-2A12-4B05-A7D7-23C1A9FFEA03}.Release|x64.ActiveCfg = Release {48AD7E0A-25B1-4974-A1E3-03F8C438D34F}.Debug|Win32.ActiveCfg = Debug|Win32 {48AD7E0A-25B1-4974-A1E3-03F8C438D34F}.Debug|Win32.Build.0 = Debug|Win32 {48AD7E0A-25B1-4974-A1E3-03F8C438D34F}.Debug|x64.ActiveCfg = Debug|Win32 @@ -510,6 +539,42 @@ Global {C34487AF-228A-4D11-8E50-27803DF76873}.Release|Win32.ActiveCfg = Release|Win32 {C34487AF-228A-4D11-8E50-27803DF76873}.Release|Win32.Build.0 = Release|Win32 {C34487AF-228A-4D11-8E50-27803DF76873}.Release|x64.ActiveCfg = Release|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Debug|Win32.ActiveCfg = Debug|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Debug|Win32.Build.0 = Debug|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Debug|x64.ActiveCfg = Debug|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Devel|Win32.ActiveCfg = Devel|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Devel|Win32.Build.0 = Devel|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Devel|x64.ActiveCfg = Devel|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Release SSE2|Win32.ActiveCfg = Release|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Release SSE2|Win32.Build.0 = Release|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Release SSE2|x64.ActiveCfg = Release|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Release SSE4|Win32.ActiveCfg = Release|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Release SSE4|Win32.Build.0 = Release|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Release SSE4|x64.ActiveCfg = Release|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Release SSSE3|Win32.ActiveCfg = Release|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Release SSSE3|Win32.Build.0 = Release|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Release SSSE3|x64.ActiveCfg = Release|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Release|Win32.ActiveCfg = Release|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Release|Win32.Build.0 = Release|Win32 + {A51123F5-9505-4EAE-85E7-D320290A272C}.Release|x64.ActiveCfg = Release|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Debug|Win32.ActiveCfg = Debug|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Debug|Win32.Build.0 = Debug|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Debug|x64.ActiveCfg = Debug|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Devel|Win32.ActiveCfg = Devel|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Devel|Win32.Build.0 = Devel|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Devel|x64.ActiveCfg = Devel|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Release SSE2|Win32.ActiveCfg = Release|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Release SSE2|Win32.Build.0 = Release|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Release SSE2|x64.ActiveCfg = Release|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Release SSE4|Win32.ActiveCfg = Release|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Release SSE4|Win32.Build.0 = Release|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Release SSE4|x64.ActiveCfg = Release|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Release SSSE3|Win32.ActiveCfg = Release|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Release SSSE3|Win32.Build.0 = Release|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Release SSSE3|x64.ActiveCfg = Release|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Release|Win32.ActiveCfg = Release|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Release|Win32.Build.0 = Release|Win32 + {4639972E-424E-4E13-8B07-CA403C481346}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -538,5 +603,10 @@ Global {04439C5F-05FB-4A9C-AAD1-5388C25377DB} = {E1828E40-2FBB-48FE-AE7F-5587755DCE0E} {F38D9DF0-F68D-49D9-B3A0-932E74FB74A0} = {E1828E40-2FBB-48FE-AE7F-5587755DCE0E} {0FADC26C-0E9D-4DD7-84B1-BF4F7754E90C} = {88F517F9-CE1C-4005-9BDF-4481FEB55053} + {A51123F5-9505-4EAE-85E7-D320290A272C} = {88F517F9-CE1C-4005-9BDF-4481FEB55053} + {4639972E-424E-4E13-8B07-CA403C481346} = {88F517F9-CE1C-4005-9BDF-4481FEB55053} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + AMDCaProjectFile = C:\pcsx2dev\pcsx2\CodeAnalyst\pcsx2_suite_2008.caw EndGlobalSection EndGlobal diff --git a/plugins/CDVDiso/build.sh b/plugins/CDVDiso/build.sh index 3b953bbd62..fbc599f31d 100644 --- a/plugins/CDVDiso/build.sh +++ b/plugins/CDVDiso/build.sh @@ -1,17 +1,34 @@ #!/bin/sh -curdir=`pwd` - echo ---------------- echo Building CDVDiso echo ---------------- -cd ${curdir}/src/Linux -make clean -make $@ +curdir=`pwd` -# copy the files -if [ -s cfgCDVDiso ] && [ -s libCDVDiso.so ] -then -cp cfgCDVDiso libCDVDiso.so ${PCSX2PLUGINS} + +if test "${CDVDisoOPTIONS+set}" != set ; then +export CDVDisoOPTIONS="" +fi + +cd src + +if [ $# -gt 0 ] && [ $1 = "all" ] +then + +aclocal +automake -a +autoconf + +./configure ${CDVDisoOPTIONS} --prefix=${PCSX2PLUGINS} +make clean +make install + +else +make $@ +fi + +if [ $? -ne 0 ] +then +exit 1 fi diff --git a/plugins/CDVDiso/src/CDVDiso.h b/plugins/CDVDiso/src/CDVDiso.h index 0c4c173a0f..8226a6e912 100644 --- a/plugins/CDVDiso/src/CDVDiso.h +++ b/plugins/CDVDiso/src/CDVDiso.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __CDVDISO_H__ +#define __CDVDISO_H__ #ifdef _MSC_VER #pragma warning(disable:4018) @@ -28,50 +30,50 @@ #ifdef __cplusplus #ifdef _MSC_VER -#define EXPORT_C(type) extern "C" __declspec(dllexport) type CALLBACK +#define EXPORT_C_(type) extern "C" __declspec(dllexport) type CALLBACK #else -#define EXPORT_C(type) extern "C" type +#define EXPORT_C_(type) extern "C" type #endif #else #ifdef _MSC_VER -#define EXPORT_C(type) __declspec(dllexport) type __stdcall +#define EXPORT_C_(type) __declspec(dllexport) type __stdcall #else -#define EXPORT_C(type) type +#define EXPORT_C_(type) type #endif #endif -EXPORT_C(u32) PS2EgetLibType(); -EXPORT_C(u32) PS2EgetLibVersion2(u32 type); -EXPORT_C(char*) PS2EgetLibName(); +EXPORT_C_(u32) PS2EgetLibType(); +EXPORT_C_(u32) PS2EgetLibVersion2(u32 type); +EXPORT_C_(char*) PS2EgetLibName(); -EXPORT_C(s32) CDVDinit(); -EXPORT_C(s32) CDVDopen(const char* pTitleFilename); -EXPORT_C(void) CDVDclose(); -EXPORT_C(void) CDVDshutdown(); -EXPORT_C(s32) CDVDreadTrack(u32 lsn, int mode); +EXPORT_C_(s32) CDVDinit(); +EXPORT_C_(s32) CDVDopen(const char* pTitleFilename); +EXPORT_C_(void) CDVDclose(); +EXPORT_C_(void) CDVDshutdown(); +EXPORT_C_(s32) CDVDreadTrack(u32 lsn, int mode); // return can be NULL (for async modes) -EXPORT_C(u8*) CDVDgetBuffer(); +EXPORT_C_(u8*) CDVDgetBuffer(); -EXPORT_C(s32) CDVDreadSubQ(u32 lsn, cdvdSubQ* subq);//read subq from disc (only cds have subq data) -EXPORT_C(s32) CDVDgetTN(cdvdTN *Buffer); //disk information -EXPORT_C(s32) CDVDgetTD(u8 Track, cdvdTD *Buffer); //track info: min,sec,frame,type -EXPORT_C(s32) CDVDgetTOC(void* toc); //gets ps2 style toc from disc -EXPORT_C(s32) CDVDgetDiskType(); //CDVD_TYPE_xxxx -EXPORT_C(s32) CDVDgetTrayStatus(); //CDVD_TRAY_xxxx -EXPORT_C(s32) CDVDctrlTrayOpen(); //open disc tray -EXPORT_C(s32) CDVDctrlTrayClose(); //close disc tray +EXPORT_C_(s32) CDVDreadSubQ(u32 lsn, cdvdSubQ* subq);//read subq from disc (only cds have subq data) +EXPORT_C_(s32) CDVDgetTN(cdvdTN *Buffer); //disk information +EXPORT_C_(s32) CDVDgetTD(u8 Track, cdvdTD *Buffer); //track info: min,sec,frame,type +EXPORT_C_(s32) CDVDgetTOC(void* toc); //gets ps2 style toc from disc +EXPORT_C_(s32) CDVDgetDiskType(); //CDVD_TYPE_xxxx +EXPORT_C_(s32) CDVDgetTrayStatus(); //CDVD_TRAY_xxxx +EXPORT_C_(s32) CDVDctrlTrayOpen(); //open disc tray +EXPORT_C_(s32) CDVDctrlTrayClose(); //close disc tray // extended funcs -EXPORT_C(void) CDVDconfigure(); -EXPORT_C(void) CDVDabout(); -EXPORT_C(s32) CDVDtest(); -EXPORT_C(void) CDVDnewDiskCB(void (*callback)()); +EXPORT_C_(void) CDVDconfigure(); +EXPORT_C_(void) CDVDabout(); +EXPORT_C_(s32) CDVDtest(); +EXPORT_C_(void) CDVDnewDiskCB(void (*callback)()); #define CDVD_LOG __Log extern FILE *cdvdLog; @@ -104,6 +106,10 @@ extern _cdIso cdIso[8]; #define MSF2SECT(m,s,f) (((m)*60+(s)-2)*75+(f)) +extern const u8 version; +extern const u8 revision; +extern const u8 build; + extern char IsoFile[256]; extern char IsoCWD[256]; extern char CdDev[256]; @@ -130,3 +136,4 @@ void UpdateZmode(); void CfgOpenFile(); void SysMessage(char *fmt, ...); +#endif \ No newline at end of file diff --git a/plugins/CDVDiso/src/CDVDisop.c b/plugins/CDVDiso/src/CDVDisop.cpp old mode 100644 new mode 100755 similarity index 90% rename from plugins/CDVDiso/src/CDVDisop.c rename to plugins/CDVDiso/src/CDVDisop.cpp index 240b6a9edb..96c16b75ce --- a/plugins/CDVDiso/src/CDVDisop.c +++ b/plugins/CDVDiso/src/CDVDisop.cpp @@ -47,17 +47,17 @@ char *methods[] = NULL }; -#ifdef _DEBUG +#ifdef PCSX2_DEBUG char *LibName = "Linuz Iso CDVD (Debug) "; #else char *LibName = "Linuz Iso CDVD "; #endif -const unsigned char version = PS2E_CDVD_VERSION; -const unsigned char revision = 0; -const unsigned char build = 8; +const u8 version = PS2E_CDVD_VERSION; +const u8 revision = 0; +const u8 build = 9; -unsigned char cdbuffer[CD_FRAMESIZE_RAW * 10] = {0}; +u8 cdbuffer[CD_FRAMESIZE_RAW * 10] = {0}; s32 msf_to_lba(u8 m, u8 s, u8 f) { @@ -80,22 +80,22 @@ void lba_to_msf(s32 lba, u8* m, u8* s, u8* f) #define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ -EXPORT_C(char*) PS2EgetLibName() +EXPORT_C_(char*) PS2EgetLibName() { return LibName; } -EXPORT_C(u32) PS2EgetLibType() +EXPORT_C_(u32) PS2EgetLibType() { return PS2E_LT_CDVD; } -EXPORT_C(u32) PS2EgetLibVersion2(u32 type) +EXPORT_C_(u32) PS2EgetLibVersion2(u32 type) { return (version << 16) | (revision << 8) | build; } -#ifdef _DEBUG +#ifdef PCSX2_DEBUG void __Log(char *fmt, ...) { va_list list; @@ -111,9 +111,9 @@ void __Log(char *fmt, ...) #endif -EXPORT_C(s32) CDVDinit() +EXPORT_C_(s32) CDVDinit() { -#ifdef _DEBUG +#ifdef PCSX2_DEBUG cdvdLog = fopen("logs/cdvdLog.txt", "w"); if (cdvdLog == NULL) { @@ -133,7 +133,7 @@ EXPORT_C(s32) CDVDinit() return 0; } -EXPORT_C(void) CDVDshutdown() +EXPORT_C_(void) CDVDshutdown() { cdvdCurrentIso[0] = 0; #ifdef CDVD_LOG @@ -141,7 +141,7 @@ EXPORT_C(void) CDVDshutdown() #endif } -EXPORT_C(s32) CDVDopen(const char* pTitle) +EXPORT_C_(s32) CDVDopen(const char* pTitle) { LoadConf(); @@ -224,7 +224,7 @@ EXPORT_C(s32) CDVDopen(const char* pTitle) return 0; } -EXPORT_C(void) CDVDclose() +EXPORT_C_(void) CDVDclose() { strcpy(cdvdCurrentIso, IsoFile); @@ -233,7 +233,7 @@ EXPORT_C(void) CDVDclose() if (fdump != NULL) isoClose(fdump); } -EXPORT_C(s32) CDVDreadSubQ(u32 lsn, cdvdSubQ* subq) +EXPORT_C_(s32) CDVDreadSubQ(u32 lsn, cdvdSubQ* subq) { // fake it u8 min, sec, frm; @@ -256,7 +256,7 @@ EXPORT_C(s32) CDVDreadSubQ(u32 lsn, cdvdSubQ* subq) return 0; } -EXPORT_C(s32) CDVDgetTN(cdvdTN *Buffer) +EXPORT_C_(s32) CDVDgetTN(cdvdTN *Buffer) { Buffer->strack = 1; Buffer->etrack = 1; @@ -264,7 +264,7 @@ EXPORT_C(s32) CDVDgetTN(cdvdTN *Buffer) return 0; } -EXPORT_C(s32) CDVDgetTD(u8 Track, cdvdTD *Buffer) +EXPORT_C_(s32) CDVDgetTD(u8 Track, cdvdTD *Buffer) { if (Track == 0) { @@ -279,8 +279,8 @@ EXPORT_C(s32) CDVDgetTD(u8 Track, cdvdTD *Buffer) return 0; } -static int layer1start = -1; -EXPORT_C(s32) CDVDgetTOC(void* toc) +static s32 layer1start = -1; +EXPORT_C_(s32) CDVDgetTOC(void* toc) { u8 type = CDVDgetDiskType(); u8* tocBuff = (u8*)toc; @@ -289,8 +289,6 @@ EXPORT_C(s32) CDVDgetTOC(void* toc) if (type == CDVD_TYPE_DVDV || type == CDVD_TYPE_PS2DVD) { - int i; - // get dvd structure format // scsi command 0x43 memset(tocBuff, 0, 2048); @@ -424,7 +422,7 @@ EXPORT_C(s32) CDVDgetTOC(void* toc) return 0; } -EXPORT_C(s32) CDVDreadTrack(u32 lsn, int mode) +EXPORT_C_(s32) CDVDreadTrack(u32 lsn, int mode) { int _lsn = lsn; @@ -461,32 +459,32 @@ EXPORT_C(s32) CDVDreadTrack(u32 lsn, int mode) return 0; } -EXPORT_C(u8*) CDVDgetBuffer() +EXPORT_C_(u8*) CDVDgetBuffer() { return pbuffer; } -EXPORT_C(s32) CDVDgetDiskType() +EXPORT_C_(s32) CDVDgetDiskType() { return cdtype; } -EXPORT_C(s32) CDVDgetTrayStatus() +EXPORT_C_(s32) CDVDgetTrayStatus() { return CDVD_TRAY_CLOSE; } -EXPORT_C(s32) CDVDctrlTrayOpen() +EXPORT_C_(s32) CDVDctrlTrayOpen() { return 0; } -EXPORT_C(s32) CDVDctrlTrayClose() +EXPORT_C_(s32) CDVDctrlTrayClose() { return 0; } -EXPORT_C(s32) CDVDtest() +EXPORT_C_(s32) CDVDtest() { if (*IsoFile == 0) return 0; diff --git a/plugins/CDVDiso/src/Linux/Config.c b/plugins/CDVDiso/src/Linux/Config.c deleted file mode 100644 index ae1aa1a4af..0000000000 --- a/plugins/CDVDiso/src/Linux/Config.c +++ /dev/null @@ -1,82 +0,0 @@ -/* CDVDiso - * Copyright (C) 2002-2004 CDVDiso Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include "CDVDiso.h" - - -const char *s_strIniPath="../inis/CDVDiso.ini"; - -void LoadConf() -{ - FILE *f; - char cfg[256]; - - //sprintf(cfg, "%s/.PS2E/CDVDiso.cfg", getenv("HOME")); - strcpy(cfg, s_strIniPath); - f = fopen(cfg, "r"); - - if (f == NULL) - { - printf("Unable to load %s\n", cfg); - strcpy(IsoFile, DEV_DEF); - strcpy(CdDev, CDDEV_DEF); - BlockDump = 0; - SaveConf(); - return; - } - - fscanf(f, "IsoFile = %[^\n]\n", IsoFile); - fscanf(f, "CdDev = %[^\n]\n", CdDev); - fscanf(f, "BlockDump = %d\n", &BlockDump); - - if (!strncmp(IsoFile, "CdDev =", 9)) *IsoFile = 0; // quick fix - if (*CdDev == 0) strcpy(CdDev, CDDEV_DEF); - - fclose(f); -} - -void SaveConf() -{ - FILE *f; - char cfg[256]; - - //sprintf(cfg, "%s/.PS2E", getenv("HOME")); - - //mkdir(cfg, 0755); - //sprintf(cfg, "%s/.PS2E/CDVDiso.cfg", getenv("HOME")); - strcpy(cfg, s_strIniPath); - - f = fopen(cfg, "w"); - if (f == NULL) - { - printf("Unable to save %s\n", cfg); - return; - } - - fprintf(f, "IsoFile = %s\n", IsoFile); - fprintf(f, "CdDev = %s\n", CdDev); - fprintf(f, "BlockDump = %d\n", BlockDump); - fclose(f); -} - diff --git a/plugins/CDVDiso/src/Linux/Config.cpp b/plugins/CDVDiso/src/Linux/Config.cpp new file mode 100755 index 0000000000..1f0b440231 --- /dev/null +++ b/plugins/CDVDiso/src/Linux/Config.cpp @@ -0,0 +1,326 @@ +/* CDVDiso + * Copyright (C) 2002-2004 CDVDiso Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Config.h" + +const char *s_strIniPath="./inis/CDVDiso.ini"; +GtkWidget *AboutDlg, *ConfDlg, *MsgDlg, *FileSel; +GtkWidget *Edit, *CdEdit; + +void LoadConf() +{ + FILE *f; + char cfg[256]; + + //sprintf(cfg, "%s/.PS2E/CDVDiso.cfg", getenv("HOME")); + strcpy(cfg, s_strIniPath); + f = fopen(cfg, "r"); + + if (f == NULL) + { + printf("Unable to load %s\n", cfg); + strcpy(IsoFile, DEV_DEF); + strcpy(CdDev, CDDEV_DEF); + BlockDump = 0; + SaveConf(); + return; + } + + fscanf(f, "IsoFile = %[^\n]\n", IsoFile); + fscanf(f, "CdDev = %[^\n]\n", CdDev); + fscanf(f, "BlockDump = %d\n", &BlockDump); + + if (!strncmp(IsoFile, "CdDev =", 9)) *IsoFile = 0; // quick fix + if (*CdDev == 0) strcpy(CdDev, CDDEV_DEF); + + fclose(f); +} + +void SaveConf() +{ + FILE *f; + char cfg[256]; + + //sprintf(cfg, "%s/.PS2E", getenv("HOME")); + + //mkdir(cfg, 0755); + //sprintf(cfg, "%s/.PS2E/CDVDiso.cfg", getenv("HOME")); + strcpy(cfg, s_strIniPath); + + f = fopen(cfg, "w"); + if (f == NULL) + { + printf("Unable to save %s\n", cfg); + return; + } + + fprintf(f, "IsoFile = %s\n", IsoFile); + fprintf(f, "CdDev = %s\n", CdDev); + fprintf(f, "BlockDump = %d\n", BlockDump); + fclose(f); +} + +void SysMessage(char *fmt, ...) +{ + va_list list; + char tmp[256]; + char cmd[256]; + + va_start(list, fmt); + vsprintf(tmp, fmt, list); + va_end(list); + + sprintf(cmd, "message \"%s\"", tmp); + SysMessageLoc(tmp); +} + +void OnFile_Ok() +{ + gchar *File; + + gtk_widget_hide(FileSel); + File = gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel)); + strcpy(IsoFile, File); + gtk_main_quit(); +} + +void OnFile_Cancel() +{ + gtk_widget_hide(FileSel); + gtk_main_quit(); +} + +void CfgOpenFile() +{ + GtkWidget *Ok, *Cancel; + + FileSel = gtk_file_selection_new("Select Iso File"); + + Ok = GTK_FILE_SELECTION(FileSel)->ok_button; + gtk_signal_connect(GTK_OBJECT(Ok), "clicked", + GTK_SIGNAL_FUNC(OnFile_Ok), NULL); + gtk_widget_show(Ok); + + Cancel = GTK_FILE_SELECTION(FileSel)->cancel_button; + gtk_signal_connect(GTK_OBJECT(Cancel), "clicked", + GTK_SIGNAL_FUNC(OnFile_Cancel), NULL); + gtk_widget_show(Cancel); + + gtk_widget_show(FileSel); + gdk_window_raise(FileSel->window); + + gtk_main(); + + SaveConf(); +} + +void OnMsg_Ok() +{ + gtk_widget_destroy(MsgDlg); + gtk_main_quit(); +} + +void SysMessageLoc(char *fmt, ...) +{ + GtkWidget *Ok, *Txt; + GtkWidget *Box, *Box1; + va_list list; + int w; + char msg[512]; + + va_start(list, fmt); + vsprintf(msg, fmt, list); + va_end(list); + + if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0; + + w = strlen(msg) * 6 + 20; + + MsgDlg = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_usize(MsgDlg, w, 70); + gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER); + gtk_window_set_title(GTK_WINDOW(MsgDlg), "cdriso Msg"); + gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 0); + + Box = gtk_vbox_new(0, 0); + gtk_container_add(GTK_CONTAINER(MsgDlg), Box); + gtk_widget_show(Box); + + Txt = gtk_label_new(msg); + + gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5); + gtk_widget_show(Txt); + + Box1 = gtk_hbutton_box_new(); + gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0); + gtk_widget_show(Box1); + + Ok = gtk_button_new_with_label("Ok"); + gtk_signal_connect(GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsg_Ok), NULL); + gtk_container_add(GTK_CONTAINER(Box1), Ok); + GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT); + gtk_widget_show(Ok); + + gtk_widget_show(MsgDlg); + + gtk_main(); +} + +void OnOk (GtkButton *button, gpointer user_data) +{ + char *tmp; + + stop = true; + tmp = gtk_entry_get_text(GTK_ENTRY(Edit)); + strcpy(IsoFile, tmp); + tmp = gtk_entry_get_text(GTK_ENTRY(CdEdit)); + strcpy(CdDev, tmp); + + if is_checked(ConfDlg, "checkBlockDump") + BlockDump = 1; + else + BlockDump = 0; + + SaveConf(); + gtk_widget_destroy(ConfDlg); + gtk_main_quit(); +} + +void OnCancel(GtkButton *button, gpointer user_data) +{ + stop = true; + gtk_widget_destroy(ConfDlg); + gtk_main_quit(); +} + +void OnFileSel_Ok() +{ + gchar *File; + + File = gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel)); + gtk_entry_set_text(GTK_ENTRY(Edit), File); + gtk_widget_destroy(FileSel); +} + +void OnFileSel_Cancel() +{ + gtk_widget_destroy(FileSel); +} + +void OnFileSel(GtkButton *button, gpointer user_data) +{ + GtkWidget *Ok, *Cancel; + + FileSel = gtk_file_selection_new("Select Psx Iso File"); + gtk_file_selection_set_filename(GTK_FILE_SELECTION(FileSel), IsoFile); + + Ok = GTK_FILE_SELECTION(FileSel)->ok_button; + gtk_signal_connect(GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnFileSel_Ok), NULL); + gtk_widget_show(Ok); + + Cancel = GTK_FILE_SELECTION(FileSel)->cancel_button; + gtk_signal_connect(GTK_OBJECT(Cancel), "clicked", GTK_SIGNAL_FUNC(OnFileSel_Cancel), NULL); + gtk_widget_show(Cancel); + + gtk_widget_show(FileSel); + gdk_window_raise(FileSel->window); +} + + +EXPORT_C_(void) CDVDconfigure() +{ + int i; + + LoadConf(); + + ConfDlg = create_Config(); + + Edit = lookup_widget(ConfDlg, "GtkEntry_Iso"); + gtk_entry_set_text(GTK_ENTRY(Edit), IsoFile); + CdEdit = lookup_widget(ConfDlg, "GtkEntry_CdDev"); + gtk_entry_set_text(GTK_ENTRY(CdEdit), CdDev); + + Progress = lookup_widget(ConfDlg, "GtkProgressBar_Progress"); + + BtnCompress = lookup_widget(ConfDlg, "GtkButton_Compress"); + BtnDecompress = lookup_widget(ConfDlg, "GtkButton_Decompress"); + BtnCreate = lookup_widget(ConfDlg, "GtkButton_Create"); + BtnCreateZ = lookup_widget(ConfDlg, "GtkButton_CreateZ"); + + methodlist = NULL; + for (i = 0; i < 2; i++) + methodlist = g_list_append(methodlist, methods[i]); + + Method = lookup_widget(ConfDlg, "GtkCombo_Method"); + gtk_combo_set_popdown_strings(GTK_COMBO(Method), methodlist); + if (strstr(IsoFile, ".Z") != NULL) + gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(Method)->entry), methods[0]); + else + gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(Method)->entry), methods[1]); + + set_checked(ConfDlg, "checkBlockDump", (BlockDump == 1)); + + gtk_widget_show_all(ConfDlg); + gtk_main(); + + return 0; +} + +void OnAboutOk(GtkMenuItem * menuitem, gpointer userdata) +{ + gtk_widget_hide(AboutDlg); + gtk_main_quit(); +} + +EXPORT_C_(void) CDVDabout() +{ + GtkWidget *Label; + GtkWidget *Ok; + GtkWidget *Box, *BBox; + char AboutText[255]; + + sprintf(AboutText, "%s %d.%d\n", LibName, revision, build); + + AboutDlg = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_usize(AboutDlg, 260, 80); + gtk_window_set_title(GTK_WINDOW(AboutDlg), "CDVD About Dialog"); + gtk_window_set_position(GTK_WINDOW(AboutDlg), GTK_WIN_POS_CENTER); + gtk_container_set_border_width(GTK_CONTAINER(AboutDlg), 10); + + Box = gtk_vbox_new(0, 0); + gtk_container_add(GTK_CONTAINER(AboutDlg), Box); + gtk_widget_show(Box); + + Label = gtk_label_new(AboutText); + gtk_box_pack_start(GTK_BOX(Box), Label, FALSE, FALSE, 0); + gtk_widget_show(Label); + + BBox = gtk_hbutton_box_new(); + gtk_box_pack_start(GTK_BOX(Box), BBox, FALSE, FALSE, 0); + gtk_widget_show(BBox); + + Ok = gtk_button_new_with_label("Ok"); + gtk_signal_connect(GTK_OBJECT(Ok), "clicked", + GTK_SIGNAL_FUNC(OnAboutOk), NULL); + gtk_container_add(GTK_CONTAINER(BBox), Ok); + GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT); + gtk_widget_show(Ok); + + gtk_widget_show(AboutDlg); + gtk_main(); +} diff --git a/plugins/CDVDiso/src/Linux/Config.h b/plugins/CDVDiso/src/Linux/Config.h index ee6fad76c7..c8cb20e594 100644 --- a/plugins/CDVDiso/src/Linux/Config.h +++ b/plugins/CDVDiso/src/Linux/Config.h @@ -16,5 +16,66 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + #ifdef __cplusplus +extern "C" +{ +#endif + +#include "support.h" +#include "callbacks.h" +#include "interface.h" + +#ifdef __cplusplus +} +#endif + +#include "CDVDiso.h" + void SaveConf(); void LoadConf(); +extern void SysMessageLoc(char *fmt, ...); + +extern char *LibName; + +extern const u8 revision; +extern const u8 build; + +extern GtkWidget *AboutDlg, *ConfDlg, *MsgDlg, *FileSel; +extern GtkWidget *Edit, *CdEdit; +extern bool stop; + +extern GtkWidget *Method,*Progress; +extern GtkWidget *BtnCompress, *BtnDecompress; +extern GtkWidget *BtnCreate, *BtnCreateZ; + +extern GList *methodlist; + +// Make it easier to check and set checkmarks in the gui +#define is_checked(main_widget, widget_name) (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)))) +#define set_checked(main_widget,widget_name, state) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)), state) + + +extern void OnFileSel(GtkButton *button, gpointer user_data); +extern void OnStop(GtkButton *button, gpointer user_data); +extern void OnCompress(GtkButton *button, gpointer user_data); +extern void OnDecompress(GtkButton *button, gpointer user_data); +extern void OnCreate(GtkButton *button, gpointer user_data); +extern void OnCreateZ(GtkButton *button, gpointer user_data); +extern void OnOk(GtkButton *button, gpointer user_data); +extern void OnCancel(GtkButton *button, gpointer user_data); + diff --git a/plugins/CDVDiso/src/Linux/Linux.c b/plugins/CDVDiso/src/Linux/Linux.c deleted file mode 100644 index dc7072fe55..0000000000 --- a/plugins/CDVDiso/src/Linux/Linux.c +++ /dev/null @@ -1,108 +0,0 @@ -/* CDVDiso - * Copyright (C) 2002-2004 CDVDiso Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -#include "Config.h" -#include "CDVDiso.h" - -void ExecCfg(char *arg) -{ - char cfg[256]; - struct stat buf; - - strcpy(cfg, "./cfgCDVDiso"); - if (stat(cfg, &buf) != -1) - { - sprintf(cfg, "%s %s", cfg, arg); - system(cfg); - return; - } - - strcpy(cfg, "./plugins/cfgCDVDiso"); - if (stat(cfg, &buf) != -1) - { - sprintf(cfg, "%s %s", cfg, arg); - system(cfg); - return; - } - - strcpy(cfg, "./cfg/cfgCDVDiso"); - if (stat(cfg, &buf) != -1) - { - sprintf(cfg, "%s %s", cfg, arg); - system(cfg); - return; - } - - sprintf(cfg, "%s/cfgCDVDiso", getenv("HOME")); - if (stat(cfg, &buf) != -1) - { - sprintf(cfg, "%s %s", cfg, arg); - system(cfg); - return; - } - - printf("cfgCDVDiso file not found!\n"); -} - -void CDVDconfigure() -{ - char *file; - getcwd(file, ArraySize(file)); - chdir("plugins"); - ExecCfg("configure"); - chdir(file); -} - -void CDVDabout() -{ - char *file; - getcwd(file, ArraySize(file)); - chdir("plugins"); - ExecCfg("about"); - chdir(file); -} - -void CfgOpenFile() -{ - char *file; - getcwd(file, ArraySize(file)); - chdir("plugins"); - ExecCfg("open"); - chdir(file); -} - -void SysMessage(char *fmt, ...) -{ - va_list list; - char tmp[256]; - char cmd[256]; - - va_start(list, fmt); - vsprintf(tmp, fmt, list); - va_end(list); - - sprintf(cmd, "message \"%s\"", tmp); - ExecCfg(cmd); -} diff --git a/plugins/CDVDiso/src/Linux/conf.c b/plugins/CDVDiso/src/Linux/Linux.cpp old mode 100644 new mode 100755 similarity index 65% rename from plugins/CDVDiso/src/Linux/conf.c rename to plugins/CDVDiso/src/Linux/Linux.cpp index 298c99962b..814e974714 --- a/plugins/CDVDiso/src/Linux/conf.c +++ b/plugins/CDVDiso/src/Linux/Linux.cpp @@ -16,211 +16,31 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "interface.h" -#include "support.h" -#include "CDVDiso.h" #include "Config.h" - -// Make it easier to check and set checkmarks in the gui -#define is_checked(main_widget, widget_name) (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)))) -#define set_checked(main_widget,widget_name, state) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)), state) - unsigned char Zbuf[CD_FRAMESIZE_RAW * 10 * 2]; -extern char *LibName; - -extern const unsigned char revision; -extern const unsigned char build; - -GtkWidget *FileSel; - -void OnFile_Ok() -{ - gchar *File; - - gtk_widget_hide(FileSel); - File = gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel)); - strcpy(IsoFile, File); - gtk_main_quit(); -} - -void OnFile_Cancel() -{ - gtk_widget_hide(FileSel); - gtk_main_quit(); -} - -void _CDRopen() -{ - GtkWidget *Ok, *Cancel; - - FileSel = gtk_file_selection_new("Select Iso File"); - - Ok = GTK_FILE_SELECTION(FileSel)->ok_button; - gtk_signal_connect(GTK_OBJECT(Ok), "clicked", - GTK_SIGNAL_FUNC(OnFile_Ok), NULL); - gtk_widget_show(Ok); - - Cancel = GTK_FILE_SELECTION(FileSel)->cancel_button; - gtk_signal_connect(GTK_OBJECT(Cancel), "clicked", - GTK_SIGNAL_FUNC(OnFile_Cancel), NULL); - gtk_widget_show(Cancel); - - gtk_widget_show(FileSel); - gdk_window_raise(FileSel->window); - - gtk_main(); - - SaveConf(); -} - -GtkWidget *MsgDlg; - -void OnMsg_Ok() -{ - gtk_widget_destroy(MsgDlg); - gtk_main_quit(); -} - -static void SysMessageLoc(char *fmt, ...) -{ - GtkWidget *Ok, *Txt; - GtkWidget *Box, *Box1; - va_list list; - int w; - char msg[512]; - - va_start(list, fmt); - vsprintf(msg, fmt, list); - va_end(list); - - if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0; - - w = strlen(msg) * 6 + 20; - - MsgDlg = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_widget_set_usize(MsgDlg, w, 70); - gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER); - gtk_window_set_title(GTK_WINDOW(MsgDlg), "cdriso Msg"); - gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 0); - - Box = gtk_vbox_new(0, 0); - gtk_container_add(GTK_CONTAINER(MsgDlg), Box); - gtk_widget_show(Box); - - Txt = gtk_label_new(msg); - - gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5); - gtk_widget_show(Txt); - - Box1 = gtk_hbutton_box_new(); - gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0); - gtk_widget_show(Box1); - - Ok = gtk_button_new_with_label("Ok"); - gtk_signal_connect(GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsg_Ok), NULL); - gtk_container_add(GTK_CONTAINER(Box1), Ok); - GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT); - gtk_widget_show(Ok); - - gtk_widget_show(MsgDlg); - - gtk_main(); -} - -GtkWidget *ConfDlg; -GtkWidget *Edit, *CdEdit; -GtkWidget *FileSel; -GtkWidget *Progress; -GtkWidget *BtnCompress; -GtkWidget *BtnDecompress; -GtkWidget *BtnCreate; -GtkWidget *BtnCreateZ; -GtkWidget *Method; +GtkWidget *Method,*Progress; +GtkWidget *BtnCompress, *BtnDecompress; +GtkWidget *BtnCreate, *BtnCreateZ; GList *methodlist; extern char *methods[]; +unsigned char param[4]; +int cddev = -1; +bool stop; -int stop; +#define CD_LEADOUT (0xaa) -void OnOk(GtkMenuItem * menuitem, gpointer userdata) +union { - char *tmp; + struct cdrom_msf msf; + unsigned char buf[CD_FRAMESIZE_RAW]; +} cr; - stop = 1; - tmp = gtk_entry_get_text(GTK_ENTRY(Edit)); - strcpy(IsoFile, tmp); - tmp = gtk_entry_get_text(GTK_ENTRY(CdEdit)); - strcpy(CdDev, tmp); - - if is_checked(ConfDlg, "checkBlockDump") - BlockDump = 1; - else - BlockDump = 0; - - SaveConf(); - gtk_widget_destroy(ConfDlg); - gtk_main_quit(); -} - -void OnCancel(GtkMenuItem * menuitem, gpointer userdata) +void OnStop(GtkButton *button, gpointer user_data) { - stop = 1; - gtk_widget_destroy(ConfDlg); - gtk_main_quit(); -} - -void OnFileSel_Ok() -{ - gchar *File; - - File = gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel)); - gtk_entry_set_text(GTK_ENTRY(Edit), File); - gtk_widget_destroy(FileSel); -} - -void OnFileSel_Cancel() -{ - gtk_widget_destroy(FileSel); -} - -void OnFileSel() -{ - GtkWidget *Ok, *Cancel; - - FileSel = gtk_file_selection_new("Select Psx Iso File"); - gtk_file_selection_set_filename(GTK_FILE_SELECTION(FileSel), IsoFile); - - Ok = GTK_FILE_SELECTION(FileSel)->ok_button; - gtk_signal_connect(GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnFileSel_Ok), NULL); - gtk_widget_show(Ok); - - Cancel = GTK_FILE_SELECTION(FileSel)->cancel_button; - gtk_signal_connect(GTK_OBJECT(Cancel), "clicked", GTK_SIGNAL_FUNC(OnFileSel_Cancel), NULL); - gtk_widget_show(Cancel); - - gtk_widget_show(FileSel); - gdk_window_raise(FileSel->window); -} - -void OnStop() -{ - stop = 1; + stop = true; } void UpdZmode() @@ -234,7 +54,7 @@ void UpdZmode() char buffer[2352 * 10]; -void OnCompress() +void OnCompress(GtkButton *button, gpointer user_data) { struct stat buf; u32 lsn; @@ -271,7 +91,7 @@ void OnCompress() gtk_widget_set_sensitive(BtnDecompress, FALSE); gtk_widget_set_sensitive(BtnCreate, FALSE); gtk_widget_set_sensitive(BtnCreateZ, FALSE); - stop = 0; + stop = false; for (lsn = 0; lsn < src->blocks; lsn++) { @@ -310,7 +130,7 @@ void OnCompress() } } -void OnDecompress() +void OnDecompress(GtkButton *button, gpointer user_data) { #if 0 struct stat buf; @@ -366,7 +186,7 @@ void OnDecompress() gtk_widget_set_sensitive(BtnDecompress, FALSE); gtk_widget_set_sensitive(BtnCreate, FALSE); gtk_widget_set_sensitive(BtnCreateZ, FALSE); - stop = 0; + stop = false; if (Zmode == 1) { @@ -433,16 +253,6 @@ void OnDecompress() #endif } -#define CD_LEADOUT (0xaa) -unsigned char param[4]; -int cddev = -1; - -union -{ - struct cdrom_msf msf; - unsigned char buf[CD_FRAMESIZE_RAW]; -} cr; - void incSector() { param[2]++; @@ -535,7 +345,7 @@ char *CDR_readTrack(unsigned char *time) } -void OnCreate() +void OnCreate(GtkButton *button, gpointer user_data) { FILE *f; struct stat buf; @@ -600,7 +410,7 @@ void OnCreate() time(&Ttime); - stop = 0; + stop = false; s = MSF2SECT(end[0], end[1], end[2]); gtk_widget_set_sensitive(BtnCompress, FALSE); gtk_widget_set_sensitive(BtnDecompress, FALSE); @@ -672,7 +482,7 @@ void OnCreate() if (!stop) SysMessageLoc("Iso Image Created OK"); } -void OnCreateZ() +void OnCreateZ(GtkButton *button, gpointer user_data) { FILE *f; FILE *t; @@ -758,7 +568,7 @@ void OnCreateZ() time(&Ttime); - stop = 0; + stop = false; s = MSF2SECT(end[0], end[1], end[2]) / blocks; gtk_widget_set_sensitive(BtnCompress, FALSE); gtk_widget_set_sensitive(BtnDecompress, FALSE); @@ -857,110 +667,3 @@ void OnCreateZ() if (!stop) SysMessageLoc("Compressed Iso Image Created OK"); } - -long CDRconfigure(void) -{ - int i; - - LoadConf(); - - ConfDlg = create_Config(); - - Edit = lookup_widget(ConfDlg, "GtkEntry_Iso"); - gtk_entry_set_text(GTK_ENTRY(Edit), IsoFile); - CdEdit = lookup_widget(ConfDlg, "GtkEntry_CdDev"); - gtk_entry_set_text(GTK_ENTRY(CdEdit), CdDev); - - Progress = lookup_widget(ConfDlg, "GtkProgressBar_Progress"); - - BtnCompress = lookup_widget(ConfDlg, "GtkButton_Compress"); - BtnDecompress = lookup_widget(ConfDlg, "GtkButton_Decompress"); - BtnCreate = lookup_widget(ConfDlg, "GtkButton_Create"); - BtnCreateZ = lookup_widget(ConfDlg, "GtkButton_CreateZ"); - - methodlist = NULL; - for (i = 0; i < 2; i++) - methodlist = g_list_append(methodlist, methods[i]); - - Method = lookup_widget(ConfDlg, "GtkCombo_Method"); - gtk_combo_set_popdown_strings(GTK_COMBO(Method), methodlist); - if (strstr(IsoFile, ".Z") != NULL) - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(Method)->entry), methods[0]); - else - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(Method)->entry), methods[1]); - - set_checked(ConfDlg, "checkBlockDump", (BlockDump == 1)); - - gtk_widget_show_all(ConfDlg); - gtk_main(); - - return 0; -} - -GtkWidget *AboutDlg; - -void OnAboutOk(GtkMenuItem * menuitem, gpointer userdata) -{ - gtk_widget_hide(AboutDlg); - gtk_main_quit(); -} - -void CDRabout(void) -{ - GtkWidget *Label; - GtkWidget *Ok; - GtkWidget *Box, *BBox; - char AboutText[255]; - - sprintf(AboutText, "%s %d.%d\n", LibName, revision, build); - - AboutDlg = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_widget_set_usize(AboutDlg, 260, 80); - gtk_window_set_title(GTK_WINDOW(AboutDlg), "CDVD About Dialog"); - gtk_window_set_position(GTK_WINDOW(AboutDlg), GTK_WIN_POS_CENTER); - gtk_container_set_border_width(GTK_CONTAINER(AboutDlg), 10); - - Box = gtk_vbox_new(0, 0); - gtk_container_add(GTK_CONTAINER(AboutDlg), Box); - gtk_widget_show(Box); - - Label = gtk_label_new(AboutText); - gtk_box_pack_start(GTK_BOX(Box), Label, FALSE, FALSE, 0); - gtk_widget_show(Label); - - BBox = gtk_hbutton_box_new(); - gtk_box_pack_start(GTK_BOX(Box), BBox, FALSE, FALSE, 0); - gtk_widget_show(BBox); - - Ok = gtk_button_new_with_label("Ok"); - gtk_signal_connect(GTK_OBJECT(Ok), "clicked", - GTK_SIGNAL_FUNC(OnAboutOk), NULL); - gtk_container_add(GTK_CONTAINER(BBox), Ok); - GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT); - gtk_widget_show(Ok); - - gtk_widget_show(AboutDlg); - gtk_main(); -} - -int main(int argc, char *argv[]) -{ - if (argc < 2) return 0; - - gtk_init(NULL, NULL); - - if (!strcmp(argv[1], "open")) - _CDRopen(); - else if (!strcmp(argv[1], "configure")) - CDRconfigure(); - else if (!strcmp(argv[1], "message")) - { - if (argc > 2) SysMessageLoc(argv[2]); - } - else - CDRabout(); - - return 0; -} - - diff --git a/plugins/CDVDiso/src/Linux/interface.c b/plugins/CDVDiso/src/Linux/interface.c index bb7f7094a7..559fbed98d 100644 --- a/plugins/CDVDiso/src/Linux/interface.c +++ b/plugins/CDVDiso/src/Linux/interface.c @@ -57,43 +57,53 @@ create_Config (void) GtkWidget *button2; Config = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (Config, "Config"); gtk_container_set_border_width (GTK_CONTAINER (Config), 5); gtk_window_set_title (GTK_WINDOW (Config), _("CDVD Config Dialog")); vbox1 = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (vbox1, "vbox1"); gtk_widget_show (vbox1); gtk_container_add (GTK_CONTAINER (Config), vbox1); gtk_container_set_border_width (GTK_CONTAINER (vbox1), 5); hbox1 = gtk_hbox_new (FALSE, 10); + gtk_widget_set_name (hbox1, "hbox1"); gtk_widget_show (hbox1); gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0); GtkEntry_Iso = gtk_entry_new (); + gtk_widget_set_name (GtkEntry_Iso, "GtkEntry_Iso"); gtk_widget_show (GtkEntry_Iso); gtk_box_pack_start (GTK_BOX (hbox1), GtkEntry_Iso, TRUE, TRUE, 0); button5 = gtk_button_new_with_mnemonic (_("Select Iso")); + gtk_widget_set_name (button5, "button5"); gtk_widget_show (button5); gtk_box_pack_start (GTK_BOX (hbox1), button5, FALSE, FALSE, 0); hbox2 = gtk_hbox_new (FALSE, 10); + gtk_widget_set_name (hbox2, "hbox2"); gtk_widget_show (hbox2); gtk_box_pack_start (GTK_BOX (vbox1), hbox2, FALSE, FALSE, 0); GtkProgressBar_Progress = gtk_progress_bar_new (); + gtk_widget_set_name (GtkProgressBar_Progress, "GtkProgressBar_Progress"); gtk_widget_show (GtkProgressBar_Progress); gtk_box_pack_start (GTK_BOX (hbox2), GtkProgressBar_Progress, TRUE, FALSE, 0); button6 = gtk_button_new_with_mnemonic (_("Stop")); + gtk_widget_set_name (button6, "button6"); gtk_widget_show (button6); gtk_box_pack_end (GTK_BOX (hbox2), button6, FALSE, FALSE, 0); hbox4 = gtk_hbox_new (FALSE, 5); + gtk_widget_set_name (hbox4, "hbox4"); gtk_widget_show (hbox4); gtk_box_pack_start (GTK_BOX (vbox1), hbox4, TRUE, TRUE, 0); label2 = gtk_label_new (_("Compression Method:")); + gtk_widget_set_name (label2, "label2"); gtk_widget_show (label2); gtk_box_pack_start (GTK_BOX (hbox4), label2, FALSE, FALSE, 0); gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER); @@ -101,6 +111,7 @@ create_Config (void) GtkCombo_Method = gtk_combo_new (); g_object_set_data (G_OBJECT (GTK_COMBO (GtkCombo_Method)->popwin), "GladeParentKey", GtkCombo_Method); + gtk_widget_set_name (GtkCombo_Method, "GtkCombo_Method"); gtk_widget_show (GtkCombo_Method); gtk_box_pack_start (GTK_BOX (hbox4), GtkCombo_Method, TRUE, FALSE, 0); GtkCombo_Method_items = g_list_append (GtkCombo_Method_items, (gpointer) ""); @@ -108,63 +119,77 @@ create_Config (void) g_list_free (GtkCombo_Method_items); combo_entry1 = GTK_COMBO (GtkCombo_Method)->entry; + gtk_widget_set_name (combo_entry1, "combo_entry1"); gtk_widget_show (combo_entry1); hbuttonbox2 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox2, "hbuttonbox2"); gtk_widget_show (hbuttonbox2); gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox2, TRUE, TRUE, 0); GtkButton_Compress = gtk_button_new_with_mnemonic (_("Compress Iso")); + gtk_widget_set_name (GtkButton_Compress, "GtkButton_Compress"); gtk_widget_show (GtkButton_Compress); gtk_container_add (GTK_CONTAINER (hbuttonbox2), GtkButton_Compress); GTK_WIDGET_SET_FLAGS (GtkButton_Compress, GTK_CAN_DEFAULT); GtkButton_Decompress = gtk_button_new_with_mnemonic (_("Decompress Iso")); + gtk_widget_set_name (GtkButton_Decompress, "GtkButton_Decompress"); gtk_widget_show (GtkButton_Decompress); gtk_container_add (GTK_CONTAINER (hbuttonbox2), GtkButton_Decompress); GTK_WIDGET_SET_FLAGS (GtkButton_Decompress, GTK_CAN_DEFAULT); hbox3 = gtk_hbox_new (FALSE, 5); + gtk_widget_set_name (hbox3, "hbox3"); gtk_widget_show (hbox3); gtk_box_pack_start (GTK_BOX (vbox1), hbox3, FALSE, FALSE, 0); label1 = gtk_label_new (_("Cdrom Device: ")); + gtk_widget_set_name (label1, "label1"); gtk_widget_show (label1); gtk_box_pack_start (GTK_BOX (hbox3), label1, FALSE, FALSE, 0); gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_CENTER); GtkEntry_CdDev = gtk_entry_new (); + gtk_widget_set_name (GtkEntry_CdDev, "GtkEntry_CdDev"); gtk_widget_show (GtkEntry_CdDev); gtk_box_pack_start (GTK_BOX (hbox3), GtkEntry_CdDev, TRUE, TRUE, 0); hbuttonbox3 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox3, "hbuttonbox3"); gtk_widget_show (hbuttonbox3); gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox3, TRUE, TRUE, 0); GtkButton_Create = gtk_button_new_with_mnemonic (_("Create Iso")); + gtk_widget_set_name (GtkButton_Create, "GtkButton_Create"); gtk_widget_show (GtkButton_Create); gtk_container_add (GTK_CONTAINER (hbuttonbox3), GtkButton_Create); GTK_WIDGET_SET_FLAGS (GtkButton_Create, GTK_CAN_DEFAULT); GtkButton_CreateZ = gtk_button_new_with_mnemonic (_("Create Compressed Iso")); + gtk_widget_set_name (GtkButton_CreateZ, "GtkButton_CreateZ"); gtk_widget_show (GtkButton_CreateZ); gtk_container_add (GTK_CONTAINER (hbuttonbox3), GtkButton_CreateZ); GTK_WIDGET_SET_FLAGS (GtkButton_CreateZ, GTK_CAN_DEFAULT); checkBlockDump = gtk_check_button_new_with_mnemonic (_("Create a dump of the running iso")); + gtk_widget_set_name (checkBlockDump, "checkBlockDump"); gtk_widget_show (checkBlockDump); gtk_box_pack_start (GTK_BOX (vbox1), checkBlockDump, FALSE, FALSE, 0); hbuttonbox1 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox1, "hbuttonbox1"); gtk_widget_show (hbuttonbox1); gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, TRUE, TRUE, 0); button1 = gtk_button_new_from_stock ("gtk-ok"); + gtk_widget_set_name (button1, "button1"); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbuttonbox1), button1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); button2 = gtk_button_new_from_stock ("gtk-cancel"); + gtk_widget_set_name (button2, "button2"); gtk_widget_show (button2); gtk_container_add (GTK_CONTAINER (hbuttonbox1), button2); GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); diff --git a/plugins/CDVDiso/src/Makefile.am b/plugins/CDVDiso/src/Makefile.am new file mode 100755 index 0000000000..01b772801a --- /dev/null +++ b/plugins/CDVDiso/src/Makefile.am @@ -0,0 +1,31 @@ +# Create a shared library libCDVDiso +AUTOMAKE_OPTIONS = foreign +noinst_LIBRARIES = libCDVDiso.a +INCLUDES = $(shell pkg-config --cflags gtk+-2.0) -I@srcdir@/../../../common/include -I@srcdir@/../../../3rdparty -I@srcdir@/Linux -I../../../../3rdparty/zlib + +# Create a shared object by faking an exe (thanks to ODE makefiles) +traplibdir=$(prefix) + +if DEBUGBUILD +preext=d +endif + +EXEEXT=$(preext)@so_ext@ + +traplib_PROGRAMS=libCDVDiso +libCDVDiso_SOURCES= +libCDVDiso_DEPENDENCIES = libCDVDiso.a +libCDVDiso_LDFLAGS= @SHARED_LDFLAGS@ +libCDVDiso_LDFLAGS+=-Wl,-soname,@libCDVDiso_SONAME@ +libCDVDiso_LDADD=$(libCDVDiso_a_OBJECTS) + +libCDVDiso_a_SOURCES = CDVDisop.cpp CDVDiso.h libiso.cpp libiso.h mkiso/mkiso.cpp + +libCDVDiso_a_SOURCES += \ +Linux/Config.cpp Linux/Config.h Linux/Linux.cpp \ +Linux/interface.h Linux/support.c \ +Linux/interface.c Linux/support.h \ +Linux/callbacks.h +#Linux/callbacks.c + +#SUBDIRS = Linux \ No newline at end of file diff --git a/plugins/CDVDiso/src/Windows/CDVDiso_vs2008.vcproj b/plugins/CDVDiso/src/Windows/CDVDiso_vs2008.vcproj index 652155f757..b9a31ebf39 100644 --- a/plugins/CDVDiso/src/Windows/CDVDiso_vs2008.vcproj +++ b/plugins/CDVDiso/src/Windows/CDVDiso_vs2008.vcproj @@ -4,9 +4,8 @@ Version="9.00" Name="CDVDiso" ProjectGUID="{5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}" - RootNamespace="CDVDiso_vs2008" - Keyword="Win32Proj" - TargetFrameworkVersion="196613" + RootNamespace="CDVDiso" + TargetFrameworkVersion="131072" > @@ -115,21 +110,8 @@ /> @@ -197,20 +178,8 @@ /> @@ -265,7 +234,7 @@ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > &2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/plugins/CDVDiso/src/libiso.c b/plugins/CDVDiso/src/libiso.cpp old mode 100644 new mode 100755 similarity index 100% rename from plugins/CDVDiso/src/libiso.c rename to plugins/CDVDiso/src/libiso.cpp diff --git a/plugins/CDVDiso/src/missing b/plugins/CDVDiso/src/missing new file mode 100755 index 0000000000..1c8ff7049d --- /dev/null +++ b/plugins/CDVDiso/src/missing @@ -0,0 +1,367 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2006-05-10.23 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case $1 in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $1 in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/plugins/CDVDiso/src/mkiso/Makefile b/plugins/CDVDiso/src/mkiso/Makefile deleted file mode 100644 index 90beb81202..0000000000 --- a/plugins/CDVDiso/src/mkiso/Makefile +++ /dev/null @@ -1,27 +0,0 @@ - -CC = gcc - -MKISO = mkiso -CFLAGS = -fPIC -Wall -O2 -fomit-frame-pointer -I.. -I. -D__LINUX__ -I../../../../3rdparty/zlib -D_FILE_OFFSET_BITS=64 -OBJS = mkiso.o ../libiso.o -LIBS = -OBJS+= ../../../../3rdparty/zlib/adler32.o ../../../../3rdparty/zlib/compress.o ../../../../3rdparty/zlib/crc32.o ../../../../3rdparty/zlib/gzio.o \ -../../../../3rdparty/zlib/uncompr.o ../../../../3rdparty/zlib/deflate.o ../../../../3rdparty/zlib/trees.o ../../../../3rdparty/zlib/zutil.o \ -../../../../3rdparty/zlib/inflate.o ../../../../3rdparty/zlib/infback.o ../../../../3rdparty/zlib/inftrees.o ../../../../3rdparty/zlib/inffast.o - -DEPS:= $(OBJS:.o=.d) - -all: mkiso - -mkiso: ${OBJS} - rm -f ${MKISO} - ${CC} ${CFLAGS} ${OBJS} -o ${MKISO} ${LIBS} - strip ${MKISO} - -clean: - rm -f ${OBJS} ${DEPS} ${MKISO} - -%.o: %.c - ${CC} ${CFLAGS} -c -o $@ $< -MD -MF $(patsubst %.o,%.d,$@) - --include ${DEPS} diff --git a/plugins/CDVDiso/src/mkiso/mkiso.c b/plugins/CDVDiso/src/mkiso/mkiso.cpp old mode 100644 new mode 100755 similarity index 98% rename from plugins/CDVDiso/src/mkiso/mkiso.c rename to plugins/CDVDiso/src/mkiso/mkiso.cpp index df31a048a3..6a25d2bb8b --- a/plugins/CDVDiso/src/mkiso/mkiso.c +++ b/plugins/CDVDiso/src/mkiso/mkiso.cpp @@ -20,6 +20,7 @@ #include #include #include +#include "string.h" #include "CDVDiso.h" @@ -150,7 +151,7 @@ void Decompress(char *filename) } -int main(int argc, char *argv[]) +/*int main(int argc, char *argv[]) { if (argc < 3) return 0; @@ -169,4 +170,4 @@ int main(int argc, char *argv[]) } return 0; -} +}*/ diff --git a/plugins/CDVDisoEFP/src/Linux/Makefile b/plugins/CDVDisoEFP/src/Linux/Makefile index 1fee325f34..4f1bf81b83 100644 --- a/plugins/CDVDisoEFP/src/Linux/Makefile +++ b/plugins/CDVDisoEFP/src/Linux/Makefile @@ -3,7 +3,7 @@ PLUGIN = libCDVDisoEFP.so PLUGINOBJS = CDVDiso.o PLUGINHEADERS = CDVDiso.h PLUGINFLAGS = -fPIC -Wall -O2 -fomit-frame-pointer -D_LARGEFILE64_SOURCE \ - -I.. -I. -I./Linux + -I.. -I. -I./Linux -m32 PLUGINLIBS = -lz -lbz2 CFG = cfgCDVDisoEFP @@ -14,7 +14,7 @@ CFGHEADERS = interface.h aboutbox.h mainbox.h selectionbox.h \ devicebox.h conversionbox.h progressbox.h messagebox.h \ tablerebuild.h device.h CD.h DVD.h CFGFLAGS = -fPIC -Wall -O2 -fomit-frame-pointer -D_LARGEFILE64_SOURCE \ - -I.. -I. -I./Linux + -I.. -I. -I./Linux -m32 CFGLIBS = -lz -lbz2 COMP = compCDVDisoEFP diff --git a/plugins/CDVDlinuz/Src/Linux/Makefile b/plugins/CDVDlinuz/Src/Linux/Makefile index be45567df9..a3525a8be4 100644 --- a/plugins/CDVDlinuz/Src/Linux/Makefile +++ b/plugins/CDVDlinuz/Src/Linux/Makefile @@ -3,14 +3,14 @@ PLUGIN = libCDVDlinuz.so PLUGINOBJS = CDVDlinuz.o ../buffer.o PLUGINHEADERS = CDVDlinuz.h ../buffer.h PLUGINFLAGS = -fPIC -Wall -O2 -fomit-frame-pointer -D_LARGEFILE64_SOURCE \ - -I.. -I. -I./Linux + -I.. -I. -I./Linux -m32 PLUGINLIBS = CFG = cfgCDVDlinuz CFGOBJS = aboutbox.o mainbox.o interface.o CFGHEADERS = aboutbox.h mainbox.h interface.h CFGFLAGS = -fPIC -Wall -O2 -fomit-frame-pointer -D_LARGEFILE64_SOURCE \ - -I.. -I. -I./Linux + -I.. -I. -I./Linux -m32 CFGLIBS = SHAREDOBJS = actualfile.o conf.o logfile.o \ diff --git a/plugins/CDVDnull/CDVD.cpp b/plugins/CDVDnull/CDVD.cpp index 7d922872a7..29ed1642cb 100644 --- a/plugins/CDVDnull/CDVD.cpp +++ b/plugins/CDVDnull/CDVD.cpp @@ -17,7 +17,6 @@ */ #include - #include "CDVD.h" const char *LibName = "CDVDnull Driver"; diff --git a/plugins/CDVDnull/CDVD.h b/plugins/CDVDnull/CDVD.h index 05858f3c41..a2c4c771fb 100644 --- a/plugins/CDVDnull/CDVD.h +++ b/plugins/CDVDnull/CDVD.h @@ -23,11 +23,8 @@ #include #endif -extern "C" -{ #define CDVDdefs #include "PS2Edefs.h" -} #ifdef __LINUX__ #include diff --git a/plugins/CDVDnull/Linux/Config.cpp b/plugins/CDVDnull/Linux/Config.cpp index fead9422be..1c641a0ffd 100644 --- a/plugins/CDVDnull/Linux/Config.cpp +++ b/plugins/CDVDnull/Linux/Config.cpp @@ -46,7 +46,7 @@ void SysMessage(const char *fmt, ...) MsgDlg = gtk_window_new(GTK_WINDOW_POPUP); gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER); - gtk_window_set_title(GTK_WINDOW(MsgDlg), "SPU2null Msg"); + gtk_window_set_title(GTK_WINDOW(MsgDlg), "CDVDnull Msg"); gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 5); Box = gtk_vbox_new(5, 0); diff --git a/plugins/CDVDnull/Linux/Config.h b/plugins/CDVDnull/Linux/Config.h new file mode 100644 index 0000000000..ac1b6a60b5 --- /dev/null +++ b/plugins/CDVDnull/Linux/Config.h @@ -0,0 +1,17 @@ +/* CDVDnull + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ \ No newline at end of file diff --git a/plugins/CDVDnull/Linux/callbacks.c b/plugins/CDVDnull/Linux/callbacks.c new file mode 100644 index 0000000000..e87ed8be2d --- /dev/null +++ b/plugins/CDVDnull/Linux/callbacks.c @@ -0,0 +1,34 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + + +void +OnConf_Ok (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConf_Cancel (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnAbout_Ok (GtkButton *button, + gpointer user_data) +{ + +} + diff --git a/plugins/CDVDnull/Linux/callbacks.h b/plugins/CDVDnull/Linux/callbacks.h new file mode 100644 index 0000000000..e606c242f0 --- /dev/null +++ b/plugins/CDVDnull/Linux/callbacks.h @@ -0,0 +1,14 @@ +#include + + +void +OnConf_Ok (GtkButton *button, + gpointer user_data); + +void +OnConf_Cancel (GtkButton *button, + gpointer user_data); + +void +OnAbout_Ok (GtkButton *button, + gpointer user_data); diff --git a/plugins/CDVDnull/Linux/interface.c b/plugins/CDVDnull/Linux/interface.c new file mode 100644 index 0000000000..f290071448 --- /dev/null +++ b/plugins/CDVDnull/Linux/interface.c @@ -0,0 +1,173 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ + g_object_set_data (G_OBJECT (component), name, widget) + +GtkWidget* +create_Config (void) +{ + GtkWidget *Config; + GtkWidget *vbox1; + GtkWidget *frame3; + GtkWidget *alignment1; + GtkWidget *check_logging; + GtkWidget *label15; + GtkWidget *hbuttonbox1; + GtkWidget *button1; + GtkWidget *button2; + + Config = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (Config, "Config"); + gtk_container_set_border_width (GTK_CONTAINER (Config), 5); + gtk_window_set_title (GTK_WINDOW (Config), _("CDVDconfig")); + + vbox1 = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (vbox1, "vbox1"); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (Config), vbox1); + gtk_container_set_border_width (GTK_CONTAINER (vbox1), 5); + + frame3 = gtk_frame_new (NULL); + gtk_widget_set_name (frame3, "frame3"); + gtk_widget_show (frame3); + gtk_box_pack_start (GTK_BOX (vbox1), frame3, TRUE, TRUE, 0); + gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_NONE); + + alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_set_name (alignment1, "alignment1"); + gtk_widget_show (alignment1); + gtk_container_add (GTK_CONTAINER (frame3), alignment1); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment1), 0, 0, 12, 0); + + check_logging = gtk_check_button_new_with_mnemonic (_("Enable Logging")); + gtk_widget_set_name (check_logging, "check_logging"); + gtk_widget_show (check_logging); + gtk_container_add (GTK_CONTAINER (alignment1), check_logging); + + label15 = gtk_label_new (_("Logging")); + gtk_widget_set_name (label15, "label15"); + gtk_widget_show (label15); + gtk_frame_set_label_widget (GTK_FRAME (frame3), label15); + gtk_label_set_use_markup (GTK_LABEL (label15), TRUE); + + hbuttonbox1 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox1, "hbuttonbox1"); + gtk_widget_show (hbuttonbox1); + gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, TRUE, TRUE, 0); + gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 30); + + button1 = gtk_button_new_with_mnemonic (_("Ok")); + gtk_widget_set_name (button1, "button1"); + gtk_widget_show (button1); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), button1); + GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); + + button2 = gtk_button_new_with_mnemonic (_("Cancel")); + gtk_widget_set_name (button2, "button2"); + gtk_widget_show (button2); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), button2); + GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) button1, "clicked", + G_CALLBACK (OnConf_Ok), + NULL); + g_signal_connect ((gpointer) button2, "clicked", + G_CALLBACK (OnConf_Cancel), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (Config, Config, "Config"); + GLADE_HOOKUP_OBJECT (Config, vbox1, "vbox1"); + GLADE_HOOKUP_OBJECT (Config, frame3, "frame3"); + GLADE_HOOKUP_OBJECT (Config, alignment1, "alignment1"); + GLADE_HOOKUP_OBJECT (Config, check_logging, "check_logging"); + GLADE_HOOKUP_OBJECT (Config, label15, "label15"); + GLADE_HOOKUP_OBJECT (Config, hbuttonbox1, "hbuttonbox1"); + GLADE_HOOKUP_OBJECT (Config, button1, "button1"); + GLADE_HOOKUP_OBJECT (Config, button2, "button2"); + + return Config; +} + +GtkWidget* +create_About (void) +{ + GtkWidget *About; + GtkWidget *vbox2; + GtkWidget *label2; + GtkWidget *label3; + GtkWidget *hbuttonbox2; + GtkWidget *button3; + + About = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (About, "About"); + gtk_container_set_border_width (GTK_CONTAINER (About), 5); + gtk_window_set_title (GTK_WINDOW (About), _("CDVDabout")); + + vbox2 = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (vbox2, "vbox2"); + gtk_widget_show (vbox2); + gtk_container_add (GTK_CONTAINER (About), vbox2); + gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5); + + label2 = gtk_label_new (_("CDVD Null Driver")); + gtk_widget_set_name (label2, "label2"); + gtk_widget_show (label2); + gtk_box_pack_start (GTK_BOX (vbox2), label2, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER); + + label3 = gtk_label_new (_("Original Author: (Not sure. linuzappz?)\nRevised by arcum42@gmail.com")); + gtk_widget_set_name (label3, "label3"); + gtk_widget_show (label3); + gtk_box_pack_start (GTK_BOX (vbox2), label3, FALSE, FALSE, 0); + + hbuttonbox2 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox2, "hbuttonbox2"); + gtk_widget_show (hbuttonbox2); + gtk_box_pack_start (GTK_BOX (vbox2), hbuttonbox2, TRUE, TRUE, 0); + gtk_box_set_spacing (GTK_BOX (hbuttonbox2), 30); + + button3 = gtk_button_new_with_mnemonic (_("Ok")); + gtk_widget_set_name (button3, "button3"); + gtk_widget_show (button3); + gtk_container_add (GTK_CONTAINER (hbuttonbox2), button3); + GTK_WIDGET_SET_FLAGS (button3, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) button3, "clicked", + G_CALLBACK (OnAbout_Ok), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (About, About, "About"); + GLADE_HOOKUP_OBJECT (About, vbox2, "vbox2"); + GLADE_HOOKUP_OBJECT (About, label2, "label2"); + GLADE_HOOKUP_OBJECT (About, label3, "label3"); + GLADE_HOOKUP_OBJECT (About, hbuttonbox2, "hbuttonbox2"); + GLADE_HOOKUP_OBJECT (About, button3, "button3"); + + return About; +} + diff --git a/plugins/CDVDnull/Linux/interface.h b/plugins/CDVDnull/Linux/interface.h new file mode 100644 index 0000000000..69c303ba3b --- /dev/null +++ b/plugins/CDVDnull/Linux/interface.h @@ -0,0 +1,6 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +GtkWidget* create_Config (void); +GtkWidget* create_About (void); diff --git a/plugins/CDVDnull/Linux/support.c b/plugins/CDVDnull/Linux/support.c new file mode 100644 index 0000000000..00aff29822 --- /dev/null +++ b/plugins/CDVDnull/Linux/support.c @@ -0,0 +1,144 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include + +#include "support.h" + +GtkWidget* +lookup_widget (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (!parent) + parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + +static GList *pixmaps_directories = NULL; + +/* Use this function to set the directory containing installed pixmaps. */ +void +add_pixmap_directory (const gchar *directory) +{ + pixmaps_directories = g_list_prepend (pixmaps_directories, + g_strdup (directory)); +} + +/* This is an internally used function to find pixmap files. */ +static gchar* +find_pixmap_file (const gchar *filename) +{ + GList *elem; + + /* We step through each of the pixmaps directory to find it. */ + elem = pixmaps_directories; + while (elem) + { + gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data, + G_DIR_SEPARATOR_S, filename); + if (g_file_test (pathname, G_FILE_TEST_EXISTS)) + return pathname; + g_free (pathname); + elem = elem->next; + } + return NULL; +} + +/* This is an internally used function to create pixmaps. */ +GtkWidget* +create_pixmap (GtkWidget *widget, + const gchar *filename) +{ + gchar *pathname = NULL; + GtkWidget *pixmap; + + if (!filename || !filename[0]) + return gtk_image_new (); + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return gtk_image_new (); + } + + pixmap = gtk_image_new_from_file (pathname); + g_free (pathname); + return pixmap; +} + +/* This is an internally used function to create pixmaps. */ +GdkPixbuf* +create_pixbuf (const gchar *filename) +{ + gchar *pathname = NULL; + GdkPixbuf *pixbuf; + GError *error = NULL; + + if (!filename || !filename[0]) + return NULL; + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return NULL; + } + + pixbuf = gdk_pixbuf_new_from_file (pathname, &error); + if (!pixbuf) + { + fprintf (stderr, "Failed to load pixbuf file: %s: %s\n", + pathname, error->message); + g_error_free (error); + } + g_free (pathname); + return pixbuf; +} + +/* This is used to set ATK action descriptions. */ +void +glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description) +{ + gint n_actions, i; + + n_actions = atk_action_get_n_actions (action); + for (i = 0; i < n_actions; i++) + { + if (!strcmp (atk_action_get_name (action, i), action_name)) + atk_action_set_description (action, i, description); + } +} + diff --git a/plugins/CDVDnull/Linux/support.h b/plugins/CDVDnull/Linux/support.h new file mode 100644 index 0000000000..a32649e53c --- /dev/null +++ b/plugins/CDVDnull/Linux/support.h @@ -0,0 +1,69 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* + * Standard gettext macros. + */ +#ifdef ENABLE_NLS +# include +# undef _ +# define _(String) dgettext (PACKAGE, String) +# define Q_(String) g_strip_context ((String), gettext (String)) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define Q_(String) g_strip_context ((String), (String)) +# define N_(String) (String) +#endif + + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* lookup_widget (GtkWidget *widget, + const gchar *widget_name); + + +/* Use this function to set the directory containing installed pixmaps. */ +void add_pixmap_directory (const gchar *directory); + + +/* + * Private Functions. + */ + +/* This is used to create the pixmaps used in the interface. */ +GtkWidget* create_pixmap (GtkWidget *widget, + const gchar *filename); + +/* This is used to create the pixbufs used in the interface. */ +GdkPixbuf* create_pixbuf (const gchar *filename); + +/* This is used to set ATK action descriptions. */ +void glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description); + diff --git a/plugins/CDVDnull/Windows/CDVDnull_vs2008.vcproj b/plugins/CDVDnull/Windows/CDVDnull_vs2008.vcproj index 26d4c17132..129cc2fa95 100644 --- a/plugins/CDVDnull/Windows/CDVDnull_vs2008.vcproj +++ b/plugins/CDVDnull/Windows/CDVDnull_vs2008.vcproj @@ -18,7 +18,7 @@ @@ -43,12 +43,8 @@ /> m_hWnd = hWnd; + + MONITORINFO mi; + mi.cbSize = sizeof(mi); + GetMonitorInfo(MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST), &mi); + + RECT r; + GetWindowRect(hWnd, &r); + + int x = (mi.rcWork.left + mi.rcWork.right - (r.right - r.left)) / 2; + int y = (mi.rcWork.top + mi.rcWork.bottom - (r.bottom - r.top)) / 2; + + SetWindowPos(hWnd, NULL, x, y, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + + dlg->OnInit(); + + return true; + } + + dlg = (CDVDDialog*)GetWindowLongPtr(hWnd, GWL_USERDATA); + + return dlg != NULL ? dlg->OnMessage(message, wParam, lParam) : FALSE; +} + +bool CDVDDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + return message == WM_COMMAND ? OnCommand((HWND)lParam, LOWORD(wParam), HIWORD(wParam)) : false; +} + +bool CDVDDialog::OnCommand(HWND hWnd, UINT id, UINT code) +{ + if(id == IDOK || id == IDCANCEL) + { + EndDialog(m_hWnd, id); + + return true; + } + + return false; +} + +string CDVDDialog::GetText(UINT id) +{ + string s; + + char* buff = NULL; + + for(int size = 256, limit = 65536; size < limit; size <<= 1) + { + buff = new char[size]; + + if(GetDlgItemText(m_hWnd, id, buff, size)) + { + s = buff; + size = limit; + } + + delete [] buff; + } + + return s; +} + +int CDVDDialog::GetTextAsInt(UINT id) +{ + return atoi(GetText(id).c_str()); +} + +void CDVDDialog::SetText(UINT id, const char* str) +{ + SetDlgItemText(m_hWnd, id, str); +} + +void CDVDDialog::SetTextAsInt(UINT id, int i) +{ + char buff[32] = {0}; + itoa(i, buff, 10); + SetText(id, buff); +} + +void CDVDDialog::ComboBoxInit(UINT id, const CDVDSetting* settings, int count, uint32 selid, uint32 maxid) +{ + HWND hWnd = GetDlgItem(m_hWnd, id); + + SendMessage(hWnd, CB_RESETCONTENT, 0, 0); + + for(int i = 0; i < count; i++) + { + if(settings[i].id <= maxid) + { + string str = settings[i].name; + + if(!settings[i].note.empty()) + { + str = str + " (" + settings[i].note + ")"; + } + + ComboBoxAppend(id, str.c_str(), (LPARAM)settings[i].id, settings[i].id == selid); + } + } +} + +int CDVDDialog::ComboBoxAppend(UINT id, const char* str, LPARAM data, bool select) +{ + HWND hWnd = GetDlgItem(m_hWnd, id); + + int item = (int)SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)str); + + SendMessage(hWnd, CB_SETITEMDATA, item, (LPARAM)data); + + if(select) + { + SendMessage(hWnd, CB_SETCURSEL, item, 0); + } + + return item; +} + +bool CDVDDialog::ComboBoxGetSelData(UINT id, INT_PTR& data) +{ + HWND hWnd = GetDlgItem(m_hWnd, id); + + int item = SendMessage(hWnd, CB_GETCURSEL, 0, 0); + + if(item >= 0) + { + data = SendMessage(hWnd, CB_GETITEMDATA, item, 0); + + return true; + } + + return false; +} diff --git a/plugins/CDVDolio/CDVDDialog.h b/plugins/CDVDolio/CDVDDialog.h new file mode 100644 index 0000000000..0abd02d4df --- /dev/null +++ b/plugins/CDVDolio/CDVDDialog.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +struct CDVDSetting +{ + uint32 id; + string name; + string note; +}; + +class CDVDDialog +{ + int m_id; + + static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +protected: + HWND m_hWnd; + + virtual void OnInit() {} + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + virtual bool OnCommand(HWND hWnd, UINT id, UINT code); + +public: + CDVDDialog (UINT id); + virtual ~CDVDDialog () {} + + INT_PTR DoModal(); + + string GetText(UINT id); + int GetTextAsInt(UINT id); + + void SetText(UINT id, const char* str); + void SetTextAsInt(UINT id, int i); + + void ComboBoxInit(UINT id, const CDVDSetting* settings, int count, uint32 selid, uint32 maxid = ~0); + int ComboBoxAppend(UINT id, const char* str, LPARAM data = 0, bool select = false); + bool ComboBoxGetSelData(UINT id, INT_PTR& data); +}; diff --git a/plugins/CDVDolio/SettingsDlg.cpp b/plugins/CDVDolio/SettingsDlg.cpp index 57f6281fc0..d1bb7c3377 100644 --- a/plugins/CDVDolio/SettingsDlg.cpp +++ b/plugins/CDVDolio/SettingsDlg.cpp @@ -2,193 +2,156 @@ // #include "stdafx.h" -#include "cdvd.h" +#include "CDVD.h" #include "SettingsDlg.h" #include -#include -// CSettingsDlg dialog - -IMPLEMENT_DYNAMIC(CSettingsDlg, CDialog) - -CSettingsDlg::CSettingsDlg(CWnd* pParent /*=NULL*/) - : CDialog(CSettingsDlg::IDD, pParent) - , m_iso(_T("")) -{ - -} - -CSettingsDlg::~CSettingsDlg() +CDVDSettingsDlg::CDVDSettingsDlg() + : CDVDDialog(IDD_CONFIG) { } -BOOL CSettingsDlg::OnInitDialog() +void CDVDSettingsDlg::OnInit() { - __super::OnInitDialog(); + __super::OnInit(); - InitDrive(); - InitISO(); + UpdateDrives(); - UpdateData(FALSE); - - return TRUE; // return TRUE unless you set the focus to a control - // EXCEPTION: OCX Property Pages should return FALSE + SetText(IDC_EDIT1, theApp.GetConfig("iso", "").c_str()); } -void CSettingsDlg::InitDrive() +bool CDVDSettingsDlg::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) { - int drive = AfxGetApp()->GetProfileInt(_T("Settings"), _T("drive"), -1); - - int sel = m_drive.GetCurSel(); - - if(sel >= 0) + if(message == WM_DEVICECHANGE && (wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE)) { - drive = m_drive.GetItemData(sel); + UpdateDrives(); + + DEV_BROADCAST_HDR* p = (DEV_BROADCAST_HDR*)lParam; + + if(p->dbch_devicetype == DBT_DEVTYP_VOLUME) + { + DEV_BROADCAST_VOLUME* v = (DEV_BROADCAST_VOLUME*)p; + + for(int i = 0; i < 32; i++) + { + if(v->dbcv_unitmask & (1 << i)) + { + // printf("%c:\n", 'A' + i); + + // TODO + } + } + } } - while(m_drive.GetCount() > 0) + return __super::OnMessage(message, wParam, lParam); +} + +bool CDVDSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code) +{ + if(id == IDOK) { - m_drive.DeleteString(0); + INT_PTR data = 0; + + if(!ComboBoxGetSelData(IDC_COMBO1, data)) + { + data = -1; + } + + theApp.SetConfig("drive", (int)data); + + theApp.SetConfig("iso", GetText(IDC_EDIT1).c_str()); } + else if(id == IDC_BUTTON1 && code == BN_CLICKED) + { + char buff[MAX_PATH] = {0}; + + OPENFILENAME ofn; + + memset(&ofn, 0, sizeof(ofn)); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = buff; + ofn.nMaxFile = countof(buff); + ofn.lpstrFilter = "ISO file\0*.iso\0All files\0*.*\0"; + ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR; + + strcpy(ofn.lpstrFile, GetText(IDC_EDIT1).c_str()); + + if(GetOpenFileName(&ofn)) + { + SetText(IDC_EDIT1, ofn.lpstrFile); + + HWND hWnd = GetDlgItem(m_hWnd, IDC_COMBO1); + + SendMessage(hWnd, CB_SETCURSEL, SendMessage(hWnd, CB_GETCOUNT, 0, 0) - 1, 0); + } + + return true; + } + + return __super::OnCommand(hWnd, id, code); +} + +void CDVDSettingsDlg::UpdateDrives() +{ + int drive = theApp.GetConfig("drive", -1); + + INT_PTR data = 0; + + if(ComboBoxGetSelData(IDC_COMBO1, data)) + { + drive = (int)data; + } + + vector drives; for(int i = 'A'; i <= 'Z'; i++) { - CString path; + string path = format("%c:", i); - path.Format(_T("%c:"), i); - - if(GetDriveType(path) == DRIVE_CDROM) + if(GetDriveType(path.c_str()) == DRIVE_CDROM) { - CString label = path; + string label = path; - path.Format(_T("\\\\.\\%c:"), i); + path = format("\\\\.\\%c:", i); CDVD cdvd; - if(cdvd.Open(path)) + if(cdvd.Open(path.c_str())) { - CString str = cdvd.GetLabel(); + string str = cdvd.GetLabel(); - if(str.IsEmpty()) + if(str.empty()) { - str = _T("(no label)"); + str = "(no label)"; } - label.Format(_T("[%s] %s"), CString(label), str); + label = "[" + label + "] " + str; } else { - label.Format(_T("[%s] (not detected)"), CString(label)); + label = "[" + label + "] (not detected)"; } - m_drive.SetItemData(m_drive.AddString(label), (DWORD_PTR)i); + CDVDSetting s; + + s.id = i; + s.name = label; + + drives.push_back(s); } } - m_drive.SetItemData(m_drive.AddString(_T("Other...")), (DWORD_PTR)-1); - - for(int i = 0, j = m_drive.GetCount(); i < j; i++) { - if((int)m_drive.GetItemData(i) == drive) - { - m_drive.SetCurSel(i); + CDVDSetting s; - return; - } + s.id = -1; + s.name = "Other..."; + + drives.push_back(s); } - m_drive.SetCurSel(-1); -} - -void CSettingsDlg::InitISO() -{ - m_iso = AfxGetApp()->GetProfileString(_T("Settings"), _T("iso"), _T("")); -} - -void CSettingsDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_COMBO1, m_drive); - DDX_Text(pDX, IDC_EDIT1, m_iso); -} - -BEGIN_MESSAGE_MAP(CSettingsDlg, CDialog) - ON_BN_CLICKED(IDC_BUTTON1, &CSettingsDlg::OnBrowse) - ON_BN_CLICKED(IDOK, &CSettingsDlg::OnBnClickedOk) -END_MESSAGE_MAP() - -// CSettingsDlg message handlers - -LRESULT CSettingsDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) -{ - if(message == WM_DEVICECHANGE) - { - if(wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE) - { - InitDrive(); - - DEV_BROADCAST_HDR* p = (DEV_BROADCAST_HDR*)lParam; - - if(p->dbch_devicetype == DBT_DEVTYP_VOLUME) - { - DEV_BROADCAST_VOLUME* v = (DEV_BROADCAST_VOLUME*)p; - - for(int i = 0; i < 32; i++) - { - if(v->dbcv_unitmask & (1 << i)) - { - TRACE(_T("%c:\n"), 'A' + i); - - // TODO - } - } - } - } - } - - return __super::WindowProc(message, wParam, lParam); -} - -void CSettingsDlg::OnBrowse() -{ - UpdateData(); - - CFileDialog fd(TRUE, NULL, m_iso, - OFN_EXPLORER | OFN_ENABLESIZING | OFN_HIDEREADONLY, - _T("ISO file|*.iso|All files|*.*|"), this); - - if(fd.DoModal() == IDOK) - { - m_iso = fd.GetPathName(); - - UpdateData(FALSE); - - for(int i = 0, j = m_drive.GetCount(); i < j; i++) - { - if((int)m_drive.GetItemData(i) < 0) - { - m_drive.SetCurSel(i); - - break; - } - } - } -} - -void CSettingsDlg::OnBnClickedOk() -{ - UpdateData(); - - int i = m_drive.GetCurSel(); - - if(i >= 0) - { - i = (int)m_drive.GetItemData(i); - } - - AfxGetApp()->WriteProfileInt(_T("Settings"), _T("drive"), i); - - AfxGetApp()->WriteProfileString(_T("Settings"), _T("iso"), m_iso); - - OnOK(); + ComboBoxInit(IDC_COMBO1, &drives[0], drives.size(), drive); } diff --git a/plugins/CDVDolio/SettingsDlg.h b/plugins/CDVDolio/SettingsDlg.h index af06248c42..7c0962547a 100644 --- a/plugins/CDVDolio/SettingsDlg.h +++ b/plugins/CDVDolio/SettingsDlg.h @@ -1,35 +1,16 @@ #pragma once -#include "afxwin.h" +#include "CDVDDialog.h" #include "resource.h" -// CSettingsDlg dialog - -class CSettingsDlg : public CDialog +class CDVDSettingsDlg : public CDVDDialog { - DECLARE_DYNAMIC(CSettingsDlg) + void UpdateDrives(); protected: - void InitDrive(); - void InitISO(); + void OnInit(); + bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + bool OnCommand(HWND hWnd, UINT id, UINT code); public: - CSettingsDlg(CWnd* pParent = NULL); // standard constructor - virtual ~CSettingsDlg(); - - virtual BOOL OnInitDialog(); - - enum { IDD = IDD_CONFIG }; - - CComboBox m_drive; - CString m_iso; - -protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - - DECLARE_MESSAGE_MAP() - - LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); - - afx_msg void OnBrowse(); - afx_msg void OnBnClickedOk(); + CDVDSettingsDlg(); }; diff --git a/plugins/CDVDolio/cdvd.cpp b/plugins/CDVDolio/cdvd.cpp index 1568bf3777..ee3d75f90f 100644 --- a/plugins/CDVDolio/cdvd.cpp +++ b/plugins/CDVDolio/cdvd.cpp @@ -22,55 +22,60 @@ #include "stdafx.h" #include "cdvd.h" #include "SettingsDlg.h" -#include -#ifdef _DEBUG -#define new DEBUG_NEW -#endif +static HMODULE s_hModule; -// -// Note! -// -// If this DLL is dynamically linked against the MFC -// DLLs, any functions exported from this DLL which -// call into MFC must have the AFX_MANAGE_STATE macro -// added at the very beginning of the function. -// -// For example: -// -// extern "C" BOOL PASCAL EXPORT ExportedFunction() -// { -// AFX_MANAGE_STATE(AfxGetStaticModuleState()); -// // normal function body here -// } -// -// It is very important that this macro appear in each -// function, prior to any calls into MFC. This means that -// it must appear as the first statement within the -// function, even before any object variable declarations -// as their constructors may generate calls into the MFC -// DLL. -// -// Please see MFC Technical Notes 33 and 58 for additional -// details. -// +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + switch(ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + s_hModule = hModule; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } -BEGIN_MESSAGE_MAP(cdvdApp, CWinApp) -END_MESSAGE_MAP() + return TRUE; +} -cdvdApp::cdvdApp() +CDVDolioApp theApp; + +const char* CDVDolioApp::m_ini = "inis/CDVDolio.ini"; +const char* CDVDolioApp::m_section = "Settings"; + +CDVDolioApp::CDVDolioApp() { } -cdvdApp theApp; - -BOOL cdvdApp::InitInstance() +HMODULE CDVDolioApp::GetModuleHandle() { - __super::InitInstance(); + return s_hModule; +} - SetRegistryKey(_T("Gabest")); +string CDVDolioApp::GetConfig(const char* entry, const char* value) +{ + char buff[4096] = {0}; + GetPrivateProfileString(m_section, entry, value, buff, countof(buff), m_ini); + return string(buff); +} - return TRUE; +void CDVDolioApp::SetConfig(const char* entry, const char* value) +{ + WritePrivateProfileString(m_section, entry, value, m_ini); +} + +int CDVDolioApp::GetConfig(const char* entry, int value) +{ + return GetPrivateProfileInt(m_section, entry, value, m_ini); +} + +void CDVDolioApp::SetConfig(const char* entry, int value) +{ + char buff[32] = {0}; + itoa(value, buff, 10); + SetConfig(entry, buff); } // @@ -78,7 +83,7 @@ BOOL cdvdApp::InitInstance() #define PS2E_LT_CDVD 0x08 #define PS2E_CDVD_VERSION 0x0005 -EXPORT_C_(UINT32) PS2EgetLibType() +EXPORT_C_(uint32) PS2EgetLibType() { return PS2E_LT_CDVD; } @@ -88,11 +93,11 @@ EXPORT_C_(char*) PS2EgetLibName() return "CDVDolio"; // olio = OverLapped I/O (duh) } -EXPORT_C_(UINT32) PS2EgetLibVersion2(UINT32 type) +EXPORT_C_(uint32) PS2EgetLibVersion2(UINT32 type) { - const UINT32 revision = 0; - const UINT32 build = 1; - const UINT32 minor = 0; + const uint32 revision = 0; + const uint32 build = 1; + const uint32 minor = 0; return (build << 0) | (revision << 8) | (PS2E_CDVD_VERSION << 16) | (minor << 24); } @@ -125,12 +130,12 @@ bool CDVD::SyncRead(int lsn) return Read(lsn) && GetBuffer(); } -bool CDVD::Open(CString path) +bool CDVD::Open(const char* path) { - m_label.Empty(); + m_label.clear(); - DWORD share = FILE_SHARE_READ; - DWORD flags = FILE_ATTRIBUTE_READONLY | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED; + uint32 share = FILE_SHARE_READ; + uint32 flags = FILE_ATTRIBUTE_READONLY | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED; m_hFile = CreateFile(path, GENERIC_READ, share, NULL, OPEN_EXISTING, flags, (HANDLE)NULL); @@ -164,8 +169,23 @@ bool CDVD::Open(CString path) return false; } - m_label = CString(CStringA((char*)&m_buff[24 + 40], 32)); - m_label.Trim(); + m_label = string((const char*)&m_buff[24 + 40], 32); + + // trim + + { + string::size_type i = m_label.find_first_not_of(' '); + string::size_type j = m_label.find_last_not_of(' '); + + if(i == string::npos) + { + m_label.clear(); + } + else + { + m_label = m_label.substr(i, (j != string::npos ? j + 1 : string::npos) - i); + } + } // m_block.count = *(DWORD*)&m_buff[24 + 80]; @@ -184,12 +204,12 @@ void CDVD::Close() m_cache.pending = false; m_cache.count = 0; - m_label.Empty(); + m_label.clear(); } -CString CDVD::GetLabel() +const char* CDVD::GetLabel() { - return m_label; + return m_label.c_str(); } bool CDVD::Read(int lsn, int mode) @@ -237,7 +257,7 @@ bool CDVD::Read(int lsn, int mode) return true; } -BYTE* CDVD::GetBuffer() +uint8* CDVD::GetBuffer() { DWORD size = 0; @@ -258,7 +278,7 @@ BYTE* CDVD::GetBuffer() return &m_buff[24]; } -UINT32 CDVD::GetTN(cdvdTN* buff) +uint32 CDVD::GetTN(cdvdTN* buff) { buff->strack = 1; buff->etrack = 1; @@ -266,7 +286,7 @@ UINT32 CDVD::GetTN(cdvdTN* buff) return 0; } -UINT32 CDVD::GetTD(BYTE track, cdvdTD* buff) +uint32 CDVD::GetTD(BYTE track, cdvdTD* buff) { if(track == 0) { @@ -285,7 +305,7 @@ static CDVD s_cdvd; // -EXPORT_C_(UINT32) CDVDinit() +EXPORT_C_(uint32) CDVDinit() { return 0; } @@ -294,22 +314,22 @@ EXPORT_C CDVDshutdown() { } -EXPORT_C_(UINT32) CDVDopen(const char* title) +EXPORT_C_(uint32) CDVDopen(const char* title) { - CString path; + string path; - int i = AfxGetApp()->GetProfileInt(_T("Settings"), _T("drive"), -1); + int i = theApp.GetConfig("drive", -1); if(i >= 'A' && i <= 'Z') { - path.Format(_T("\\\\.\\%c:"), i); + path = format("\\\\.\\%c:", i); } else { - path = AfxGetApp()->GetProfileString(_T("Settings"), _T("iso"), _T("")); + path = theApp.GetConfig("iso", ""); } - return s_cdvd.Open(path) ? 0 : -1; + return s_cdvd.Open(path.c_str()) ? 0 : -1; } EXPORT_C CDVDclose() @@ -317,61 +337,59 @@ EXPORT_C CDVDclose() s_cdvd.Close(); } -EXPORT_C_(UINT32) CDVDreadTrack(int lsn, int mode) +EXPORT_C_(uint32) CDVDreadTrack(int lsn, int mode) { return s_cdvd.Read(lsn, mode) ? 0 : -1; } -EXPORT_C_(BYTE*) CDVDgetBuffer() +EXPORT_C_(uint8*) CDVDgetBuffer() { return s_cdvd.GetBuffer(); } -EXPORT_C_(UINT32) CDVDreadSubQ(UINT32 lsn, cdvdSubQ* subq) +EXPORT_C_(uint32) CDVDreadSubQ(uint32 lsn, cdvdSubQ* subq) { return -1; } -EXPORT_C_(UINT32) CDVDgetTN(cdvdTN* buff) +EXPORT_C_(uint32) CDVDgetTN(cdvdTN* buff) { return s_cdvd.GetTN(buff); } -EXPORT_C_(UINT32) CDVDgetTD(BYTE track, cdvdTD* buff) +EXPORT_C_(uint32) CDVDgetTD(uint8 track, cdvdTD* buff) { return s_cdvd.GetTD(track, buff); } -EXPORT_C_(UINT32) CDVDgetTOC(void* toc) +EXPORT_C_(uint32) CDVDgetTOC(void* toc) { return -1; // TODO } -EXPORT_C_(UINT32) CDVDgetDiskType() +EXPORT_C_(uint32) CDVDgetDiskType() { return CDVD_TYPE_PS2DVD; // TODO } -EXPORT_C_(UINT32) CDVDgetTrayStatus() +EXPORT_C_(uint32) CDVDgetTrayStatus() { return CDVD_TRAY_CLOSE; } -EXPORT_C_(UINT32) CDVDctrlTrayOpen() +EXPORT_C_(uint32) CDVDctrlTrayOpen() { return 0; } -EXPORT_C_(UINT32) CDVDctrlTrayClose() +EXPORT_C_(uint32) CDVDctrlTrayClose() { return 0; } EXPORT_C CDVDconfigure() { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - - CSettingsDlg dlg; + CDVDSettingsDlg dlg; if(IDOK == dlg.DoModal()) { @@ -384,7 +402,7 @@ EXPORT_C CDVDabout() { } -EXPORT_C_(UINT32) CDVDtest() +EXPORT_C_(uint32) CDVDtest() { return 0; } diff --git a/plugins/CDVDolio/cdvd.def b/plugins/CDVDolio/cdvd.def index 4d845a37ae..c47fee74cb 100644 --- a/plugins/CDVDolio/cdvd.def +++ b/plugins/CDVDolio/cdvd.def @@ -1,6 +1,6 @@ ; cdvd.def : Declares the module parameters for the DLL. -LIBRARY "cdvd" +LIBRARY "CDVDolio" EXPORTS ; Explicit exports can go here diff --git a/plugins/CDVDolio/cdvd.h b/plugins/CDVDolio/cdvd.h index 26d6c9c97b..23fb70f985 100644 --- a/plugins/CDVDolio/cdvd.h +++ b/plugins/CDVDolio/cdvd.h @@ -21,48 +21,31 @@ #pragma once -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -class cdvdApp : public CWinApp -{ -public: - cdvdApp(); - -public: - virtual BOOL InitInstance(); - - DECLARE_MESSAGE_MAP() -}; - -// - struct cdvdSubQ { - BYTE ctrl:4; // control and mode bits - BYTE mode:4; // control and mode bits - BYTE trackNum; // current track number (1 to 99) - BYTE trackIndex; // current index within track (0 to 99) - BYTE trackM; // current minute location on the disc (BCD encoded) - BYTE trackS; // current sector location on the disc (BCD encoded) - BYTE trackF; // current frame location on the disc (BCD encoded) - BYTE pad; // unused - BYTE discM; // current minute offset from first track (BCD encoded) - BYTE discS; // current sector offset from first track (BCD encoded) - BYTE discF; // current frame offset from first track (BCD encoded) + uint8 ctrl:4; // control and mode bits + uint8 mode:4; // control and mode bits + uint8 trackNum; // current track number (1 to 99) + uint8 trackIndex; // current index within track (0 to 99) + uint8 trackM; // current minute location on the disc (BCD encoded) + uint8 trackS; // current sector location on the disc (BCD encoded) + uint8 trackF; // current frame location on the disc (BCD encoded) + uint8 pad; // unused + uint8 discM; // current minute offset from first track (BCD encoded) + uint8 discS; // current sector offset from first track (BCD encoded) + uint8 discF; // current frame offset from first track (BCD encoded) }; struct cdvdTD // NOT bcd coded { - UINT32 lsn; - BYTE type; + uint32 lsn; + uint8 type; }; struct cdvdTN { - BYTE strack; // number of the first track (usually 1) - BYTE etrack; // number of the last track + uint8 strack; // number of the first track (usually 1) + uint8 etrack; // number of the last track }; // CDVDreadTrack mode values: @@ -109,14 +92,34 @@ struct cdvdTN #define CACHE_BLOCK_COUNT 16 +class CDVDolioApp +{ + static const char* m_ini; + static const char* m_section; + +public: + CDVDolioApp(); + + HMODULE GetModuleHandle(); + + string GetConfig(const char* entry, const char* value); + void SetConfig(const char* entry, const char* value); + int GetConfig(const char* entry, int value); + void SetConfig(const char* entry, int value); +}; + +extern CDVDolioApp theApp; + +// + class CDVD { HANDLE m_hFile; - CString m_label; + string m_label; OVERLAPPED m_overlapped; struct {int count, size, offset;} m_block; - struct {BYTE buff[2048 * CACHE_BLOCK_COUNT]; bool pending; int start, count;} m_cache; - BYTE m_buff[2352]; + struct {uint8 buff[2048 * CACHE_BLOCK_COUNT]; bool pending; int start, count;} m_cache; + uint8 m_buff[2352]; LARGE_INTEGER MakeOffset(int lsn); bool SyncRead(int lsn); @@ -125,12 +128,12 @@ public: CDVD(); virtual ~CDVD(); - bool Open(CString path); + bool Open(const char* path); void Close(); - CString GetLabel(); + const char* GetLabel(); bool Read(int lsn, int mode = CDVD_MODE_2048); - BYTE* GetBuffer(); - UINT32 GetTN(cdvdTN* buff); - UINT32 GetTD(BYTE track, cdvdTD* buff); + uint8* GetBuffer(); + uint32 GetTN(cdvdTN* buff); + uint32 GetTD(uint8 track, cdvdTD* buff); }; diff --git a/plugins/CDVDolio/cdvd_vs2008.vcproj b/plugins/CDVDolio/cdvd_vs2008.vcproj index 04c092dc00..8ef2a9ee4f 100644 --- a/plugins/CDVDolio/cdvd_vs2008.vcproj +++ b/plugins/CDVDolio/cdvd_vs2008.vcproj @@ -23,7 +23,7 @@ Name="Debug|Win32" ConfigurationType="2" InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\ProjectRootDir.vsprops;..\..\common\vsprops\BaseProperties.vsprops;.\vsprops\debug.vsprops" - UseOfMFC="1" + UseOfMFC="0" CharacterSet="2" > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -600,10 +147,75 @@ Name="VCPostBuildEventTool" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -916,10 +786,75 @@ Name="VCPostBuildEventTool" /> + + + + + + + + + + + + + + + + + + + @@ -979,10 +914,75 @@ Name="VCPostBuildEventTool" /> + + + + + + + + + + + + + + + + + + + + + @@ -1075,62 +1079,6 @@ UsePrecompiledHeader="1" /> - - - - - - - - - - - - - - - - - - - - - @@ -1139,6 +1087,14 @@ UsePrecompiledHeader="1" /> + + + @@ -1147,6 +1103,14 @@ UsePrecompiledHeader="1" /> + + + @@ -1155,6 +1119,14 @@ UsePrecompiledHeader="1" /> + + + @@ -1163,6 +1135,14 @@ UsePrecompiledHeader="1" /> + + + @@ -1171,6 +1151,14 @@ UsePrecompiledHeader="1" /> + + + @@ -1179,6 +1167,14 @@ UsePrecompiledHeader="1" /> + + + @@ -1187,6 +1183,14 @@ UsePrecompiledHeader="1" /> + + + @@ -1206,6 +1210,10 @@ RelativePath=".\cdvd.h" > + + diff --git a/plugins/CDVDolio/stdafx.cpp b/plugins/CDVDolio/stdafx.cpp index e48c42db5b..ad51702df7 100644 --- a/plugins/CDVDolio/stdafx.cpp +++ b/plugins/CDVDolio/stdafx.cpp @@ -6,3 +6,34 @@ // TODO: reference any additional headers you need in STDAFX.H // and not in this file + +string format(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + + int result = -1, length = 256; + + char* buffer = NULL; + + while(result == -1) + { + if(buffer) delete [] buffer; + + buffer = new char[length + 1]; + + memset(buffer, 0, length + 1); + + result = _vsnprintf(buffer, length, fmt, args); + + length *= 2; + } + + va_end(args); + + string s(buffer); + + delete [] buffer; + + return s; +} diff --git a/plugins/CDVDolio/stdafx.h b/plugins/CDVDolio/stdafx.h index 3f39fe0d2a..75fa739cf5 100644 --- a/plugins/CDVDolio/stdafx.h +++ b/plugins/CDVDolio/stdafx.h @@ -4,60 +4,98 @@ #pragma once -#pragma warning(disable: 4996) +#pragma warning(disable: 4996 4995 4324 4100 4101 4201) -#ifndef VC_EXTRALEAN -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers -#endif +#ifdef _WINDOWS + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. // Modify the following defines if you have to target a platform prior to the ones specified below. // Refer to MSDN for the latest info on corresponding values for different platforms. -#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. -#define WINVER 0x0510 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. + +#ifndef WINVER // Specifies that the minimum required platform is Windows Vista. +#define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows. #endif -#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. -#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 2000 or later. -#endif +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif -#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98. #define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. #endif -#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. -#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later. +#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0. +#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE. #endif -#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#include // MFC core and standard components -//#include // MFC extensions -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT -//#include +#include +#include +#include +#include #include -#include -#include -#include +#include -#define countof(a) (sizeof(a)/sizeof(a[0])) +#endif + +// stdc + +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace std; +using namespace stdext; + +extern string format(const char* fmt, ...); + +// syntactic sugar + +// put these into vc9/common7/ide/usertype.dat to have them highlighted + +typedef unsigned char uint8; +typedef signed char int8; +typedef unsigned short uint16; +typedef signed short int16; +typedef unsigned int uint32; +typedef signed int int32; +typedef unsigned long long uint64; +typedef signed long long int64; + +#define countof(a) (sizeof(a) / sizeof(a[0])) #define EXPORT_C extern "C" __declspec(dllexport) void __stdcall #define EXPORT_C_(type) extern "C" __declspec(dllexport) type __stdcall +#define ALIGN_STACK(n) __declspec(align(n)) int __dummy; + #ifndef RESTRICT #ifdef __INTEL_COMPILER #define RESTRICT restrict - #elif _MSC_VER >= 1400 + #elif _MSC_VER >= 1400 // TODO: gcc #define RESTRICT __restrict #else #define RESTRICT #endif #endif -#pragma warning(disable : 4995 4324 4100) +#if defined(_DEBUG) && defined(_MSC_VER) + #define ASSERT assert +#else + #define ASSERT(exp) ((void)0) +#endif #ifdef _M_SSE -#error No SSE please! + #error No SSE please! #endif diff --git a/plugins/CDVDolio/vsprops/debug.vsprops b/plugins/CDVDolio/vsprops/debug.vsprops index 9d5c60bf96..b7506beeec 100644 --- a/plugins/CDVDolio/vsprops/debug.vsprops +++ b/plugins/CDVDolio/vsprops/debug.vsprops @@ -10,7 +10,7 @@ PreprocessorDefinitions="_DEBUG" MinimalRebuild="true" BasicRuntimeChecks="1" - RuntimeLibrary="1" + RuntimeLibrary="3" /> -#ifdef __cplusplus -extern "C" -{ -#endif #define FWdefs #include "PS2Edefs.h" -#ifdef __cplusplus -} -#endif #ifdef _WIN32 @@ -62,7 +55,7 @@ extern "C" typedef struct { - int Log; + s32 Log; } Config; extern Config conf; diff --git a/plugins/FWnull/Linux/Config.cpp b/plugins/FWnull/Linux/Config.cpp index 515914ca1b..c40b4055e8 100644 --- a/plugins/FWnull/Linux/Config.cpp +++ b/plugins/FWnull/Linux/Config.cpp @@ -29,12 +29,18 @@ using namespace std; #include "FW.h" #include "Config.h" + #ifdef __cplusplus extern "C" { -#include "interface.h" +#endif + #include "support.h" -//#include "callbacks.h" +#include "callbacks.h" +#include "interface.h" + +#ifdef __cplusplus } +#endif GtkWidget *MsgDlg, *About, *Conf; extern string s_strIniPath; @@ -45,7 +51,7 @@ void OnMsg_Ok() gtk_main_quit(); } -void cfgSysMessage(char *fmt, ...) +void SysMessage(char *fmt, ...) { GtkWidget *Ok,*Txt; GtkWidget *Box,*Box1; @@ -86,21 +92,23 @@ void cfgSysMessage(char *fmt, ...) gtk_main(); } - + void OnAbout_Ok(GtkButton *button, gpointer user_data) { gtk_widget_destroy(About); gtk_main_quit(); } -void CFGabout() +EXPORT_C_(void) FWabout() { About = create_About(); gtk_widget_show_all(About); gtk_main(); } -void OnConf_Ok(GtkButton *button, gpointer user_data) { +void OnConf_Ok(GtkButton *button, gpointer user_data) +{ + conf.Log = is_checked(Conf, "check_logging"); SaveConfig(); gtk_widget_destroy(Conf); @@ -113,36 +121,16 @@ void OnConf_Cancel(GtkButton *button, gpointer user_data) gtk_main_quit(); } -void CFGconfigure() +EXPORT_C_(void) FWconfigure() { + LoadConfig(); Conf = create_Config(); - LoadConfig(); - + set_checked(Conf, "check_logging", conf.Log); gtk_widget_show_all(Conf); gtk_main(); } -long CFGmessage(char *msg) { - cfgSysMessage(msg); - - return 0; -} - -/*int main(int argc, char *argv[]) { - gtk_init(NULL, NULL); - - if (!strcmp(argv[1], "configure")) { - CFGconfigure(); - } else if (!strcmp(argv[1], "about")) { - CFGabout(); - } else if (!strcmp(argv[1], "message")) { - CFGmessage(argv[2]); - } - - return 0; -}*/ - void LoadConfig() { FILE *f; @@ -156,6 +144,7 @@ void LoadConfig() SaveConfig();//save and return return; } + fscanf(f, "logging = %hhx\n", &conf.Log); //fscanf(f, "options = %hhx\n", &confOptions); fclose(f); } @@ -169,10 +158,10 @@ void SaveConfig() f = fopen(cfg,"w"); if (f == NULL) { - printf("failed to open %s\n", s_strIniPath.c_str()); + printf("failed to open '%s'\n", s_strIniPath.c_str()); return; } - + fprintf(f, "logging = %hhx\n", conf.Log); //fprintf(f, "options = %hhx\n", confOptions); fclose(f); } diff --git a/plugins/FWnull/Linux/Config.h b/plugins/FWnull/Linux/Config.h index 824a7dafe7..7251ed01eb 100644 --- a/plugins/FWnull/Linux/Config.h +++ b/plugins/FWnull/Linux/Config.h @@ -18,8 +18,7 @@ void SaveConf(); void LoadConf(); +void SysMessage(char *fmt, ...); -extern long CFGmessage(char *msg); -extern void CFGconfigure(); -extern void cfgSysMessage(char *fmt, ...); -extern void CFGabout(); +#define is_checked(main_widget, widget_name) (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)))) +#define set_checked(main_widget,widget_name, state) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)), state) diff --git a/plugins/FWnull/Linux/firewire.glade b/plugins/FWnull/Linux/firewire.glade index cef4eab65e..17c3f83051 100644 --- a/plugins/FWnull/Linux/firewire.glade +++ b/plugins/FWnull/Linux/firewire.glade @@ -6,7 +6,7 @@ 5 True - DEV9config + FWconfig GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False @@ -27,240 +27,37 @@ False 5 - - - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - 5 - True - True - 5 - - - - True - Device: - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - False - True - False - True - False - - - - True - True - True - True - 0 - - True - * - False - - - - - - True - GTK_SELECTION_BROWSE - - - - True - - - - True - - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - - - - - - - 0 - False - False - - - - - - - - True - Ethernet - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - True 0 0.5 - GTK_SHADOW_ETCHED_IN + GTK_SHADOW_NONE - - 5 + True - True - 5 + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 - + True - Device: - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 + True + Enable Logging + True + GTK_RELIEF_NORMAL + True + False + False + True - - 0 - False - False - - - - - - True - False - True - False - True - False - - - - True - True - True - True - 0 - - True - * - False - - - - - - True - GTK_SELECTION_BROWSE - - - - True - - - - True - - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - - - - - - - 0 - False - False - @@ -268,9 +65,9 @@ True - Hdd + <b>Logging</b> False - False + True GTK_JUSTIFY_LEFT False False @@ -340,7 +137,7 @@ 5 True - DEV9about + FWabout GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False @@ -389,7 +186,8 @@ True - Author: linuzappz <linuzappz@hotmail.com> + Original Author: linuzappz <linuzappz@hotmail.com> +Revised by arcum42@gmail.com False False GTK_JUSTIFY_LEFT diff --git a/plugins/FWnull/Linux/interface.c b/plugins/FWnull/Linux/interface.c index 5c23358a21..13f79cea74 100644 --- a/plugins/FWnull/Linux/interface.c +++ b/plugins/FWnull/Linux/interface.c @@ -31,19 +31,9 @@ create_Config (void) { GtkWidget *Config; GtkWidget *vbox1; - GtkWidget *frame2; - GtkWidget *hbox1; - GtkWidget *label4; - GtkWidget *GtkCombo_Eth; - GList *GtkCombo_Eth_items = NULL; - GtkWidget *combo_entry1; - GtkWidget *label1; GtkWidget *frame3; - GtkWidget *hbox2; - GtkWidget *label5; - GtkWidget *GtkCombo_Hdd; - GList *GtkCombo_Hdd_items = NULL; - GtkWidget *entry1; + GtkWidget *alignment1; + GtkWidget *check_logging; GtkWidget *label15; GtkWidget *hbuttonbox1; GtkWidget *button1; @@ -52,7 +42,7 @@ create_Config (void) Config = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_name (Config, "Config"); gtk_container_set_border_width (GTK_CONTAINER (Config), 5); - gtk_window_set_title (GTK_WINDOW (Config), _("DEV9config")); + gtk_window_set_title (GTK_WINDOW (Config), _("FWconfig")); vbox1 = gtk_vbox_new (FALSE, 5); gtk_widget_set_name (vbox1, "vbox1"); @@ -60,77 +50,28 @@ create_Config (void) gtk_container_add (GTK_CONTAINER (Config), vbox1); gtk_container_set_border_width (GTK_CONTAINER (vbox1), 5); - frame2 = gtk_frame_new (NULL); - gtk_widget_set_name (frame2, "frame2"); - gtk_widget_show (frame2); - gtk_box_pack_start (GTK_BOX (vbox1), frame2, TRUE, TRUE, 0); - - hbox1 = gtk_hbox_new (TRUE, 5); - gtk_widget_set_name (hbox1, "hbox1"); - gtk_widget_show (hbox1); - gtk_container_add (GTK_CONTAINER (frame2), hbox1); - gtk_container_set_border_width (GTK_CONTAINER (hbox1), 5); - - label4 = gtk_label_new (_("Device:")); - gtk_widget_set_name (label4, "label4"); - gtk_widget_show (label4); - gtk_box_pack_start (GTK_BOX (hbox1), label4, FALSE, FALSE, 0); - gtk_label_set_justify (GTK_LABEL (label4), GTK_JUSTIFY_CENTER); - - GtkCombo_Eth = gtk_combo_new (); - g_object_set_data (G_OBJECT (GTK_COMBO (GtkCombo_Eth)->popwin), - "GladeParentKey", GtkCombo_Eth); - gtk_widget_set_name (GtkCombo_Eth, "GtkCombo_Eth"); - gtk_widget_show (GtkCombo_Eth); - gtk_box_pack_start (GTK_BOX (hbox1), GtkCombo_Eth, FALSE, FALSE, 0); - GtkCombo_Eth_items = g_list_append (GtkCombo_Eth_items, (gpointer) ""); - gtk_combo_set_popdown_strings (GTK_COMBO (GtkCombo_Eth), GtkCombo_Eth_items); - g_list_free (GtkCombo_Eth_items); - - combo_entry1 = GTK_COMBO (GtkCombo_Eth)->entry; - gtk_widget_set_name (combo_entry1, "combo_entry1"); - gtk_widget_show (combo_entry1); - - label1 = gtk_label_new (_("Ethernet")); - gtk_widget_set_name (label1, "label1"); - gtk_widget_show (label1); - gtk_frame_set_label_widget (GTK_FRAME (frame2), label1); - frame3 = gtk_frame_new (NULL); gtk_widget_set_name (frame3, "frame3"); gtk_widget_show (frame3); gtk_box_pack_start (GTK_BOX (vbox1), frame3, TRUE, TRUE, 0); + gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_NONE); - hbox2 = gtk_hbox_new (TRUE, 5); - gtk_widget_set_name (hbox2, "hbox2"); - gtk_widget_show (hbox2); - gtk_container_add (GTK_CONTAINER (frame3), hbox2); - gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5); + alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_set_name (alignment1, "alignment1"); + gtk_widget_show (alignment1); + gtk_container_add (GTK_CONTAINER (frame3), alignment1); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment1), 0, 0, 12, 0); - label5 = gtk_label_new (_("Device:")); - gtk_widget_set_name (label5, "label5"); - gtk_widget_show (label5); - gtk_box_pack_start (GTK_BOX (hbox2), label5, FALSE, FALSE, 0); - gtk_label_set_justify (GTK_LABEL (label5), GTK_JUSTIFY_CENTER); + check_logging = gtk_check_button_new_with_mnemonic (_("Enable Logging")); + gtk_widget_set_name (check_logging, "check_logging"); + gtk_widget_show (check_logging); + gtk_container_add (GTK_CONTAINER (alignment1), check_logging); - GtkCombo_Hdd = gtk_combo_new (); - g_object_set_data (G_OBJECT (GTK_COMBO (GtkCombo_Hdd)->popwin), - "GladeParentKey", GtkCombo_Hdd); - gtk_widget_set_name (GtkCombo_Hdd, "GtkCombo_Hdd"); - gtk_widget_show (GtkCombo_Hdd); - gtk_box_pack_start (GTK_BOX (hbox2), GtkCombo_Hdd, FALSE, FALSE, 0); - GtkCombo_Hdd_items = g_list_append (GtkCombo_Hdd_items, (gpointer) ""); - gtk_combo_set_popdown_strings (GTK_COMBO (GtkCombo_Hdd), GtkCombo_Hdd_items); - g_list_free (GtkCombo_Hdd_items); - - entry1 = GTK_COMBO (GtkCombo_Hdd)->entry; - gtk_widget_set_name (entry1, "entry1"); - gtk_widget_show (entry1); - - label15 = gtk_label_new (_("Hdd")); + label15 = gtk_label_new (_("Logging")); gtk_widget_set_name (label15, "label15"); gtk_widget_show (label15); gtk_frame_set_label_widget (GTK_FRAME (frame3), label15); + gtk_label_set_use_markup (GTK_LABEL (label15), TRUE); hbuttonbox1 = gtk_hbutton_box_new (); gtk_widget_set_name (hbuttonbox1, "hbuttonbox1"); @@ -160,17 +101,9 @@ create_Config (void) /* Store pointers to all widgets, for use by lookup_widget(). */ GLADE_HOOKUP_OBJECT_NO_REF (Config, Config, "Config"); GLADE_HOOKUP_OBJECT (Config, vbox1, "vbox1"); - GLADE_HOOKUP_OBJECT (Config, frame2, "frame2"); - GLADE_HOOKUP_OBJECT (Config, hbox1, "hbox1"); - GLADE_HOOKUP_OBJECT (Config, label4, "label4"); - GLADE_HOOKUP_OBJECT (Config, GtkCombo_Eth, "GtkCombo_Eth"); - GLADE_HOOKUP_OBJECT (Config, combo_entry1, "combo_entry1"); - GLADE_HOOKUP_OBJECT (Config, label1, "label1"); GLADE_HOOKUP_OBJECT (Config, frame3, "frame3"); - GLADE_HOOKUP_OBJECT (Config, hbox2, "hbox2"); - GLADE_HOOKUP_OBJECT (Config, label5, "label5"); - GLADE_HOOKUP_OBJECT (Config, GtkCombo_Hdd, "GtkCombo_Hdd"); - GLADE_HOOKUP_OBJECT (Config, entry1, "entry1"); + GLADE_HOOKUP_OBJECT (Config, alignment1, "alignment1"); + GLADE_HOOKUP_OBJECT (Config, check_logging, "check_logging"); GLADE_HOOKUP_OBJECT (Config, label15, "label15"); GLADE_HOOKUP_OBJECT (Config, hbuttonbox1, "hbuttonbox1"); GLADE_HOOKUP_OBJECT (Config, button1, "button1"); @@ -192,7 +125,7 @@ create_About (void) About = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_name (About, "About"); gtk_container_set_border_width (GTK_CONTAINER (About), 5); - gtk_window_set_title (GTK_WINDOW (About), _("DEV9about")); + gtk_window_set_title (GTK_WINDOW (About), _("FWabout")); vbox2 = gtk_vbox_new (FALSE, 5); gtk_widget_set_name (vbox2, "vbox2"); @@ -206,7 +139,7 @@ create_About (void) gtk_box_pack_start (GTK_BOX (vbox2), label2, FALSE, FALSE, 0); gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER); - label3 = gtk_label_new (_("Author: linuzappz ")); + label3 = gtk_label_new (_("Original Author: linuzappz \nRevised by arcum42@gmail.com")); gtk_widget_set_name (label3, "label3"); gtk_widget_show (label3); gtk_box_pack_start (GTK_BOX (vbox2), label3, FALSE, FALSE, 0); diff --git a/plugins/FWnull/Makefile.am b/plugins/FWnull/Makefile.am index 708c80c51b..bde89b4aef 100644 --- a/plugins/FWnull/Makefile.am +++ b/plugins/FWnull/Makefile.am @@ -22,12 +22,11 @@ libFWnull_LDFLAGS= @SHARED_LDFLAGS@ libFWnull_LDFLAGS+=-Wl,-soname,@libFWnull_SONAME@ libFWnull_LDADD=$(libFWnull_a_OBJECTS) -libFWnull_a_SOURCES = FW.cpp Linux/Config.cpp Linux/Linux.cpp \ -FW.h Linux/Config.h Linux/Linux.h +libFWnull_a_SOURCES = FW.cpp FW.h Linux/Config.cpp Linux/Config.h libFWnull_a_SOURCES += \ Linux/interface.h Linux/support.c \ Linux/interface.c Linux/support.h \ -Linux/callbacks.c Linux/callbacks.h +Linux/callbacks.h #SUBDIRS = Linux \ No newline at end of file diff --git a/plugins/FWnull/Windows/FWnull_vc2008.vcproj b/plugins/FWnull/Windows/FWnull_vc2008.vcproj index 7ca94e36c7..651030099f 100644 --- a/plugins/FWnull/Windows/FWnull_vc2008.vcproj +++ b/plugins/FWnull/Windows/FWnull_vc2008.vcproj @@ -39,9 +39,6 @@ /> @@ -105,10 +102,6 @@ /> GetProfileInt(_T("GPUSettings"), _T("filter"), 0); - rs.m_dither = AfxGetApp()->GetProfileInt(_T("GPUSettings"), _T("dithering"), 1); - rs.m_aspectratio = AfxGetApp()->GetProfileInt(_T("GPUSettings"), _T("AspectRatio"), 1); - rs.m_vsync = !!AfxGetApp()->GetProfileInt(_T("GPUSettings"), _T("vsync"), FALSE); - rs.m_scale.cx = AfxGetApp()->GetProfileInt(_T("GPUSettings"), _T("scale_x"), 0); - rs.m_scale.cy = AfxGetApp()->GetProfileInt(_T("GPUSettings"), _T("scale_y"), 0); - - int threads = AfxGetApp()->GetProfileInt(_T("GPUSettings"), _T("swthreads"), 1); - - int renderer = AfxGetApp()->GetProfileInt(_T("GPUSettings"), _T("Renderer"), 1); + int renderer = theApp.GetConfig("Renderer", 1); switch(renderer) { default: - case 0: s_gpu = new GPURendererSW(rs, threads); break; - case 1: s_gpu = new GPURendererSW(rs, threads); break; - case 2: s_gpu = new GPURendererSW(rs, threads); break; - // TODO: case 3: s_gpu = new GPURendererNull(rs, threads); break; + case 0: s_gpu = new GPURendererSW(new GSDevice7()); break; + case 1: s_gpu = new GPURendererSW(new GSDevice9()); break; + case 2: s_gpu = new GPURendererSW(new GSDevice10()); break; + // TODO: case 3: s_gpu = new GPURendererNull(new GSDeviceNull()); break; } - s_hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); - if(!s_gpu->Create(hWnd)) { GPUclose(); @@ -131,10 +122,8 @@ EXPORT_C_(INT32) GPUopen(HWND hWnd) return 0; } -EXPORT_C_(INT32) GPUconfigure() +EXPORT_C_(int32) GPUconfigure() { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - GPUSettingsDlg dlg; if(IDOK == dlg.DoModal()) @@ -146,10 +135,8 @@ EXPORT_C_(INT32) GPUconfigure() return 0; } -EXPORT_C_(INT32) GPUtest() +EXPORT_C_(int32) GPUtest() { - // TODO - return 0; } @@ -158,76 +145,79 @@ EXPORT_C GPUabout() // TODO } -EXPORT_C GPUwriteDataMem(const BYTE* mem, UINT32 size) +EXPORT_C GPUwriteDataMem(const uint8* mem, uint32 size) { s_gpu->WriteData(mem, size); } -EXPORT_C GPUwriteData(UINT32 data) +EXPORT_C GPUwriteData(uint32 data) { - s_gpu->WriteData((BYTE*)&data, 1); + s_gpu->WriteData((uint8*)&data, 1); } -EXPORT_C GPUreadDataMem(BYTE* mem, UINT32 size) +EXPORT_C GPUreadDataMem(uint8* mem, uint32 size) { s_gpu->ReadData(mem, size); } -EXPORT_C_(UINT32) GPUreadData() +EXPORT_C_(uint32) GPUreadData() { - UINT32 data = 0; + uint32 data = 0; - s_gpu->ReadData((BYTE*)&data, 1); + s_gpu->ReadData((uint8*)&data, 1); return data; } -EXPORT_C GPUwriteStatus(UINT32 status) +EXPORT_C GPUwriteStatus(uint32 status) { s_gpu->WriteStatus(status); } -EXPORT_C_(UINT32) GPUreadStatus() +EXPORT_C_(uint32) GPUreadStatus() { return s_gpu->ReadStatus(); } -EXPORT_C_(UINT32) GPUdmaChain(const BYTE* mem, UINT32 addr) +EXPORT_C_(uint32) GPUdmaChain(const uint8* mem, uint32 addr) { - // TODO - - UINT32 last[3]; + uint32 last[3]; memset(last, 0xff, sizeof(last)); do { - if(addr == last[1] || addr == last[2]) break; + if(addr == last[1] || addr == last[2]) + { + break; + } + (addr < last[0] ? last[1] : last[2]) = addr; + last[0] = addr; - BYTE size = mem[addr + 3]; + uint8 size = mem[addr + 3]; if(size > 0) { s_gpu->WriteData(&mem[addr + 4], size); } - addr = *(UINT32*)&mem[addr] & 0xffffff; + addr = *(uint32*)&mem[addr] & 0xffffff; } while(addr != 0xffffff); return 0; } -EXPORT_C_(UINT32) GPUgetMode() +EXPORT_C_(uint32) GPUgetMode() { // TODO return 0; } -EXPORT_C GPUsetMode(UINT32) +EXPORT_C GPUsetMode(uint32 mode) { // TODO } @@ -239,9 +229,7 @@ EXPORT_C GPUupdateLace() EXPORT_C GPUmakeSnapshot() { - LPCTSTR path = _T("C:\\"); // TODO - - s_gpu->MakeSnapshot(path); + s_gpu->MakeSnapshot("c:/"); // TODO } EXPORT_C GPUdisplayText(char* text) @@ -249,12 +237,12 @@ EXPORT_C GPUdisplayText(char* text) // TODO } -EXPORT_C GPUdisplayFlags(UINT32 flags) +EXPORT_C GPUdisplayFlags(uint32 flags) { // TODO } -EXPORT_C_(INT32) GPUfreeze(UINT32 type, GPUFreezeData* data) +EXPORT_C_(int32) GPUfreeze(uint32 type, GPUFreezeData* data) { if(!data || data->version != 1) { @@ -290,12 +278,12 @@ EXPORT_C_(INT32) GPUfreeze(UINT32 type, GPUFreezeData* data) return 0; } -EXPORT_C GPUgetScreenPic(BYTE* mem) +EXPORT_C GPUgetScreenPic(uint8* mem) { // TODO } -EXPORT_C GPUshowScreenPic(BYTE* mem) +EXPORT_C GPUshowScreenPic(uint8* mem) { // TODO } diff --git a/plugins/GSdx/GPU.h b/plugins/GSdx/GPU.h index d341870565..d1ec2d6a3e 100644 --- a/plugins/GSdx/GPU.h +++ b/plugins/GSdx/GPU.h @@ -33,209 +33,209 @@ enum }; REG32_(GPUReg, STATUS) - UINT32 TX:4; - UINT32 TY:1; - UINT32 ABR:2; - UINT32 TP:2; - UINT32 DTD:1; - UINT32 DFE:1; - UINT32 MD:1; - UINT32 ME:1; - UINT32 _PAD0:3; - UINT32 WIDTH1:1; - UINT32 WIDTH0:2; - UINT32 HEIGHT:1; - UINT32 ISPAL:1; - UINT32 ISRGB24:1; - UINT32 ISINTER:1; - UINT32 DEN:1; - UINT32 _PAD1:2; - UINT32 IDLE:1; - UINT32 IMG:1; - UINT32 COM:1; - UINT32 DMA:2; - UINT32 LCF:1; + uint32 TX:4; + uint32 TY:1; + uint32 ABR:2; + uint32 TP:2; + uint32 DTD:1; + uint32 DFE:1; + uint32 MD:1; + uint32 ME:1; + uint32 _PAD0:3; + uint32 WIDTH1:1; + uint32 WIDTH0:2; + uint32 HEIGHT:1; + uint32 ISPAL:1; + uint32 ISRGB24:1; + uint32 ISINTER:1; + uint32 DEN:1; + uint32 _PAD1:2; + uint32 IDLE:1; + uint32 IMG:1; + uint32 COM:1; + uint32 DMA:2; + uint32 LCF:1; /* - UINT32 TX:4; - UINT32 TY:1; - UINT32 ABR:2; - UINT32 TP:2; - UINT32 DTD:1; - UINT32 DFE:1; - UINT32 PBW:1; - UINT32 PBC:1; - UINT32 _PAD0:3; - UINT32 HRES2:1; - UINT32 HRES1:2; - UINT32 VRES:1; - UINT32 ISPAL:1; - UINT32 ISRGB24:1; - UINT32 ISINTER:1; - UINT32 ISSTOP:1; - UINT32 _PAD1:1; - UINT32 DMARDY:1; - UINT32 IDIDLE:1; - UINT32 DATARDY:1; - UINT32 ISEMPTY:1; - UINT32 TMODE:2; - UINT32 ODE:1; + uint32 TX:4; + uint32 TY:1; + uint32 ABR:2; + uint32 TP:2; + uint32 DTD:1; + uint32 DFE:1; + uint32 PBW:1; + uint32 PBC:1; + uint32 _PAD0:3; + uint32 HRES2:1; + uint32 HRES1:2; + uint32 VRES:1; + uint32 ISPAL:1; + uint32 ISRGB24:1; + uint32 ISINTER:1; + uint32 ISSTOP:1; + uint32 _PAD1:1; + uint32 DMARDY:1; + uint32 IDIDLE:1; + uint32 DATARDY:1; + uint32 ISEMPTY:1; + uint32 TMODE:2; + uint32 ODE:1; */ REG_END REG32_(GPUReg, PACKET) - UINT32 _PAD:24; - UINT32 OPTION:5; - UINT32 TYPE:3; + uint32 _PAD:24; + uint32 OPTION:5; + uint32 TYPE:3; REG_END REG32_(GPUReg, PRIM) - UINT32 VTX:24; - UINT32 TGE:1; - UINT32 ABE:1; - UINT32 TME:1; - UINT32 _PAD2:1; - UINT32 IIP:1; - UINT32 TYPE:3; + uint32 VTX:24; + uint32 TGE:1; + uint32 ABE:1; + uint32 TME:1; + uint32 _PAD2:1; + uint32 IIP:1; + uint32 TYPE:3; REG_END REG32_(GPUReg, POLYGON) - UINT32 _PAD:24; - UINT32 TGE:1; - UINT32 ABE:1; - UINT32 TME:1; - UINT32 VTX:1; - UINT32 IIP:1; - UINT32 TYPE:3; + uint32 _PAD:24; + uint32 TGE:1; + uint32 ABE:1; + uint32 TME:1; + uint32 VTX:1; + uint32 IIP:1; + uint32 TYPE:3; REG_END REG32_(GPUReg, LINE) - UINT32 _PAD:24; - UINT32 ZERO1:1; - UINT32 ABE:1; - UINT32 ZERO2:1; - UINT32 PLL:1; - UINT32 IIP:1; - UINT32 TYPE:3; + uint32 _PAD:24; + uint32 ZERO1:1; + uint32 ABE:1; + uint32 ZERO2:1; + uint32 PLL:1; + uint32 IIP:1; + uint32 TYPE:3; REG_END REG32_(GPUReg, SPRITE) - UINT32 _PAD:24; - UINT32 ZERO:1; - UINT32 ABE:1; - UINT32 TME:1; - UINT32 SIZE:2; - UINT32 TYPE:3; + uint32 _PAD:24; + uint32 ZERO:1; + uint32 ABE:1; + uint32 TME:1; + uint32 SIZE:2; + uint32 TYPE:3; REG_END REG32_(GPUReg, RESET) - UINT32 _PAD:32; + uint32 _PAD:32; REG_END REG32_(GPUReg, DEN) - UINT32 DEN:1; - UINT32 _PAD:31; + uint32 DEN:1; + uint32 _PAD:31; REG_END REG32_(GPUReg, DMA) - UINT32 DMA:2; - UINT32 _PAD:30; + uint32 DMA:2; + uint32 _PAD:30; REG_END REG32_(GPUReg, DAREA) - UINT32 X:10; - UINT32 Y:9; - UINT32 _PAD:13; + uint32 X:10; + uint32 Y:9; + uint32 _PAD:13; REG_END REG32_(GPUReg, DHRANGE) - UINT32 X1:12; - UINT32 X2:12; - UINT32 _PAD:8; + uint32 X1:12; + uint32 X2:12; + uint32 _PAD:8; REG_END REG32_(GPUReg, DVRANGE) - UINT32 Y1:10; - UINT32 Y2:11; - UINT32 _PAD:11; + uint32 Y1:10; + uint32 Y2:11; + uint32 _PAD:11; REG_END REG32_(GPUReg, DMODE) - UINT32 WIDTH0:2; - UINT32 HEIGHT:1; - UINT32 ISPAL:1; - UINT32 ISRGB24:1; - UINT32 ISINTER:1; - UINT32 WIDTH1:1; - UINT32 REVERSE:1; - UINT32 _PAD:24; + uint32 WIDTH0:2; + uint32 HEIGHT:1; + uint32 ISPAL:1; + uint32 ISRGB24:1; + uint32 ISINTER:1; + uint32 WIDTH1:1; + uint32 REVERSE:1; + uint32 _PAD:24; REG_END REG32_(GPUReg, GPUINFO) - UINT32 PARAM:24; - UINT32 _PAD:8; + uint32 PARAM:24; + uint32 _PAD:8; REG_END REG32_(GPUReg, MODE) - UINT32 TX:4; - UINT32 TY:1; - UINT32 ABR:2; - UINT32 TP:2; - UINT32 DTD:1; - UINT32 DFE:1; - UINT32 _PAD:21; + uint32 TX:4; + uint32 TY:1; + uint32 ABR:2; + uint32 TP:2; + uint32 DTD:1; + uint32 DFE:1; + uint32 _PAD:21; REG_END REG32_(GPUReg, MASK) - UINT32 MD:1; - UINT32 ME:1; - UINT32 _PAD:30; + uint32 MD:1; + uint32 ME:1; + uint32 _PAD:30; REG_END REG32_(GPUReg, DRAREA) - UINT32 X:10; - UINT32 Y:10; - UINT32 _PAD:12; + uint32 X:10; + uint32 Y:10; + uint32 _PAD:12; REG_END REG32_(GPUReg, DROFF) - INT32 X:11; - INT32 Y:11; - INT32 _PAD:10; + int32 X:11; + int32 Y:11; + int32 _PAD:10; REG_END REG32_(GPUReg, RGB) - UINT32 R:8; - UINT32 G:8; - UINT32 B:8; - UINT32 _PAD:8; + uint32 R:8; + uint32 G:8; + uint32 B:8; + uint32 _PAD:8; REG_END REG32_(GPUReg, XY) - INT32 X:11; - INT32 _PAD1:5; - INT32 Y:11; - INT32 _PAD2:5; + int32 X:11; + int32 _PAD1:5; + int32 Y:11; + int32 _PAD2:5; REG_END REG32_(GPUReg, UV) - UINT32 U:8; - UINT32 V:8; - UINT32 _PAD:16; + uint32 U:8; + uint32 V:8; + uint32 _PAD:16; REG_END REG32_(GPUReg, TWIN) - UINT32 TWW:5; - UINT32 TWH:5; - UINT32 TWX:5; - UINT32 TWY:5; - UINT32 _PAD:12; + uint32 TWW:5; + uint32 TWH:5; + uint32 TWX:5; + uint32 TWY:5; + uint32 _PAD:12; REG_END REG32_(GPUReg, CLUT) - UINT32 _PAD1:16; - UINT32 X:6; - UINT32 Y:9; - UINT32 _PAD2:1; + uint32 _PAD1:16; + uint32 X:6; + uint32 Y:9; + uint32 _PAD2:1; REG_END REG32_SET(GPUReg) @@ -266,10 +266,10 @@ REG_SET_END struct GPUFreezeData { - UINT32 version; // == 1 - UINT32 status; - UINT32 control[256]; - UINT16 vram[1024 * 1024]; + uint32 version; // == 1 + uint32 status; + uint32 control[256]; + uint16 vram[1024 * 1024]; }; #pragma pack(pop) diff --git a/plugins/GSdx/GPUDrawScanline.cpp b/plugins/GSdx/GPUDrawScanline.cpp index 9fc3c64e01..a1e0e2cabb 100644 --- a/plugins/GSdx/GPUDrawScanline.cpp +++ b/plugins/GSdx/GPUDrawScanline.cpp @@ -51,7 +51,7 @@ void GPUDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f) if(m_env.sel.twin) { - DWORD u, v; + uint32 u, v; u = ~(env.TWIN.TWW << 3) & 0xff; v = ~(env.TWIN.TWH << 3) & 0xff; @@ -69,7 +69,7 @@ void GPUDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f) // - f->ssl = m_ds.Lookup(m_env.sel); + f->ssl = m_ds[m_env.sel]; f->sr = NULL; // TODO @@ -84,7 +84,7 @@ void GPUDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f) sel.twin = m_env.sel.twin; sel.sprite = m_env.sel.sprite; - f->ssp = m_sp.Lookup(sel); + f->ssp = m_sp[sel]; } void GPUDrawScanline::EndDraw(const GSRasterizerStats& stats) @@ -100,7 +100,7 @@ GPUDrawScanline::GPUSetupPrimMap::GPUSetupPrimMap(GPUScanlineEnvironment& env) { } -GPUSetupPrimCodeGenerator* GPUDrawScanline::GPUSetupPrimMap::Create(DWORD key, void* ptr, size_t maxsize) +GPUSetupPrimCodeGenerator* GPUDrawScanline::GPUSetupPrimMap::Create(uint32 key, void* ptr, size_t maxsize) { return new GPUSetupPrimCodeGenerator(m_env, ptr, maxsize); } @@ -113,7 +113,7 @@ GPUDrawScanline::GPUDrawScanlineMap::GPUDrawScanlineMap(GPUScanlineEnvironment& { } -GPUDrawScanlineCodeGenerator* GPUDrawScanline::GPUDrawScanlineMap::Create(DWORD key, void* ptr, size_t maxsize) +GPUDrawScanlineCodeGenerator* GPUDrawScanline::GPUDrawScanlineMap::Create(uint32 key, void* ptr, size_t maxsize) { return new GPUDrawScanlineCodeGenerator(m_env, ptr, maxsize); } diff --git a/plugins/GSdx/GPUDrawScanline.h b/plugins/GSdx/GPUDrawScanline.h index 9a39d87875..9d6f01fda3 100644 --- a/plugins/GSdx/GPUDrawScanline.h +++ b/plugins/GSdx/GPUDrawScanline.h @@ -34,24 +34,24 @@ class GPUDrawScanline : public GSAlignedClass<16>, public IDrawScanline // - class GPUSetupPrimMap : public GSCodeGeneratorFunctionMap + class GPUSetupPrimMap : public GSCodeGeneratorFunctionMap { GPUScanlineEnvironment& m_env; public: GPUSetupPrimMap(GPUScanlineEnvironment& env); - GPUSetupPrimCodeGenerator* Create(DWORD key, void* ptr, size_t maxsize); + GPUSetupPrimCodeGenerator* Create(uint32 key, void* ptr, size_t maxsize); } m_sp; // - class GPUDrawScanlineMap : public GSCodeGeneratorFunctionMap + class GPUDrawScanlineMap : public GSCodeGeneratorFunctionMap { GPUScanlineEnvironment& m_env; public: GPUDrawScanlineMap(GPUScanlineEnvironment& env); - GPUDrawScanlineCodeGenerator* Create(DWORD key, void* ptr, size_t maxsize); + GPUDrawScanlineCodeGenerator* Create(uint32 key, void* ptr, size_t maxsize); } m_ds; protected: diff --git a/plugins/GSdx/GPUDrawScanlineCodeGenerator.cpp b/plugins/GSdx/GPUDrawScanlineCodeGenerator.cpp index 523b434f11..1a7699658d 100644 --- a/plugins/GSdx/GPUDrawScanlineCodeGenerator.cpp +++ b/plugins/GSdx/GPUDrawScanlineCodeGenerator.cpp @@ -119,7 +119,7 @@ void GPUDrawScanlineCodeGenerator::Init(int params) mov(eax, dword[esp + _top]); - // WORD* fb = &m_env.vm[(top << (10 + m_env.sel.scalex)) + left]; + // uint16* fb = &m_env.vm[(top << (10 + m_env.sel.scalex)) + left]; mov(edi, eax); shl(edi, 10 + m_env.sel.scalex); @@ -222,7 +222,7 @@ void GPUDrawScanlineCodeGenerator::Step() // fb += 8; - add(edi, 8 * sizeof(WORD)); + add(edi, 8 * sizeof(uint16)); if(m_env.sel.tme) { @@ -1020,7 +1020,7 @@ const GSVector4i GPUDrawScanlineCodeGenerator::m_test[8] = GSVector4i::zero(), }; -__declspec(align(16)) const WORD GPUDrawScanlineCodeGenerator::m_dither[4][16] = +__declspec(align(16)) const uint16 GPUDrawScanlineCodeGenerator::m_dither[4][16] = { {7, 0, 6, 1, 7, 0, 6, 1, 7, 0, 6, 1, 7, 0, 6, 1}, {2, 5, 3, 4, 2, 5, 3, 4, 2, 5, 3, 4, 2, 5, 3, 4}, diff --git a/plugins/GSdx/GPUDrawScanlineCodeGenerator.h b/plugins/GSdx/GPUDrawScanlineCodeGenerator.h index 6e1d7f4256..423074b8bf 100644 --- a/plugins/GSdx/GPUDrawScanlineCodeGenerator.h +++ b/plugins/GSdx/GPUDrawScanlineCodeGenerator.h @@ -32,7 +32,7 @@ class GPUDrawScanlineCodeGenerator : public CodeGenerator void operator = (const GPUDrawScanlineCodeGenerator&); static const GSVector4i m_test[8]; - static const WORD m_dither[4][16]; + static const uint16 m_dither[4][16]; util::Cpu m_cpu; diff --git a/plugins/GSdx/GPUDrawingEnvironment.h b/plugins/GSdx/GPUDrawingEnvironment.h index e42064a450..c89ea4920a 100644 --- a/plugins/GSdx/GPUDrawingEnvironment.h +++ b/plugins/GSdx/GPUDrawingEnvironment.h @@ -55,21 +55,19 @@ public: DVRANGE.Y2 = 256; } - CRect GetDisplayRect() + GSVector4i GetDisplayRect() { static int s_width[] = {256, 320, 512, 640, 368, 384, 512, 640}; static int s_height[] = {240, 480}; - CRect r; + GSVector4i r; r.left = DAREA.X & ~7; // FIXME r.top = DAREA.Y; r.right = r.left + s_width[(STATUS.WIDTH1 << 2) | STATUS.WIDTH0]; r.bottom = r.top + (DVRANGE.Y2 - DVRANGE.Y1) * s_height[STATUS.HEIGHT] / 240; - r &= CRect(0, 0, 1024, 512); - - return r; + return r.rintersect(GSVector4i(0, 0, 1024, 512)); } int GetFPS() diff --git a/plugins/GSdx/GPULocalMemory.cpp b/plugins/GSdx/GPULocalMemory.cpp index f5a1b8a6ec..65a82716ba 100644 --- a/plugins/GSdx/GPULocalMemory.cpp +++ b/plugins/GSdx/GPULocalMemory.cpp @@ -21,22 +21,23 @@ #include "StdAfx.h" #include "GPULocalMemory.h" +#include "GSdx.h" const GSVector4i GPULocalMemory::m_xxxa(0x00008000); const GSVector4i GPULocalMemory::m_xxbx(0x00007c00); const GSVector4i GPULocalMemory::m_xgxx(0x000003e0); const GSVector4i GPULocalMemory::m_rxxx(0x0000001f); -GPULocalMemory::GPULocalMemory(const CSize& scale) +GPULocalMemory::GPULocalMemory() { - m_scale.cx = min(max(scale.cx, 0), 2); - m_scale.cy = min(max(scale.cy, 0), 2); + m_scale.x = min(max(theApp.GetConfig("scale_x", 0), 0), 2); + m_scale.y = min(max(theApp.GetConfig("scale_y", 0), 0), 2); // - int size = (1 << (12 + 11)) * sizeof(WORD); + int size = (1 << (12 + 11)) * sizeof(uint16); - m_vm = (WORD*)VirtualAlloc(NULL, size * 2, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + m_vm = (uint16*)VirtualAlloc(NULL, size * 2, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); memset(m_vm, 0, size); @@ -49,7 +50,7 @@ GPULocalMemory::GPULocalMemory(const CSize& scale) size = 256 * 256 * (1 + 1 + 4) * 32; - m_texture.buff[0] = (BYTE*)VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + m_texture.buff[0] = (uint8*)VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); m_texture.buff[1] = m_texture.buff[0] + 256 * 256 * 32; m_texture.buff[2] = m_texture.buff[1] + 256 * 256 * 32; @@ -61,8 +62,8 @@ GPULocalMemory::GPULocalMemory(const CSize& scale) { for(int x = 0; x < 16; x++, offset += 256 * 256) { - m_texture.page[0][y][x] = &((BYTE*)m_texture.buff[0])[offset]; - m_texture.page[1][y][x] = &((BYTE*)m_texture.buff[1])[offset]; + m_texture.page[0][y][x] = &((uint8*)m_texture.buff[0])[offset]; + m_texture.page[1][y][x] = &((uint8*)m_texture.buff[1])[offset]; } } @@ -70,7 +71,7 @@ GPULocalMemory::GPULocalMemory(const CSize& scale) { for(int x = 0; x < 16; x++, offset += 256 * 256) { - m_texture.page[2][y][x] = &((DWORD*)m_texture.buff[2])[offset]; + m_texture.page[2][y][x] = &((uint32*)m_texture.buff[2])[offset]; } } } @@ -82,18 +83,18 @@ GPULocalMemory::~GPULocalMemory() VirtualFree(m_texture.buff[0], 0, MEM_RELEASE); } -const WORD* GPULocalMemory::GetCLUT(int tp, int cx, int cy) +const uint16* GPULocalMemory::GetCLUT(int tp, int cx, int cy) { if(m_clut.dirty || m_clut.tp != tp || m_clut.cx != cx || m_clut.cy != cy) { - WORD* src = GetPixelAddressScaled(cx << 4, cy); - WORD* dst = m_clut.buff; + uint16* src = GetPixelAddressScaled(cx << 4, cy); + uint16* dst = m_clut.buff; - if(m_scale.cx == 0) + if(m_scale.x == 0) { memcpy(dst, src, (tp == 0 ? 16 : 256) * 2); } - else if(m_scale.cx == 1) + else if(m_scale.x == 1) { if(tp == 0) { @@ -110,7 +111,7 @@ const WORD* GPULocalMemory::GetCLUT(int tp, int cx, int cy) } } } - else if(m_scale.cx == 2) + else if(m_scale.x == 2) { if(tp == 0) { @@ -152,7 +153,7 @@ const void* GPULocalMemory::GetTexture(int tp, int tx, int ty) void* buff = m_texture.page[tp][ty][tx]; - UINT32 flag = 1 << tx; + uint32 flag = 1 << tx; if((m_texture.valid[tp][ty] & flag) == 0) { @@ -161,16 +162,16 @@ const void* GPULocalMemory::GetTexture(int tp, int tx, int ty) switch(tp) { case 0: - ReadPage4(tx, ty, (BYTE*)buff); + ReadPage4(tx, ty, (uint8*)buff); bpp = 4; break; case 1: - ReadPage8(tx, ty, (BYTE*)buff); + ReadPage8(tx, ty, (uint8*)buff); bpp = 8; break; case 2: case 3: - ReadPage16(tx, ty, (WORD*)buff); + ReadPage16(tx, ty, (uint16*)buff); bpp = 16; default: // FIXME: __assume(0); // vc9 generates bogus code in release mode @@ -185,7 +186,7 @@ const void* GPULocalMemory::GetTexture(int tp, int tx, int ty) return buff; } -void GPULocalMemory::Invalidate(const CRect& r) +void GPULocalMemory::Invalidate(const GSVector4i& r) { if(!m_clut.dirty) { @@ -207,7 +208,7 @@ void GPULocalMemory::Invalidate(const CRect& r) for(int x = 0, xe = min(r.right, 1024), i = 0; x < xe; x += 64, i++) { - DWORD flag = 1 << i; + uint32 flag = 1 << i; if(r.left >= x + 256) continue; @@ -224,14 +225,14 @@ void GPULocalMemory::Invalidate(const CRect& r) } } -void GPULocalMemory::FillRect(const CRect& r, WORD c) +void GPULocalMemory::FillRect(const GSVector4i& r, uint16 c) { Invalidate(r); - WORD* RESTRICT dst = GetPixelAddressScaled(r.left, r.top); + uint16* RESTRICT dst = GetPixelAddressScaled(r.left, r.top); - int w = r.Width() << m_scale.cx; - int h = r.Height() << m_scale.cy; + int w = r.width() << m_scale.x; + int h = r.height() << m_scale.y; int pitch = GetWidth(); @@ -244,32 +245,32 @@ void GPULocalMemory::FillRect(const CRect& r, WORD c) } } -void GPULocalMemory::WriteRect(const CRect& r, const WORD* RESTRICT src) +void GPULocalMemory::WriteRect(const GSVector4i& r, const uint16* RESTRICT src) { Invalidate(r); - WORD* RESTRICT dst = GetPixelAddressScaled(r.left, r.top); + uint16* RESTRICT dst = GetPixelAddressScaled(r.left, r.top); - int w = r.Width(); - int h = r.Height(); + int w = r.width(); + int h = r.height(); int pitch = GetWidth(); - if(m_scale.cx == 0) + if(m_scale.x == 0) { for(int j = 0; j < h; j++, src += w) { - for(int k = 1 << m_scale.cy; k >= 1; k--, dst += pitch) + for(int k = 1 << m_scale.y; k >= 1; k--, dst += pitch) { memcpy(dst, src, w * 2); } } } - else if(m_scale.cx == 1) + else if(m_scale.x == 1) { for(int j = 0; j < h; j++, src += w) { - for(int k = 1 << m_scale.cy; k >= 1; k--, dst += pitch) + for(int k = 1 << m_scale.y; k >= 1; k--, dst += pitch) { for(int i = 0; i < w; i++) { @@ -279,11 +280,11 @@ void GPULocalMemory::WriteRect(const CRect& r, const WORD* RESTRICT src) } } } - else if(m_scale.cx == 2) + else if(m_scale.x == 2) { for(int j = 0; j < h; j++, src += w) { - for(int k = 1 << m_scale.cy; k >= 1; k--, dst += pitch) + for(int k = 1 << m_scale.y; k >= 1; k--, dst += pitch) { for(int i = 0; i < w; i++) { @@ -301,23 +302,23 @@ void GPULocalMemory::WriteRect(const CRect& r, const WORD* RESTRICT src) } } -void GPULocalMemory::ReadRect(const CRect& r, WORD* RESTRICT dst) +void GPULocalMemory::ReadRect(const GSVector4i& r, uint16* RESTRICT dst) { - WORD* RESTRICT src = GetPixelAddressScaled(r.left, r.top); + uint16* RESTRICT src = GetPixelAddressScaled(r.left, r.top); - int w = r.Width(); - int h = r.Height(); + int w = r.width(); + int h = r.height(); - int pitch = GetWidth() << m_scale.cy; + int pitch = GetWidth() << m_scale.y; - if(m_scale.cx == 0) + if(m_scale.x == 0) { for(int j = 0; j < h; j++, src += pitch, dst += w) { memcpy(dst, src, w * 2); } } - else if(m_scale.cx == 1) + else if(m_scale.x == 1) { for(int j = 0; j < h; j++, src += pitch, dst += w) { @@ -327,7 +328,7 @@ void GPULocalMemory::ReadRect(const CRect& r, WORD* RESTRICT dst) } } } - else if(m_scale.cx == 2) + else if(m_scale.x == 2) { for(int j = 0; j < h; j++, src += pitch, dst += w) { @@ -343,31 +344,31 @@ void GPULocalMemory::ReadRect(const CRect& r, WORD* RESTRICT dst) } } -void GPULocalMemory::MoveRect(const CPoint& src, const CPoint& dst, int w, int h) +void GPULocalMemory::MoveRect(int sx, int sy, int dx, int dy, int w, int h) { - Invalidate(CRect(dst, CSize(w, h))); + Invalidate(GSVector4i(dx, dy, dx + w, dy + h)); - WORD* s = GetPixelAddressScaled(src.x, src.y); - WORD* d = GetPixelAddressScaled(dst.x, dst.y); + uint16* s = GetPixelAddressScaled(sx, sy); + uint16* d = GetPixelAddressScaled(dx, dy); - w <<= m_scale.cx; - h <<= m_scale.cy; + w <<= m_scale.x; + h <<= m_scale.y; int pitch = GetWidth(); for(int i = 0; i < h; i++, s += pitch, d += pitch) { - memcpy(d, s, w * sizeof(WORD)); + memcpy(d, s, w * sizeof(uint16)); } } -void GPULocalMemory::ReadPage4(int tx, int ty, BYTE* RESTRICT dst) +void GPULocalMemory::ReadPage4(int tx, int ty, uint8* RESTRICT dst) { - WORD* src = GetPixelAddressScaled(tx << 6, ty << 8); + uint16* src = GetPixelAddressScaled(tx << 6, ty << 8); - int pitch = GetWidth() << m_scale.cy; + int pitch = GetWidth() << m_scale.y; - if(m_scale.cx == 0) + if(m_scale.x == 0) { for(int j = 0; j < 256; j++, src += pitch, dst += 256) { @@ -380,7 +381,7 @@ void GPULocalMemory::ReadPage4(int tx, int ty, BYTE* RESTRICT dst) } } } - else if(m_scale.cx == 1) + else if(m_scale.x == 1) { for(int j = 0; j < 256; j++, src += pitch, dst += 256) { @@ -393,7 +394,7 @@ void GPULocalMemory::ReadPage4(int tx, int ty, BYTE* RESTRICT dst) } } } - else if(m_scale.cx == 2) + else if(m_scale.x == 2) { for(int j = 0; j < 256; j++, src += pitch, dst += 256) { @@ -412,36 +413,36 @@ void GPULocalMemory::ReadPage4(int tx, int ty, BYTE* RESTRICT dst) } } -void GPULocalMemory::ReadPage8(int tx, int ty, BYTE* RESTRICT dst) +void GPULocalMemory::ReadPage8(int tx, int ty, uint8* RESTRICT dst) { - WORD* src = GetPixelAddressScaled(tx << 6, ty << 8); + uint16* src = GetPixelAddressScaled(tx << 6, ty << 8); - int pitch = GetWidth() << m_scale.cy; + int pitch = GetWidth() << m_scale.y; - if(m_scale.cx == 0) + if(m_scale.x == 0) { for(int j = 0; j < 256; j++, src += pitch, dst += 256) { memcpy(dst, src, 256); } } - else if(m_scale.cx == 1) + else if(m_scale.x == 1) { for(int j = 0; j < 256; j++, src += pitch, dst += 256) { for(int i = 0; i < 128; i++) { - ((WORD*)dst)[i] = src[i * 2]; + ((uint16*)dst)[i] = src[i * 2]; } } } - else if(m_scale.cx == 2) + else if(m_scale.x == 2) { for(int j = 0; j < 256; j++, src += pitch, dst += 256) { for(int i = 0; i < 128; i++) { - ((WORD*)dst)[i] = src[i * 4]; + ((uint16*)dst)[i] = src[i * 4]; } } } @@ -451,20 +452,20 @@ void GPULocalMemory::ReadPage8(int tx, int ty, BYTE* RESTRICT dst) } } -void GPULocalMemory::ReadPage16(int tx, int ty, WORD* RESTRICT dst) +void GPULocalMemory::ReadPage16(int tx, int ty, uint16* RESTRICT dst) { - WORD* src = GetPixelAddressScaled(tx << 6, ty << 8); + uint16* src = GetPixelAddressScaled(tx << 6, ty << 8); - int pitch = GetWidth() << m_scale.cy; + int pitch = GetWidth() << m_scale.y; - if(m_scale.cx == 0) + if(m_scale.x == 0) { for(int j = 0; j < 256; j++, src += pitch, dst += 256) { memcpy(dst, src, 512); } } - else if(m_scale.cx == 1) + else if(m_scale.x == 1) { for(int j = 0; j < 256; j++, src += pitch, dst += 256) { @@ -474,7 +475,7 @@ void GPULocalMemory::ReadPage16(int tx, int ty, WORD* RESTRICT dst) } } } - else if(m_scale.cx == 2) + else if(m_scale.x == 2) { for(int j = 0; j < 256; j++, src += pitch, dst += 256) { @@ -490,9 +491,9 @@ void GPULocalMemory::ReadPage16(int tx, int ty, WORD* RESTRICT dst) } } -void GPULocalMemory::ReadFrame32(const CRect& r, DWORD* RESTRICT dst, bool rgb24) +void GPULocalMemory::ReadFrame32(const GSVector4i& r, uint32* RESTRICT dst, bool rgb24) { - WORD* src = GetPixelAddress(r.left, r.top); + uint16* src = GetPixelAddress(r.left, r.top); int pitch = GetWidth(); @@ -500,19 +501,19 @@ void GPULocalMemory::ReadFrame32(const CRect& r, DWORD* RESTRICT dst, bool rgb24 { for(int i = r.top; i < r.bottom; i++, src += pitch, dst += pitch) { - Expand24(src, dst, r.Width()); + Expand24(src, dst, r.width()); } } else { for(int i = r.top; i < r.bottom; i++, src += pitch, dst += pitch) { - Expand16(src, dst, r.Width()); + Expand16(src, dst, r.width()); } } } -void GPULocalMemory::Expand16(const WORD* RESTRICT src, DWORD* RESTRICT dst, int pixels) +void GPULocalMemory::Expand16(const uint16* RESTRICT src, uint32* RESTRICT dst, int pixels) { GSVector4i rm = m_rxxx; GSVector4i gm = m_xgxx; @@ -534,11 +535,11 @@ void GPULocalMemory::Expand16(const WORD* RESTRICT src, DWORD* RESTRICT dst, int } } -void GPULocalMemory::Expand24(const WORD* RESTRICT src, DWORD* RESTRICT dst, int pixels) +void GPULocalMemory::Expand24(const uint16* RESTRICT src, uint32* RESTRICT dst, int pixels) { - BYTE* s = (BYTE*)src; + uint8* s = (uint8*)src; - if(m_scale.cx == 0) + if(m_scale.x == 0) { for(int i = 0; i < pixels; i += 2, s += 6) { @@ -546,7 +547,7 @@ void GPULocalMemory::Expand24(const WORD* RESTRICT src, DWORD* RESTRICT dst, int dst[i + 1] = (s[5] << 16) | (s[4] << 8) | s[3]; } } - else if(m_scale.cx == 1) + else if(m_scale.x == 1) { for(int i = 0; i < pixels; i += 4, s += 12) { @@ -554,7 +555,7 @@ void GPULocalMemory::Expand24(const WORD* RESTRICT src, DWORD* RESTRICT dst, int dst[i + 2] = dst[i + 3] = (s[9] << 16) | (s[8] << 8) | s[5]; } } - else if(m_scale.cx == 2) + else if(m_scale.x == 2) { for(int i = 0; i < pixels; i += 8, s += 24) { @@ -568,23 +569,25 @@ void GPULocalMemory::Expand24(const WORD* RESTRICT src, DWORD* RESTRICT dst, int } } -void GPULocalMemory::SaveBMP(LPCTSTR path, CRect r, int tp, int cx, int cy) +void GPULocalMemory::SaveBMP(const string& path, const GSVector4i& r2, int tp, int cx, int cy) { - r.left <<= m_scale.cx; - r.top <<= m_scale.cy; - r.right <<= m_scale.cx; - r.bottom <<= m_scale.cy; + GSVector4i r; + + r.left = r2.left << m_scale.x; + r.top = r2.top << m_scale.y; + r.right = r2.right << m_scale.x; + r.bottom = r2.bottom << m_scale.y; r.left &= ~1; r.right &= ~1; - if(FILE* fp = _tfopen(path, _T("wb"))) + if(FILE* fp = fopen(path.c_str(), "wb")) { BITMAPINFOHEADER bih; memset(&bih, 0, sizeof(bih)); bih.biSize = sizeof(bih); - bih.biWidth = r.Width(); - bih.biHeight = r.Height(); + bih.biWidth = r.width(); + bih.biHeight = r.height(); bih.biPlanes = 1; bih.biBitCount = 32; bih.biCompression = BI_RGB; @@ -602,10 +605,10 @@ void GPULocalMemory::SaveBMP(LPCTSTR path, CRect r, int tp, int cx, int cy) int pitch = GetWidth(); - WORD* buff = (WORD*)_aligned_malloc(pitch * sizeof(WORD), 16); - DWORD* buff32 = (DWORD*)_aligned_malloc(pitch * sizeof(DWORD), 16); - WORD* src = GetPixelAddress(r.left, r.bottom - 1); - const WORD* clut = GetCLUT(tp, cx, cy); + uint16* buff = (uint16*)_aligned_malloc(pitch * sizeof(WORD), 16); + uint32* buff32 = (uint32*)_aligned_malloc(pitch * sizeof(uint32), 16); + uint16* src = GetPixelAddress(r.left, r.bottom - 1); + const uint16* clut = GetCLUT(tp, cx, cy); for(int j = r.bottom - 1; j >= r.top; j--, src -= pitch) { @@ -613,26 +616,26 @@ void GPULocalMemory::SaveBMP(LPCTSTR path, CRect r, int tp, int cx, int cy) { case 0: // 4 bpp - for(int i = 0, k = r.Width() / 2; i < k; i++) + for(int i = 0, k = r.width() / 2; i < k; i++) { - buff[i * 2 + 0] = clut[((BYTE*)src)[i] & 0xf]; - buff[i * 2 + 1] = clut[((BYTE*)src)[i] >> 4]; + buff[i * 2 + 0] = clut[((uint8*)src)[i] & 0xf]; + buff[i * 2 + 1] = clut[((uint8*)src)[i] >> 4]; } break; case 1: // 8 bpp - for(int i = 0, k = r.Width(); i < k; i++) + for(int i = 0, k = r.width(); i < k; i++) { - buff[i] = clut[((BYTE*)src)[i]]; + buff[i] = clut[((uint8*)src)[i]]; } break; case 2: // 16 bpp; - for(int i = 0, k = r.Width(); i < k; i++) + for(int i = 0, k = r.width(); i < k; i++) { buff[i] = src[i]; } @@ -646,14 +649,14 @@ void GPULocalMemory::SaveBMP(LPCTSTR path, CRect r, int tp, int cx, int cy) break; } - Expand16(buff, buff32, r.Width()); + Expand16(buff, buff32, r.width()); - for(int i = 0, k = r.Width(); i < k; i++) + for(int i = 0, k = r.width(); i < k; i++) { buff32[i] = (buff32[i] & 0xff00ff00) | ((buff32[i] & 0x00ff0000) >> 16) | ((buff32[i] & 0x000000ff) << 16); } - fwrite(buff32, 1, r.Width() * 4, fp); + fwrite(buff32, 1, r.width() * 4, fp); } _aligned_free(buff); diff --git a/plugins/GSdx/GPULocalMemory.h b/plugins/GSdx/GPULocalMemory.h index 4d7111e7d4..e693bad81a 100644 --- a/plugins/GSdx/GPULocalMemory.h +++ b/plugins/GSdx/GPULocalMemory.h @@ -31,55 +31,56 @@ class GPULocalMemory static const GSVector4i m_xgxx; static const GSVector4i m_rxxx; - WORD* m_vm; + uint16* m_vm; struct { - WORD* buff; + uint16* buff; int tp, cx, cy; bool dirty; } m_clut; struct { - BYTE* buff[3]; + uint8* buff[3]; void* page[3][2][16]; - WORD valid[3][2]; + uint16 valid[3][2]; } m_texture; - CSize m_scale; + GSVector2i m_scale; public: - GPULocalMemory(const CSize& scale); + GPULocalMemory(); virtual ~GPULocalMemory(); - CSize GetScale() {return m_scale;} - int GetWidth() {return 1 << (10 + m_scale.cx);} - int GetHeight() {return 1 << (9 + m_scale.cy);} + GSVector2i GetScale() {return m_scale;} - WORD* GetPixelAddress(int x, int y) const {return &m_vm[(y << (10 + m_scale.cx)) + x];} - WORD* GetPixelAddressScaled(int x, int y) const {return &m_vm[((y << m_scale.cy) << (10 + m_scale.cx)) + (x << m_scale.cx)];} + int GetWidth() {return 1 << (10 + m_scale.x);} + int GetHeight() {return 1 << (9 + m_scale.y);} - const WORD* GetCLUT(int tp, int cx, int cy); + uint16* GetPixelAddress(int x, int y) const {return &m_vm[(y << (10 + m_scale.x)) + x];} + uint16* GetPixelAddressScaled(int x, int y) const {return &m_vm[((y << m_scale.y) << (10 + m_scale.x)) + (x << m_scale.x)];} + + const uint16* GetCLUT(int tp, int cx, int cy); const void* GetTexture(int tp, int tx, int ty); - void Invalidate(const CRect& r); + void Invalidate(const GSVector4i& r); - void FillRect(const CRect& r, WORD c); - void WriteRect(const CRect& r, const WORD* RESTRICT src); - void ReadRect(const CRect& r, WORD* RESTRICT dst); - void MoveRect(const CPoint& src, const CPoint& dst, int w, int h); + void FillRect(const GSVector4i& r, uint16 c); + void WriteRect(const GSVector4i& r, const uint16* RESTRICT src); + void ReadRect(const GSVector4i& r, uint16* RESTRICT dst); + void MoveRect(int sx, int sy, int dx, int dy, int w, int h); - void ReadPage4(int tx, int ty, BYTE* RESTRICT dst); - void ReadPage8(int tx, int ty, BYTE* RESTRICT dst); - void ReadPage16(int tx, int ty, WORD* RESTRICT dst); + void ReadPage4(int tx, int ty, uint8* RESTRICT dst); + void ReadPage8(int tx, int ty, uint8* RESTRICT dst); + void ReadPage16(int tx, int ty, uint16* RESTRICT dst); - void ReadFrame32(const CRect& r, DWORD* RESTRICT dst, bool rgb24); + void ReadFrame32(const GSVector4i& r, uint32* RESTRICT dst, bool rgb24); - void Expand16(const WORD* RESTRICT src, DWORD* RESTRICT dst, int pixels); - void Expand24(const WORD* RESTRICT src, DWORD* RESTRICT dst, int pixels); + void Expand16(const uint16* RESTRICT src, uint32* RESTRICT dst, int pixels); + void Expand24(const uint16* RESTRICT src, uint32* RESTRICT dst, int pixels); - void SaveBMP(LPCTSTR path, CRect r, int tp, int cx, int cy); + void SaveBMP(const string& path, const GSVector4i& r, int tp, int cx, int cy); }; #pragma warning(default: 4244) \ No newline at end of file diff --git a/plugins/GSdx/GPURenderer.cpp b/plugins/GSdx/GPURenderer.cpp index 8680530c07..4e2ba0d3a0 100644 --- a/plugins/GSdx/GPURenderer.cpp +++ b/plugins/GSdx/GPURenderer.cpp @@ -21,5 +21,196 @@ #include "StdAfx.h" #include "GPURenderer.h" +#include "GSdx.h" + +map GPURenderer::m_wnd2gpu; + +GPURenderer::GPURenderer(GSDevice* dev) + : m_dev(dev) + , m_hWnd(NULL) + , m_wndproc(NULL) +{ + m_filter = theApp.GetConfig("filter", 0); + m_dither = theApp.GetConfig("dithering", 1); + m_aspectratio = theApp.GetConfig("AspectRatio", 1); + m_vsync = !!theApp.GetConfig("vsync", 0); + m_scale = m_mem.GetScale(); +} + +GPURenderer::~GPURenderer() +{ + if(m_wndproc) + { + SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_wndproc); + + m_wnd2gpu.erase(m_hWnd); + } +} + +bool GPURenderer::Create(HWND hWnd) +{ + // TODO: move subclassing inside GSWnd::Attach + + m_hWnd = hWnd; + + m_wndproc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC); + SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)WndProc); + + if(!m_wnd.Attach(m_hWnd)) + { + return false; + } + + m_wnd2gpu[hWnd] = this; + + DWORD style = GetWindowLong(hWnd, GWL_STYLE); + style |= WS_OVERLAPPEDWINDOW; + SetWindowLong(hWnd, GWL_STYLE, style); + + m_wnd.Show(); + + if(!m_dev->Create(&m_wnd, m_vsync)) + { + return false; + } + + Reset(); + + return true; +} + +bool GPURenderer::Merge() +{ + GSTexture* st[2] = {GetOutput(), NULL}; + + if(!st[0]) + { + return false; + } + + GSVector2i s = st[0]->GetSize(); + + GSVector4 sr[2]; + GSVector4 dr[2]; + + sr[0] = GSVector4(0, 0, 1, 1); + dr[0] = GSVector4(0, 0, s.x, s.y); + + m_dev->Merge(st, sr, dr, s, 1, 1, GSVector4(0, 0, 0, 1)); + + return true; +} + +void GPURenderer::VSync() +{ + GSPerfMonAutoTimer pmat(m_perfmon); + + m_perfmon.Put(GSPerfMon::Frame); + + // m_env.STATUS.LCF = ~m_env.STATUS.LCF; // ? + + if(!IsWindow(m_hWnd)) return; + + Flush(); + + if(!Merge()) return; + + // osd + + if((m_perfmon.GetFrame() & 0x1f) == 0) + { + m_perfmon.Update(); + + double fps = 1000.0f / m_perfmon.Get(GSPerfMon::Frame); + + GSVector4i r = m_env.GetDisplayRect(); + + int w = r.width() << m_scale.x; + int h = r.height() << m_scale.y; + + string s = format( + "%I64d | %d x %d | %.2f fps (%d%%) | %d/%d | %d%% CPU | %.2f | %.2f", + m_perfmon.GetFrame(), w, h, fps, (int)(100.0 * fps / m_env.GetFPS()), + (int)m_perfmon.Get(GSPerfMon::Prim), + (int)m_perfmon.Get(GSPerfMon::Draw), + m_perfmon.CPU(), + m_perfmon.Get(GSPerfMon::Swizzle) / 1024, + m_perfmon.Get(GSPerfMon::Unswizzle) / 1024 + ); + + double fillrate = m_perfmon.Get(GSPerfMon::Fillrate); + + if(fillrate > 0) + { + s = format("%s | %.2f mpps", s.c_str(), fps * fillrate / (1024 * 1024)); + } + + SetWindowText(m_hWnd, s.c_str()); + } + + if(m_dev->IsLost()) + { + ResetDevice(); + } + + GSVector4i r; + + GetClientRect(m_hWnd, r); + + m_dev->Present(r.fit(m_aspectratio), 0); +} + +bool GPURenderer::MakeSnapshot(const string& path) +{ + time_t t = time(NULL); + + char buff[16]; + + if(!strftime(buff, sizeof(buff), "%Y%m%d%H%M%S", localtime(&t))) + { + return false; + } + + if(GSTexture* t = m_dev->GetCurrent()) + { + return t->Save(format("%s_%s.bmp", path.c_str(), buff)); + } + + return false; +} + +LRESULT CALLBACK GPURenderer::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + map::iterator i = m_wnd2gpu.find(hWnd); + + if(i != m_wnd2gpu.end()) + { + return i->second->OnMessage(message, wParam, lParam); + } + + ASSERT(0); + + return 0; +} + +LRESULT GPURenderer::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + if(message == WM_KEYUP) + { + switch(wParam) + { + case VK_DELETE: + m_filter = (m_filter + 1) % 3; + return 0; + case VK_END: + m_dither = m_dither ? 0 : 1; + return 0; + case VK_NEXT: + m_aspectratio = (m_aspectratio + 1) % 3; + return 0; + } + } + + return CallWindowProc(m_wndproc, m_hWnd, message, wParam, lParam); +} -CAtlMap GPURendererBase::m_wnd2gpu; \ No newline at end of file diff --git a/plugins/GSdx/GPURenderer.h b/plugins/GSdx/GPURenderer.h index 17df468a44..45940ce8b9 100644 --- a/plugins/GSdx/GPURenderer.h +++ b/plugins/GSdx/GPURenderer.h @@ -23,107 +23,45 @@ #include "GPUState.h" #include "GSVertexList.h" +#include "GSDevice.h" -struct GPURendererSettings +class GPURenderer : public GPUState { + bool Merge(); + +protected: + GSDevice* m_dev; int m_filter; int m_dither; int m_aspectratio; bool m_vsync; - CSize m_scale; -}; + GSVector2i m_scale; + + virtual void ResetDevice() {} + virtual GSTexture* GetOutput() = 0; -class GPURendererBase : public GPUState, protected GPURendererSettings -{ -protected: HWND m_hWnd; WNDPROC m_wndproc; - static CAtlMap m_wnd2gpu; + static map m_wnd2gpu; + GSWnd m_wnd; - static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) - { - if(CAtlMap::CPair* pair = m_wnd2gpu.Lookup(hWnd)) - { - return pair->m_value->OnMessage(message, wParam, lParam); - } + static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); - ASSERT(0); - - return 0; - } - - LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam) - { - if(message == WM_KEYUP) - { - switch(wParam) - { - case VK_DELETE: - m_filter = (m_filter + 1) % 3; - return 0; - case VK_END: - m_dither = m_dither ? 0 : 1; - return 0; - case VK_NEXT: - m_aspectratio = (m_aspectratio + 1) % 3; - return 0; - } - } - - return m_wndproc(m_hWnd, message, wParam, lParam); - } + LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); public: - GPURendererBase(const GPURendererSettings& rs) - : GPUState(rs.m_scale) - , m_hWnd(NULL) - , m_wndproc(NULL) - { - m_filter = rs.m_filter; - m_dither = rs.m_dither; - m_aspectratio = rs.m_aspectratio; - m_vsync = rs.m_vsync; - m_scale = m_mem.GetScale(); - } + GPURenderer(GSDevice* dev); + virtual ~GPURenderer(); - virtual ~GPURendererBase() - { - if(m_wndproc) - { - SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_wndproc); - - m_wnd2gpu.RemoveKey(m_hWnd); - } - } - - virtual bool Create(HWND hWnd) - { - m_hWnd = hWnd; - - m_wndproc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC); - SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)WndProc); - m_wnd2gpu.SetAt(hWnd, this); - - DWORD style = GetWindowLong(hWnd, GWL_STYLE); - style |= WS_OVERLAPPEDWINDOW; - SetWindowLong(hWnd, GWL_STYLE, style); - UpdateWindow(hWnd); - - ShowWindow(hWnd, SW_SHOWNORMAL); - - return true; - } - - virtual void VSync() = 0; - virtual bool MakeSnapshot(LPCTSTR path) = 0; + virtual bool Create(HWND hWnd); + virtual void VSync(); + virtual bool MakeSnapshot(const string& path); }; -template -class GPURenderer : public GPURendererBase +template +class GPURendererT : public GPURenderer { protected: - typedef typename Device::Texture Texture; - Vertex* m_vertices; int m_count; int m_maxcount; @@ -137,66 +75,6 @@ protected: __super::Reset(); } - void VertexKick() - { - if(m_vl.GetCount() < m_env.PRIM.VTX) - { - return; - } - - if(m_count > m_maxcount) - { - m_maxcount = max(10000, m_maxcount * 3/2); - m_vertices = (Vertex*)_aligned_realloc(m_vertices, sizeof(Vertex) * m_maxcount, 16); - m_maxcount -= 100; - } - - Vertex* v = &m_vertices[m_count]; - - int count = 0; - - switch(m_env.PRIM.TYPE) - { - case GPU_POLYGON: - m_vl.GetAt(0, v[0]); - m_vl.GetAt(1, v[1]); - m_vl.GetAt(2, v[2]); - m_vl.RemoveAll(); - count = 3; - break; - case GPU_LINE: - m_vl.GetAt(0, v[0]); - m_vl.GetAt(1, v[1]); - m_vl.RemoveAll(); - count = 2; - break; - case GPU_SPRITE: - m_vl.GetAt(0, v[0]); - m_vl.GetAt(1, v[1]); - m_vl.RemoveAll(); - count = 2; - break; - default: - ASSERT(0); - m_vl.RemoveAll(); - count = 0; - break; - } - - (this->*m_fpDrawingKickHandlers[m_env.PRIM.TYPE])(v, count); - - m_count += count; - } - - typedef void (GPURenderer::*DrawingKickHandler)(Vertex* v, int& count); - - DrawingKickHandler m_fpDrawingKickHandlers[4]; - - void DrawingKickNull(Vertex* v, int& count) - { - ASSERT(0); - } - void ResetPrim() { m_vl.RemoveAll(); @@ -207,20 +85,18 @@ protected: if(m_count > 0) { /* - Dump(_T("db")); + Dump("db"); if(m_env.PRIM.TME) { - CRect r; + GSVector4i r; r.left = m_env.STATUS.TX << 6; r.top = m_env.STATUS.TY << 8; r.right = r.left + 256; r.bottom = r.top + 256; - CString str; - str.Format(_T("da_%d_%d_%d_%d_%d"), m_env.STATUS.TP, r); - Dump(str, m_env.STATUS.TP, r, false); + Dump(format("da_%d_%d_%d_%d_%d", m_env.STATUS.TP, r).c_str(), m_env.STATUS.TP, r, false); } */ @@ -228,167 +104,75 @@ protected: m_count = 0; - //Dump(_T("dc"), false); + //Dump("dc", false); } } - virtual void ResetDevice() {} - virtual void Draw() = 0; - virtual bool GetOutput(Texture& t) = 0; - - bool Merge() + void GrowVertexBuffer() { - Texture st[2]; - - if(!GetOutput(st[0])) - { - return false; - } - - CSize s; - - s.cx = st[0].GetWidth(); - s.cy = st[0].GetHeight(); - - GSVector4 sr[2]; - - sr[0].x = 0; - sr[0].y = 0; - sr[0].z = 1.0f; - sr[0].w = 1.0f; - - GSVector4 dr[2]; - - dr[0].x = 0; - dr[0].y = 0; - dr[0].z = (float)s.cx; - dr[0].w = (float)s.cy; - - GSVector4 c(0, 0, 0, 1); - - m_dev.Merge(st, sr, dr, s, 1, 1, c); - - return true; - } - -public: - Device m_dev; - -public: - GPURenderer(const GPURendererSettings& rs) - : GPURendererBase(rs) - , m_count(0) - , m_maxcount(10000) - { - m_vertices = (Vertex*)_aligned_malloc(sizeof(Vertex) * m_maxcount, 16); + m_maxcount = max(10000, m_maxcount * 3/2); + m_vertices = (Vertex*)_aligned_realloc(m_vertices, sizeof(Vertex) * m_maxcount, 16); m_maxcount -= 100; - - for(int i = 0; i < countof(m_fpDrawingKickHandlers); i++) - { - m_fpDrawingKickHandlers[i] = &GPURenderer::DrawingKickNull; - } } - virtual ~GPURenderer() + __forceinline Vertex* DrawingKick(int& count) + { + count = (int)m_env.PRIM.VTX; + + if(m_vl.GetCount() < count) + { + return NULL; + } + + if(m_count >= m_maxcount) + { + GrowVertexBuffer(); + } + + Vertex* v = &m_vertices[m_count]; + + switch(m_env.PRIM.TYPE) + { + case GPU_POLYGON: + m_vl.GetAt(0, v[0]); + m_vl.GetAt(1, v[1]); + m_vl.GetAt(2, v[2]); + m_vl.RemoveAll(); + break; + case GPU_LINE: + m_vl.GetAt(0, v[0]); + m_vl.GetAt(1, v[1]); + m_vl.RemoveAll(); + break; + case GPU_SPRITE: + m_vl.GetAt(0, v[0]); + m_vl.GetAt(1, v[1]); + m_vl.RemoveAll(); + break; + default: + ASSERT(0); + m_vl.RemoveAll(); + return NULL; + } + + return v; + } + + virtual void VertexKick() = 0; + + virtual void Draw() = 0; + +public: + GPURendererT(GSDevice* dev) + : GPURenderer(dev) + , m_count(0) + , m_maxcount(0) + , m_vertices(NULL) + { + } + + virtual ~GPURendererT() { if(m_vertices) _aligned_free(m_vertices); } - - virtual bool Create(HWND hWnd) - { - if(!__super::Create(hWnd)) - { - return false; - } - - if(!m_dev.Create(hWnd, m_vsync)) - { - return false; - } - - Reset(); - - return true; - } - - virtual void VSync() - { - GSPerfMonAutoTimer pmat(m_perfmon); - - // m_env.STATUS.LCF = ~m_env.STATUS.LCF; // ? - - if(!IsWindow(m_hWnd)) - { - return; - } - - Flush(); - - m_perfmon.Put(GSPerfMon::Frame); - - if(!Merge()) - { - return; - } - - // osd - - static UINT64 s_frame = 0; - static CString s_stats; - - if(m_perfmon.GetFrame() - s_frame >= 30) - { - m_perfmon.Update(); - - s_frame = m_perfmon.GetFrame(); - - double fps = 1000.0f / m_perfmon.Get(GSPerfMon::Frame); - - CRect r = m_env.GetDisplayRect(); - - int w = r.Width() << m_scale.cx; - int h = r.Height() << m_scale.cy; - - s_stats.Format( - _T("%I64d | %d x %d | %.2f fps (%d%%) | %d/%d | %d%% CPU | %.2f | %.2f"), - m_perfmon.GetFrame(), w, h, fps, (int)(100.0 * fps / m_env.GetFPS()), - (int)m_perfmon.Get(GSPerfMon::Prim), - (int)m_perfmon.Get(GSPerfMon::Draw), - m_perfmon.CPU(), - m_perfmon.Get(GSPerfMon::Swizzle) / 1024, - m_perfmon.Get(GSPerfMon::Unswizzle) / 1024 - ); - - double fillrate = m_perfmon.Get(GSPerfMon::Fillrate); - - if(fillrate > 0) - { - s_stats.Format(_T("%s | %.2f mpps"), CString(s_stats), fps * fillrate / (1024 * 1024)); - } - - SetWindowText(m_hWnd, s_stats); - } - - if(m_dev.IsLost()) - { - ResetDevice(); - } - - CRect r; - - GetClientRect(m_hWnd, &r); - - GSUtil::FitRect(r, m_aspectratio); - - m_dev.Present(r); - } - - virtual bool MakeSnapshot(LPCTSTR path) - { - CString fn; - - fn.Format(_T("%s_%s"), path, CTime::GetCurrentTime().Format(_T("%Y%m%d%H%M%S"))); - - return m_dev.SaveCurrent(fn + _T(".bmp")); - } }; diff --git a/plugins/GSdx/GPURendererSW.cpp b/plugins/GSdx/GPURendererSW.cpp index 71e1d083f6..c4b63199c2 100644 --- a/plugins/GSdx/GPURendererSW.cpp +++ b/plugins/GSdx/GPURendererSW.cpp @@ -21,3 +21,190 @@ #include "StdAfx.h" #include "GPURendererSW.h" +#include "GSdx.h" + +GPURendererSW::GPURendererSW(GSDevice* dev) + : GPURendererT(dev) + , m_texture(NULL) +{ + m_rl.Create(this, theApp.GetConfig("swthreads", 1)); +} + +GPURendererSW::~GPURendererSW() +{ +} + +void GPURendererSW::ResetDevice() +{ + delete m_texture; + + m_texture = NULL; +} + +GSTexture* GPURendererSW::GetOutput() +{ + GSVector4i r = m_env.GetDisplayRect(); + + r.left <<= m_scale.x; + r.top <<= m_scale.y; + r.right <<= m_scale.x; + r.bottom <<= m_scale.y; + + // TODO + static uint32* buff = (uint32*)_aligned_malloc(m_mem.GetWidth() * m_mem.GetHeight() * sizeof(uint32), 16); + + m_mem.ReadFrame32(r, buff, !!m_env.STATUS.ISRGB24); + + int w = r.width(); + int h = r.height(); + + if(m_texture) + { + if(m_texture->GetWidth() != w || m_texture->GetHeight() != h) + { + delete m_texture; + + m_texture = NULL; + } + } + + if(!m_texture) + { + m_texture = m_dev->CreateTexture(w, h); + + if(!m_texture) + { + return NULL; + } + } + + m_texture->Update(r.rsize(), buff, m_mem.GetWidth() * sizeof(uint32)); + + return m_texture; +} + +void GPURendererSW::Draw() +{ + const GPUDrawingEnvironment& env = m_env; + + // + + GPUScanlineParam p; + + p.sel.key = 0; + p.sel.iip = env.PRIM.IIP; + p.sel.me = env.STATUS.ME; + + if(env.PRIM.ABE) + { + p.sel.abe = env.PRIM.ABE; + p.sel.abr = env.STATUS.ABR; + } + + p.sel.tge = env.PRIM.TGE; + + if(env.PRIM.TME) + { + p.sel.tme = env.PRIM.TME; + p.sel.tlu = env.STATUS.TP < 2; + p.sel.twin = (env.TWIN.u32 & 0xfffff) != 0; + p.sel.ltf = m_filter == 1 && env.PRIM.TYPE == GPU_POLYGON || m_filter == 2 ? 1 : 0; + + const void* t = m_mem.GetTexture(env.STATUS.TP, env.STATUS.TX, env.STATUS.TY); + + if(!t) {ASSERT(0); return;} + + p.tex = t; + p.clut = m_mem.GetCLUT(env.STATUS.TP, env.CLUT.X, env.CLUT.Y); + } + + p.sel.dtd = m_dither ? env.STATUS.DTD : 0; + p.sel.md = env.STATUS.MD; + p.sel.sprite = env.PRIM.TYPE == GPU_SPRITE; + p.sel.scalex = m_mem.GetScale().x; + + // + + GSRasterizerData data; + + data.vertices = m_vertices; + data.count = m_count; + data.param = &p; + + data.scissor.left = (int)m_env.DRAREATL.X << m_scale.x; + data.scissor.top = (int)m_env.DRAREATL.Y << m_scale.y; + data.scissor.right = min((int)(m_env.DRAREABR.X + 1) << m_scale.x, m_mem.GetWidth()); + data.scissor.bottom = min((int)(m_env.DRAREABR.Y + 1) << m_scale.y, m_mem.GetHeight()); + + switch(env.PRIM.TYPE) + { + case GPU_POLYGON: data.primclass = GS_TRIANGLE_CLASS; break; + case GPU_LINE: data.primclass = GS_LINE_CLASS; break; + case GPU_SPRITE: data.primclass = GS_SPRITE_CLASS; break; + default: __assume(0); + } + + m_rl.Draw(&data); + + GSRasterizerStats stats; + + m_rl.GetStats(stats); + + m_perfmon.Put(GSPerfMon::Draw, 1); + m_perfmon.Put(GSPerfMon::Prim, stats.prims); + m_perfmon.Put(GSPerfMon::Fillrate, stats.pixels); + + // TODO + + { + GSVector4 tl(+1e10f); + GSVector4 br(-1e10f); + + for(int i = 0, j = m_count; i < j; i++) + { + GSVector4 p = m_vertices[i].p; + + tl = tl.minv(p); + br = br.maxv(p); + } + + GSVector4i r = GSVector4i(tl.xyxy(br)).rintersect(data.scissor); + + r.left >>= m_scale.x; + r.top >>= m_scale.y; + r.right >>= m_scale.x; + r.bottom >>= m_scale.y; + + Invalidate(r); + } +} + +void GPURendererSW::VertexKick() +{ + GSVertexSW& dst = m_vl.AddTail(); + + // TODO: x/y + off.x/y should wrap around at +/-1024 + + int x = (int)(m_v.XY.X + m_env.DROFF.X) << m_scale.x; + int y = (int)(m_v.XY.Y + m_env.DROFF.Y) << m_scale.y; + + int s = m_v.UV.X; + int t = m_v.UV.Y; + + GSVector4 pt(x, y, s, t); + + dst.p = pt.xyxy(GSVector4::zero()); + dst.t = (pt.zwzw(GSVector4::zero()) + GSVector4(0.125f)) * 256.0f; + // dst.c = GSVector4(m_v.RGB.u32) * 128.0f; + dst.c = GSVector4(GSVector4i::load((int)m_v.RGB.u32).u8to32() << 7); + + int count = 0; + + if(GSVertexSW* v = DrawingKick(count)) + { + // TODO + + m_count += count; + } +} + diff --git a/plugins/GSdx/GPURendererSW.h b/plugins/GSdx/GPURendererSW.h index 2ee2599b29..aef5a140b1 100644 --- a/plugins/GSdx/GPURendererSW.h +++ b/plugins/GSdx/GPURendererSW.h @@ -24,205 +24,18 @@ #include "GPURenderer.h" #include "GPUDrawScanline.h" -template -class GPURendererSW : public GPURenderer +class GPURendererSW : public GPURendererT { protected: GSRasterizerList m_rl; - Texture m_texture; + GSTexture* m_texture; - void ResetDevice() - { - m_texture = Texture(); - } - - bool GetOutput(Texture& t) - { - CRect r = m_env.GetDisplayRect(); - - r.left <<= m_scale.cx; - r.top <<= m_scale.cy; - r.right <<= m_scale.cx; - r.bottom <<= m_scale.cy; - - // TODO - static DWORD* buff = (DWORD*)_aligned_malloc(m_mem.GetWidth() * m_mem.GetHeight() * sizeof(DWORD), 16); - - m_mem.ReadFrame32(r, buff, !!m_env.STATUS.ISRGB24); - - r.OffsetRect(-r.TopLeft()); - - if(m_texture.GetWidth() != r.Width() || m_texture.GetHeight() != r.Height()) - { - m_texture = Texture(); - } - - if(!m_texture && !m_dev.CreateTexture(m_texture, r.Width(), r.Height())) - { - return false; - } - - m_texture.Update(r, buff, m_mem.GetWidth() * sizeof(DWORD)); - - t = m_texture; - - return true; - } - - void VertexKick() - { - GSVertexSW& v = m_vl.AddTail(); - - // TODO: x/y + off.x/y should wrap around at +/-1024 - - int x = (int)(m_v.XY.X + m_env.DROFF.X) << m_scale.cx; - int y = (int)(m_v.XY.Y + m_env.DROFF.Y) << m_scale.cy; - - int s = m_v.UV.X; - int t = m_v.UV.Y; - - GSVector4 pt(x, y, s, t); - - v.p = pt.xyxy(GSVector4::zero()); - v.t = (pt.zwzw(GSVector4::zero()) + GSVector4(0.125f)) * 256.0f; - v.c = GSVector4((DWORD)m_v.RGB.ai32) * 128.0f; - - __super::VertexKick(); - } - - void DrawingKickTriangle(GSVertexSW* v, int& count) - { - // TODO - } - - void DrawingKickLine(GSVertexSW* v, int& count) - { - // TODO - } - - void DrawingKickSprite(GSVertexSW* v, int& count) - { - // TODO - } - - GSVector4i GetScissor() - { - GSVector4i v; - - v.x = (int)m_env.DRAREATL.X << m_scale.cx; - v.y = (int)m_env.DRAREATL.Y << m_scale.cy; - v.z = min((int)(m_env.DRAREABR.X + 1) << m_scale.cx, m_mem.GetWidth()); - v.w = min((int)(m_env.DRAREABR.Y + 1) << m_scale.cy, m_mem.GetHeight()); - - return v; - } - - void Draw() - { - const GPUDrawingEnvironment& env = m_env; - - // - - GPUScanlineParam p; - - p.sel.key = 0; - p.sel.iip = env.PRIM.IIP; - p.sel.me = env.STATUS.ME; - - if(env.PRIM.ABE) - { - p.sel.abe = env.PRIM.ABE; - p.sel.abr = env.STATUS.ABR; - } - - p.sel.tge = env.PRIM.TGE; - - if(env.PRIM.TME) - { - p.sel.tme = env.PRIM.TME; - p.sel.tlu = env.STATUS.TP < 2; - p.sel.twin = (env.TWIN.ai32 & 0xfffff) != 0; - p.sel.ltf = m_filter == 1 && env.PRIM.TYPE == GPU_POLYGON || m_filter == 2 ? 1 : 0; - - const void* t = m_mem.GetTexture(env.STATUS.TP, env.STATUS.TX, env.STATUS.TY); - - if(!t) {ASSERT(0); return;} - - p.tex = t; - p.clut = m_mem.GetCLUT(env.STATUS.TP, env.CLUT.X, env.CLUT.Y); - } - - p.sel.dtd = m_dither ? env.STATUS.DTD : 0; - p.sel.md = env.STATUS.MD; - p.sel.sprite = env.PRIM.TYPE == GPU_SPRITE; - p.sel.scalex = m_mem.GetScale().cx; - - // - - GSRasterizerData data; - - data.scissor = GetScissor(); - data.vertices = m_vertices; - data.count = m_count; - data.param = &p; - - switch(env.PRIM.TYPE) - { - case GPU_POLYGON: data.primclass = GS_TRIANGLE_CLASS; break; - case GPU_LINE: data.primclass = GS_LINE_CLASS; break; - case GPU_SPRITE: data.primclass = GS_SPRITE_CLASS; break; - default: __assume(0); - } - - m_rl.Draw(&data); - - GSRasterizerStats stats; - - m_rl.GetStats(stats); - - m_perfmon.Put(GSPerfMon::Draw, 1); - m_perfmon.Put(GSPerfMon::Prim, stats.prims); - m_perfmon.Put(GSPerfMon::Fillrate, stats.pixels); - - // TODO - - { - GSVector4 tl(+1e10f); - GSVector4 br(-1e10f); - - for(int i = 0, j = m_count; i < j; i++) - { - GSVector4 p = m_vertices[i].p; - - tl = tl.minv(p); - br = br.maxv(p); - } - - GSVector4i scissor = data.scissor; - - CRect r; - - r.left = max(scissor.x, min(scissor.z, (int)tl.x)) >> m_scale.cx; - r.top = max(scissor.y, min(scissor.w, (int)tl.y)) >> m_scale.cy; - r.right = max(scissor.x, min(scissor.z, (int)br.x)) >> m_scale.cx; - r.bottom = max(scissor.y, min(scissor.w, (int)br.y)) >> m_scale.cy; - - Invalidate(r); - } - } + void ResetDevice(); + GSTexture* GetOutput(); + void VertexKick(); + void Draw(); public: - GPURendererSW(const GPURendererSettings& rs, int threads) - : GPURenderer(rs) - { - m_rl.Create(this, threads); - - m_fpDrawingKickHandlers[GPU_POLYGON] = (DrawingKickHandler)&GPURendererSW::DrawingKickTriangle; - m_fpDrawingKickHandlers[GPU_LINE] = (DrawingKickHandler)&GPURendererSW::DrawingKickLine; - m_fpDrawingKickHandlers[GPU_SPRITE] = (DrawingKickHandler)&GPURendererSW::DrawingKickSprite; - } - - virtual ~GPURendererSW() - { - } + GPURendererSW(GSDevice* dev); + virtual ~GPURendererSW(); }; diff --git a/plugins/GSdx/GPUScanlineEnvironment.h b/plugins/GSdx/GPUScanlineEnvironment.h index 4c7d9e66da..189341e7f8 100644 --- a/plugins/GSdx/GPUScanlineEnvironment.h +++ b/plugins/GSdx/GPUScanlineEnvironment.h @@ -28,32 +28,32 @@ union GPUScanlineSelector { struct { - DWORD iip:1; // 0 - DWORD me:1; // 1 - DWORD abe:1; // 2 - DWORD abr:2; // 3 - DWORD tge:1; // 5 - DWORD tme:1; // 6 - DWORD twin:1; // 7 - DWORD tlu:1; // 8 - DWORD dtd:1; // 9 - DWORD ltf:1; // 10 - DWORD md:1; // 11 - DWORD sprite:1; // 12 - DWORD scalex:2; // 13 + uint32 iip:1; // 0 + uint32 me:1; // 1 + uint32 abe:1; // 2 + uint32 abr:2; // 3 + uint32 tge:1; // 5 + uint32 tme:1; // 6 + uint32 twin:1; // 7 + uint32 tlu:1; // 8 + uint32 dtd:1; // 9 + uint32 ltf:1; // 10 + uint32 md:1; // 11 + uint32 sprite:1; // 12 + uint32 scalex:2; // 13 }; struct { - DWORD _pad1:1; // 0 - DWORD rfb:2; // 1 - DWORD _pad2:2; // 3 - DWORD tfx:2; // 5 + uint32 _pad1:1; // 0 + uint32 rfb:2; // 1 + uint32 _pad2:2; // 3 + uint32 tfx:2; // 5 }; - DWORD key; + uint32 key; - operator DWORD() {return key;} + operator uint32() {return key;} }; __declspec(align(16)) struct GPUScanlineParam @@ -61,17 +61,16 @@ __declspec(align(16)) struct GPUScanlineParam GPUScanlineSelector sel; const void* tex; - const WORD* clut; + const uint16* clut; }; __declspec(align(16)) struct GPUScanlineEnvironment { GPUScanlineSelector sel; - // GPULocalMemory* mem; // TODO: obsolite void* vm; const void* tex; - const WORD* clut; + const uint16* clut; // GSVector4i md; // similar to gs fba diff --git a/plugins/GSdx/GPUSettingsDlg.cpp b/plugins/GSdx/GPUSettingsDlg.cpp index 0d937ad0f2..815a6d77f8 100644 --- a/plugins/GSdx/GPUSettingsDlg.cpp +++ b/plugins/GSdx/GPUSettingsDlg.cpp @@ -23,279 +23,181 @@ #include "GSdx.h" #include "GSUtil.h" #include "GPUSettingsDlg.h" -#include -#include +#include "resource.h" GSSetting GPUSettingsDlg::g_renderers[] = { - {0, _T("Direct3D7 (Software)"), NULL}, - {1, _T("Direct3D9 (Software)"), NULL}, - {2, _T("Direct3D10 (Software)"), NULL}, -// {3, _T("Null (Null)"), NULL}, -}; - -GSSetting GPUSettingsDlg::g_psversion[] = -{ - {D3DPS_VERSION(3, 0), _T("Pixel Shader 3.0"), NULL}, - {D3DPS_VERSION(2, 0), _T("Pixel Shader 2.0"), NULL}, - //{D3DPS_VERSION(1, 4), _T("Pixel Shader 1.4"), NULL}, - //{D3DPS_VERSION(1, 1), _T("Pixel Shader 1.1"), NULL}, - //{D3DPS_VERSION(0, 0), _T("Fixed Pipeline (bogus)"), NULL}, + {0, "Direct3D7 (Software)", NULL}, + {1, "Direct3D9 (Software)", NULL}, + {2, "Direct3D10 (Software)", NULL}, + {3, "Direct3D11 (Software)", NULL}, +// {4, "Null (Null)", NULL}, }; GSSetting GPUSettingsDlg::g_filter[] = { - {0, _T("Nearest"), NULL}, - {1, _T("Bilinear (polygons only)"), NULL}, - {2, _T("Bilinear"), NULL}, + {0, "Nearest", NULL}, + {1, "Bilinear (polygons only)", NULL}, + {2, "Bilinear", NULL}, }; GSSetting GPUSettingsDlg::g_dithering[] = { - {0, _T("Disabled"), NULL}, - {1, _T("Auto"), NULL}, + {0, "Disabled", NULL}, + {1, "Auto", NULL}, }; GSSetting GPUSettingsDlg::g_aspectratio[] = { - {0, _T("Stretch"), NULL}, - {1, _T("4:3"), NULL}, - {2, _T("16:9"), NULL}, + {0, "Stretch", NULL}, + {1, "4:3", NULL}, + {2, "16:9", NULL}, }; -GSSetting GPUSettingsDlg::g_internalresolution[] = +GSSetting GPUSettingsDlg::g_scale[] = { - {0 | (0 << 2), _T("H x 1 - V x 1"), NULL}, - {1 | (0 << 2), _T("H x 2 - V x 1"), NULL}, - {0 | (1 << 2), _T("H x 1 - V x 2"), NULL}, - {1 | (1 << 2), _T("H x 2 - V x 2"), NULL}, - {2 | (1 << 2), _T("H x 4 - V x 2"), NULL}, - {1 | (2 << 2), _T("H x 2 - V x 4"), NULL}, - {2 | (2 << 2), _T("H x 4 - V x 4"), NULL}, + {0 | (0 << 2), "H x 1 - V x 1", NULL}, + {1 | (0 << 2), "H x 2 - V x 1", NULL}, + {0 | (1 << 2), "H x 1 - V x 2", NULL}, + {1 | (1 << 2), "H x 2 - V x 2", NULL}, + {2 | (1 << 2), "H x 4 - V x 2", NULL}, + {1 | (2 << 2), "H x 2 - V x 4", NULL}, + {2 | (2 << 2), "H x 4 - V x 4", NULL}, }; -IMPLEMENT_DYNAMIC(GPUSettingsDlg, CDialog) - -GPUSettingsDlg::GPUSettingsDlg(CWnd* pParent /*=NULL*/) - : CDialog(GPUSettingsDlg::IDD, pParent) -{ - -} - -GPUSettingsDlg::~GPUSettingsDlg() +GPUSettingsDlg::GPUSettingsDlg() + : GSDialog(IDD_GPUCONFIG) { } -LRESULT GPUSettingsDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) +void GPUSettingsDlg::OnInit() { - LRESULT ret = __super::DefWindowProc(message, wParam, lParam); + __super::OnInit(); - if(message == WM_INITDIALOG) - { - SendMessage(WM_KICKIDLE); - } - - return ret; -} - -void GPUSettingsDlg::DoDataExchange(CDataExchange* pDX) -{ - __super::DoDataExchange(pDX); - DDX_Control(pDX, IDC_COMBO3, m_resolution); - DDX_Control(pDX, IDC_COMBO1, m_renderer); - DDX_Control(pDX, IDC_COMBO4, m_psversion); - DDX_Control(pDX, IDC_COMBO2, m_filter); - DDX_Control(pDX, IDC_COMBO5, m_dithering); - DDX_Control(pDX, IDC_COMBO6, m_aspectratio); - DDX_Control(pDX, IDC_COMBO7, m_internalresolution); - DDX_Control(pDX, IDC_SPIN3, m_swthreads); - DDX_Control(pDX, IDC_EDIT3, m_swthreadsedit); -} - -BEGIN_MESSAGE_MAP(GPUSettingsDlg, CDialog) - ON_MESSAGE_VOID(WM_KICKIDLE, OnKickIdle) - ON_UPDATE_COMMAND_UI(IDC_COMBO4, OnUpdateD3D9Options) - ON_UPDATE_COMMAND_UI(IDC_COMBO7, OnUpdateSWOptions) - ON_UPDATE_COMMAND_UI(IDC_SPIN3, OnUpdateSWOptions) - ON_UPDATE_COMMAND_UI(IDC_EDIT3, OnUpdateSWOptions) - ON_CBN_SELCHANGE(IDC_COMBO1, &GPUSettingsDlg::OnCbnSelchangeCombo1) -END_MESSAGE_MAP() - -void GPUSettingsDlg::OnKickIdle() -{ - UpdateDialogControls(this, false); -} - -BOOL GPUSettingsDlg::OnInitDialog() -{ - __super::OnInitDialog(); - - CWinApp* pApp = AfxGetApp(); - - D3DCAPS9 caps; - memset(&caps, 0, sizeof(caps)); - caps.PixelShaderVersion = D3DPS_VERSION(0, 0); - - m_modes.RemoveAll(); - - // windowed + m_modes.clear(); { D3DDISPLAYMODE mode; memset(&mode, 0, sizeof(mode)); - m_modes.AddTail(mode); + m_modes.push_back(mode); - int iItem = m_resolution.AddString(_T("Windowed")); - m_resolution.SetItemDataPtr(iItem, m_modes.GetTailPosition()); - m_resolution.SetCurSel(iItem); - } + ComboBoxAppend(IDC_RESOLUTION, "Windowed", (LPARAM)&m_modes.back(), true); - // fullscreen - - if(CComPtr d3d = Direct3DCreate9(D3D_SDK_VERSION)) - { - UINT ModeWidth = pApp->GetProfileInt(_T("Settings"), _T("ModeWidth"), 0); - UINT ModeHeight = pApp->GetProfileInt(_T("Settings"), _T("ModeHeight"), 0); - UINT ModeRefreshRate = pApp->GetProfileInt(_T("Settings"), _T("ModeRefreshRate"), 0); - - UINT nModes = d3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8); - - for(UINT i = 0; i < nModes; i++) + if(CComPtr d3d = Direct3DCreate9(D3D_SDK_VERSION)) { - D3DDISPLAYMODE mode; + uint32 w = theApp.GetConfig("ModeWidth", 0); + uint32 h = theApp.GetConfig("ModeHeight", 0); + uint32 hz = theApp.GetConfig("ModeRefreshRate", 0); - if(S_OK == d3d->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &mode)) + uint32 n = d3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8); + + for(uint32 i = 0; i < n; i++) { - CString str; - str.Format(_T("%dx%d %dHz"), mode.Width, mode.Height, mode.RefreshRate); - int iItem = m_resolution.AddString(str); - - m_modes.AddTail(mode); - m_resolution.SetItemDataPtr(iItem, m_modes.GetTailPosition()); - - if(ModeWidth == mode.Width && ModeHeight == mode.Height && ModeRefreshRate == mode.RefreshRate) + if(S_OK == d3d->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &mode)) { - m_resolution.SetCurSel(iItem); + m_modes.push_back(mode); + + string str = format("%dx%d %dHz", mode.Width, mode.Height, mode.RefreshRate); + + ComboBoxAppend(IDC_RESOLUTION, str.c_str(), (LPARAM)&m_modes.back(), w == mode.Width && h == mode.Height && hz == mode.RefreshRate); } } } - - d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps); } bool isdx10avail = GSUtil::IsDirect3D10Available(); + bool isdx11avail = GSUtil::IsDirect3D11Available(); - CAtlArray renderers; + vector renderers; for(size_t i = 0; i < countof(g_renderers); i++) { - if(i == 2 && !isdx10avail) continue; + if(i >= 3 && i <= 5 && !isdx10avail) continue; + if(i >= 6 && i <= 8 && !isdx11avail) continue; - renderers.Add(g_renderers[i]); + renderers.push_back(g_renderers[i]); } - GSSetting::InitComboBox(renderers.GetData(), renderers.GetCount(), m_renderer, pApp->GetProfileInt(_T("GPUSettings"), _T("Renderer"), 1)); - GSSetting::InitComboBox(g_psversion, countof(g_psversion), m_psversion, pApp->GetProfileInt(_T("Settings"), _T("PixelShaderVersion2"), D3DPS_VERSION(2, 0)), caps.PixelShaderVersion); - GSSetting::InitComboBox(g_filter, countof(g_filter), m_filter, pApp->GetProfileInt(_T("GPUSettings"), _T("filter"), 0)); - GSSetting::InitComboBox(g_dithering, countof(g_dithering), m_dithering, pApp->GetProfileInt(_T("GPUSettings"), _T("dithering"), 1)); - GSSetting::InitComboBox(g_aspectratio, countof(g_aspectratio), m_aspectratio, pApp->GetProfileInt(_T("GPUSettings"), _T("AspectRatio"), 1)); - GSSetting::InitComboBox(g_internalresolution, countof(g_internalresolution), m_internalresolution, pApp->GetProfileInt(_T("GPUSettings"), _T("scale_x"), 0) | (pApp->GetProfileInt(_T("GPUSettings"), _T("scale_y"), 0) << 2)); - + ComboBoxInit(IDC_RENDERER, &renderers[0], renderers.size(), theApp.GetConfig("Renderer", 0)); + ComboBoxInit(IDC_FILTER, g_filter, countof(g_filter), theApp.GetConfig("filter", 0)); + ComboBoxInit(IDC_DITHERING, g_dithering, countof(g_dithering), theApp.GetConfig("dithering", 1)); + ComboBoxInit(IDC_ASPECTRATIO, g_aspectratio, countof(g_aspectratio), theApp.GetConfig("AspectRatio", 1)); + ComboBoxInit(IDC_SCALE, g_scale, countof(g_scale), theApp.GetConfig("scale_x", 0) | (theApp.GetConfig("scale_y", 0) << 2)); - OnCbnSelchangeCombo1(); + SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETRANGE, 0, MAKELPARAM(16, 1)); + SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfig("swthreads", 1), 0)); - // - - m_swthreads.SetRange(1, 16); - m_swthreads.SetPos(pApp->GetProfileInt(_T("GPUSettings"), _T("swthreads"), 1)); - - // - - UpdateData(FALSE); - - return TRUE; // return TRUE unless you set the focus to a control - // EXCEPTION: OCX Property Pages should return FALSE + UpdateControls(); } -void GPUSettingsDlg::OnOK() +bool GPUSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code) { - CWinApp* pApp = AfxGetApp(); - - UpdateData(); - - if(m_resolution.GetCurSel() >= 0) + if(id == IDC_RENDERER && code == CBN_SELCHANGE) { - D3DDISPLAYMODE& mode = m_modes.GetAt((POSITION)m_resolution.GetItemData(m_resolution.GetCurSel())); - pApp->WriteProfileInt(_T("Settings"), _T("ModeWidth"), mode.Width); - pApp->WriteProfileInt(_T("Settings"), _T("ModeHeight"), mode.Height); - pApp->WriteProfileInt(_T("Settings"), _T("ModeRefreshRate"), mode.RefreshRate); + UpdateControls(); + } + else if(id == IDOK) + { + INT_PTR data; + + if(ComboBoxGetSelData(IDC_RESOLUTION, data)) + { + const D3DDISPLAYMODE* mode = (D3DDISPLAYMODE*)data; + + theApp.SetConfig("ModeWidth", (int)mode->Width); + theApp.SetConfig("ModeHeight", (int)mode->Height); + theApp.SetConfig("ModeRefreshRate", (int)mode->RefreshRate); + } + + if(ComboBoxGetSelData(IDC_RENDERER, data)) + { + theApp.SetConfig("Renderer", (int)data); + } + + if(ComboBoxGetSelData(IDC_FILTER, data)) + { + theApp.SetConfig("filter", (int)data); + } + + if(ComboBoxGetSelData(IDC_DITHERING, data)) + { + theApp.SetConfig("dithering", (int)data); + } + + if(ComboBoxGetSelData(IDC_ASPECTRATIO, data)) + { + theApp.SetConfig("AspectRatio", (int)data); + } + + if(ComboBoxGetSelData(IDC_SCALE, data)) + { + theApp.SetConfig("scale_x", data & 3); + theApp.SetConfig("scale_y", (data >> 2) & 3); + } + + theApp.SetConfig("swthreads", (int)SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_GETPOS, 0, 0)); } - if(m_renderer.GetCurSel() >= 0) - { - pApp->WriteProfileInt(_T("GPUSettings"), _T("Renderer"), (DWORD)m_renderer.GetItemData(m_renderer.GetCurSel())); - } - - if(m_psversion.GetCurSel() >= 0) - { - pApp->WriteProfileInt(_T("Settings"), _T("PixelShaderVersion2"), (DWORD)m_psversion.GetItemData(m_psversion.GetCurSel())); - } - - if(m_filter.GetCurSel() >= 0) - { - pApp->WriteProfileInt(_T("GPUSettings"), _T("filter"), (DWORD)m_filter.GetItemData(m_filter.GetCurSel())); - } - - if(m_dithering.GetCurSel() >= 0) - { - pApp->WriteProfileInt(_T("GPUSettings"), _T("dithering"), (DWORD)m_dithering.GetItemData(m_dithering.GetCurSel())); - } - - if(m_aspectratio.GetCurSel() >= 0) - { - pApp->WriteProfileInt(_T("GPUSettings"), _T("AspectRatio"), (DWORD)m_aspectratio.GetItemData(m_aspectratio.GetCurSel())); - } - - if(m_internalresolution.GetCurSel() >= 0) - { - DWORD value = (DWORD)m_internalresolution.GetItemData(m_internalresolution.GetCurSel()); - - pApp->WriteProfileInt(_T("GPUSettings"), _T("scale_x"), value & 3); - pApp->WriteProfileInt(_T("GPUSettings"), _T("scale_y"), (value >> 2) & 3); - } - - pApp->WriteProfileInt(_T("GPUSettings"), _T("swthreads"), m_swthreads.GetPos()); - - __super::OnOK(); + return __super::OnCommand(hWnd, id, code); } -void GPUSettingsDlg::OnUpdateResolution(CCmdUI* pCmdUI) +void GPUSettingsDlg::UpdateControls() { - UpdateData(); + INT_PTR i; - int i = (int)m_renderer.GetItemData(m_renderer.GetCurSel()); + if(ComboBoxGetSelData(IDC_RENDERER, i)) + { + bool dx9 = i == 1; + bool dx10 = i == 2; + bool dx11 = i == 3; + bool sw = i >= 0 && i <= 3; - pCmdUI->Enable(i == 1); -} - -void GPUSettingsDlg::OnUpdateD3D9Options(CCmdUI* pCmdUI) -{ - int i = (int)m_renderer.GetItemData(m_renderer.GetCurSel()); - - pCmdUI->Enable(i == 1); -} - -void GPUSettingsDlg::OnUpdateSWOptions(CCmdUI* pCmdUI) -{ - int i = (int)m_renderer.GetItemData(m_renderer.GetCurSel()); - - pCmdUI->Enable(i >= 0 && i <= 2); -} - -void GPUSettingsDlg::OnCbnSelchangeCombo1() -{ - int i = (int)m_renderer.GetItemData(m_renderer.GetCurSel()); - - GetDlgItem(IDC_LOGO9)->ShowWindow(i == 1 ? SW_SHOW : SW_HIDE); - GetDlgItem(IDC_LOGO10)->ShowWindow(i == 2 ? SW_SHOW : SW_HIDE); -} + ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO9), dx9 ? SW_SHOW : SW_HIDE); + ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO10), dx10 ? SW_SHOW : SW_HIDE); + // TODO: ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO11), dx11 ? SW_SHOW : SW_HIDE); + + EnableWindow(GetDlgItem(m_hWnd, IDC_SCALE), sw); + EnableWindow(GetDlgItem(m_hWnd, IDC_SWTHREADS_EDIT), sw); + EnableWindow(GetDlgItem(m_hWnd, IDC_SWTHREADS), sw); + } +} \ No newline at end of file diff --git a/plugins/GSdx/GPUSettingsDlg.h b/plugins/GSdx/GPUSettingsDlg.h index 4602ef685b..ef6a764ef2 100644 --- a/plugins/GSdx/GPUSettingsDlg.h +++ b/plugins/GSdx/GPUSettingsDlg.h @@ -21,51 +21,25 @@ #pragma once +#include "GSDialog.h" #include "GSSetting.h" -#include "resource.h" -class GPUSettingsDlg : public CDialog +class GPUSettingsDlg : public GSDialog { - DECLARE_DYNAMIC(GPUSettingsDlg) + list m_modes; -private: - CAtlList m_modes; + void UpdateControls(); + +protected: + void OnInit(); + bool OnCommand(HWND hWnd, UINT id, UINT code); public: - GPUSettingsDlg(CWnd* pParent = NULL); // standard constructor - virtual ~GPUSettingsDlg(); + GPUSettingsDlg(); - static GSSetting g_renderers[]; - static GSSetting g_psversion[]; + static GSSetting g_renderers[]; static GSSetting g_filter[]; static GSSetting g_dithering[]; static GSSetting g_aspectratio[]; - static GSSetting g_internalresolution[]; - -// Dialog Data - enum { IDD = IDD_GPUCONFIG }; - CComboBox m_resolution; - CComboBox m_renderer; - CComboBox m_psversion; - CComboBox m_filter; - CComboBox m_dithering; - CComboBox m_aspectratio; - CComboBox m_internalresolution; - CSpinButtonCtrl m_swthreads; - CEdit m_swthreadsedit; - -protected: - virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam); - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - virtual BOOL OnInitDialog(); - virtual void OnOK(); - - DECLARE_MESSAGE_MAP() - -public: - afx_msg void OnKickIdle(); - afx_msg void OnUpdateResolution(CCmdUI* pCmdUI); - afx_msg void OnUpdateD3D9Options(CCmdUI* pCmdUI); - afx_msg void OnUpdateSWOptions(CCmdUI* pCmdUI); - afx_msg void OnCbnSelchangeCombo1(); + static GSSetting g_scale[]; }; diff --git a/plugins/GSdx/GPUSetupPrimCodeGenerator.cpp b/plugins/GSdx/GPUSetupPrimCodeGenerator.cpp index d70903dbbb..43ebb94d93 100644 --- a/plugins/GSdx/GPUSetupPrimCodeGenerator.cpp +++ b/plugins/GSdx/GPUSetupPrimCodeGenerator.cpp @@ -38,8 +38,6 @@ GPUSetupPrimCodeGenerator::GPUSetupPrimCodeGenerator(GPUScanlineEnvironment& env void GPUSetupPrimCodeGenerator::Generate() { - const int params = 0; - if(m_env.sel.tme && !m_env.sel.twin) { pcmpeqd(xmm0, xmm0); diff --git a/plugins/GSdx/GPUState.cpp b/plugins/GSdx/GPUState.cpp index 8aa4d30ea3..8fad682df1 100644 --- a/plugins/GSdx/GPUState.cpp +++ b/plugins/GSdx/GPUState.cpp @@ -22,9 +22,8 @@ #include "stdafx.h" #include "GPUState.h" -GPUState::GPUState(const CSize& scale) - : m_mem(scale) - , s_n(0) +GPUState::GPUState() + : s_n(0) { memset(m_status, 0, sizeof(m_status)); @@ -64,7 +63,7 @@ void GPUState::Reset() { m_env.Reset(); - m_mem.Invalidate(CRect(0, 0, 1024, 512)); + m_mem.Invalidate(GSVector4i(0, 0, 1024, 512)); memset(&m_v, 0, sizeof(m_v)); } @@ -88,18 +87,18 @@ void GPUState::SetPrim(GPUReg* r) switch(r->PRIM.TYPE) { case GPU_POLYGON: - PRIM.ai32 = (r->PRIM.ai32 & 0xF7000000) | 3; // TYPE IIP TME ABE TGE + PRIM.u32 = (r->PRIM.u32 & 0xF7000000) | 3; // TYPE IIP TME ABE TGE break; case GPU_LINE: - PRIM.ai32 = (r->PRIM.ai32 & 0xF2000000) | 2; // TYPE IIP ABE + PRIM.u32 = (r->PRIM.u32 & 0xF2000000) | 2; // TYPE IIP ABE PRIM.TGE = 1; // ? break; case GPU_SPRITE: - PRIM.ai32 = (r->PRIM.ai32 & 0xE7000000) | 2; // TYPE TME ABE TGE + PRIM.u32 = (r->PRIM.u32 & 0xE7000000) | 2; // TYPE TME ABE TGE break; } - if(m_env.PRIM.ai32 != PRIM.ai32) + if(m_env.PRIM.u32 != PRIM.u32) { Flush(); @@ -109,38 +108,38 @@ void GPUState::SetPrim(GPUReg* r) void GPUState::SetCLUT(GPUReg* r) { - UINT32 mask = 0xFFFF0000; // X Y + uint32 mask = 0xFFFF0000; // X Y - UINT32 value = (m_env.CLUT.ai32 & ~mask) | (r->ai32 & mask); + uint32 value = (m_env.CLUT.u32 & ~mask) | (r->u32 & mask); - if(m_env.CLUT.ai32 != value) + if(m_env.CLUT.u32 != value) { Flush(); - m_env.CLUT.ai32 = value; + m_env.CLUT.u32 = value; } } void GPUState::SetTPAGE(GPUReg* r) { - UINT32 mask = 0x000001FF; // TP ABR TY TX + uint32 mask = 0x000001FF; // TP ABR TY TX - UINT32 value = (m_env.STATUS.ai32 & ~mask) | ((r->ai32 >> 16) & mask); + uint32 value = (m_env.STATUS.u32 & ~mask) | ((r->u32 >> 16) & mask); - if(m_env.STATUS.ai32 != value) + if(m_env.STATUS.u32 != value) { Flush(); - m_env.STATUS.ai32 = value; + m_env.STATUS.u32 = value; } } -void GPUState::Invalidate(const CRect& r) +void GPUState::Invalidate(const GSVector4i& r) { m_mem.Invalidate(r); } -void GPUState::WriteData(const BYTE* mem, UINT32 size) +void GPUState::WriteData(const uint8* mem, uint32 size) { GSPerfMonAutoTimer pmat(m_perfmon); @@ -164,7 +163,7 @@ void GPUState::WriteData(const BYTE* mem, UINT32 size) m_write.Remove(i); } -void GPUState::ReadData(BYTE* mem, UINT32 size) +void GPUState::ReadData(uint8* mem, uint32 size) { GSPerfMonAutoTimer pmat(m_perfmon); @@ -176,7 +175,7 @@ void GPUState::ReadData(BYTE* mem, UINT32 size) { // ASSERT(0); - TRACE(_T("WARNING: ReadData\n")); + // printf"WARNING: ReadData\n"); // memset(&mem[remaining], 0, bytes - remaining); @@ -193,38 +192,38 @@ void GPUState::ReadData(BYTE* mem, UINT32 size) } } -void GPUState::WriteStatus(UINT32 status) +void GPUState::WriteStatus(uint32 status) { GSPerfMonAutoTimer pmat(m_perfmon); - UINT32 b = status >> 24; + uint32 b = status >> 24; m_status[b] = status; (this->*m_fpGPUStatusCommandHandlers[b])((GPUReg*)&status); } -UINT32 GPUState::ReadStatus() +uint32 GPUState::ReadStatus() { GSPerfMonAutoTimer pmat(m_perfmon); m_env.STATUS.LCF = ~m_env.STATUS.LCF; // ? - return m_env.STATUS.ai32; + return m_env.STATUS.u32; } void GPUState::Freeze(GPUFreezeData* data) { - data->status = m_env.STATUS.ai32; + data->status = m_env.STATUS.u32; memcpy(data->control, m_status, 256 * 4); - m_mem.ReadRect(CRect(0, 0, 1024, 512), data->vram); + m_mem.ReadRect(GSVector4i(0, 0, 1024, 512), data->vram); } void GPUState::Defrost(const GPUFreezeData* data) { - m_env.STATUS.ai32 = data->status; + m_env.STATUS.u32 = data->status; memcpy(m_status, data->control, 256 * 4); - m_mem.WriteRect(CRect(0, 0, 1024, 512), data->vram); + m_mem.WriteRect(GSVector4i(0, 0, 1024, 512), data->vram); for(int i = 0; i <= 8; i++) { @@ -289,24 +288,24 @@ void GPUState::SCH_DisplayMode(GPUReg* r) void GPUState::SCH_GPUInfo(GPUReg* r) { - UINT32 value = 0; + uint32 value = 0; switch(r->GPUINFO.PARAM) { case 0x2: - value = m_env.TWIN.ai32; + value = m_env.TWIN.u32; break; case 0x0: case 0x1: case 0x3: - value = m_env.DRAREATL.ai32; + value = m_env.DRAREATL.u32; break; case 0x4: - value = m_env.DRAREABR.ai32; + value = m_env.DRAREABR.u32; break; case 0x5: case 0x6: - value = m_env.DROFF.ai32; + value = m_env.DROFF.u32; break; case 0x7: value = 2; @@ -321,7 +320,7 @@ void GPUState::SCH_GPUInfo(GPUReg* r) } m_read.RemoveAll(); - m_read.Append((BYTE*)&value, 4); + m_read.Append((uint8*)&value, 4); m_read.cur = 0; } @@ -343,20 +342,20 @@ int GPUState::PH_Command(GPUReg* r, int size) Flush(); - CRect r2; + GSVector4i r2; r2.left = r[1].XY.X; r2.top = r[1].XY.Y; r2.right = r2.left + r[2].XY.X; r2.bottom = r2.top + r[2].XY.Y; - WORD c = (WORD)(((r[0].RGB.R >> 3) << 10) | ((r[0].RGB.R >> 3) << 5) | (r[0].RGB.R >> 3)); + uint16 c = (uint16)(((r[0].RGB.R >> 3) << 10) | ((r[0].RGB.R >> 3) << 5) | (r[0].RGB.R >> 3)); m_mem.FillRect(r2, c); Invalidate(r2); - Dump(_T("f")); + Dump("f"); return 3; } @@ -439,7 +438,7 @@ int GPUState::PH_Line(GPUReg* r, int size) for(int i = 1; i < size; i++) { - if(r[i].ai32 == 0x55555555) + if(r[i].u32 == 0x55555555) { vertices = i - 1; } @@ -553,22 +552,20 @@ int GPUState::PH_Move(GPUReg* r, int size) Flush(); - CPoint src, dst; + int sx = r[1].XY.X; + int sy = r[1].XY.Y; - src.x = r[1].XY.X; - src.y = r[1].XY.Y; - - dst.x = r[2].XY.X; - dst.y = r[2].XY.Y; + int dx = r[2].XY.X; + int dy = r[2].XY.Y; int w = r[3].XY.X; int h = r[3].XY.Y; - m_mem.MoveRect(src, dst, w, h); + m_mem.MoveRect(sx, sy, dx, dy, w, h); - Invalidate(CRect(dst, CSize(w, h))); + Invalidate(GSVector4i(dx, dy, dx + w, dy + h)); - // Dump(_T("m")); + // Dump("m"); return 4; } @@ -586,18 +583,18 @@ int GPUState::PH_Write(GPUReg* r, int size) Flush(); - CRect r2; + GSVector4i r2; r2.left = r[1].XY.X; r2.top = r[1].XY.Y; r2.right = r2.left + w; r2.bottom = r2.top + h; - m_mem.WriteRect(r2, (const WORD*)&r[3]); + m_mem.WriteRect(r2, (const uint16*)&r[3]); Invalidate(r2); - Dump(_T("w")); + Dump("w"); m_perfmon.Put(GSPerfMon::Swizzle, w * h * 2); @@ -613,7 +610,7 @@ int GPUState::PH_Read(GPUReg* r, int size) int w = r[2].XY.X; int h = r[2].XY.Y; - CRect r2; + GSVector4i r2; r2.left = r[1].XY.X; r2.top = r[1].XY.Y; @@ -624,9 +621,9 @@ int GPUState::PH_Read(GPUReg* r, int size) m_read.cur = 0; m_read.Reserve(m_read.bytes); - m_mem.ReadRect(r2, (WORD*)m_read.buff); + m_mem.ReadRect(r2, (uint16*)m_read.buff); - Dump(_T("r")); + Dump("r"); m_env.STATUS.IMG = 1; @@ -693,7 +690,7 @@ GPUState::Buffer::Buffer() { bytes = 0; maxbytes = 4096; - buff = (BYTE*)_aligned_malloc(maxbytes, 16); + buff = (uint8*)_aligned_malloc(maxbytes, 16); cur = 0; } @@ -708,11 +705,11 @@ void GPUState::Buffer::Reserve(int size) { maxbytes = (maxbytes + size + 1023) & ~1023; - buff = (BYTE*)_aligned_realloc(buff, maxbytes, 16); + buff = (uint8*)_aligned_realloc(buff, maxbytes, 16); } } -void GPUState::Buffer::Append(const BYTE* src, int size) +void GPUState::Buffer::Append(const uint8* src, int size) { Reserve(bytes + (int)size); diff --git a/plugins/GSdx/GPUState.h b/plugins/GSdx/GPUState.h index 8888dd7ce3..15d4d9c767 100644 --- a/plugins/GSdx/GPUState.h +++ b/plugins/GSdx/GPUState.h @@ -65,14 +65,14 @@ class GPUState : public GSAlignedClass<16> public: int bytes; int maxbytes; - BYTE* buff; + uint8* buff; int cur; public: Buffer(); ~Buffer(); void Reserve(int size); - void Append(const BYTE* src, int size); + void Append(const uint8* src, int size); void Remove(int size); void RemoveAll(); }; @@ -88,10 +88,10 @@ protected: int s_n; - void Dump(LPCTSTR s, UINT32 TP, const CRect& r, int inc = true) + void Dump(const string& s, uint32 TP, const GSVector4i& r, int inc = true) { //if(m_perfmon.GetFrame() < 1000) - //if((m_env.TWIN.ai32 & 0xfffff) == 0) + //if((m_env.TWIN.u32 & 0xfffff) == 0) //if(!m_env.STATUS.ME && !m_env.STATUS.MD) return; @@ -103,14 +103,12 @@ protected: #ifdef DEBUG dir = 2; #endif - CString str; - str.Format(_T("c:\\temp%d\\%04d_%s.bmp"), dir, s_n, s); - m_mem.SaveBMP(str, r, TP, m_env.CLUT.X, m_env.CLUT.Y); + m_mem.SaveBMP(format("c:\\temp%d\\%04d_%s.bmp", dir, s_n, s), r, TP, m_env.CLUT.X, m_env.CLUT.Y); } - void Dump(LPCTSTR s, int inc = true) + void Dump(const string& s, int inc = true) { - Dump(s, 2, CRect(0, 0, 1024, 512), inc); + Dump(s, 2, GSVector4i(0, 0, 1024, 512), inc); } public: @@ -118,10 +116,10 @@ public: GPULocalMemory m_mem; GPUVertex m_v; GSPerfMon m_perfmon; - UINT32 m_status[256]; + uint32 m_status[256]; public: - GPUState(const CSize& scale); + GPUState(); virtual ~GPUState(); virtual void Reset(); @@ -129,13 +127,13 @@ public: virtual void FlushPrim() = 0; virtual void ResetPrim() = 0; virtual void VertexKick() = 0; - virtual void Invalidate(const CRect& r); + virtual void Invalidate(const GSVector4i& r); - void WriteData(const BYTE* mem, UINT32 size); - void ReadData(BYTE* mem, UINT32 size); + void WriteData(const uint8* mem, uint32 size); + void ReadData(uint8* mem, uint32 size); - void WriteStatus(UINT32 status); - UINT32 ReadStatus(); + void WriteStatus(uint32 status); + uint32 ReadStatus(); void Freeze(GPUFreezeData* data); void Defrost(const GPUFreezeData* data); diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index 3dd274f709..f7751d5d33 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -21,8 +21,10 @@ #include "stdafx.h" #include "GSUtil.h" -#include "GSRendererHW9.h" -#include "GSRendererHW10.h" +#include "GSRendererDX9.h" +#include "GSRendererDX10.h" +#include "GSRendererDX11.h" +#include "GSRendererOGL.h" #include "GSRendererSW.h" #include "GSRendererNull.h" #include "GSSettingsDlg.h" @@ -33,11 +35,11 @@ #define PS2E_X86_64 0x02 // 64 bit static HRESULT s_hr = E_FAIL; -static GSRendererBase* s_gs = NULL; +static GSRenderer* s_gs = NULL; static void (*s_irq)() = NULL; -static BYTE* s_basemem = NULL; +static uint8* s_basemem = NULL; -EXPORT_C_(UINT32) PS2EgetLibType() +EXPORT_C_(uint32) PS2EgetLibType() { return PS2E_LT_GS; } @@ -47,15 +49,15 @@ EXPORT_C_(char*) PS2EgetLibName() return GSUtil::GetLibName(); } -EXPORT_C_(UINT32) PS2EgetLibVersion2(UINT32 type) +EXPORT_C_(uint32) PS2EgetLibVersion2(uint32 type) { - const UINT32 revision = 0; - const UINT32 build = 1; + const uint32 revision = 0; + const uint32 build = 1; return (build << 0) | (revision << 8) | (PS2E_GS_VERSION << 16) | (PLUGIN_VERSION << 24); } -EXPORT_C_(UINT32) PS2EgetCpuPlatform() +EXPORT_C_(uint32) PS2EgetCpuPlatform() { #if _M_AMD64 return PS2E_X86_64; @@ -64,21 +66,23 @@ EXPORT_C_(UINT32) PS2EgetCpuPlatform() #endif } -EXPORT_C GSsetBaseMem(BYTE* mem) +EXPORT_C GSsetBaseMem(uint8* mem) { s_basemem = mem - 0x12000000; } EXPORT_C_(INT32) GSinit() { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if(!GSUtil::CheckSSE()) + { + return -1; + } return 0; } EXPORT_C GSshutdown() { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); } EXPORT_C GSclose() @@ -87,53 +91,55 @@ EXPORT_C GSclose() s_gs = NULL; +#ifdef _WINDOWS + if(SUCCEEDED(s_hr)) { ::CoUninitialize(); s_hr = E_FAIL; } + +#endif } static INT32 GSopen(void* dsp, char* title, int mt, int renderer) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); + GSclose(); - if(!GSUtil::CheckDirectX() || !GSUtil::CheckSSE()) +#ifdef _WINDOWS + + s_hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); + + if(!GSUtil::CheckDirectX()) { return -1; } - GSclose(); - - GSRendererSettings rs; - - rs.m_interlace = AfxGetApp()->GetProfileInt(_T("Settings"), _T("interlace"), 0); - rs.m_aspectratio = AfxGetApp()->GetProfileInt(_T("Settings"), _T("aspectratio"), 1); - rs.m_filter = AfxGetApp()->GetProfileInt(_T("Settings"), _T("filter"), 1); - rs.m_vsync = !!AfxGetApp()->GetProfileInt(_T("Settings"), _T("vsync"), FALSE); - rs.m_nativeres = !!AfxGetApp()->GetProfileInt(_T("Settings"), _T("nativeres"), FALSE); - rs.m_aa1 = !!AfxGetApp()->GetProfileInt(_T("Settings"), _T("aa1"), FALSE); - rs.m_blur = !!AfxGetApp()->GetProfileInt(_T("Settings"), _T("blur"), FALSE); - - int threads = AfxGetApp()->GetProfileInt(_T("Settings"), _T("swthreads"), 1); +#endif switch(renderer) { default: - case 0: s_gs = new GSRendererHW9(s_basemem, !!mt, s_irq, rs); break; - case 1: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, rs, threads); break; - case 2: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, rs); break; - case 3: s_gs = new GSRendererHW10(s_basemem, !!mt, s_irq, rs); break; - case 4: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, rs, threads); break; - case 5: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, rs); break; - case 6: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, rs, threads); break; - case 7: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, rs); break; + case 0: s_gs = new GSRendererDX9(s_basemem, !!mt, s_irq); break; + case 1: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDevice9()); break; + case 2: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDevice9()); break; + case 3: s_gs = new GSRendererDX10(s_basemem, !!mt, s_irq); break; + case 4: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDevice10()); break; + case 5: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDevice10()); break; + case 6: s_gs = new GSRendererDX11(s_basemem, !!mt, s_irq); break; + case 7: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDevice11()); break; + case 8: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDevice11()); break; + #if 0 + case 9: s_gs = new GSRendererOGL(s_basemem, !!mt, s_irq); break; + case 10: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDeviceOGL()); break; + case 11: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDeviceOGL()); break; + #endif + case 12: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDeviceNull()); break; + case 13: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDeviceNull()); break; } - s_hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); - - if(!s_gs->Create(CString(title))) + if(!s_gs->Create(title)) { GSclose(); @@ -142,7 +148,7 @@ static INT32 GSopen(void* dsp, char* title, int mt, int renderer) s_gs->m_wnd.Show(); - *(HWND*)dsp = s_gs->m_wnd; + *(HWND*)dsp = (HWND)s_gs->m_wnd.GetHandle(); // if(mt) _mm_setcsr(MXCSR); @@ -151,16 +157,20 @@ static INT32 GSopen(void* dsp, char* title, int mt, int renderer) EXPORT_C_(INT32) GSopen(void* dsp, char* title, int mt) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); int renderer; - if (mt == 2){ //pcsx2 sent a switch renderer request + if(mt == 2) + { + // pcsx2 sent a switch renderer request renderer = 1; //DX9 sw mt = 1; } - else { //normal init - renderer = AfxGetApp()->GetProfileInt(_T("Settings"), _T("renderer"), 0); + else + { + // normal init + renderer = theApp.GetConfig("renderer", 0); } + return GSopen(dsp, title, mt, renderer); } @@ -169,56 +179,71 @@ EXPORT_C GSreset() s_gs->Reset(); } -EXPORT_C GSgifSoftReset(int mask) +EXPORT_C GSgifSoftReset(uint32 mask) { - s_gs->SoftReset((BYTE)mask); + s_gs->SoftReset(mask); } -EXPORT_C GSwriteCSR(UINT32 csr) +EXPORT_C GSwriteCSR(uint32 csr) { s_gs->WriteCSR(csr); } -EXPORT_C GSreadFIFO(BYTE* mem) +EXPORT_C GSreadFIFO(uint8* mem) { s_gs->ReadFIFO(mem, 1); } -EXPORT_C GSreadFIFO2(BYTE* mem, UINT32 size) +EXPORT_C GSreadFIFO2(uint8* mem, uint32 size) { s_gs->ReadFIFO(mem, size); } -EXPORT_C GSgifTransfer1(BYTE* mem, UINT32 addr) +EXPORT_C GSgifTransfer1(uint8* mem, uint32 addr) { s_gs->Transfer<0>(mem + addr, (0x4000 - addr) / 16); } -EXPORT_C GSgifTransfer2(BYTE* mem, UINT32 size) +EXPORT_C GSgifTransfer2(uint8* mem, uint32 size) { s_gs->Transfer<1>(mem, size); } -EXPORT_C GSgifTransfer3(BYTE* mem, UINT32 size) +EXPORT_C GSgifTransfer3(uint8* mem, uint32 size) { s_gs->Transfer<2>(mem, size); } EXPORT_C GSvsync(int field) { +#ifdef _WINDOWS + + MSG msg; + + memset(&msg, 0, sizeof(msg)); + + while(msg.message != WM_QUIT && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + +#endif + s_gs->VSync(field); } -EXPORT_C_(UINT32) GSmakeSnapshot(char* path) +EXPORT_C_(uint32) GSmakeSnapshot(char* path) { - return s_gs->MakeSnapshot(CString(path) + _T("gsdx")); + return s_gs->MakeSnapshot(string(path) + "gsdx"); } -EXPORT_C GSkeyEvent(keyEvent* ev) +EXPORT_C GSkeyEvent(GSKeyEventData* e) { + s_gs->KeyEvent(e); } -EXPORT_C_(INT32) GSfreeze(int mode, GSFreezeData* data) +EXPORT_C_(int) GSfreeze(int mode, GSFreezeData* data) { if(mode == FREEZE_SAVE) { @@ -238,8 +263,6 @@ EXPORT_C_(INT32) GSfreeze(int mode, GSFreezeData* data) EXPORT_C GSconfigure() { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - GSSettingsDlg dlg; if(IDOK == dlg.DoModal()) @@ -252,16 +275,6 @@ EXPORT_C GSconfigure() EXPORT_C_(INT32) GStest() { return 0; - - // TODO - - /* - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - - CComPtr dev; - - return SUCCEEDED(D3D10CreateDevice(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &dev)) ? 0 : -1; - */ } EXPORT_C GSabout() @@ -273,12 +286,12 @@ EXPORT_C GSirqCallback(void (*irq)()) s_irq = irq; } -EXPORT_C GSsetGameCRC(DWORD crc, int options) +EXPORT_C GSsetGameCRC(uint32 crc, int options) { s_gs->SetGameCRC(crc, options); } -EXPORT_C GSgetLastTag(UINT32* tag) +EXPORT_C GSgetLastTag(uint32* tag) { s_gs->GetLastTag(tag); } @@ -288,6 +301,8 @@ EXPORT_C GSsetFrameSkip(int frameskip) s_gs->SetFrameSkip(frameskip); } +#ifdef _WINDOWS + EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { int renderer = -1; @@ -303,25 +318,25 @@ EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) ::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS); - CAtlArray buff; + vector buff; if(FILE* fp = fopen(lpszCmdLine, "rb")) { GSinit(); - BYTE regs[0x2000]; + uint8 regs[0x2000]; GSsetBaseMem(regs); HWND hWnd = NULL; - GSopen(&hWnd, _T(""), true, renderer); + GSopen(&hWnd, "", true, renderer); - DWORD crc; + uint32 crc; fread(&crc, 4, 1, fp); GSsetGameCRC(crc, 0); GSFreezeData fd; fread(&fd.size, 4, 1, fp); - fd.data = new BYTE[fd.size]; + fd.data = new uint8[fd.size]; fread(fd.data, fd.size, 1, fp); GSfreeze(FREEZE_LOAD, &fd); delete [] fd.data; @@ -348,20 +363,20 @@ EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) switch(index) { case 0: - if(buff.GetCount() < 0x4000) buff.SetCount(0x4000); + if(buff.size() < 0x4000) buff.resize(0x4000); addr = 0x4000 - size; - fread(buff.GetData() + addr, size, 1, fp); - GSgifTransfer1(buff.GetData(), addr); + fread(&buff[0] + addr, size, 1, fp); + GSgifTransfer1(&buff[0], addr); break; case 1: - if(buff.GetCount() < size) buff.SetCount(size); - fread(buff.GetData(), size, 1, fp); - GSgifTransfer2(buff.GetData(), size / 16); + if(buff.size() < size) buff.resize(size); + fread(&buff[0], size, 1, fp); + GSgifTransfer2(&buff[0], size / 16); break; case 2: - if(buff.GetCount() < size) buff.SetCount(size); - fread(buff.GetData(), size, 1, fp); - GSgifTransfer3(buff.GetData(), size / 16); + if(buff.size() < size) buff.resize(size); + fread(&buff[0], size, 1, fp); + GSgifTransfer3(&buff[0], size / 16); break; } break; @@ -371,8 +386,8 @@ EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) break; case 2: fread(&size, 4, 1, fp); - if(buff.GetCount() < size) buff.SetCount(size); - GSreadFIFO2(buff.GetData(), size / 16); + if(buff.size() < size) buff.resize(size); + GSreadFIFO2(&buff[0], size / 16); break; case 3: fread(regs, 0x2000, 1, fp); @@ -394,15 +409,15 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow { ::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS); - FILE* file = _tfopen(_T("c:\\log.txt"), _T("a")); + FILE* file = fopen("c:\\log.txt", "a"); - _ftprintf(file, _T("-------------------------\n\n")); + fprintf(file, "-------------------------\n\n"); if(1) { GSLocalMemory mem; - static struct {int psm; LPCSTR name;} s_format[] = + static struct {int psm; const char* name;} s_format[] = { {PSM_PSMCT32, "32"}, {PSM_PSMCT24, "24"}, @@ -419,9 +434,9 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow {PSM_PSMZ16S, "16ZS"}, }; - BYTE* ptr = (BYTE*)_aligned_malloc(1024 * 1024 * 4, 16); + uint8* ptr = (uint8*)_aligned_malloc(1024 * 1024 * 4, 16); - for(int i = 0; i < 1024 * 1024 * 4; i++) ptr[i] = (BYTE)i; + for(int i = 0; i < 1024 * 1024 * 4; i++) ptr[i] = (uint8)i; // @@ -432,7 +447,7 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow int w = 1 << tbw; int h = 1 << tbw; - _ftprintf(file, _T("%d x %d\n\n"), w, h); + fprintf(file, "%d x %d\n\n", w, h); for(int i = 0; i < countof(s_format); i++) { @@ -464,7 +479,7 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow TRXREG.RRW = w; TRXREG.RRH = h; - CRect r(0, 0, w, h); + GSVector4i r(0, 0, w, h); GIFRegTEX0 TEX0; @@ -496,7 +511,7 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow end = clock(); - _ftprintf(file, _T("%6d %6d | "), (int)((float)trlen * n / (end - start) / 1000), (int)((float)(w * h) * n / (end - start) / 1000)); + fprintf(file, "%6d %6d | ", (int)((float)trlen * n / (end - start) / 1000), (int)((float)(w * h) * n / (end - start) / 1000)); start = clock(); @@ -510,7 +525,7 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow end = clock(); - _ftprintf(file, _T("%6d %6d | "), (int)((float)trlen * n / (end - start) / 1000), (int)((float)(w * h) * n / (end - start) / 1000)); + fprintf(file, "%6d %6d | ", (int)((float)trlen * n / (end - start) / 1000), (int)((float)(w * h) * n / (end - start) / 1000)); start = clock(); @@ -521,7 +536,7 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow end = clock(); - _ftprintf(file, _T("%6d %6d "), (int)((float)len * n / (end - start) / 1000), (int)((float)(w * h) * n / (end - start) / 1000)); + fprintf(file, "%6d %6d ", (int)((float)len * n / (end - start) / 1000), (int)((float)(w * h) * n / (end - start) / 1000)); if(psm.pal > 0) { @@ -534,15 +549,15 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow end = clock(); - _ftprintf(file, _T("| %6d %6d "), (int)((float)len * n / (end - start) / 1000), (int)((float)(w * h) * n / (end - start) / 1000)); + fprintf(file, "| %6d %6d ", (int)((float)len * n / (end - start) / 1000), (int)((float)(w * h) * n / (end - start) / 1000)); } - _ftprintf(file, _T("\n")); + fprintf(file, "\n"); fflush(file); } - _ftprintf(file, _T("\n")); + fprintf(file, "\n"); } _aligned_free(ptr); @@ -554,9 +569,9 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow { GSLocalMemory mem; - BYTE* ptr = (BYTE*)_aligned_malloc(1024 * 1024 * 4, 16); + uint8* ptr = (uint8*)_aligned_malloc(1024 * 1024 * 4, 16); - for(int i = 0; i < 1024 * 1024 * 4; i++) ptr[i] = (BYTE)i; + for(int i = 0; i < 1024 * 1024 * 4; i++) ptr[i] = (uint8)i; const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[PSM_PSMCT32]; @@ -591,3 +606,4 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow fclose(file); } +#endif diff --git a/plugins/GSdx/GS.h b/plugins/GSdx/GS.h index f670531aa4..3ef534c9bc 100644 --- a/plugins/GSdx/GS.h +++ b/plugins/GSdx/GS.h @@ -28,6 +28,9 @@ #define PLUGIN_VERSION 15 +#define MAX_PAGES 512 +#define MAX_BLOCKS 16384 + #include "GSVector.h" #pragma pack(push, 1) @@ -212,23 +215,25 @@ enum GS_AFAIL #define REG32(name) \ union name \ { \ - UINT32 ai32; \ + uint32 u32; \ struct { \ #define REG64(name) \ union name \ { \ - UINT64 i64; \ - UINT32 ai32[2]; \ + uint64 u64; \ + uint32 u32[2]; \ void operator = (const GSVector4i& v) {GSVector4i::storel(this, v);} \ + bool operator == (const union name& r) const {return ((GSVector4i)r).eq(*this);} \ + bool operator != (const union name& r) const {return !((GSVector4i)r).eq(*this);} \ operator GSVector4i() const {return GSVector4i::loadl(this);} \ struct { \ #define REG128(name)\ union name \ { \ - UINT64 ai64[2]; \ - UINT32 ai32[4]; \ + uint64 u64[2]; \ + uint32 u32[4]; \ struct { \ #define REG32_(prefix, name) REG32(prefix##name) @@ -241,176 +246,176 @@ union name \ #define REG32_SET(name) \ union name \ { \ - UINT32 ai32; \ + uint32 u32; \ #define REG64_SET(name) \ union name \ { \ - UINT64 i64; \ - UINT32 ai32[2]; \ + uint64 u64; \ + uint32 u32[2]; \ #define REG128_SET(name)\ union name \ { \ - __m128i ai128; \ - UINT64 ai64[2]; \ - UINT32 ai32[4]; \ + __m128i m128; \ + uint64 u64[2]; \ + uint32 u32[4]; \ #define REG_SET_END }; REG64_(GSReg, BGCOLOR) - UINT32 R:8; - UINT32 G:8; - UINT32 B:8; - UINT32 _PAD1:8; - UINT32 _PAD2:32; + uint32 R:8; + uint32 G:8; + uint32 B:8; + uint32 _PAD1:8; + uint32 _PAD2:32; REG_END REG64_(GSReg, BUSDIR) - UINT32 DIR:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; + uint32 DIR:1; + uint32 _PAD1:31; + uint32 _PAD2:32; REG_END REG64_(GSReg, CSR) - UINT32 rSIGNAL:1; - UINT32 rFINISH:1; - UINT32 rHSINT:1; - UINT32 rVSINT:1; - UINT32 rEDWINT:1; - UINT32 rZERO1:1; - UINT32 rZERO2:1; - UINT32 r_PAD1:1; - UINT32 rFLUSH:1; - UINT32 rRESET:1; - UINT32 r_PAD2:2; - UINT32 rNFIELD:1; - UINT32 rFIELD:1; - UINT32 rFIFO:2; - UINT32 rREV:8; - UINT32 rID:8; - UINT32 wSIGNAL:1; - UINT32 wFINISH:1; - UINT32 wHSINT:1; - UINT32 wVSINT:1; - UINT32 wEDWINT:1; - UINT32 wZERO1:1; - UINT32 wZERO2:1; - UINT32 w_PAD1:1; - UINT32 wFLUSH:1; - UINT32 wRESET:1; - UINT32 w_PAD2:2; - UINT32 wNFIELD:1; - UINT32 wFIELD:1; - UINT32 wFIFO:2; - UINT32 wREV:8; - UINT32 wID:8; + uint32 rSIGNAL:1; + uint32 rFINISH:1; + uint32 rHSINT:1; + uint32 rVSINT:1; + uint32 rEDWINT:1; + uint32 rZERO1:1; + uint32 rZERO2:1; + uint32 r_PAD1:1; + uint32 rFLUSH:1; + uint32 rRESET:1; + uint32 r_PAD2:2; + uint32 rNFIELD:1; + uint32 rFIELD:1; + uint32 rFIFO:2; + uint32 rREV:8; + uint32 rID:8; + uint32 wSIGNAL:1; + uint32 wFINISH:1; + uint32 wHSINT:1; + uint32 wVSINT:1; + uint32 wEDWINT:1; + uint32 wZERO1:1; + uint32 wZERO2:1; + uint32 w_PAD1:1; + uint32 wFLUSH:1; + uint32 wRESET:1; + uint32 w_PAD2:2; + uint32 wNFIELD:1; + uint32 wFIELD:1; + uint32 wFIFO:2; + uint32 wREV:8; + uint32 wID:8; REG_END REG64_(GSReg, DISPFB) // (-1/2) - UINT32 FBP:9; - UINT32 FBW:6; - UINT32 PSM:5; - UINT32 _PAD:12; - UINT32 DBX:11; - UINT32 DBY:11; - UINT32 _PAD2:10; + uint32 FBP:9; + uint32 FBW:6; + uint32 PSM:5; + uint32 _PAD:12; + uint32 DBX:11; + uint32 DBY:11; + uint32 _PAD2:10; REG_END2 - UINT32 Block() const {return FBP << 5;} + uint32 Block() const {return FBP << 5;} REG_END2 REG64_(GSReg, DISPLAY) // (-1/2) - UINT32 DX:12; - UINT32 DY:11; - UINT32 MAGH:4; - UINT32 MAGV:2; - UINT32 _PAD:3; - UINT32 DW:12; - UINT32 DH:11; - UINT32 _PAD2:9; + uint32 DX:12; + uint32 DY:11; + uint32 MAGH:4; + uint32 MAGV:2; + uint32 _PAD:3; + uint32 DW:12; + uint32 DH:11; + uint32 _PAD2:9; REG_END REG64_(GSReg, EXTBUF) - UINT32 EXBP:14; - UINT32 EXBW:6; - UINT32 FBIN:2; - UINT32 WFFMD:1; - UINT32 EMODA:2; - UINT32 EMODC:2; - UINT32 _PAD1:5; - UINT32 WDX:11; - UINT32 WDY:11; - UINT32 _PAD2:10; + uint32 EXBP:14; + uint32 EXBW:6; + uint32 FBIN:2; + uint32 WFFMD:1; + uint32 EMODA:2; + uint32 EMODC:2; + uint32 _PAD1:5; + uint32 WDX:11; + uint32 WDY:11; + uint32 _PAD2:10; REG_END REG64_(GSReg, EXTDATA) - UINT32 SX:12; - UINT32 SY:11; - UINT32 SMPH:4; - UINT32 SMPV:2; - UINT32 _PAD1:3; - UINT32 WW:12; - UINT32 WH:11; - UINT32 _PAD2:9; + uint32 SX:12; + uint32 SY:11; + uint32 SMPH:4; + uint32 SMPV:2; + uint32 _PAD1:3; + uint32 WW:12; + uint32 WH:11; + uint32 _PAD2:9; REG_END REG64_(GSReg, EXTWRITE) - UINT32 WRITE:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; + uint32 WRITE:1; + uint32 _PAD1:31; + uint32 _PAD2:32; REG_END REG64_(GSReg, IMR) - UINT32 _PAD1:8; - UINT32 SIGMSK:1; - UINT32 FINISHMSK:1; - UINT32 HSMSK:1; - UINT32 VSMSK:1; - UINT32 EDWMSK:1; - UINT32 _PAD2:19; - UINT32 _PAD3:32; + uint32 _PAD1:8; + uint32 SIGMSK:1; + uint32 FINISHMSK:1; + uint32 HSMSK:1; + uint32 VSMSK:1; + uint32 EDWMSK:1; + uint32 _PAD2:19; + uint32 _PAD3:32; REG_END REG64_(GSReg, PMODE) - UINT32 EN1:1; - UINT32 EN2:1; - UINT32 CRTMD:3; - UINT32 MMOD:1; - UINT32 AMOD:1; - UINT32 SLBG:1; - UINT32 ALP:8; - UINT32 _PAD:16; - UINT32 _PAD1:32; + uint32 EN1:1; + uint32 EN2:1; + uint32 CRTMD:3; + uint32 MMOD:1; + uint32 AMOD:1; + uint32 SLBG:1; + uint32 ALP:8; + uint32 _PAD:16; + uint32 _PAD1:32; REG_END REG64_(GSReg, SIGLBLID) - UINT32 SIGID:32; - UINT32 LBLID:32; + uint32 SIGID:32; + uint32 LBLID:32; REG_END REG64_(GSReg, SMODE1) - UINT32 RC:3; - UINT32 LC:7; - UINT32 T1248:2; - UINT32 SLCK:1; - UINT32 CMOD:2; - UINT32 EX:1; - UINT32 PRST:1; - UINT32 SINT:1; - UINT32 XPCK:1; - UINT32 PCK2:2; - UINT32 SPML:4; - UINT32 GCONT:1; // YCrCb - UINT32 PHS:1; - UINT32 PVS:1; - UINT32 PEHS:1; - UINT32 PEVS:1; - UINT32 CLKSEL:2; - UINT32 NVCK:1; - UINT32 SLCK2:1; - UINT32 VCKSEL:2; - UINT32 VHP:1; - UINT32 _PAD1:27; + uint32 RC:3; + uint32 LC:7; + uint32 T1248:2; + uint32 SLCK:1; + uint32 CMOD:2; + uint32 EX:1; + uint32 PRST:1; + uint32 SINT:1; + uint32 XPCK:1; + uint32 PCK2:2; + uint32 SPML:4; + uint32 GCONT:1; // YCrCb + uint32 PHS:1; + uint32 PVS:1; + uint32 PEHS:1; + uint32 PEVS:1; + uint32 CLKSEL:2; + uint32 NVCK:1; + uint32 SLCK2:1; + uint32 VCKSEL:2; + uint32 VHP:1; + uint32 _PAD1:27; REG_END /* @@ -430,26 +435,30 @@ CLKSEL=1 CMOD=0 EX=0 GCONT=0 LC=32 NVCK=1 PCK2=0 PEHS=0 PEVS=0 PHS=0 PRST=1 PVS= */ REG64_(GSReg, SMODE2) - UINT32 INT:1; - UINT32 FFMD:1; - UINT32 DPMS:2; - UINT32 _PAD2:28; - UINT32 _PAD3:32; + uint32 INT:1; + uint32 FFMD:1; + uint32 DPMS:2; + uint32 _PAD2:28; + uint32 _PAD3:32; REG_END REG64_(GSReg, SRFSH) + uint32 _DUMMY; // TODO REG_END REG64_(GSReg, SYNCH1) + uint32 _DUMMY; // TODO REG_END REG64_(GSReg, SYNCH2) + uint32 _DUMMY; // TODO REG_END REG64_(GSReg, SYNCV) + uint64 _DUMMY; // TODO REG_END @@ -474,58 +483,60 @@ REG_SET_END // #define SET_GIF_REG(gifTag, iRegNo, uiValue) \ - {((GIFTag*)&gifTag)->ai64[1] |= (((uiValue) & 0xf) << ((iRegNo) << 2));} + {((GIFTag*)&gifTag)->u64[1] |= (((uiValue) & 0xf) << ((iRegNo) << 2));} #ifdef _M_AMD64 #define GET_GIF_REG(tag, reg) \ - (((tag).ai64[1] >> ((reg) << 2)) & 0xf) + (((tag).u64[1] >> ((reg) << 2)) & 0xf) #else #define GET_GIF_REG(tag, reg) \ - (((tag).ai32[2 + ((reg) >> 3)] >> (((reg) & 7) << 2)) & 0xf) + (((tag).u32[2 + ((reg) >> 3)] >> (((reg) & 7) << 2)) & 0xf) #endif // // GIFTag REG128(GIFTag) - UINT32 NLOOP:15; - UINT32 EOP:1; - UINT32 _PAD1:16; - UINT32 _PAD2:14; - UINT32 PRE:1; - UINT32 PRIM:11; - UINT32 FLG:2; // enum GIF_FLG - UINT32 NREG:4; - UINT64 REGS:64; + uint32 NLOOP:15; + uint32 EOP:1; + uint32 _PAD1:16; + uint32 _PAD2:14; + uint32 PRE:1; + uint32 PRIM:11; + uint32 FLG:2; // enum GIF_FLG + uint32 NREG:4; + uint64 REGS:64; REG_END // GIFReg REG64_(GIFReg, ALPHA) - UINT32 A:2; - UINT32 B:2; - UINT32 C:2; - UINT32 D:2; - UINT32 _PAD1:24; - UINT32 FIX:8; - UINT32 _PAD2:24; + uint32 A:2; + uint32 B:2; + uint32 C:2; + uint32 D:2; + uint32 _PAD1:24; + uint32 FIX:8; + uint32 _PAD2:24; REG_END2 - __forceinline bool IsOpaque() const {return (A == B || C == 2 && FIX == 0) && D == 0 || (A == 0 && B == 2 && C == 2 && D == 2 && FIX == 0x80);} // output will be Cs/As + // opaque => output will be Cs/As + __forceinline bool IsOpaque() const {return (A == B || C == 2 && FIX == 0) && D == 0 || (A == 0 && B == D && C == 2 && FIX == 0x80);} + __forceinline bool IsOpaque(int amin, int amax) const {return (A == B || amax == 0) && D == 0 || A == 0 && B == D && amin == 0x80 && amax == 0x80;} REG_END2 REG64_(GIFReg, BITBLTBUF) - UINT32 SBP:14; - UINT32 _PAD1:2; - UINT32 SBW:6; - UINT32 _PAD2:2; - UINT32 SPSM:6; - UINT32 _PAD3:2; - UINT32 DBP:14; - UINT32 _PAD4:2; - UINT32 DBW:6; - UINT32 _PAD5:2; - UINT32 DPSM:6; - UINT32 _PAD6:2; + uint32 SBP:14; + uint32 _PAD1:2; + uint32 SBW:6; + uint32 _PAD2:2; + uint32 SPSM:6; + uint32 _PAD3:2; + uint32 DBP:14; + uint32 _PAD4:2; + uint32 DBW:6; + uint32 _PAD5:2; + uint32 DPSM:6; + uint32 _PAD6:2; REG_END REG64_(GIFReg, CLAMP) @@ -533,212 +544,212 @@ union { struct { - UINT32 WMS:2; - UINT32 WMT:2; - UINT32 MINU:10; - UINT32 MAXU:10; - UINT32 _PAD1:8; - UINT32 _PAD2:2; - UINT32 MAXV:10; - UINT32 _PAD3:20; + uint32 WMS:2; + uint32 WMT:2; + uint32 MINU:10; + uint32 MAXU:10; + uint32 _PAD1:8; + uint32 _PAD2:2; + uint32 MAXV:10; + uint32 _PAD3:20; }; struct { - UINT64 _PAD4:24; - UINT64 MINV:10; - UINT64 _PAD5:30; + uint64 _PAD4:24; + uint64 MINV:10; + uint64 _PAD5:30; }; }; REG_END REG64_(GIFReg, COLCLAMP) - UINT32 CLAMP:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; + uint32 CLAMP:1; + uint32 _PAD1:31; + uint32 _PAD2:32; REG_END REG64_(GIFReg, DIMX) - INT32 DM00:3; - INT32 _PAD00:1; - INT32 DM01:3; - INT32 _PAD01:1; - INT32 DM02:3; - INT32 _PAD02:1; - INT32 DM03:3; - INT32 _PAD03:1; - INT32 DM10:3; - INT32 _PAD10:1; - INT32 DM11:3; - INT32 _PAD11:1; - INT32 DM12:3; - INT32 _PAD12:1; - INT32 DM13:3; - INT32 _PAD13:1; - INT32 DM20:3; - INT32 _PAD20:1; - INT32 DM21:3; - INT32 _PAD21:1; - INT32 DM22:3; - INT32 _PAD22:1; - INT32 DM23:3; - INT32 _PAD23:1; - INT32 DM30:3; - INT32 _PAD30:1; - INT32 DM31:3; - INT32 _PAD31:1; - INT32 DM32:3; - INT32 _PAD32:1; - INT32 DM33:3; - INT32 _PAD33:1; + int32 DM00:3; + int32 _PAD00:1; + int32 DM01:3; + int32 _PAD01:1; + int32 DM02:3; + int32 _PAD02:1; + int32 DM03:3; + int32 _PAD03:1; + int32 DM10:3; + int32 _PAD10:1; + int32 DM11:3; + int32 _PAD11:1; + int32 DM12:3; + int32 _PAD12:1; + int32 DM13:3; + int32 _PAD13:1; + int32 DM20:3; + int32 _PAD20:1; + int32 DM21:3; + int32 _PAD21:1; + int32 DM22:3; + int32 _PAD22:1; + int32 DM23:3; + int32 _PAD23:1; + int32 DM30:3; + int32 _PAD30:1; + int32 DM31:3; + int32 _PAD31:1; + int32 DM32:3; + int32 _PAD32:1; + int32 DM33:3; + int32 _PAD33:1; REG_END REG64_(GIFReg, DTHE) - UINT32 DTHE:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; + uint32 DTHE:1; + uint32 _PAD1:31; + uint32 _PAD2:32; REG_END REG64_(GIFReg, FBA) - UINT32 FBA:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; + uint32 FBA:1; + uint32 _PAD1:31; + uint32 _PAD2:32; REG_END REG64_(GIFReg, FINISH) - UINT32 _PAD1:32; - UINT32 _PAD2:32; + uint32 _PAD1:32; + uint32 _PAD2:32; REG_END REG64_(GIFReg, FOG) - UINT32 _PAD1:32; - UINT32 _PAD2:24; - UINT32 F:8; + uint32 _PAD1:32; + uint32 _PAD2:24; + uint32 F:8; REG_END REG64_(GIFReg, FOGCOL) - UINT32 FCR:8; - UINT32 FCG:8; - UINT32 FCB:8; - UINT32 _PAD1:8; - UINT32 _PAD2:32; + uint32 FCR:8; + uint32 FCG:8; + uint32 FCB:8; + uint32 _PAD1:8; + uint32 _PAD2:32; REG_END REG64_(GIFReg, FRAME) - UINT32 FBP:9; - UINT32 _PAD1:7; - UINT32 FBW:6; - UINT32 _PAD2:2; - UINT32 PSM:6; - UINT32 _PAD3:2; - UINT32 FBMSK:32; + uint32 FBP:9; + uint32 _PAD1:7; + uint32 FBW:6; + uint32 _PAD2:2; + uint32 PSM:6; + uint32 _PAD3:2; + uint32 FBMSK:32; REG_END2 - UINT32 Block() const {return FBP << 5;} + uint32 Block() const {return FBP << 5;} REG_END2 REG64_(GIFReg, HWREG) - UINT32 DATA_LOWER:32; - UINT32 DATA_UPPER:32; + uint32 DATA_LOWER:32; + uint32 DATA_UPPER:32; REG_END REG64_(GIFReg, LABEL) - UINT32 ID:32; - UINT32 IDMSK:32; + uint32 ID:32; + uint32 IDMSK:32; REG_END REG64_(GIFReg, MIPTBP1) - UINT64 TBP1:14; - UINT64 TBW1:6; - UINT64 TBP2:14; - UINT64 TBW2:6; - UINT64 TBP3:14; - UINT64 TBW3:6; - UINT64 _PAD:4; + uint64 TBP1:14; + uint64 TBW1:6; + uint64 TBP2:14; + uint64 TBW2:6; + uint64 TBP3:14; + uint64 TBW3:6; + uint64 _PAD:4; REG_END REG64_(GIFReg, MIPTBP2) - UINT64 TBP4:14; - UINT64 TBW4:6; - UINT64 TBP5:14; - UINT64 TBW5:6; - UINT64 TBP6:14; - UINT64 TBW6:6; - UINT64 _PAD:4; + uint64 TBP4:14; + uint64 TBW4:6; + uint64 TBP5:14; + uint64 TBW5:6; + uint64 TBP6:14; + uint64 TBW6:6; + uint64 _PAD:4; REG_END REG64_(GIFReg, NOP) - UINT32 _PAD1:32; - UINT32 _PAD2:32; + uint32 _PAD1:32; + uint32 _PAD2:32; REG_END REG64_(GIFReg, PABE) - UINT32 PABE:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; + uint32 PABE:1; + uint32 _PAD1:31; + uint32 _PAD2:32; REG_END REG64_(GIFReg, PRIM) - UINT32 PRIM:3; - UINT32 IIP:1; - UINT32 TME:1; - UINT32 FGE:1; - UINT32 ABE:1; - UINT32 AA1:1; - UINT32 FST:1; - UINT32 CTXT:1; - UINT32 FIX:1; - UINT32 _PAD1:21; - UINT32 _PAD2:32; + uint32 PRIM:3; + uint32 IIP:1; + uint32 TME:1; + uint32 FGE:1; + uint32 ABE:1; + uint32 AA1:1; + uint32 FST:1; + uint32 CTXT:1; + uint32 FIX:1; + uint32 _PAD1:21; + uint32 _PAD2:32; REG_END REG64_(GIFReg, PRMODE) - UINT32 _PRIM:3; - UINT32 IIP:1; - UINT32 TME:1; - UINT32 FGE:1; - UINT32 ABE:1; - UINT32 AA1:1; - UINT32 FST:1; - UINT32 CTXT:1; - UINT32 FIX:1; - UINT32 _PAD2:21; - UINT32 _PAD3:32; + uint32 _PRIM:3; + uint32 IIP:1; + uint32 TME:1; + uint32 FGE:1; + uint32 ABE:1; + uint32 AA1:1; + uint32 FST:1; + uint32 CTXT:1; + uint32 FIX:1; + uint32 _PAD2:21; + uint32 _PAD3:32; REG_END REG64_(GIFReg, PRMODECONT) - UINT32 AC:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; + uint32 AC:1; + uint32 _PAD1:31; + uint32 _PAD2:32; REG_END REG64_(GIFReg, RGBAQ) - UINT32 R:8; - UINT32 G:8; - UINT32 B:8; - UINT32 A:8; + uint32 R:8; + uint32 G:8; + uint32 B:8; + uint32 A:8; float Q; REG_END REG64_(GIFReg, SCANMSK) - UINT32 MSK:2; - UINT32 _PAD1:30; - UINT32 _PAD2:32; + uint32 MSK:2; + uint32 _PAD1:30; + uint32 _PAD2:32; REG_END REG64_(GIFReg, SCISSOR) - UINT32 SCAX0:11; - UINT32 _PAD1:5; - UINT32 SCAX1:11; - UINT32 _PAD2:5; - UINT32 SCAY0:11; - UINT32 _PAD3:5; - UINT32 SCAY1:11; - UINT32 _PAD4:5; + uint32 SCAX0:11; + uint32 _PAD1:5; + uint32 SCAX1:11; + uint32 _PAD2:5; + uint32 SCAY0:11; + uint32 _PAD3:5; + uint32 SCAY1:11; + uint32 _PAD4:5; REG_END REG64_(GIFReg, SIGNAL) - UINT32 ID:32; - UINT32 IDMSK:32; + uint32 ID:32; + uint32 IDMSK:32; REG_END REG64_(GIFReg, ST) @@ -747,16 +758,16 @@ REG64_(GIFReg, ST) REG_END REG64_(GIFReg, TEST) - UINT32 ATE:1; - UINT32 ATST:3; - UINT32 AREF:8; - UINT32 AFAIL:2; - UINT32 DATE:1; - UINT32 DATM:1; - UINT32 ZTE:1; - UINT32 ZTST:2; - UINT32 _PAD1:13; - UINT32 _PAD2:32; + uint32 ATE:1; + uint32 ATST:3; + uint32 AREF:8; + uint32 AFAIL:2; + uint32 DATE:1; + uint32 DATM:1; + uint32 ZTE:1; + uint32 ZTST:2; + uint32 _PAD1:13; + uint32 _PAD2:32; REG_END2 __forceinline bool DoFirstPass() {return !ATE || ATST != 0;} // not all pixels fail automatically __forceinline bool DoSecondPass() {return ATE && ATST != 1 && AFAIL != 0;} // pixels may fail, write fb/z @@ -768,152 +779,179 @@ union { struct { - UINT32 TBP0:14; - UINT32 TBW:6; - UINT32 PSM:6; - UINT32 TW:4; - UINT32 _PAD1:2; - UINT32 _PAD2:2; - UINT32 TCC:1; - UINT32 TFX:2; - UINT32 CBP:14; - UINT32 CPSM:4; - UINT32 CSM:1; - UINT32 CSA:5; - UINT32 CLD:3; + uint32 TBP0:14; + uint32 TBW:6; + uint32 PSM:6; + uint32 TW:4; + uint32 _PAD1:2; + uint32 _PAD2:2; + uint32 TCC:1; + uint32 TFX:2; + uint32 CBP:14; + uint32 CPSM:4; + uint32 CSM:1; + uint32 CSA:5; + uint32 CLD:3; }; struct { - UINT64 _PAD3:30; - UINT64 TH:4; - UINT64 _PAD4:30; + uint64 _PAD3:30; + uint64 TH:4; + uint64 _PAD4:30; }; }; REG_END REG64_(GIFReg, TEX1) - UINT32 LCM:1; - UINT32 _PAD1:1; - UINT32 MXL:3; - UINT32 MMAG:1; - UINT32 MMIN:3; - UINT32 MTBA:1; - UINT32 _PAD2:9; - UINT32 L:2; - UINT32 _PAD3:11; - UINT32 K:12; - UINT32 _PAD4:20; + uint32 LCM:1; + uint32 _PAD1:1; + uint32 MXL:3; + uint32 MMAG:1; + uint32 MMIN:3; + uint32 MTBA:1; + uint32 _PAD2:9; + uint32 L:2; + uint32 _PAD3:11; + uint32 K:12; + uint32 _PAD4:20; REG_END2 + + bool IsMinLinear() const {return (MMIN == 1) || (MMIN & 4);} + bool IsMagLinear() const {return MMAG;} + bool IsLinear() const { - bool mmag = (MMAG & 1); - bool mmin = (MMIN == 1) || (MMIN & 4); + bool mmin = IsMinLinear(); + bool mmag = IsMagLinear(); return !LCM ? mmag || mmin : K <= 0 ? mmag : mmin; } + + bool IsLinear(float qmin, float qmax) const + { + bool mmin = IsMinLinear(); + bool mmag = IsMagLinear(); + + if(mmag == mmin) return mmag; + + float LODmin = K; + float LODmax = K; + + if(!LCM) + { + float f = (float)(1 << L) / log(2.0f); + + LODmin += log(1.0f / abs(qmax)) * f; + LODmax += log(1.0f / abs(qmin)) * f; + } + + return LODmax <= 0 ? mmag : LODmin > 0 ? mmin : mmag || mmin; + } + REG_END2 REG64_(GIFReg, TEX2) - UINT32 _PAD1:20; - UINT32 PSM:6; - UINT32 _PAD2:6; - UINT32 _PAD3:5; - UINT32 CBP:14; - UINT32 CPSM:4; - UINT32 CSM:1; - UINT32 CSA:5; - UINT32 CLD:3; + uint32 _PAD1:20; + uint32 PSM:6; + uint32 _PAD2:6; + uint32 _PAD3:5; + uint32 CBP:14; + uint32 CPSM:4; + uint32 CSM:1; + uint32 CSA:5; + uint32 CLD:3; REG_END REG64_(GIFReg, TEXA) - UINT32 TA0:8; - UINT32 _PAD1:7; - UINT32 AEM:1; - UINT32 _PAD2:16; - UINT32 TA1:8; - UINT32 _PAD3:24; + uint32 TA0:8; + uint32 _PAD1:7; + uint32 AEM:1; + uint32 _PAD2:16; + uint32 TA1:8; + uint32 _PAD3:24; REG_END REG64_(GIFReg, TEXCLUT) - UINT32 CBW:6; - UINT32 COU:6; - UINT32 COV:10; - UINT32 _PAD1:10; - UINT32 _PAD2:32; + uint32 CBW:6; + uint32 COU:6; + uint32 COV:10; + uint32 _PAD1:10; + uint32 _PAD2:32; REG_END REG64_(GIFReg, TEXFLUSH) - UINT32 _PAD1:32; - UINT32 _PAD2:32; + uint32 _PAD1:32; + uint32 _PAD2:32; REG_END REG64_(GIFReg, TRXDIR) - UINT32 XDIR:2; - UINT32 _PAD1:30; - UINT32 _PAD2:32; + uint32 XDIR:2; + uint32 _PAD1:30; + uint32 _PAD2:32; REG_END REG64_(GIFReg, TRXPOS) - UINT32 SSAX:11; - UINT32 _PAD1:5; - UINT32 SSAY:11; - UINT32 _PAD2:5; - UINT32 DSAX:11; - UINT32 _PAD3:5; - UINT32 DSAY:11; - UINT32 DIR:2; - UINT32 _PAD4:3; + uint32 SSAX:11; + uint32 _PAD1:5; + uint32 SSAY:11; + uint32 _PAD2:5; + uint32 DSAX:11; + uint32 _PAD3:5; + uint32 DSAY:11; + uint32 DIRY:1; + uint32 DIRX:1; + uint32 _PAD4:3; REG_END REG64_(GIFReg, TRXREG) - UINT32 RRW:12; - UINT32 _PAD1:20; - UINT32 RRH:12; - UINT32 _PAD2:20; + uint32 RRW:12; + uint32 _PAD1:20; + uint32 RRH:12; + uint32 _PAD2:20; REG_END // GSState::GIFPackedRegHandlerUV and GSState::GIFRegHandlerUV will make sure that the _PAD1/2 bits are set to zero REG64_(GIFReg, UV) - UINT32 U:16; -// UINT32 _PAD1:2; - UINT32 V:16; -// UINT32 _PAD2:2; - UINT32 _PAD3:32; + uint32 U:16; +// uint32 _PAD1:2; + uint32 V:16; +// uint32 _PAD2:2; + uint32 _PAD3:32; REG_END // GSState::GIFRegHandlerXYOFFSET will make sure that the _PAD1/2 bits are set to zero REG64_(GIFReg, XYOFFSET) - UINT32 OFX; // :16; UINT32 _PAD1:16; - UINT32 OFY; // :16; UINT32 _PAD2:16; + uint32 OFX; // :16; uint32 _PAD1:16; + uint32 OFY; // :16; uint32 _PAD2:16; REG_END REG64_(GIFReg, XYZ) - UINT32 X:16; - UINT32 Y:16; - UINT32 Z:32; + uint32 X:16; + uint32 Y:16; + uint32 Z:32; REG_END REG64_(GIFReg, XYZF) - UINT32 X:16; - UINT32 Y:16; - UINT32 Z:24; - UINT32 F:8; + uint32 X:16; + uint32 Y:16; + uint32 Z:24; + uint32 F:8; REG_END REG64_(GIFReg, ZBUF) - UINT32 ZBP:9; - UINT32 _PAD1:15; - // UINT32 PSM:4; - // UINT32 _PAD2:4; - UINT32 PSM:6; - UINT32 _PAD2:2; - UINT32 ZMSK:1; - UINT32 _PAD3:31; + uint32 ZBP:9; + uint32 _PAD1:15; + // uint32 PSM:4; + // uint32 _PAD2:4; + uint32 PSM:6; + uint32 _PAD2:2; + uint32 ZMSK:1; + uint32 _PAD3:31; REG_END2 - UINT32 Block() const {return ZBP << 5;} + uint32 Block() const {return ZBP << 5;} REG_END2 REG64_SET(GIFReg) @@ -962,87 +1000,87 @@ REG_SET_END // GIFPacked REG128_(GIFPacked, PRIM) - UINT32 PRIM:11; - UINT32 _PAD1:21; - UINT32 _PAD2:32; - UINT32 _PAD3:32; - UINT32 _PAD4:32; + uint32 PRIM:11; + uint32 _PAD1:21; + uint32 _PAD2:32; + uint32 _PAD3:32; + uint32 _PAD4:32; REG_END REG128_(GIFPacked, RGBA) - UINT32 R:8; - UINT32 _PAD1:24; - UINT32 G:8; - UINT32 _PAD2:24; - UINT32 B:8; - UINT32 _PAD3:24; - UINT32 A:8; - UINT32 _PAD4:24; + uint32 R:8; + uint32 _PAD1:24; + uint32 G:8; + uint32 _PAD2:24; + uint32 B:8; + uint32 _PAD3:24; + uint32 A:8; + uint32 _PAD4:24; REG_END REG128_(GIFPacked, STQ) float S; float T; float Q; - UINT32 _PAD1:32; + uint32 _PAD1:32; REG_END REG128_(GIFPacked, UV) - UINT32 U:14; - UINT32 _PAD1:18; - UINT32 V:14; - UINT32 _PAD2:18; - UINT32 _PAD3:32; - UINT32 _PAD4:32; + uint32 U:14; + uint32 _PAD1:18; + uint32 V:14; + uint32 _PAD2:18; + uint32 _PAD3:32; + uint32 _PAD4:32; REG_END REG128_(GIFPacked, XYZF2) - UINT32 X:16; - UINT32 _PAD1:16; - UINT32 Y:16; - UINT32 _PAD2:16; - UINT32 _PAD3:4; - UINT32 Z:24; - UINT32 _PAD4:4; - UINT32 _PAD5:4; - UINT32 F:8; - UINT32 _PAD6:3; - UINT32 ADC:1; - UINT32 _PAD7:16; + uint32 X:16; + uint32 _PAD1:16; + uint32 Y:16; + uint32 _PAD2:16; + uint32 _PAD3:4; + uint32 Z:24; + uint32 _PAD4:4; + uint32 _PAD5:4; + uint32 F:8; + uint32 _PAD6:3; + uint32 ADC:1; + uint32 _PAD7:16; REG_END REG128_(GIFPacked, XYZ2) - UINT32 X:16; - UINT32 _PAD1:16; - UINT32 Y:16; - UINT32 _PAD2:16; - UINT32 Z:32; - UINT32 _PAD3:15; - UINT32 ADC:1; - UINT32 _PAD4:16; + uint32 X:16; + uint32 _PAD1:16; + uint32 Y:16; + uint32 _PAD2:16; + uint32 Z:32; + uint32 _PAD3:15; + uint32 ADC:1; + uint32 _PAD4:16; REG_END REG128_(GIFPacked, FOG) - UINT32 _PAD1:32; - UINT32 _PAD2:32; - UINT32 _PAD3:32; - UINT32 _PAD4:4; - UINT32 F:8; - UINT32 _PAD5:20; + uint32 _PAD1:32; + uint32 _PAD2:32; + uint32 _PAD3:32; + uint32 _PAD4:4; + uint32 F:8; + uint32 _PAD5:20; REG_END REG128_(GIFPacked, A_D) - UINT64 DATA:64; - UINT32 ADDR:8; // enum GIF_A_D_REG - UINT32 _PAD1:24; - UINT32 _PAD2:32; + uint64 DATA:64; + uint32 ADDR:8; // enum GIF_A_D_REG + uint32 _PAD1:24; + uint32 _PAD2:32; REG_END REG128_(GIFPacked, NOP) - UINT32 _PAD1:32; - UINT32 _PAD2:32; - UINT32 _PAD3:32; - UINT32 _PAD4:32; + uint32 _PAD1:32; + uint32 _PAD2:32; + uint32 _PAD3:32; + uint32 _PAD4:32; REG_END REG128_SET(GIFPackedReg) @@ -1061,21 +1099,41 @@ REG_SET_END __declspec(align(16)) struct GIFPath { GIFTag tag; - UINT32 nreg; - UINT32 _pad[3]; + uint32 reg; + uint32 nreg; + uint32 nloop; + uint32 adonly; GSVector4i regs; void SetTag(const void* mem) { GSVector4i v = GSVector4i::load(mem); GSVector4i::store(&tag, v); - nreg = 0; + reg = 0; regs = v.uph8(v >> 4) & 0x0f0f0f0f; + nreg = tag.NREG; + nloop = tag.NLOOP; + adonly = nreg == 1 && regs.u8[0] == GIF_REG_A_D; } - DWORD GetReg() + __forceinline uint8 GetReg() { - return regs.u8[nreg]; // (DWORD)GET_GIF_REG(tag, nreg); + return regs.u8[reg]; // GET_GIF_REG(tag, reg); + } + + __forceinline bool StepReg() + { + if((++reg & 0xf) == nreg) + { + reg = 0; + + if(--nloop == 0) + { + return false; + } + } + + return true; } }; @@ -1086,36 +1144,36 @@ struct GSPrivRegSet struct { GSRegPMODE PMODE; - UINT64 _pad1; + uint64 _pad1; GSRegSMODE1 SMODE1; - UINT64 _pad2; + uint64 _pad2; GSRegSMODE2 SMODE2; - UINT64 _pad3; + uint64 _pad3; GSRegSRFSH SRFSH; - UINT64 _pad4; + uint64 _pad4; GSRegSYNCH1 SYNCH1; - UINT64 _pad5; + uint64 _pad5; GSRegSYNCH2 SYNCH2; - UINT64 _pad6; + uint64 _pad6; GSRegSYNCV SYNCV; - UINT64 _pad7; + uint64 _pad7; struct { GSRegDISPFB DISPFB; - UINT64 _pad1; + uint64 _pad1; GSRegDISPLAY DISPLAY; - UINT64 _pad2; + uint64 _pad2; } DISP[2]; GSRegEXTBUF EXTBUF; - UINT64 _pad8; + uint64 _pad8; GSRegEXTDATA EXTDATA; - UINT64 _pad9; + uint64 _pad9; GSRegEXTWRITE EXTWRITE; - UINT64 _pad10; + uint64 _pad10; GSRegBGCOLOR BGCOLOR; - UINT64 _pad11; + uint64 _pad11; }; - BYTE _pad12[0x1000]; + uint8 _pad12[0x1000]; }; union @@ -1123,27 +1181,27 @@ struct GSPrivRegSet struct { GSRegCSR CSR; - UINT64 _pad13; + uint64 _pad13; GSRegIMR IMR; - UINT64 _pad14; - UINT64 _unk1[4]; + uint64 _pad14; + uint64 _unk1[4]; GSRegBUSDIR BUSDIR; - UINT64 _pad15; - UINT64 _unk2[6]; + uint64 _pad15; + uint64 _unk2[6]; GSRegSIGLBLID SIGLBLID; - UINT64 _pad16; + uint64 _pad16; }; - BYTE _pad17[0x1000]; + uint8 _pad17[0x1000]; }; }; #pragma pack(pop) enum {KEYPRESS=1, KEYRELEASE=2}; -struct keyEvent {UINT32 key, event;}; +struct GSKeyEventData {uint32 key, type;}; enum {FREEZE_LOAD=0, FREEZE_SAVE=1, FREEZE_SIZE=2}; -struct GSFreezeData {int size; BYTE* data;}; +struct GSFreezeData {int size; uint8* data;}; enum stateType {ST_WRITE, ST_TRANSFER, ST_VSYNC}; diff --git a/plugins/GSdx/GSBlock.h b/plugins/GSdx/GSBlock.h index e244a2b240..7b548bf3bf 100644 --- a/plugins/GSdx/GSBlock.h +++ b/plugins/GSdx/GSBlock.h @@ -42,10 +42,8 @@ class GSBlock static const GSVector4i m_uw8hmask3; public: - template __forceinline static void WriteColumn32(BYTE* RESTRICT dst, const BYTE* RESTRICT src, int srcpitch) + template __forceinline static void WriteColumn32(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch) { - #if _M_SSE >= 0x200 - const GSVector4i* s0 = (const GSVector4i*)&src[srcpitch * 0]; const GSVector4i* s1 = (const GSVector4i*)&src[srcpitch * 1]; @@ -92,33 +90,10 @@ public: #endif } - - #else - - const BYTE* d = &columnTable32[(i & 3) << 1][0]; - - for(int j = 0; j < 2; j++, d += 8, src += srcpitch) - { - for(int i = 0; i < 8; i++) - { - if(mask == 0xffffffff) - { - ((DWORD*)dst)[d[i]] = ((DWORD*)src)[i]; - } - else - { - ((DWORD*)dst)[d[i]] = (((DWORD*)dst)[d[i]] & ~mask) | (((DWORD*)src)[i] & mask); - } - } - } - - #endif } - template __forceinline static void WriteColumn16(BYTE* RESTRICT dst, const BYTE* RESTRICT src, int srcpitch) + template __forceinline static void WriteColumn16(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch) { - #if _M_SSE >= 0x200 - const GSVector4i* s0 = (const GSVector4i*)&src[srcpitch * 0]; const GSVector4i* s1 = (const GSVector4i*)&src[srcpitch * 1]; @@ -134,26 +109,10 @@ public: ((GSVector4i*)dst)[i * 4 + 1] = v2; ((GSVector4i*)dst)[i * 4 + 2] = v1; ((GSVector4i*)dst)[i * 4 + 3] = v3; - - #else - - const BYTE* d = &columnTable16[(i & 3) << 1][0]; - - for(int j = 0; j < 2; j++, d += 16, src += srcpitch) - { - for(int i = 0; i < 16; i++) - { - ((WORD*)dst)[d[i]] = ((WORD*)src)[i]; - } - } - - #endif } - template __forceinline static void WriteColumn8(BYTE* RESTRICT dst, const BYTE* RESTRICT src, int srcpitch) + template __forceinline static void WriteColumn8(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch) { - #if _M_SSE >= 0x200 - GSVector4i v0 = GSVector4i::load(&src[srcpitch * 0]); GSVector4i v1 = GSVector4i::load(&src[srcpitch * 1]); GSVector4i v2 = GSVector4i::load(&src[srcpitch * 2]); @@ -178,28 +137,12 @@ public: ((GSVector4i*)dst)[i * 4 + 1] = v2; ((GSVector4i*)dst)[i * 4 + 2] = v1; ((GSVector4i*)dst)[i * 4 + 3] = v3; - - #else - - const BYTE* d = &columnTable8[(i & 3) << 2][0]; - - for(int j = 0; j < 4; j++, d += 16, src += srcpitch) - { - for(int i = 0; i < 16; i++) - { - dst[d[i]] = src[i]; - } - } - - #endif } - template __forceinline static void WriteColumn4(BYTE* RESTRICT dst, const BYTE* RESTRICT src, int srcpitch) + template __forceinline static void WriteColumn4(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch) { // TODO: pshufb - #if _M_SSE >= 0x200 - GSVector4i v0 = GSVector4i::load(&src[srcpitch * 0]); GSVector4i v1 = GSVector4i::load(&src[srcpitch * 1]); GSVector4i v2 = GSVector4i::load(&src[srcpitch * 2]); @@ -225,26 +168,9 @@ public: ((GSVector4i*)dst)[i * 4 + 1] = v1; ((GSVector4i*)dst)[i * 4 + 2] = v2; ((GSVector4i*)dst)[i * 4 + 3] = v3; - - #else - - const WORD* d = &columnTable4[(i & 3) << 2][0]; - - for(int j = 0; j < 4; j++, d += 32, src += srcpitch) - { - for(int i = 0; i < 32; i++) - { - DWORD addr = d[i]; - BYTE c = (src[i >> 1] >> ((i & 1) << 2)) & 0x0f; - DWORD shift = (addr & 1) << 2; - dst[addr >> 1] = (dst[addr >> 1] & (0xf0 >> shift)) | (c << shift); - } - } - - #endif } - template static void WriteColumn32(int y, BYTE* RESTRICT dst, const BYTE* RESTRICT src, int srcpitch) + template static void WriteColumn32(int y, uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch) { switch((y >> 1) & 3) { @@ -256,7 +182,7 @@ public: } } - template static void WriteColumn16(int y, BYTE* RESTRICT dst, const BYTE* RESTRICT src, int srcpitch) + template static void WriteColumn16(int y, uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch) { switch((y >> 1) & 3) { @@ -268,7 +194,7 @@ public: } } - template static void WriteColumn8(int y, BYTE* RESTRICT dst, const BYTE* RESTRICT src, int srcpitch) + template static void WriteColumn8(int y, uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch) { switch((y >> 2) & 3) { @@ -280,7 +206,7 @@ public: } } - template static void WriteColumn4(int y, BYTE* RESTRICT dst, const BYTE* RESTRICT src, int srcpitch) + template static void WriteColumn4(int y, uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch) { switch((y >> 2) & 3) { @@ -292,10 +218,8 @@ public: } } - template static void WriteBlock32(BYTE* RESTRICT dst, const BYTE* RESTRICT src, int srcpitch) + template static void WriteBlock32(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch) { - #if _M_SSE >= 0x200 - WriteColumn32<0, aligned, mask>(dst, src, srcpitch); src += srcpitch * 2; WriteColumn32<1, aligned, mask>(dst, src, srcpitch); @@ -303,33 +227,10 @@ public: WriteColumn32<2, aligned, mask>(dst, src, srcpitch); src += srcpitch * 2; WriteColumn32<3, aligned, mask>(dst, src, srcpitch); - - #else - - const BYTE* d = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, d += 8, src += srcpitch) - { - for(int i = 0; i < 8; i++) - { - if(mask == 0xffffffff) - { - ((DWORD*)dst)[d[i]] = ((DWORD*)src)[i]; - } - else - { - ((DWORD*)dst)[d[i]] = (((DWORD*)dst)[d[i]] & ~mask) | (((DWORD*)src)[i] & mask); - } - } - } - - #endif } - template static void WriteBlock16(BYTE* RESTRICT dst, const BYTE* RESTRICT src, int srcpitch) + template static void WriteBlock16(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch) { - #if _M_SSE >= 0x200 - WriteColumn16<0, aligned>(dst, src, srcpitch); src += srcpitch * 2; WriteColumn16<1, aligned>(dst, src, srcpitch); @@ -337,26 +238,10 @@ public: WriteColumn16<2, aligned>(dst, src, srcpitch); src += srcpitch * 2; WriteColumn16<3, aligned>(dst, src, srcpitch); - - #else - - const BYTE* d = &columnTable16[0][0]; - - for(int j = 0; j < 8; j++, d += 16, src += srcpitch) - { - for(int i = 0; i < 16; i++) - { - ((WORD*)dst)[d[i]] = ((WORD*)src)[i]; - } - } - - #endif } - template static void WriteBlock8(BYTE* RESTRICT dst, const BYTE* RESTRICT src, int srcpitch) + template static void WriteBlock8(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch) { - #if _M_SSE >= 0x200 - WriteColumn8<0, aligned>(dst, src, srcpitch); src += srcpitch * 4; WriteColumn8<1, aligned>(dst, src, srcpitch); @@ -364,26 +249,10 @@ public: WriteColumn8<2, aligned>(dst, src, srcpitch); src += srcpitch * 4; WriteColumn8<3, aligned>(dst, src, srcpitch); - - #else - - const BYTE* d = &columnTable8[0][0]; - - for(int j = 0; j < 16; j++, d += 16, src += srcpitch) - { - for(int i = 0; i < 16; i++) - { - dst[d[i]] = src[i]; - } - } - - #endif } - template static void WriteBlock4(BYTE* RESTRICT dst, const BYTE* RESTRICT src, int srcpitch) + template static void WriteBlock4(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch) { - #if _M_SSE >= 0x200 - WriteColumn4<0, aligned>(dst, src, srcpitch); src += srcpitch * 4; WriteColumn4<1, aligned>(dst, src, srcpitch); @@ -391,29 +260,10 @@ public: WriteColumn4<2, aligned>(dst, src, srcpitch); src += srcpitch * 4; WriteColumn4<3, aligned>(dst, src, srcpitch); - - #else - - const WORD* d = &columnTable4[0][0]; - - for(int j = 0; j < 16; j++, d += 32, src += srcpitch) - { - for(int i = 0; i < 32; i++) - { - DWORD addr = d[i]; - BYTE c = (src[i >> 1] >> ((i & 1) << 2)) & 0x0f; - DWORD shift = (addr & 1) << 2; - dst[addr >> 1] = (dst[addr >> 1] & (0xf0 >> shift)) | (c << shift); - } - } - - #endif } - template __forceinline static void ReadColumn32(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + template __forceinline static void ReadColumn32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { - #if _M_SSE >= 0x200 - const GSVector4i* s = (const GSVector4i*)src; GSVector4i v0 = s[i * 4 + 0]; @@ -430,23 +280,9 @@ public: GSVector4i::store(&d0[1], v1); GSVector4i::store(&d1[0], v2); GSVector4i::store(&d1[1], v3); - - #else - - const BYTE* s = &columnTable32[(i & 3) << 1][0]; - - for(int j = 0; j < 2; j++, s += 8, dst += dstpitch) - { - for(int i = 0; i < 8; i++) - { - ((DWORD*)dst)[i] = ((DWORD*)src)[s[i]]; - } - } - - #endif } - template __forceinline static void ReadColumn16(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + template __forceinline static void ReadColumn16(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { #if _M_SSE >= 0x301 @@ -468,7 +304,7 @@ public: GSVector4i::store(&d1[0], v1); GSVector4i::store(&d1[1], v3); - #elif _M_SSE >= 0x200 + #else const GSVector4i* s = (const GSVector4i*)src; @@ -489,22 +325,10 @@ public: GSVector4i::store(&d1[0], v2); GSVector4i::store(&d1[1], v3); - #else - - const BYTE* s = &columnTable16[(i & 3) << 1][0]; - - for(int j = 0; j < 2; j++, s += 16, dst += dstpitch) - { - for(int i = 0; i < 16; i++) - { - ((WORD*)dst)[i] = ((WORD*)src)[s[i]]; - } - } - #endif } - template __forceinline static void ReadColumn8(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + template __forceinline static void ReadColumn8(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { #if _M_SSE >= 0x301 @@ -540,7 +364,7 @@ public: GSVector4i::store(&dst[dstpitch * 2], v1); GSVector4i::store(&dst[dstpitch * 3], v2); - #elif _M_SSE >= 0x200 + #else const GSVector4i* s = (const GSVector4i*)src; @@ -570,22 +394,10 @@ public: GSVector4i::store(&dst[dstpitch * 2], v2); GSVector4i::store(&dst[dstpitch * 3], v3); - #else - - const BYTE* s = &columnTable8[(i & 3) << 2][0]; - - for(int j = 0; j < 4; j++, s += 16, dst += dstpitch) - { - for(int i = 0; i < 16; i++) - { - dst[i] = src[s[i]]; - } - } - #endif } - template __forceinline static void ReadColumn4(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + template __forceinline static void ReadColumn4(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { #if _M_SSE >= 0x301 @@ -619,7 +431,7 @@ public: GSVector4i::store(&dst[dstpitch * 2], v2); GSVector4i::store(&dst[dstpitch * 3], v3); - #elif _M_SSE >= 0x200 + #else const GSVector4i* s = (const GSVector4i*)src; @@ -657,25 +469,10 @@ public: GSVector4i::store(&dst[dstpitch * 2], v2); GSVector4i::store(&dst[dstpitch * 3], v3); - #else - - const WORD* s = &columnTable4[(i & 3) << 2][0]; - - for(int j = 0; j < 4; j++, s += 32, dst += dstpitch) - { - for(int i = 0; i < 32; i++) - { - DWORD addr = s[i]; - BYTE c = (src[addr >> 1] >> ((addr & 1) << 2)) & 0x0f; - int shift = (i & 1) << 2; - dst[i >> 1] = (dst[i >> 1] & (0xf0 >> shift)) | (c << shift); - } - } - #endif } - template static void ReadColumn32(int y, const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + template static void ReadColumn32(int y, const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { switch((y >> 1) & 3) { @@ -687,7 +484,7 @@ public: } } - template static void ReadColumn16(int y, const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + template static void ReadColumn16(int y, const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { switch((y >> 1) & 3) { @@ -699,7 +496,7 @@ public: } } - template static void ReadColumn8(int y, const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + template static void ReadColumn8(int y, const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { switch((y >> 2) & 3) { @@ -711,7 +508,7 @@ public: } } - template static void ReadColumn4(int y, const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + template static void ReadColumn4(int y, const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { switch((y >> 2) & 3) { @@ -723,10 +520,8 @@ public: } } - template static void ReadBlock32(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + template static void ReadBlock32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { - #if _M_SSE >= 0x200 - ReadColumn32<0, aligned>(src, dst, dstpitch); dst += dstpitch * 2; ReadColumn32<1, aligned>(src, dst, dstpitch); @@ -734,26 +529,10 @@ public: ReadColumn32<2, aligned>(src, dst, dstpitch); dst += dstpitch * 2; ReadColumn32<3, aligned>(src, dst, dstpitch); - - #else - - const BYTE* s = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, s += 8, dst += dstpitch) - { - for(int i = 0; i < 8; i++) - { - ((DWORD*)dst)[i] = ((DWORD*)src)[s[i]]; - } - } - - #endif } - template static void ReadBlock16(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + template static void ReadBlock16(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { - #if _M_SSE >= 0x200 - ReadColumn16<0, aligned>(src, dst, dstpitch); dst += dstpitch * 2; ReadColumn16<1, aligned>(src, dst, dstpitch); @@ -761,26 +540,10 @@ public: ReadColumn16<2, aligned>(src, dst, dstpitch); dst += dstpitch * 2; ReadColumn16<3, aligned>(src, dst, dstpitch); - - #else - - const BYTE* s = &columnTable16[0][0]; - - for(int j = 0; j < 8; j++, s += 16, dst += dstpitch) - { - for(int i = 0; i < 16; i++) - { - ((WORD*)dst)[i] = ((WORD*)src)[s[i]]; - } - } - - #endif } - template static void ReadBlock8(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + template static void ReadBlock8(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { - #if _M_SSE >= 0x200 - ReadColumn8<0, aligned>(src, dst, dstpitch); dst += dstpitch * 4; ReadColumn8<1, aligned>(src, dst, dstpitch); @@ -788,26 +551,10 @@ public: ReadColumn8<2, aligned>(src, dst, dstpitch); dst += dstpitch * 4; ReadColumn8<3, aligned>(src, dst, dstpitch); - - #else - - const BYTE* s = &columnTable8[0][0]; - - for(int j = 0; j < 16; j++, s += 16, dst += dstpitch) - { - for(int i = 0; i < 16; i++) - { - dst[i] = src[s[i]]; - } - } - - #endif } - template static void ReadBlock4(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + template static void ReadBlock4(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { - #if _M_SSE >= 0x200 - ReadColumn4<0, aligned>(src, dst, dstpitch); dst += dstpitch * 4; ReadColumn4<1, aligned>(src, dst, dstpitch); @@ -815,29 +562,10 @@ public: ReadColumn4<2, aligned>(src, dst, dstpitch); dst += dstpitch * 4; ReadColumn4<3, aligned>(src, dst, dstpitch); - - #else - - const WORD* s = &columnTable4[0][0]; - - for(int j = 0; j < 16; j++, s += 32, dst += dstpitch) - { - for(int i = 0; i < 32; i++) - { - DWORD addr = s[i]; - BYTE c = (src[addr >> 1] >> ((addr & 1) << 2)) & 0x0f; - int shift = (i & 1) << 2; - dst[i >> 1] = (dst[i >> 1] & (0xf0 >> shift)) | (c << shift); - } - } - - #endif } - __forceinline static void ReadBlock4P(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + __forceinline static void ReadBlock4P(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { - #if _M_SSE >= 0x200 - const GSVector4i* s = (const GSVector4i*)src; GSVector4i v0, v1, v2, v3; @@ -896,18 +624,10 @@ public: dst += dstpitch * 2; } - - #else - - // TODO - - #endif } - __forceinline static void ReadBlock8HP(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + __forceinline static void ReadBlock8HP(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { - #if _M_SSE >= 0x200 - const GSVector4i* s = (const GSVector4i*)src; GSVector4i v0, v1, v2, v3; @@ -931,26 +651,10 @@ public: dst += dstpitch; } - - #else - - const BYTE* s = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, s += 8, dst += dstpitch) - { - for(int i = 0; i < 8; i++) - { - ((BYTE*)dst)[i] = ((DWORD*)src)[s[i]] >> 24; - } - } - - #endif } - __forceinline static void ReadBlock4HLP(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + __forceinline static void ReadBlock4HLP(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { - #if _M_SSE >= 0x200 - const GSVector4i* s = (const GSVector4i*)src; GSVector4i v0, v1, v2, v3; @@ -976,26 +680,10 @@ public: dst += dstpitch; } - - #else - - const BYTE* s = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, s += 8, dst += dstpitch) - { - for(int i = 0; i < 8; i++) - { - ((BYTE*)dst)[i] = (((DWORD*)src)[s[i]] >> 24) & 0xf; - } - } - - #endif } - __forceinline static void ReadBlock4HHP(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch) + __forceinline static void ReadBlock4HHP(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch) { - #if _M_SSE >= 0x200 - const GSVector4i* s = (const GSVector4i*)src; GSVector4i v0, v1, v2, v3; @@ -1019,26 +707,10 @@ public: dst += dstpitch; } - - #else - - const BYTE* s = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, s += 8, dst += dstpitch) - { - for(int i = 0; i < 8; i++) - { - ((BYTE*)dst)[i] = ((DWORD*)src)[s[i]] >> 28; - } - } - - #endif } - static void UnpackBlock24(const BYTE* RESTRICT src, int srcpitch, DWORD* RESTRICT dst) + static void UnpackBlock24(const uint8* RESTRICT src, int srcpitch, uint32* RESTRICT dst) { - #if _M_SSE >= 0x200 - GSVector4i mask = GSVector4i::x00ffffff(); for(int i = 0; i < 4; i++, src += srcpitch * 2) @@ -1061,24 +733,10 @@ public: ((GSVector4i*)dst)[i * 4 + 3] = v0.upl32(v0.srl<3>()).upl64(v0.srl<6>().upl32(v0.srl<9>())) & mask; } - - #else - - for(int j = 0, diff = srcpitch - 8 * 3; j < 8; j++, src += diff, dst += 8) - { - for(int i = 0; i < 8; i++, src += 3) - { - dst[i] = (src[2] << 16) | (src[1] << 8) | src[0]; - } - } - - #endif } - static void UnpackBlock8H(const BYTE* RESTRICT src, int srcpitch, DWORD* RESTRICT dst) + static void UnpackBlock8H(const uint8* RESTRICT src, int srcpitch, uint32* RESTRICT dst) { - #if _M_SSE >= 0x200 - GSVector4i zero = GSVector4i::zero(); for(int i = 0; i < 4; i++, src += srcpitch * 2) @@ -1093,34 +751,20 @@ public: ((GSVector4i*)dst)[i * 4 + 2] = zero.upl16(v1); ((GSVector4i*)dst)[i * 4 + 3] = zero.uph16(v1); } - - #else - - for(int j = 0; j < 8; j++, src += srcpitch, dst += 8) - { - for(int i = 0; i < 8; i++) - { - dst[i] = src[i] << 24; - } - } - - #endif } - static void UnpackBlock4HL(const BYTE* RESTRICT src, int srcpitch, DWORD* RESTRICT dst) + static void UnpackBlock4HL(const uint8* RESTRICT src, int srcpitch, uint32* RESTRICT dst) { - #if _M_SSE >= 0x200 - GSVector4i zero = GSVector4i::zero(); GSVector4i mask(0x0f0f0f0f); for(int i = 0; i < 2; i++, src += srcpitch * 4) { GSVector4i v( - *(DWORD*)&src[srcpitch * 0], - *(DWORD*)&src[srcpitch * 1], - *(DWORD*)&src[srcpitch * 2], - *(DWORD*)&src[srcpitch * 3]); + *(uint32*)&src[srcpitch * 0], + *(uint32*)&src[srcpitch * 1], + *(uint32*)&src[srcpitch * 2], + *(uint32*)&src[srcpitch * 3]); GSVector4i lo = v & mask; GSVector4i hi = (v >> 4) & mask; @@ -1142,35 +786,20 @@ public: ((GSVector4i*)dst)[i * 8 + 6] = zero.upl16(v5); ((GSVector4i*)dst)[i * 8 + 7] = zero.uph16(v5); } - - #else - - for(int j = 0; j < 8; j++, src += srcpitch, dst += 8) - { - for(int i = 0; i < 4; i++) - { - dst[i * 2 + 0] = (src[i] & 0x0f) << 24; - dst[i * 2 + 1] = (src[i] & 0xf0) << 20; - } - } - - #endif } - static void UnpackBlock4HH(const BYTE* RESTRICT src, int srcpitch, DWORD* RESTRICT dst) + static void UnpackBlock4HH(const uint8* RESTRICT src, int srcpitch, uint32* RESTRICT dst) { - #if _M_SSE >= 0x200 - GSVector4i zero = GSVector4i::zero(); GSVector4i mask(0xf0f0f0f0); for(int i = 0; i < 2; i++, src += srcpitch * 4) { GSVector4i v( - *(DWORD*)&src[srcpitch * 0], - *(DWORD*)&src[srcpitch * 1], - *(DWORD*)&src[srcpitch * 2], - *(DWORD*)&src[srcpitch * 3]); + *(uint32*)&src[srcpitch * 0], + *(uint32*)&src[srcpitch * 1], + *(uint32*)&src[srcpitch * 2], + *(uint32*)&src[srcpitch * 3]); GSVector4i lo = (v << 4) & mask; GSVector4i hi = v & mask; @@ -1192,25 +821,10 @@ public: ((GSVector4i*)dst)[i * 8 + 6] = zero.upl16(v5); ((GSVector4i*)dst)[i * 8 + 7] = zero.uph16(v5); } - - #else - - for(int j = 0; j < 8; j++, src += srcpitch, dst += 8) - { - for(int i = 0; i < 4; i++) - { - dst[i * 2 + 0] = (src[i] & 0x0f) << 28; - dst[i * 2 + 1] = (src[i] & 0xf0) << 24; - } - } - - #endif } - template static void ExpandBlock24(const DWORD* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA) + template static void ExpandBlock24(const uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA) { - #if _M_SSE >= 0x200 - const GSVector4i* s = (const GSVector4i*)src; GSVector4i TA0(TEXA.TA0 << 24); @@ -1241,35 +855,10 @@ public: d1[1] = v3 | TA0; } } - - #else - - DWORD TA0 = TEXA.TA0 << 24; - - for(int j = 0; j < 8; j++, src += 8, dst += dstpitch) - { - for(int i = 0; i < 8; i++) - { - DWORD c = src[i] & 0xffffff; - - if(AEM) - { - ((DWORD*)dst)[i] = c | (c ? TA0 : 0); - } - else - { - ((DWORD*)dst)[i] = c | TA0; - } - } - } - - #endif } - static void ExpandBlock16(const WORD* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA) // do not inline, uses too many xmm regs + static void ExpandBlock16(const uint16* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA) // do not inline, uses too many xmm regs { - #if _M_SSE >= 0x200 - const GSVector4i* s = (const GSVector4i*)src; GSVector4i TA0(TEXA.TA0 << 24); @@ -1321,37 +910,9 @@ public: ((GSVector4i*)dst)[3] = ((h & rm) << 3) | ((h & gm) << 6) | ((h & bm) << 9) | TA0.blend(TA1, h.sra16(15)); } } - - #else - - DWORD TA0 = TEXA.TA0 << 24; - DWORD TA1 = TEXA.TA1 << 24; - - if(TEXA.AEM) - { - for(int j = 0; j < 8; j++, src += 16, dst += dstpitch) - { - for(int i = 0; i < 16; i++) - { - ((DWORD*)dst)[i] = ((src[i] & 0x8000) ? TA1 : src[i] ? TA0 : 0) | ((src[i] & 0x7c00) << 9) | ((src[i] & 0x03e0) << 6) | ((src[i] & 0x001f) << 3); - } - } - } - else - { - for(int j = 0; j < 8; j++, src += 16, dst += dstpitch) - { - for(int i = 0; i < 16; i++) - { - ((DWORD*)dst)[i] = ((src[i] & 0x8000) ? TA1 : TA0) | ((src[i] & 0x7c00) << 9) | ((src[i] & 0x03e0) << 6) | ((src[i] & 0x001f) << 3); - } - } - } - - #endif } - __forceinline static void ExpandBlock8_32(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const DWORD* RESTRICT pal) + __forceinline static void ExpandBlock8_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal) { for(int j = 0; j < 16; j++, dst += dstpitch) { @@ -1359,7 +920,7 @@ public: } } - __forceinline static void ExpandBlock8_16(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const DWORD* RESTRICT pal) + __forceinline static void ExpandBlock8_16(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal) { for(int j = 0; j < 16; j++, dst += dstpitch) { @@ -1367,7 +928,7 @@ public: } } - __forceinline static void ExpandBlock4_32(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const UINT64* RESTRICT pal) + __forceinline static void ExpandBlock4_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint64* RESTRICT pal) { for(int j = 0; j < 16; j++, dst += dstpitch) { @@ -1375,7 +936,7 @@ public: } } - __forceinline static void ExpandBlock4_16(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const UINT64* RESTRICT pal) + __forceinline static void ExpandBlock4_16(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint64* RESTRICT pal) { for(int j = 0; j < 16; j++, dst += dstpitch) { @@ -1383,7 +944,7 @@ public: } } - __forceinline static void ExpandBlock8H_32(DWORD* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const DWORD* RESTRICT pal) + __forceinline static void ExpandBlock8H_32(uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal) { for(int j = 0; j < 8; j++, dst += dstpitch) { @@ -1394,7 +955,7 @@ public: } } - __forceinline static void ExpandBlock8H_16(DWORD* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const DWORD* RESTRICT pal) + __forceinline static void ExpandBlock8H_16(uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal) { for(int j = 0; j < 8; j++, dst += dstpitch) { @@ -1411,14 +972,14 @@ public: for(int i = 0; i < 8; i++) { - ((WORD*)dst)[i] = (WORD)pal[src[j * 8 + i] >> 24]; + ((uint16*)dst)[i] = (uint16)pal[src[j * 8 + i] >> 24]; } #endif } } - __forceinline static void ExpandBlock4HL_32(DWORD* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const DWORD* RESTRICT pal) + __forceinline static void ExpandBlock4HL_32(uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal) { for(int j = 0; j < 8; j++, dst += dstpitch) { @@ -1429,7 +990,7 @@ public: } } - __forceinline static void ExpandBlock4HL_16(DWORD* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const DWORD* RESTRICT pal) + __forceinline static void ExpandBlock4HL_16(uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal) { for(int j = 0; j < 8; j++, dst += dstpitch) { @@ -1446,14 +1007,14 @@ public: for(int i = 0; i < 8; i++) { - ((WORD*)dst)[i] = (WORD)pal[(src[j * 8 + i] >> 24) & 0xf]; + ((uint16*)dst)[i] = (uint16)pal[(src[j * 8 + i] >> 24) & 0xf]; } #endif } } - __forceinline static void ExpandBlock4HH_32(DWORD* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const DWORD* RESTRICT pal) + __forceinline static void ExpandBlock4HH_32(uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal) { for(int j = 0; j < 8; j++, dst += dstpitch) { @@ -1464,7 +1025,7 @@ public: } } - __forceinline static void ExpandBlock4HH_16(DWORD* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const DWORD* RESTRICT pal) + __forceinline static void ExpandBlock4HH_16(uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal) { for(int j = 0; j < 8; j++, dst += dstpitch) { @@ -1481,17 +1042,15 @@ public: for(int i = 0; i < 8; i++) { - ((WORD*)dst)[i] = (WORD)pal[src[j * 8 + i] >> 28]; + ((uint16*)dst)[i] = (uint16)pal[src[j * 8 + i] >> 28]; } #endif } } - __forceinline static void UnpackAndWriteBlock24(const BYTE* RESTRICT src, int srcpitch, BYTE* RESTRICT dst) + __forceinline static void UnpackAndWriteBlock24(const uint8* RESTRICT src, int srcpitch, uint8* RESTRICT dst) { - #if _M_SSE >= 0x200 - GSVector4i mask(0x00ffffff); for(int i = 0; i < 4; i++, src += srcpitch * 2) @@ -1534,23 +1093,9 @@ public: #endif } - - #else - - const BYTE* d = &columnTable32[0][0]; - - for(int j = 0, diff = srcpitch - 8 * 3; j < 8; j++, src += diff, d += 8) - { - for(int i = 0; i < 8; i++, src += 3) - { - ((DWORD*)dst)[d[i]] = (((DWORD*)dst)[d[i]] & ~0x00ffffff) | (src[2] << 16) | (src[1] << 8) | src[0]; - } - } - - #endif } - __forceinline static void UnpackAndWriteBlock8H(const BYTE* RESTRICT src, int srcpitch, BYTE* RESTRICT dst) + __forceinline static void UnpackAndWriteBlock8H(const uint8* RESTRICT src, int srcpitch, uint8* RESTRICT dst) { #if _M_SSE >= 0x301 @@ -1576,7 +1121,7 @@ public: ((GSVector4i*)dst)[i * 4 + 3] = ((GSVector4i*)dst)[i * 4 + 3].blend8(v3, mask); } - #elif _M_SSE >= 0x200 + #else GSVector4i mask(0xff000000); @@ -1600,22 +1145,10 @@ public: ((GSVector4i*)dst)[i * 4 + 3] = ((GSVector4i*)dst)[i * 4 + 3].blend8(v3, mask); } - #else - - const BYTE* d = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, src += srcpitch, dst += 8) - { - for(int i = 0; i < 8; i++) - { - ((DWORD*)dst)[d[i]] = (((DWORD*)dst)[d[i]] & ~0xff000000) | (src[i] << 24); - } - } - #endif } - __forceinline static void UnpackAndWriteBlock4HL(const BYTE* RESTRICT src, int srcpitch, BYTE* RESTRICT dst) + __forceinline static void UnpackAndWriteBlock4HL(const uint8* RESTRICT src, int srcpitch, uint8* RESTRICT dst) { #if _M_SSE >= 0x301 @@ -1629,10 +1162,10 @@ public: for(int i = 0; i < 2; i++, src += srcpitch * 4) { GSVector4i v( - *(DWORD*)&src[srcpitch * 0], - *(DWORD*)&src[srcpitch * 1], - *(DWORD*)&src[srcpitch * 2], - *(DWORD*)&src[srcpitch * 3]); + *(uint32*)&src[srcpitch * 0], + *(uint32*)&src[srcpitch * 1], + *(uint32*)&src[srcpitch * 2], + *(uint32*)&src[srcpitch * 3]); GSVector4i lo = v & mask; GSVector4i hi = (v >> 4) & mask; @@ -1666,13 +1199,13 @@ public: } } - #elif _M_SSE >= 0x200 + #else /* - __declspec(align(16)) DWORD block[8 * 8]; + __declspec(align(16)) uint32 block[8 * 8]; UnpackBlock4HL(src, srcpitch, block); - WriteBlock32(dst, (BYTE*)block, sizeof(block) / 8); + WriteBlock32(dst, (uint8*)block, sizeof(block) / 8); */ GSVector4i mask(0x0f0f0f0f); GSVector4i mask2(0x0f000000); @@ -1680,10 +1213,10 @@ public: for(int i = 0; i < 2; i++, src += srcpitch * 4) { GSVector4i v( - *(DWORD*)&src[srcpitch * 0], - *(DWORD*)&src[srcpitch * 1], - *(DWORD*)&src[srcpitch * 2], - *(DWORD*)&src[srcpitch * 3]); + *(uint32*)&src[srcpitch * 0], + *(uint32*)&src[srcpitch * 1], + *(uint32*)&src[srcpitch * 2], + *(uint32*)&src[srcpitch * 3]); GSVector4i lo = v & mask; GSVector4i hi = (v >> 4) & mask; @@ -1727,23 +1260,10 @@ public: } } - #else - - const BYTE* d = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, d += 8, src += srcpitch) - { - for(int i = 0; i < 4; i++) - { - ((DWORD*)dst)[d[i * 2 + 0]] = (((DWORD*)dst)[d[i * 2 + 0]] & ~0x0f000000) | ((src[i] & 0x0f) << 24); - ((DWORD*)dst)[d[i * 2 + 1]] = (((DWORD*)dst)[d[i * 2 + 1]] & ~0x0f000000) | ((src[i] & 0xf0) << 20); - } - } - #endif } - __forceinline static void UnpackAndWriteBlock4HH(const BYTE* RESTRICT src, int srcpitch, BYTE* RESTRICT dst) + __forceinline static void UnpackAndWriteBlock4HH(const uint8* RESTRICT src, int srcpitch, uint8* RESTRICT dst) { #if _M_SSE >= 0x301 @@ -1757,10 +1277,10 @@ public: for(int i = 0; i < 2; i++, src += srcpitch * 4) { GSVector4i v( - *(DWORD*)&src[srcpitch * 0], - *(DWORD*)&src[srcpitch * 1], - *(DWORD*)&src[srcpitch * 2], - *(DWORD*)&src[srcpitch * 3]); + *(uint32*)&src[srcpitch * 0], + *(uint32*)&src[srcpitch * 1], + *(uint32*)&src[srcpitch * 2], + *(uint32*)&src[srcpitch * 3]); GSVector4i lo = (v << 4) & mask; GSVector4i hi = v & mask; @@ -1794,13 +1314,13 @@ public: } } - #elif _M_SSE >= 0x200 + #else /* - __declspec(align(16)) DWORD block[8 * 8]; + __declspec(align(16)) uint32 block[8 * 8]; UnpackBlock4HH(src, srcpitch, block); - WriteBlock32(dst, (BYTE*)block, sizeof(block) / 8); + WriteBlock32(dst, (uint8*)block, sizeof(block) / 8); */ GSVector4i mask(0xf0f0f0f0); GSVector4i mask2(0xf0000000); @@ -1808,10 +1328,10 @@ public: for(int i = 0; i < 2; i++, src += srcpitch * 4) { GSVector4i v( - *(DWORD*)&src[srcpitch * 0], - *(DWORD*)&src[srcpitch * 1], - *(DWORD*)&src[srcpitch * 2], - *(DWORD*)&src[srcpitch * 3]); + *(uint32*)&src[srcpitch * 0], + *(uint32*)&src[srcpitch * 1], + *(uint32*)&src[srcpitch * 2], + *(uint32*)&src[srcpitch * 3]); GSVector4i lo = (v << 4) & mask; GSVector4i hi = v & mask; @@ -1855,26 +1375,11 @@ public: } } - #else - - const BYTE* d = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, d += 8, src += srcpitch) - { - for(int i = 0; i < 4; i++) - { - ((DWORD*)dst)[d[i * 2 + 0]] = (((DWORD*)dst)[d[i * 2 + 0]] & ~0xf0000000) | ((src[i] & 0x0f) << 28); - ((DWORD*)dst)[d[i * 2 + 1]] = (((DWORD*)dst)[d[i * 2 + 1]] & ~0xf0000000) | ((src[i] & 0xf0) << 24); - } - } - #endif } - template __forceinline static void ReadAndExpandBlock24(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA) + template __forceinline static void ReadAndExpandBlock24(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA) { - #if _M_SSE >= 0x200 - const GSVector4i* s = (const GSVector4i*)src; GSVector4i TA0(TEXA.TA0 << 24); @@ -1912,34 +1417,9 @@ public: d1[1] = v3 | TA0; } } - - #else - - DWORD TA0 = TEXA.TA0 << 24; - - const BYTE* s = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, s += 8, dst += dstpitch) - { - for(int i = 0; i < 8; i++) - { - DWORD c = ((DWORD*)src)[s[i]] & 0xffffff; - - if(AEM) - { - ((DWORD*)dst)[i] = c | (c ? TA0 : 0); - } - else - { - ((DWORD*)dst)[i] = c | TA0; - } - } - } - - #endif } - __forceinline static void ReadAndExpandBlock8_32(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const DWORD* RESTRICT pal) + __forceinline static void ReadAndExpandBlock8_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal) { #if _M_SSE >= 0x401 @@ -1985,32 +1465,20 @@ public: dst += dstpitch; } - #elif _M_SSE >= 0x200 - - __declspec(align(16)) BYTE block[16 * 16]; - - ReadBlock8(src, (BYTE*)block, sizeof(block) / 16); - - ExpandBlock8_32(block, dst, dstpitch, pal); - #else - const BYTE* s = &columnTable8[0][0]; + __declspec(align(16)) uint8 block[16 * 16]; - for(int j = 0; j < 16; j++, s += 16, dst += dstpitch) - { - for(int i = 0; i < 16; i++) - { - ((DWORD*)dst)[i] = pal[src[s[i]]]; - } - } + ReadBlock8(src, (uint8*)block, sizeof(block) / 16); + + ExpandBlock8_32(block, dst, dstpitch, pal); #endif } // TODO: ReadAndExpandBlock8_16 - __forceinline static void ReadAndExpandBlock4_32(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const UINT64* RESTRICT pal) + __forceinline static void ReadAndExpandBlock4_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint64* RESTRICT pal) { #if _M_SSE >= 0x401 @@ -2072,38 +1540,20 @@ public: dst += dstpitch; } - #elif _M_SSE >= 0x200 - - __declspec(align(16)) BYTE block[(32 / 2) * 16]; - - ReadBlock4(src, (BYTE*)block, sizeof(block) / 16); - - ExpandBlock4_32(block, dst, dstpitch, pal); - #else - const WORD* s = &columnTable4[0][0]; + __declspec(align(16)) uint8 block[(32 / 2) * 16]; - for(int j = 0; j < 16; j++, s += 32, dst += dstpitch) - { - for(int i = 0; i < 16; i++) - { - BYTE a0 = s[i * 2 + 0]; - BYTE a1 = s[i * 2 + 1]; + ReadBlock4(src, (uint8*)block, sizeof(block) / 16); - BYTE c0 = (src[a0 >> 1] >> ((a0 & 1) << 2)) & 0x0f; - BYTE c1 = (src[a1 >> 1] >> ((a1 & 1) << 2)) & 0x0f; - - ((UINT64*)dst)[i] = pal[(c1 << 4) | c0]; - } - } + ExpandBlock4_32(block, dst, dstpitch, pal); #endif } // TODO: ReadAndExpandBlock4_16 - __forceinline static void ReadAndExpandBlock8H_32(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const DWORD* RESTRICT pal) + __forceinline static void ReadAndExpandBlock8H_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal) { #if _M_SSE >= 0x401 @@ -2131,32 +1581,20 @@ public: dst += dstpitch; } - #elif _M_SSE >= 0x200 - - __declspec(align(16)) DWORD block[8 * 8]; - - ReadBlock32(src, (BYTE*)block, sizeof(block) / 8); - - ExpandBlock8H_32(block, dst, dstpitch, pal); - #else - const BYTE* s = &columnTable32[0][0]; + __declspec(align(16)) uint32 block[8 * 8]; - for(int j = 0; j < 8; j++, s += 8, dst += dstpitch) - { - for(int i = 0; i < 8; i++) - { - ((DWORD*)dst)[i] = pal[((DWORD*)src)[s[i]] >> 24]; - } - } + ReadBlock32(src, (uint8*)block, sizeof(block) / 8); + + ExpandBlock8H_32(block, dst, dstpitch, pal); #endif } // TODO: ReadAndExpandBlock8H_16 - __forceinline static void ReadAndExpandBlock4HL_32(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const DWORD* RESTRICT pal) + __forceinline static void ReadAndExpandBlock4HL_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal) { #if _M_SSE >= 0x401 @@ -2184,32 +1622,20 @@ public: dst += dstpitch; } - #elif _M_SSE >= 0x200 - - __declspec(align(16)) DWORD block[8 * 8]; - - ReadBlock32(src, (BYTE*)block, sizeof(block) / 8); - - ExpandBlock4HL_32(block, dst, dstpitch, pal); - #else - const BYTE* s = &columnTable32[0][0]; + __declspec(align(16)) uint32 block[8 * 8]; - for(int j = 0; j < 8; j++, s += 8, dst += dstpitch) - { - for(int i = 0; i < 8; i++) - { - ((DWORD*)dst)[i] = pal[(((DWORD*)src)[s[i]] >> 24) & 0xf]; - } - } + ReadBlock32(src, (uint8*)block, sizeof(block) / 8); + + ExpandBlock4HL_32(block, dst, dstpitch, pal); #endif } // TODO: ReadAndExpandBlock4HL_16 - __forceinline static void ReadAndExpandBlock4HH_32(const BYTE* RESTRICT src, BYTE* RESTRICT dst, int dstpitch, const DWORD* RESTRICT pal) + __forceinline static void ReadAndExpandBlock4HH_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal) { #if _M_SSE >= 0x401 @@ -2237,25 +1663,13 @@ public: dst += dstpitch; } - #elif _M_SSE >= 0x200 - - __declspec(align(16)) DWORD block[8 * 8]; - - ReadBlock32(src, (BYTE*)block, sizeof(block) / 8); - - ExpandBlock4HH_32(block, dst, dstpitch, pal); - #else - const BYTE* s = &columnTable32[0][0]; + __declspec(align(16)) uint32 block[8 * 8]; - for(int j = 0; j < 8; j++, s += 8, dst += dstpitch) - { - for(int i = 0; i < 8; i++) - { - ((DWORD*)dst)[i] = pal[((DWORD*)src)[s[i]] >> 28]; - } - } + ReadBlock32(src, (uint8*)block, sizeof(block) / 8); + + ExpandBlock4HH_32(block, dst, dstpitch, pal); #endif } diff --git a/plugins/GSdx/GSCapture.cpp b/plugins/GSdx/GSCapture.cpp index bd1ccca41e..685141bd93 100644 --- a/plugins/GSdx/GSCapture.cpp +++ b/plugins/GSdx/GSCapture.cpp @@ -46,24 +46,24 @@ class __declspec(uuid("F8BB6F4F-0965-4ED4-BA74-C6A01E6E6C77")) #endif GSSource : public CBaseFilter, private CCritSec, public IGSSource { - CSize m_size; + GSVector2i m_size; REFERENCE_TIME m_atpf; REFERENCE_TIME m_now; STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv) { return - QI(IGSSource) + riid == __uuidof(IGSSource) ? GetInterface((IGSSource*)this, ppv) : __super::NonDelegatingQueryInterface(riid, ppv); } class GSSourceOutputPin : public CBaseOutputPin { - CSize m_size; - CAtlArray m_mts; + GSVector2i m_size; + vector m_mts; public: - GSSourceOutputPin(CSize size, REFERENCE_TIME atpf, CBaseFilter* pFilter, CCritSec* pLock, HRESULT& hr) + GSSourceOutputPin(const GSVector2i& size, REFERENCE_TIME atpf, CBaseFilter* pFilter, CCritSec* pLock, HRESULT& hr) : CBaseOutputPin("GSSourceOutputPin", pFilter, pLock, &hr, L"Output") , m_size(size) { @@ -75,38 +75,34 @@ GSSource : public CBaseFilter, private CCritSec, public IGSSource memset(&vih, 0, sizeof(vih)); vih.AvgTimePerFrame = atpf; vih.bmiHeader.biSize = sizeof(vih.bmiHeader); - vih.bmiHeader.biWidth = m_size.cx; - vih.bmiHeader.biHeight = m_size.cy; - - #if _M_SSE >= 0x200 + vih.bmiHeader.biWidth = m_size.x; + vih.bmiHeader.biHeight = m_size.y; // YUY2 mt.subtype = MEDIASUBTYPE_YUY2; - mt.lSampleSize = m_size.cx * m_size.cy * 2; + mt.lSampleSize = m_size.x * m_size.y * 2; vih.bmiHeader.biCompression = '2YUY'; vih.bmiHeader.biPlanes = 1; vih.bmiHeader.biBitCount = 16; - vih.bmiHeader.biSizeImage = m_size.cx * m_size.cy * 2; - mt.SetFormat((BYTE*)&vih, sizeof(vih)); + vih.bmiHeader.biSizeImage = m_size.x * m_size.y * 2; + mt.SetFormat((uint8*)&vih, sizeof(vih)); - m_mts.Add(mt); - - #endif + m_mts.push_back(mt); // RGB32 mt.subtype = MEDIASUBTYPE_RGB32; - mt.lSampleSize = m_size.cx * m_size.cy * 4; + mt.lSampleSize = m_size.x * m_size.y * 4; vih.bmiHeader.biCompression = BI_RGB; vih.bmiHeader.biPlanes = 1; vih.bmiHeader.biBitCount = 32; - vih.bmiHeader.biSizeImage = m_size.cx * m_size.cy * 4; - mt.SetFormat((BYTE*)&vih, sizeof(vih)); + vih.bmiHeader.biSizeImage = m_size.x * m_size.y * 4; + mt.SetFormat((uint8*)&vih, sizeof(vih)); - m_mts.Add(mt); + m_mts.push_back(mt); } HRESULT GSSourceOutputPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties) @@ -137,9 +133,9 @@ GSSource : public CBaseFilter, private CCritSec, public IGSSource HRESULT CheckMediaType(const CMediaType* pmt) { - for(int i = 0, j = m_mts.GetCount(); i < j; i++) + for(vector::iterator i = m_mts.begin(); i != m_mts.end(); i++) { - if(m_mts[i].majortype == pmt->majortype && m_mts[i].subtype == pmt->subtype) + if(i->majortype == pmt->majortype && i->subtype == pmt->subtype) { return S_OK; } @@ -171,7 +167,7 @@ GSSource : public CBaseFilter, private CCritSec, public IGSSource } }; - CAutoPtr m_output; + GSSourceOutputPin* m_output; public: @@ -182,12 +178,17 @@ public: , m_atpf(10000000i64 / fps) , m_now(0) { - m_output.Attach(new GSSourceOutputPin(m_size, m_atpf, this, this, hr)); + m_output = new GSSourceOutputPin(m_size, m_atpf, this, this, hr); // FIXME if(fps == 60) m_atpf = 166834; // = 10000000i64 / 59.94 } + virtual ~GSSource() + { + delete m_output; + } + DECLARE_IUNKNOWN; int GetPinCount() @@ -197,7 +198,7 @@ public: CBasePin* GetPin(int n) { - return n == 0 ? m_output.m_p : NULL; + return n == 0 ? m_output : NULL; } // IGSSource @@ -231,17 +232,15 @@ public: const CMediaType& mt = m_output->CurrentMediaType(); - BYTE* src = (BYTE*)bits; + uint8* src = (uint8*)bits; + uint8* dst = NULL; - BYTE* dst = NULL; sample->GetPointer(&dst); - int w = m_size.cx; - int h = m_size.cy; + int w = m_size.x; + int h = m_size.y; int srcpitch = pitch; - #if _M_SSE >= 0x200 - if(mt.subtype == MEDIASUBTYPE_YUY2) { int dstpitch = ((VIDEOINFOHEADER*)mt.Format())->bmiHeader.biWidth * 2; @@ -255,8 +254,8 @@ public: { for(int j = 0; j < h; j++, dst += dstpitch, src += srcpitch) { - DWORD* s = (DWORD*)src; - WORD* d = (WORD*)dst; + uint32* s = (uint32*)src; + uint16* d = (uint16*)dst; for(int i = 0; i < w; i += 2) { @@ -269,7 +268,7 @@ public: GSVector4 c = lo.hadd(hi) + offset; - *((DWORD*)&d[i]) = GSVector4i(c).rgba32(); + *((uint32*)&d[i]) = GSVector4i(c).rgba32(); } } } @@ -277,8 +276,8 @@ public: { for(int j = 0; j < h; j++, dst += dstpitch, src += srcpitch) { - DWORD* s = (DWORD*)src; - WORD* d = (WORD*)dst; + uint32* s = (uint32*)src; + uint16* d = (uint16*)dst; for(int i = 0; i < w; i += 2) { @@ -291,16 +290,12 @@ public: GSVector4 c = lo.hadd(hi) + offset; - *((DWORD*)&d[i]) = GSVector4i(c).rgba32(); + *((uint32*)&d[i]) = GSVector4i(c).rgba32(); } } } } - else - - #endif - - if(mt.subtype == MEDIASUBTYPE_RGB32) + else if(mt.subtype == MEDIASUBTYPE_RGB32) { int dstpitch = ((VIDEOINFOHEADER*)mt.Format())->bmiHeader.biWidth * 4; @@ -323,7 +318,7 @@ public: d[i] = s[i].shuffle8(mask); } - #elif _M_SSE >= 0x200 + #else GSVector4i* s = (GSVector4i*)src; GSVector4i* d = (GSVector4i*)dst; @@ -333,16 +328,6 @@ public: d[i] = ((s[i] & 0x00ff0000) >> 16) | ((s[i] & 0x000000ff) << 16) | (s[i] & 0x0000ff00); } - #else - - DWORD* s = (DWORD*)src; - DWORD* d = (DWORD*)dst; - - for(int i = 0; i < w; i++) - { - d[i] = ((s[i] & 0x00ff0000) >> 16) | ((s[i] & 0x000000ff) << 16) | (s[i] & 0x0000ff00); - } - #endif } else @@ -423,14 +408,14 @@ bool GSCapture::BeginCapture(int fps) EndCapture(); - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - GSCaptureDlg dlg; if(IDOK != dlg.DoModal()) return false; - m_size.cx = (dlg.m_width + 7) & ~7; - m_size.cy = (dlg.m_height + 7) & ~7; + m_size.x = (dlg.m_width + 7) & ~7; + m_size.y = (dlg.m_height + 7) & ~7; + + wstring fn(dlg.m_filename.begin(), dlg.m_filename.end()); // @@ -442,12 +427,12 @@ bool GSCapture::BeginCapture(int fps) if(FAILED(hr = m_graph.CoCreateInstance(CLSID_FilterGraph)) || FAILED(hr = cgb.CoCreateInstance(CLSID_CaptureGraphBuilder2)) || FAILED(hr = cgb->SetFiltergraph(m_graph)) - || FAILED(hr = cgb->SetOutputFileName(&MEDIASUBTYPE_Avi, CStringW(dlg.m_filename), &mux, NULL))) + || FAILED(hr = cgb->SetOutputFileName(&MEDIASUBTYPE_Avi, fn.c_str(), &mux, NULL))) { return false; } - m_src = new GSSource(m_size.cx, m_size.cy, fps, NULL, hr); + m_src = new GSSource(m_size.x, m_size.y, fps, NULL, hr); if(FAILED(hr = m_graph->AddFilter(m_src, L"Source")) || FAILED(hr = m_graph->AddFilter(dlg.m_enc, L"Encoder"))) @@ -465,7 +450,8 @@ bool GSCapture::BeginCapture(int fps) { CFilterInfo fi; pBF->QueryFilterInfo(&fi); - printf("Filter [%p]: %s\n", pBF.p, CStringA(fi.achName)); + wstring s(fi.achName); + printf("Filter [%p]: %s\n", pBF.p, string(s.begin(), s.end()).c_str()); BeginEnumPins(pBF, pEP, pPin) { @@ -474,7 +460,8 @@ bool GSCapture::BeginCapture(int fps) CPinInfo pi; pPin->QueryPinInfo(&pi); - printf("- Pin [%p - %p]: %s (%s)\n", pPin.p, pPinTo.p, CStringA(pi.achName), pi.dir ? "out" : "in"); + wstring s(pi.achName); + printf("- Pin [%p - %p]: %s (%s)\n", pPin.p, pPinTo.p, string(s.begin(), s.end()).c_str(), pi.dir ? "out" : "in"); BeginEnumMediaTypes(pPin, pEMT, pmt) { diff --git a/plugins/GSdx/GSCapture.h b/plugins/GSdx/GSCapture.h index 74a1808160..c6b71a2f12 100644 --- a/plugins/GSdx/GSCapture.h +++ b/plugins/GSdx/GSCapture.h @@ -22,11 +22,12 @@ #pragma once #include "GSCaptureDlg.h" +#include "GSVector.h" class GSCapture : protected CCritSec { bool m_capturing; - CSize m_size; + GSVector2i m_size; CComPtr m_graph; CComPtr m_src; @@ -39,5 +40,5 @@ public: bool EndCapture(); bool IsCapturing() {return m_capturing;} - CSize GetSize() {return m_size;} + GSVector2i GetSize() {return m_size;} }; diff --git a/plugins/GSdx/GSCaptureDlg.cpp b/plugins/GSdx/GSCaptureDlg.cpp index 8dcd094875..d918cbb18c 100644 --- a/plugins/GSdx/GSCaptureDlg.cpp +++ b/plugins/GSdx/GSCaptureDlg.cpp @@ -20,224 +20,180 @@ */ #include "stdafx.h" -#include +#include "GSdx.h" #include "GSCaptureDlg.h" -// GSCaptureDlg dialog - -IMPLEMENT_DYNAMIC(GSCaptureDlg, CDialog) -GSCaptureDlg::GSCaptureDlg(CWnd* pParent /*=NULL*/) - : CDialog(GSCaptureDlg::IDD, pParent) -{ - m_width = AfxGetApp()->GetProfileInt(_T("Capture"), _T("Width"), 640); - m_height = AfxGetApp()->GetProfileInt(_T("Capture"), _T("Height"), 480); - m_filename = AfxGetApp()->GetProfileString(_T("Capture"), _T("FileName")); -} - -GSCaptureDlg::~GSCaptureDlg() +GSCaptureDlg::GSCaptureDlg() + : GSDialog(IDD_CAPTURE) { + m_width = theApp.GetConfig("CaptureWidth", 640); + m_height = theApp.GetConfig("CaptureHeight", 480); + m_filename = theApp.GetConfig("CaptureFileName", ""); } int GSCaptureDlg::GetSelCodec(Codec& c) { - int iSel = m_codeclist.GetCurSel(); + INT_PTR data = 0; - if(iSel < 0) return 0; - - POSITION pos = (POSITION)m_codeclist.GetItemDataPtr(iSel); - - if(pos == NULL) return 2; - - c = m_codecs.GetAt(pos); - - if(!c.filter) + if(ComboBoxGetSelData(IDC_CODECS, data)) { - c.moniker->BindToObject(NULL, NULL, __uuidof(IBaseFilter), (void**)&c.filter); + if(data == 0) return 2; - if(!c.filter) return 0; + c = *(Codec*)data; + + if(!c.filter) + { + c.moniker->BindToObject(NULL, NULL, __uuidof(IBaseFilter), (void**)&c.filter); + + if(!c.filter) return 0; + } + + return 1; } - return 1; + return 0; } -LRESULT GSCaptureDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) +void GSCaptureDlg::OnInit() { - LRESULT ret = __super::DefWindowProc(message, wParam, lParam); + __super::OnInit(); - if(message == WM_INITDIALOG) SendMessage(WM_KICKIDLE); + SetTextAsInt(IDC_WIDTH, m_width); + SetTextAsInt(IDC_HEIGHT, m_height); + SetText(IDC_FILENAME, m_filename.c_str()); - return(ret); -} + m_codecs.clear(); -void GSCaptureDlg::DoDataExchange(CDataExchange* pDX) -{ - __super::DoDataExchange(pDX); + string selected = theApp.GetConfig("CaptureVideoCodecDisplayName", ""); - DDX_Text(pDX, IDC_EDIT1, m_filename); - DDX_Control(pDX, IDC_COMBO1, m_codeclist); - DDX_Text(pDX, IDC_EDIT2, m_width); - DDX_Text(pDX, IDC_EDIT4, m_height); -} - -BOOL GSCaptureDlg::OnInitDialog() -{ - __super::OnInitDialog(); - - m_codecs.RemoveAll(); - - m_codeclist.ResetContent(); - m_codeclist.SetItemDataPtr(m_codeclist.AddString(_T("Uncompressed")), NULL); + ComboBoxAppend(IDC_CODECS, "Uncompressed", 0, true); BeginEnumSysDev(CLSID_VideoCompressorCategory, moniker) { Codec c; + c.moniker = moniker; - LPOLESTR strName = NULL; - if(FAILED(moniker->GetDisplayName(NULL, NULL, &strName))) + wstring prefix; + + LPOLESTR str = NULL; + + if(FAILED(moniker->GetDisplayName(NULL, NULL, &str))) continue; - c.DisplayName = strName; - CoTaskMemFree(strName); + if(wcsstr(str, L"@device:dmo:")) prefix = L"(DMO) "; + else if(wcsstr(str, L"@device:sw:")) prefix = L"(DS) "; + else if(wcsstr(str, L"@device:cm:")) prefix = L"(VfW) "; + + c.DisplayName = str; + + CoTaskMemFree(str); CComPtr pPB; - moniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB); + + if(FAILED(moniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB))) + continue; CComVariant var; + if(FAILED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL))) continue; - c.FriendlyName = var.bstrVal; + c.FriendlyName = prefix + var.bstrVal; - CStringW str = CStringW(c.DisplayName).MakeLower(); - CString prefix; - if(str.Find(L"@device:dmo:") == 0) prefix = _T("(DMO) "); - else if(str.Find(L"@device:sw:") == 0) prefix = _T("(DS) "); - else if(str.Find(L"@device:cm:") == 0) prefix = _T("(VfW) "); - c.FriendlyName = prefix + c.FriendlyName; + m_codecs.push_back(c); - m_codeclist.SetItemDataPtr(m_codeclist.AddString(c.FriendlyName), m_codecs.AddTail(c)); + string s(c.FriendlyName.begin(), c.FriendlyName.end()); + + ComboBoxAppend(IDC_CODECS, s.c_str(), (LPARAM)&m_codecs.back(), s == selected); } EndEnumSysDev +} - // - - CString DisplayNameToFind = AfxGetApp()->GetProfileString(_T("Capture"), _T("VideoCodecDisplayName")); - - for(int i = 0; i < m_codeclist.GetCount(); i++) +bool GSCaptureDlg::OnCommand(HWND hWnd, UINT id, UINT code) +{ + if(id == IDC_BROWSE && code == BN_CLICKED) { - CString DisplayName; + char buff[MAX_PATH] = {0}; - POSITION pos = (POSITION)m_codeclist.GetItemDataPtr(i); + OPENFILENAME ofn; - if(pos) DisplayName = m_codecs.GetAt(pos).DisplayName; + memset(&ofn, 0, sizeof(ofn)); - if(DisplayName == DisplayNameToFind) + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = buff; + ofn.nMaxFile = countof(buff); + ofn.lpstrFilter = "Avi files (*.avi)\0*.avi\0"; + ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; + + strcpy(ofn.lpstrFile, m_filename.c_str()); + + if(GetSaveFileName(&ofn)) { - m_codeclist.SetCurSel(i); - break; + m_filename = ofn.lpstrFile; + + SetText(IDC_FILENAME, m_filename.c_str()); } + + return true; } - - // - - UpdateData(FALSE); - - return TRUE; // return TRUE unless you set the focus to a control - // EXCEPTION: OCX Property Pages should return FALSE -} - -BEGIN_MESSAGE_MAP(GSCaptureDlg, CDialog) - ON_MESSAGE_VOID(WM_KICKIDLE, OnKickIdle) - ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1) - ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2) - ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateButton2) - ON_BN_CLICKED(IDOK, OnBnClickedOk) - ON_UPDATE_COMMAND_UI(IDOK, OnUpdateOK) -END_MESSAGE_MAP() - -// GSCaptureDlg message handlers - -void GSCaptureDlg::OnKickIdle() -{ - UpdateDialogControls(this, false); -} - -void GSCaptureDlg::OnBnClickedButton1() -{ - UpdateData(); - - DWORD flags = OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST; - - CFileDialog fd(FALSE, _T("avi"), m_filename, flags, _T("Avi files (*.avi)|*.avi||"), this, 0); - - if(fd.DoModal() == IDOK) + else if(id == IDC_CONFIGURE && code == BN_CLICKED) { - m_filename = fd.GetPathName(); + Codec c; - UpdateData(FALSE); - } -} - -void GSCaptureDlg::OnBnClickedButton2() -{ - Codec c; - - if(GetSelCodec(c) != 1) return; - - if(CComQIPtr pSPP = c.filter) - { - CAUUID caGUID; - - memset(&caGUID, 0, sizeof(caGUID)); - - if(SUCCEEDED(pSPP->GetPages(&caGUID))) + if(GetSelCodec(c) == 1) { - IUnknown* lpUnk = NULL; - pSPP.QueryInterface(&lpUnk); - OleCreatePropertyFrame(m_hWnd, 0, 0, CStringW(c.FriendlyName), 1, (IUnknown**)&lpUnk, caGUID.cElems, caGUID.pElems, 0, 0, NULL); - lpUnk->Release(); + if(CComQIPtr pSPP = c.filter) + { + CAUUID caGUID; - if(caGUID.pElems) CoTaskMemFree(caGUID.pElems); + memset(&caGUID, 0, sizeof(caGUID)); + + if(SUCCEEDED(pSPP->GetPages(&caGUID))) + { + IUnknown* lpUnk = NULL; + pSPP.QueryInterface(&lpUnk); + OleCreatePropertyFrame(m_hWnd, 0, 0, c.FriendlyName.c_str(), 1, (IUnknown**)&lpUnk, caGUID.cElems, caGUID.pElems, 0, 0, NULL); + lpUnk->Release(); + + if(caGUID.pElems) CoTaskMemFree(caGUID.pElems); + } + } + else if(CComQIPtr pAMVfWCD = c.filter) + { + if(pAMVfWCD->ShowDialog(VfwCompressDialog_QueryConfig, NULL) == S_OK) + { + pAMVfWCD->ShowDialog(VfwCompressDialog_Config, m_hWnd); + } + } } + + return true; } - else if(CComQIPtr pAMVfWCD = c.filter) + else if(id == IDOK) { - if(pAMVfWCD->ShowDialog(VfwCompressDialog_QueryConfig, NULL) == S_OK) + m_width = GetTextAsInt(IDC_WIDTH); + m_height = GetTextAsInt(IDC_HEIGHT); + m_filename = GetText(IDC_FILENAME); + + Codec c; + + if(GetSelCodec(c) == 0) { - pAMVfWCD->ShowDialog(VfwCompressDialog_Config, m_hWnd); + return false; } + + m_enc = c.filter; + + theApp.SetConfig("CaptureWidth", m_width); + theApp.SetConfig("CaptureHeight", m_height); + theApp.SetConfig("CaptureFileName", m_filename.c_str()); + + wstring s = wstring(c.DisplayName.m_str); + + theApp.SetConfig("CaptureVideoCodecDisplayName", string(s.begin(), s.end()).c_str()); } -} -void GSCaptureDlg::OnUpdateButton2(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(m_codeclist.GetCurSel() >= 0 && m_codeclist.GetItemDataPtr(m_codeclist.GetCurSel()) != NULL); -} - -void GSCaptureDlg::OnBnClickedOk() -{ - UpdateData(); - - Codec c; - - if(GetSelCodec(c) == 0) return; - - m_enc = c.filter; - - AfxGetApp()->WriteProfileInt(_T("Capture"), _T("Width"), m_width); - AfxGetApp()->WriteProfileInt(_T("Capture"), _T("Height"), m_height); - AfxGetApp()->WriteProfileString(_T("Capture"), _T("FileName"), m_filename); - AfxGetApp()->WriteProfileString(_T("Capture"), _T("VideoCodecDisplayName"), CString(c.DisplayName)); - - OnOK(); -} - -void GSCaptureDlg::OnUpdateOK(CCmdUI* pCmdUI) -{ - CString str; - - GetDlgItem(IDC_EDIT1)->GetWindowText(str); - - pCmdUI->Enable(!str.IsEmpty() && m_codeclist.GetCurSel() >= 0); -} + return __super::OnCommand(hWnd, id, code); +} \ No newline at end of file diff --git a/plugins/GSdx/GSCaptureDlg.h b/plugins/GSdx/GSCaptureDlg.h index 419b0cd62a..ceb0b04f64 100644 --- a/plugins/GSdx/GSCaptureDlg.h +++ b/plugins/GSdx/GSCaptureDlg.h @@ -21,53 +21,33 @@ #pragma once +#include "GSDialog.h" #include "resource.h" #include "baseclasses/streams.h" -// GSCaptureDlg dialog - -class GSCaptureDlg : public CDialog +class GSCaptureDlg : public GSDialog { - DECLARE_DYNAMIC(GSCaptureDlg) - -private: struct Codec { CComPtr moniker; CComPtr filter; - CString FriendlyName; + wstring FriendlyName; CComBSTR DisplayName; }; - CAtlList m_codecs; + list m_codecs; int GetSelCodec(Codec& c); -public: - GSCaptureDlg(CWnd* pParent = NULL); // standard constructor - virtual ~GSCaptureDlg(); - - CComPtr m_enc; - -// Dialog Data - enum { IDD = IDD_CAPTURE }; - CString m_filename; - CComboBox m_codeclist; - protected: - virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam); - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - virtual BOOL OnInitDialog(); - - DECLARE_MESSAGE_MAP() + void OnInit(); + bool OnCommand(HWND hWnd, UINT id, UINT code); public: - afx_msg void OnKickIdle(); - afx_msg void OnBnClickedButton1(); - afx_msg void OnBnClickedButton2(); - afx_msg void OnUpdateButton2(CCmdUI* pCmdUI); - afx_msg void OnBnClickedOk(); - afx_msg void OnUpdateOK(CCmdUI* pCmdUI); + GSCaptureDlg(); + int m_width; int m_height; + string m_filename; + CComPtr m_enc; }; diff --git a/plugins/GSdx/GSClut.cpp b/plugins/GSdx/GSClut.cpp index d850ac266f..59a717e82a 100644 --- a/plugins/GSdx/GSClut.cpp +++ b/plugins/GSdx/GSClut.cpp @@ -26,11 +26,11 @@ GSClut::GSClut(const GSLocalMemory* mem) : m_mem(mem) { - BYTE* p = (BYTE*)VirtualAlloc(NULL, 2 * 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + uint8* p = (uint8*)VirtualAlloc(NULL, 2 * 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - m_clut = (WORD*)&p[0]; // 1k + 1k for buffer overruns (sfex: PSM == PSM_PSMT8, CPSM == PSM_PSMCT32, CSA != 0) - m_buff32 = (DWORD*)&p[2048]; // 1k - m_buff64 = (UINT64*)&p[4096]; // 2k + m_clut = (uint16*)&p[0]; // 1k + 1k for buffer overruns (sfex: PSM == PSM_PSMT8, CPSM == PSM_PSMCT32, CSA != 0) + m_buff32 = (uint32*)&p[2048]; // 1k + m_buff64 = (uint64*)&p[4096]; // 2k m_write.dirty = true; m_read.dirty = true; @@ -106,7 +106,7 @@ bool GSClut::WriteTest(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) case 3: m_CBP[1] = TEX0.CBP; break; case 4: if(m_CBP[0] == TEX0.CBP) return false; m_CBP[0] = TEX0.CBP; break; case 5: if(m_CBP[1] == TEX0.CBP) return false; m_CBP[1] = TEX0.CBP; break; - case 6: ASSERT(0); return false; + case 6: ASSERT(0); return false; // ffx2 menu case 7: ASSERT(0); return false; default: __assume(0); } @@ -126,83 +126,85 @@ void GSClut::Write(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) void GSClut::WriteCLUT32_I8_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { + ALIGN_STACK(16); + ASSERT(TEX0.CSA == 0); - WriteCLUT_T32_I8_CSM1(&m_mem->m_vm32[m_mem->BlockAddress32(0, 0, TEX0.CBP, 1)], m_clut + (TEX0.CSA << 4)); + WriteCLUT_T32_I8_CSM1((uint32*)m_mem->BlockPtr32(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4)); } void GSClut::WriteCLUT32_I4_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { + ALIGN_STACK(16); + ASSERT(TEX0.CSA < 16); - GSVector4i dummy; // this just forces stack alignment and enables inlining the next call - - WriteCLUT_T32_I4_CSM1(&m_mem->m_vm32[m_mem->BlockAddress32(0, 0, TEX0.CBP, 1)], m_clut + (TEX0.CSA << 4)); + WriteCLUT_T32_I4_CSM1((uint32*)m_mem->BlockPtr32(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4)); } void GSClut::WriteCLUT16_I8_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { ASSERT(TEX0.CSA < 16); - WriteCLUT_T16_I8_CSM1(&m_mem->m_vm16[m_mem->BlockAddress16(0, 0, TEX0.CBP, 1)], m_clut + (TEX0.CSA << 4)); + WriteCLUT_T16_I8_CSM1((uint16*)m_mem->BlockPtr16(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4)); } void GSClut::WriteCLUT16_I4_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { ASSERT(TEX0.CSA < 32); - WriteCLUT_T16_I4_CSM1(&m_mem->m_vm16[m_mem->BlockAddress16(0, 0, TEX0.CBP, 1)], m_clut + (TEX0.CSA << 4)); + WriteCLUT_T16_I4_CSM1((uint16*)m_mem->BlockPtr16(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4)); } void GSClut::WriteCLUT16S_I8_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { - WriteCLUT_T16_I8_CSM1(&m_mem->m_vm16[m_mem->BlockAddress16S(0, 0, TEX0.CBP, 1)], m_clut + (TEX0.CSA << 4)); + WriteCLUT_T16_I8_CSM1((uint16*)m_mem->BlockPtr16S(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4)); } void GSClut::WriteCLUT16S_I4_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { - WriteCLUT_T16_I4_CSM1(&m_mem->m_vm16[m_mem->BlockAddress16S(0, 0, TEX0.CBP, 1)], m_clut + (TEX0.CSA << 4)); + WriteCLUT_T16_I4_CSM1((uint16*)m_mem->BlockPtr16S(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4)); } template void GSClut::WriteCLUT32_CSM2(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { - WORD* RESTRICT clut = m_clut + (TEX0.CSA << 4); + uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4); - DWORD base = m_mem->PixelAddress32(0, TEXCLUT.COV, TEX0.CBP, TEXCLUT.CBW); + uint32 base = m_mem->PixelAddress32(0, TEXCLUT.COV, TEX0.CBP, TEXCLUT.CBW); int* offset = &m_mem->rowOffset32[TEXCLUT.COU << 4]; for(int i = 0; i < n; i++) { - DWORD c = m_mem->ReadPixel32(base + offset[i]); + uint32 c = m_mem->ReadPixel32(base + offset[i]); - clut[i] = (WORD)(c & 0xffff); - clut[i + 256] = (WORD)(c >> 16); + clut[i] = (uint16)(c & 0xffff); + clut[i + 256] = (uint16)(c >> 16); } } template void GSClut::WriteCLUT16_CSM2(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { - WORD* RESTRICT clut = m_clut + (TEX0.CSA << 4); + uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4); - DWORD base = m_mem->PixelAddress16(0, TEXCLUT.COV, TEX0.CBP, TEXCLUT.CBW); + uint32 base = m_mem->PixelAddress16(0, TEXCLUT.COV, TEX0.CBP, TEXCLUT.CBW); int* offset = &m_mem->rowOffset16[TEXCLUT.COU << 4]; for(int i = 0; i < n; i++) { - clut[i] = (WORD)m_mem->ReadPixel16(base + offset[i]); + clut[i] = (uint16)m_mem->ReadPixel16(base + offset[i]); } } template void GSClut::WriteCLUT16S_CSM2(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { - WORD* RESTRICT clut = m_clut + (TEX0.CSA << 4); + uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4); - DWORD base = m_mem->PixelAddress16S(0, TEXCLUT.COV, TEX0.CBP, TEXCLUT.CBW); + uint32 base = m_mem->PixelAddress16S(0, TEXCLUT.COV, TEX0.CBP, TEXCLUT.CBW); int* offset = &m_mem->rowOffset16S[TEXCLUT.COU << 4]; for(int i = 0; i < n; i++) { - clut[i] = (WORD)m_mem->ReadPixel16(base + offset[i]); + clut[i] = (uint16)m_mem->ReadPixel16(base + offset[i]); } } @@ -213,7 +215,7 @@ void GSClut::Read(const GIFRegTEX0& TEX0) m_read.TEX0 = TEX0; m_read.dirty = false; - WORD* clut = m_clut + (TEX0.CSA << 4); + uint16* clut = m_clut + (TEX0.CSA << 4); if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) { @@ -257,7 +259,7 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) m_read.dirty = false; m_read.adirty = true; - WORD* clut = m_clut + (TEX0.CSA << 4); + uint16* clut = m_clut + (TEX0.CSA << 4); if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) { @@ -272,7 +274,7 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) case PSM_PSMT4HH: // TODO: merge these functions ReadCLUT_T32_I4(clut, m_buff32); - ExpandCLUT64_T32_I8(m_buff32, (UINT64*)m_buff64); // sw renderer does not need m_buff64 anymore + ExpandCLUT64_T32_I8(m_buff32, (uint64*)m_buff64); // sw renderer does not need m_buff64 anymore break; } } @@ -289,7 +291,7 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) case PSM_PSMT4HH: // TODO: merge these functions Expand16(clut, m_buff32, 16, TEXA); - ExpandCLUT64_T32_I8(m_buff32, (UINT64*)m_buff64); // sw renderer does not need m_buff64 anymore + ExpandCLUT64_T32_I8(m_buff32, (uint64*)m_buff64); // sw renderer does not need m_buff64 anymore break; } } @@ -306,9 +308,9 @@ void GSClut::GetAlphaMinMax32(int& amin, int& amax) { m_read.adirty = false; - // DWORD bpp = GSLocalMemory::m_psm[m_read.TEX0.PSM].trbpp; - DWORD cbpp = GSLocalMemory::m_psm[m_read.TEX0.CPSM].trbpp; - DWORD pal = GSLocalMemory::m_psm[m_read.TEX0.PSM].pal; + // uint32 bpp = GSLocalMemory::m_psm[m_read.TEX0.PSM].trbpp; + uint32 cbpp = GSLocalMemory::m_psm[m_read.TEX0.CPSM].trbpp; + uint32 pal = GSLocalMemory::m_psm[m_read.TEX0.PSM].pal; if(cbpp == 24 && m_read.TEXA.AEM == 0) { @@ -352,10 +354,8 @@ void GSClut::GetAlphaMinMax32(int& amin, int& amax) // -void GSClut::WriteCLUT_T32_I8_CSM1(const DWORD* RESTRICT src, WORD* RESTRICT clut) +void GSClut::WriteCLUT_T32_I8_CSM1(const uint32* RESTRICT src, uint16* RESTRICT clut) { - #if _M_SSE >= 0x200 - for(int i = 0; i < 64; i += 16) { WriteCLUT_T32_I4_CSM1(&src[i + 0], &clut[i * 2 + 0]); @@ -363,26 +363,10 @@ void GSClut::WriteCLUT_T32_I8_CSM1(const DWORD* RESTRICT src, WORD* RESTRICT clu WriteCLUT_T32_I4_CSM1(&src[i + 128], &clut[i * 2 + 128]); WriteCLUT_T32_I4_CSM1(&src[i + 192], &clut[i * 2 + 144]); } - - #else - - for(int j = 0; j < 2; j++, src += 128, clut += 128) - { - for(int i = 0; i < 128; i++) - { - DWORD c = src[clutTableT32I8[i]]; - clut[i] = (WORD)(c & 0xffff); - clut[i + 256] = (WORD)(c >> 16); - } - } - - #endif } -__forceinline void GSClut::WriteCLUT_T32_I4_CSM1(const DWORD* RESTRICT src, WORD* RESTRICT clut) +__forceinline void GSClut::WriteCLUT_T32_I4_CSM1(const uint32* RESTRICT src, uint16* RESTRICT clut) { - #if _M_SSE >= 0x200 - GSVector4i* s = (GSVector4i*)src; GSVector4i* d = (GSVector4i*)clut; @@ -400,23 +384,10 @@ __forceinline void GSClut::WriteCLUT_T32_I4_CSM1(const DWORD* RESTRICT src, WORD d[1] = v1; d[32] = v2; d[33] = v3; - - #else - - for(int i = 0; i < 16; i++) - { - DWORD c = src[clutTableT32I4[i]]; - clut[i] = (WORD)(c & 0xffff); - clut[i + 256] = (WORD)(c >> 16); - } - - #endif } -void GSClut::WriteCLUT_T16_I8_CSM1(const WORD* RESTRICT src, WORD* RESTRICT clut) +void GSClut::WriteCLUT_T16_I8_CSM1(const uint16* RESTRICT src, uint16* RESTRICT clut) { - #if _M_SSE >= 0x200 - GSVector4i* s = (GSVector4i*)src; GSVector4i* d = (GSVector4i*)clut; @@ -436,21 +407,9 @@ void GSClut::WriteCLUT_T16_I8_CSM1(const WORD* RESTRICT src, WORD* RESTRICT clut d[i + 2] = v1; d[i + 3] = v3; } - - #else - - for(int j = 0; j < 8; j++, src += 32, clut += 32) - { - for(int i = 0; i < 32; i++) - { - clut[i] = src[clutTableT16I8[i]]; - } - } - - #endif } -__forceinline void GSClut::WriteCLUT_T16_I4_CSM1(const WORD* RESTRICT src, WORD* RESTRICT clut) +__forceinline void GSClut::WriteCLUT_T16_I4_CSM1(const uint16* RESTRICT src, uint16* RESTRICT clut) { for(int i = 0; i < 16; i++) { @@ -458,29 +417,16 @@ __forceinline void GSClut::WriteCLUT_T16_I4_CSM1(const WORD* RESTRICT src, WORD* } } -void GSClut::ReadCLUT_T32_I8(const WORD* RESTRICT clut, DWORD* RESTRICT dst) +void GSClut::ReadCLUT_T32_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst) { - #if _M_SSE >= 0x200 - for(int i = 0; i < 256; i += 16) { ReadCLUT_T32_I4(&clut[i], &dst[i]); } - - #else - - for(int i = 0; i < 256; i++) - { - dst[i] = ((DWORD)clut[i + 256] << 16) | clut[i]; - } - - #endif } -__forceinline void GSClut::ReadCLUT_T32_I4(const WORD* RESTRICT clut, DWORD* RESTRICT dst) +__forceinline void GSClut::ReadCLUT_T32_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst) { - #if _M_SSE >= 0x200 - GSVector4i* s = (GSVector4i*)clut; GSVector4i* d = (GSVector4i*)dst; @@ -495,21 +441,10 @@ __forceinline void GSClut::ReadCLUT_T32_I4(const WORD* RESTRICT clut, DWORD* RES d[1] = v1; d[2] = v2; d[3] = v3; - - #else - - for(int i = 0; i < 16; i++) - { - dst[i] = ((DWORD)clut[i + 256] << 16) | clut[i]; - } - - #endif } -__forceinline void GSClut::ReadCLUT_T32_I4(const WORD* RESTRICT clut, DWORD* RESTRICT dst32, UINT64* RESTRICT dst64) +__forceinline void GSClut::ReadCLUT_T32_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst32, uint64* RESTRICT dst64) { - #if _M_SSE >= 0x200 - GSVector4i* s = (GSVector4i*)clut; GSVector4i* d32 = (GSVector4i*)dst32; GSVector4i* d64 = (GSVector4i*)dst64; @@ -530,53 +465,18 @@ __forceinline void GSClut::ReadCLUT_T32_I4(const WORD* RESTRICT clut, DWORD* RES ExpandCLUT64_T32(s1, s0, s1, s2, s3, &d64[32]); ExpandCLUT64_T32(s2, s0, s1, s2, s3, &d64[64]); ExpandCLUT64_T32(s3, s0, s1, s2, s3, &d64[96]); - - #else - - for(int i = 0; i < 16; i++) - { - dst[i] = ((DWORD)clut[i + 256] << 16) | clut[i]; - } - - DWORD* d = (DWORD*)dst64; - - for(int j = 0; j < 16; j++, d += 32) - { - DWORD hi = dst32[j]; - - for(int i = 0; i < 16; i++) - { - d[i * 2 + 0] = dst32[i]; - d[i * 2 + 1] = hi; - } - } - - #endif } -void GSClut::ReadCLUT_T16_I8(const WORD* RESTRICT clut, DWORD* RESTRICT dst) +void GSClut::ReadCLUT_T16_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst) { - #if _M_SSE >= 0x200 - for(int i = 0; i < 256; i += 16) { ReadCLUT_T16_I4(&clut[i], &dst[i]); } - - #else - - for(int i = 0; i < 256; i++) - { - dst[i] = (DWORD)clut[i]; - } - - #endif } -__forceinline void GSClut::ReadCLUT_T16_I4(const WORD* RESTRICT clut, DWORD* RESTRICT dst) +__forceinline void GSClut::ReadCLUT_T16_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst) { - #if _M_SSE >= 0x200 - GSVector4i* s = (GSVector4i*)clut; GSVector4i* d = (GSVector4i*)dst; @@ -587,21 +487,10 @@ __forceinline void GSClut::ReadCLUT_T16_I4(const WORD* RESTRICT clut, DWORD* RES d[1] = v0.uph16(); d[2] = v1.upl16(); d[3] = v1.uph16(); - - #else - - for(int i = 0; i < 16; i++) - { - dst[i] = (DWORD)clut[i]; - } - - #endif } -__forceinline void GSClut::ReadCLUT_T16_I4(const WORD* RESTRICT clut, DWORD* RESTRICT dst32, UINT64* RESTRICT dst64) +__forceinline void GSClut::ReadCLUT_T16_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst32, uint64* RESTRICT dst64) { - #if _M_SSE >= 0x200 - GSVector4i* s = (GSVector4i*)clut; GSVector4i* d32 = (GSVector4i*)dst32; GSVector4i* d64 = (GSVector4i*)dst64; @@ -623,33 +512,10 @@ __forceinline void GSClut::ReadCLUT_T16_I4(const WORD* RESTRICT clut, DWORD* RES ExpandCLUT64_T16(s1, s0, s1, s2, s3, &d64[32]); ExpandCLUT64_T16(s2, s0, s1, s2, s3, &d64[64]); ExpandCLUT64_T16(s3, s0, s1, s2, s3, &d64[96]); - - #else - - for(int i = 0; i < 16; i++) - { - dst32[i] = (DWORD)clut[i]; - } - - DWORD* d = (DWORD*)dst64; - - for(int j = 0; j < 16; j++, d += 32) - { - DWORD hi = dst32[j] << 16; - - for(int i = 0; i < 16; i++) - { - d[i * 2 + 0] = hi | (dst32[i] & 0xffff); - } - } - - #endif } -void GSClut::ExpandCLUT64_T32_I8(const DWORD* RESTRICT src, UINT64* RESTRICT dst) +void GSClut::ExpandCLUT64_T32_I8(const uint32* RESTRICT src, uint64* RESTRICT dst) { - #if _M_SSE >= 0x200 - GSVector4i* s = (GSVector4i*)src; GSVector4i* d = (GSVector4i*)dst; @@ -662,23 +528,6 @@ void GSClut::ExpandCLUT64_T32_I8(const DWORD* RESTRICT src, UINT64* RESTRICT dst ExpandCLUT64_T32(s1, s0, s1, s2, s3, &d[32]); ExpandCLUT64_T32(s2, s0, s1, s2, s3, &d[64]); ExpandCLUT64_T32(s3, s0, s1, s2, s3, &d[96]); - - #else - - DWORD* d = (DWORD*)dst; - - for(int j = 0; j < 16; j++, d += 32) - { - DWORD hi = src[j]; - - for(int i = 0; i < 16; i++) - { - d[i * 2 + 0] = src[i]; - d[i * 2 + 1] = hi; - } - } - - #endif } __forceinline void GSClut::ExpandCLUT64_T32(const GSVector4i& hi, const GSVector4i& lo0, const GSVector4i& lo1, const GSVector4i& lo2, const GSVector4i& lo3, GSVector4i* dst) @@ -707,10 +556,8 @@ __forceinline void GSClut::ExpandCLUT64_T32(const GSVector4i& hi, const GSVector dst[1] = lo.uph32(hi); } -void GSClut::ExpandCLUT64_T16_I8(const DWORD* RESTRICT src, UINT64* RESTRICT dst) +void GSClut::ExpandCLUT64_T16_I8(const uint32* RESTRICT src, uint64* RESTRICT dst) { - #if _M_SSE >= 0x200 - GSVector4i* s = (GSVector4i*)src; GSVector4i* d = (GSVector4i*)dst; @@ -723,22 +570,6 @@ void GSClut::ExpandCLUT64_T16_I8(const DWORD* RESTRICT src, UINT64* RESTRICT dst ExpandCLUT64_T16(s1, s0, s1, s2, s3, &d[32]); ExpandCLUT64_T16(s2, s0, s1, s2, s3, &d[64]); ExpandCLUT64_T16(s3, s0, s1, s2, s3, &d[96]); - - #else - - DWORD* d = (DWORD*)dst; - - for(int j = 0; j < 16; j++, d += 32) - { - DWORD hi = src[j] << 16; - - for(int i = 0; i < 16; i++) - { - d[i * 2 + 0] = hi | (src[i] & 0xffff); - } - } - - #endif } __forceinline void GSClut::ExpandCLUT64_T16(const GSVector4i& hi, const GSVector4i& lo0, const GSVector4i& lo1, const GSVector4i& lo2, const GSVector4i& lo3, GSVector4i* dst) @@ -769,21 +600,17 @@ __forceinline void GSClut::ExpandCLUT64_T16(const GSVector4i& hi, const GSVector // TODO -static const GSVector4i s_am(0x00008000); static const GSVector4i s_bm(0x00007c00); static const GSVector4i s_gm(0x000003e0); static const GSVector4i s_rm(0x0000001f); -void GSClut::Expand16(const WORD* RESTRICT src, DWORD* RESTRICT dst, int w, const GIFRegTEXA& TEXA) +void GSClut::Expand16(const uint16* RESTRICT src, uint32* RESTRICT dst, int w, const GIFRegTEXA& TEXA) { - #if _M_SSE >= 0x200 - ASSERT((w & 7) == 0); const GSVector4i rm = s_rm; const GSVector4i gm = s_gm; const GSVector4i bm = s_bm; - // const GSVector4i am = s_am; GSVector4i TA0(TEXA.TA0 << 24); GSVector4i TA1(TEXA.TA1 << 24); @@ -798,12 +625,6 @@ void GSClut::Expand16(const WORD* RESTRICT src, DWORD* RESTRICT dst, int w, cons for(int i = 0, j = w >> 3; i < j; i++) { c = s[i]; - /* - cl = c.upl16(); - ch = c.uph16(); - d[i * 2 + 0] = ((cl & rm) << 3) | ((cl & gm) << 6) | ((cl & bm) << 9) | TA1.blend(TA0, cl < am); - d[i * 2 + 1] = ((ch & rm) << 3) | ((ch & gm) << 6) | ((ch & bm) << 9) | TA1.blend(TA0, ch < am); - */ cl = c.upl16(c); ch = c.uph16(c); d[i * 2 + 0] = ((cl & rm) << 3) | ((cl & gm) << 6) | ((cl & bm) << 9) | TA0.blend8(TA1, cl.sra16(15)); @@ -815,55 +636,27 @@ void GSClut::Expand16(const WORD* RESTRICT src, DWORD* RESTRICT dst, int w, cons for(int i = 0, j = w >> 3; i < j; i++) { c = s[i]; - /* - cl = c.upl16(); - ch = c.uph16(); - d[i * 2 + 0] = ((cl & rm) << 3) | ((cl & gm) << 6) | ((cl & bm) << 9) | TA1.blend(TA0, cl < am).andnot(cl == GSVector4i::zero()); - d[i * 2 + 1] = ((ch & rm) << 3) | ((ch & gm) << 6) | ((ch & bm) << 9) | TA1.blend(TA0, ch < am).andnot(ch == GSVector4i::zero()); - */ cl = c.upl16(c); ch = c.uph16(c); d[i * 2 + 0] = ((cl & rm) << 3) | ((cl & gm) << 6) | ((cl & bm) << 9) | TA0.blend8(TA1, cl.sra16(15)).andnot(cl == GSVector4i::zero()); d[i * 2 + 1] = ((ch & rm) << 3) | ((ch & gm) << 6) | ((ch & bm) << 9) | TA0.blend8(TA1, ch.sra16(15)).andnot(ch == GSVector4i::zero()); } } - - #else - - DWORD TA0 = (DWORD)TEXA.TA0 << 24; - DWORD TA1 = (DWORD)TEXA.TA1 << 24; - - if(!TEXA.AEM) - { - for(int i = 0; i < w; i++) - { - dst[i] = ((src[i] & 0x8000) ? TA1 : TA0) | ((src[i] & 0x7c00) << 9) | ((src[i] & 0x03e0) << 6) | ((src[i] & 0x001f) << 3); - } - } - else - { - for(int i = 0; i < w; i++) - { - dst[i] = ((src[i] & 0x8000) ? TA1 : src[i] ? TA0 : 0) | ((src[i] & 0x7c00) << 9) | ((src[i] & 0x03e0) << 6) | ((src[i] & 0x001f) << 3); - } - } - - #endif } // bool GSClut::WriteState::IsDirty(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { - return dirty || !(GSVector4i::load(this) == GSVector4i::load(&TEX0, &TEXCLUT)).alltrue(); + return dirty || !GSVector4i::load(this).eq(GSVector4i::load(&TEX0, &TEXCLUT)); } bool GSClut::ReadState::IsDirty(const GIFRegTEX0& TEX0) { - return dirty || !(GSVector4i::load(this) == GSVector4i::load(&TEX0, &this->TEXA)).alltrue(); + return dirty || !GSVector4i::load(this).eq(GSVector4i::load(&TEX0, &this->TEXA)); } bool GSClut::ReadState::IsDirty(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) { - return dirty || !(GSVector4i::load(this) == GSVector4i::load(&TEX0, &TEXA)).alltrue(); -} + return dirty || !GSVector4i::load(this).eq(GSVector4i::load(&TEX0, &TEXA)); +} \ No newline at end of file diff --git a/plugins/GSdx/GSClut.h b/plugins/GSdx/GSClut.h index 9c7fa4241a..2d8333cfb4 100644 --- a/plugins/GSdx/GSClut.h +++ b/plugins/GSdx/GSClut.h @@ -32,10 +32,10 @@ __declspec(align(16)) class GSClut : public GSAlignedClass<16> { const GSLocalMemory* m_mem; - DWORD m_CBP[2]; - WORD* m_clut; - DWORD* m_buff32; - UINT64* m_buff64; + uint32 m_CBP[2]; + uint16* m_clut; + uint32* m_buff32; + uint64* m_buff64; __declspec(align(16)) struct WriteState { @@ -73,24 +73,24 @@ __declspec(align(16)) class GSClut : public GSAlignedClass<16> void WriteCLUT_NULL(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) {} - static void WriteCLUT_T32_I8_CSM1(const DWORD* RESTRICT src, WORD* RESTRICT clut); - static void WriteCLUT_T32_I4_CSM1(const DWORD* RESTRICT src, WORD* RESTRICT clut); - static void WriteCLUT_T16_I8_CSM1(const WORD* RESTRICT src, WORD* RESTRICT clut); - static void WriteCLUT_T16_I4_CSM1(const WORD* RESTRICT src, WORD* RESTRICT clut); - static void ReadCLUT_T32_I8(const WORD* RESTRICT clut, DWORD* RESTRICT dst); - static void ReadCLUT_T32_I4(const WORD* RESTRICT clut, DWORD* RESTRICT dst); - static void ReadCLUT_T32_I4(const WORD* RESTRICT clut, DWORD* RESTRICT dst32, UINT64* RESTRICT dst64); - static void ReadCLUT_T16_I8(const WORD* RESTRICT clut, DWORD* RESTRICT dst); - static void ReadCLUT_T16_I4(const WORD* RESTRICT clut, DWORD* RESTRICT dst); - static void ReadCLUT_T16_I4(const WORD* RESTRICT clut, DWORD* RESTRICT dst32, UINT64* RESTRICT dst64); - static void ExpandCLUT64_T32_I8(const DWORD* RESTRICT src, UINT64* RESTRICT dst); + static void WriteCLUT_T32_I8_CSM1(const uint32* RESTRICT src, uint16* RESTRICT clut); + static void WriteCLUT_T32_I4_CSM1(const uint32* RESTRICT src, uint16* RESTRICT clut); + static void WriteCLUT_T16_I8_CSM1(const uint16* RESTRICT src, uint16* RESTRICT clut); + static void WriteCLUT_T16_I4_CSM1(const uint16* RESTRICT src, uint16* RESTRICT clut); + static void ReadCLUT_T32_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst); + static void ReadCLUT_T32_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst); + static void ReadCLUT_T32_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst32, uint64* RESTRICT dst64); + static void ReadCLUT_T16_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst); + static void ReadCLUT_T16_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst); + static void ReadCLUT_T16_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst32, uint64* RESTRICT dst64); + static void ExpandCLUT64_T32_I8(const uint32* RESTRICT src, uint64* RESTRICT dst); static void ExpandCLUT64_T32(const GSVector4i& hi, const GSVector4i& lo0, const GSVector4i& lo1, const GSVector4i& lo2, const GSVector4i& lo3, GSVector4i* dst); static void ExpandCLUT64_T32(const GSVector4i& hi, const GSVector4i& lo, GSVector4i* dst); - static void ExpandCLUT64_T16_I8(const DWORD* RESTRICT src, UINT64* RESTRICT dst); + static void ExpandCLUT64_T16_I8(const uint32* RESTRICT src, uint64* RESTRICT dst); static void ExpandCLUT64_T16(const GSVector4i& hi, const GSVector4i& lo0, const GSVector4i& lo1, const GSVector4i& lo2, const GSVector4i& lo3, GSVector4i* dst); static void ExpandCLUT64_T16(const GSVector4i& hi, const GSVector4i& lo, GSVector4i* dst); - static void Expand16(const WORD* RESTRICT src, DWORD* RESTRICT dst, int w, const GIFRegTEXA& TEXA); + static void Expand16(const uint16* RESTRICT src, uint32* RESTRICT dst, int w, const GIFRegTEXA& TEXA); public: GSClut(const GSLocalMemory* mem); @@ -103,8 +103,8 @@ public: void Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); void GetAlphaMinMax32(int& amin, int& amax); - DWORD operator [] (size_t i) const {return m_buff32[i];} + uint32 operator [] (size_t i) const {return m_buff32[i];} - operator const DWORD*() const {return m_buff32;} - operator const UINT64*() const {return m_buff64;} + operator const uint32*() const {return m_buff32;} + operator const uint64*() const {return m_buff64;} }; diff --git a/plugins/GSdx/GSCodeBuffer.cpp b/plugins/GSdx/GSCodeBuffer.cpp index fe8214b97a..83b0f45f61 100644 --- a/plugins/GSdx/GSCodeBuffer.cpp +++ b/plugins/GSdx/GSCodeBuffer.cpp @@ -32,9 +32,9 @@ GSCodeBuffer::GSCodeBuffer(size_t blocksize) GSCodeBuffer::~GSCodeBuffer() { - while(!m_buffers.IsEmpty()) + for(list::iterator i = m_buffers.begin(); i != m_buffers.end(); i++) { - VirtualFree(m_buffers.RemoveHead(), 0, MEM_RELEASE); + VirtualFree(*i, 0, MEM_RELEASE); } } @@ -47,14 +47,14 @@ void* GSCodeBuffer::GetBuffer(size_t size) if(m_ptr == NULL || m_pos + size > m_blocksize) { - m_ptr = (BYTE*)VirtualAlloc(NULL, m_blocksize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + m_ptr = (uint8*)VirtualAlloc(NULL, m_blocksize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); m_pos = 0; - m_buffers.AddTail(m_ptr); + m_buffers.push_back(m_ptr); } - BYTE* ptr = &m_ptr[m_pos]; + uint8* ptr = &m_ptr[m_pos]; m_reserved = size; diff --git a/plugins/GSdx/GSCodeBuffer.h b/plugins/GSdx/GSCodeBuffer.h index 5aaed5bc38..badaed81a8 100644 --- a/plugins/GSdx/GSCodeBuffer.h +++ b/plugins/GSdx/GSCodeBuffer.h @@ -23,10 +23,10 @@ class GSCodeBuffer { - CAtlList m_buffers; + list m_buffers; size_t m_blocksize; size_t m_pos, m_reserved; - BYTE* m_ptr; + uint8* m_ptr; public: GSCodeBuffer(size_t blocksize = 4096 * 64); // 256k diff --git a/plugins/GSdx/GSCrc.cpp b/plugins/GSdx/GSCrc.cpp index 34307df48b..00fa942582 100644 --- a/plugins/GSdx/GSCrc.cpp +++ b/plugins/GSdx/GSCrc.cpp @@ -24,117 +24,128 @@ CRC::Game CRC::m_games[] = { - {0x00000000, None, Unknown}, - {0x2113EA2E, MetalSlug6, Unknown}, - {0x42E05BAF, TomoyoAfter, JP}, - {0x7800DC84, Clannad, JP}, - {0xa39517ab, FFX, EU}, - {0xa39517ae, FFX, FR}, - {0x941bb7d9, FFX, DE}, - {0xa39517a9, FFX, IT}, - {0x941bb7de, FFX, ES}, - {0xb4414ea1, FFX, RU}, - {0xee97db5b, FFX, RU}, - {0xaec495cc, FFX, RU}, - {0xbb3d833a, FFX, US}, - {0x6a4efe60, FFX, JP}, - {0x3866ca7e, FFX, ASIA}, // int. - {0x658597e2, FFX, JP}, // int. - {0x9aac5309, FFX2, EU}, - {0x9aac530c, FFX2, FR}, - {0x9aac530a, FFX2, FR}, // ? - {0x9aac530d, FFX2, DE}, - {0x9aac530b, FFX2, IT}, - {0x48fe0c71, FFX2, US}, - {0xe1fd9a2d, FFX2, JP}, // int. - {0x78da0252, FFXII, EU}, - {0xc1274668, FFXII, EU}, - {0xdc2a467e, FFXII, EU}, - {0xca284668, FFXII, EU}, - {0x280AD120, FFXII, JP}, - {0x8BE3D7B2, ShadowHearts, Unknown}, - {0xDEFA4763, ShadowHearts, US}, - {0x21068223, Okami, US}, - {0x891f223f, Okami, FR}, - {0xC5DEFEA0, Okami, JP}, - {0x053D2239, MetalGearSolid3, US}, - {0x086273D2, MetalGearSolid3, FR}, - {0x26A6E286, MetalGearSolid3, EU}, - {0xAA31B5BF, MetalGearSolid3, Unknown}, - {0x9F185CE1, MetalGearSolid3, Unknown}, - {0x98D4BC93, MetalGearSolid3, EU}, - {0x86BC3040, MetalGearSolid3, US}, //Subsistance disc 1 - {0x0481AD8A, MetalGearSolid3, JP}, - {0x79ED26AD, MetalGearSolid3, EU}, - {0x5E31EA42, MetalGearSolid3, EU}, - {0x278722BF, DBZBT2, US}, - {0xFE961D28, DBZBT2, US}, - {0x0393B6BE, DBZBT2, EU}, - {0xE2F289ED, DBZBT2, JP}, // Sparking Neo! - {0x35AA84D1, DBZBT2, Unknown}, - {0x428113C2, DBZBT3, US}, - {0xA422BB13, DBZBT3, EU}, - {0x983c53d2, DBZBT3, Unknown}, - {0x72B3802A, SFEX3, US}, - {0x71521863, SFEX3, US}, - {0x28703748, Bully, US}, - {0xC78A495D, BullyCC, US}, - {0xC19A374E, SoTC, US}, - {0x7D8F539A, SoTC, EU}, - {0x3122B508, OnePieceGrandAdventure, US}, - {0x6F8545DB, ICO, US}, - {0xB01A4C95, ICO, JP}, - {0x5C991F4E, ICO, Unknown}, - {0x7ACF7E03, ICO, Unknown}, - {0xAEAD1CA3, GT4, JP}, - {0x44A61C8F, GT4, Unknown}, - {0x0086E35B, GT4, Unknown}, - {0x77E61C8A, GT4, Unknown}, - {0xC164550A, WildArms5, JPUNDUB}, - {0xC1640D2C, WildArms5, US}, - {0x0FCF8FE4, WildArms5, EU}, - {0x2294D322, WildArms5, JP}, - {0x565B6170, WildArms5, JP}, - {0x8B029334, Manhunt2, Unknown}, - {0x09F49E37, CrashBandicootWoC, Unknown}, - {0x013E349D, ResidentEvil4, US}, - {0x6BA2F6B9, ResidentEvil4, Unknown}, - {0x60FA8C69, ResidentEvil4, JP}, - {0x72E1E60E, Spartan, Unknown}, - {0x5ED8FB53, AceCombat4, JP}, - {0x1B9B7563, AceCombat4, Unknown}, - {0xEC432B24, Drakengard2, Unknown}, - {0xFC46EA61, Tekken5, JP}, - {0x1F88EE37, Tekken5, Unknown}, - {0x652050D2, Tekken5, Unknown}, - {0x9E98B8AE, IkkiTousen, JP}, - {0xD6385328, GodOfWar, US}, - {0xFB0E6D72, GodOfWar, EU}, - {0xEB001875, GodOfWar, EU}, - {0xA61A4C6D, GodOfWar, Unknown}, - {0xE23D532B, GodOfWar, Unknown}, - {0xDF1AF973, GodOfWar, Unknown}, - {0x2F123FD8, GodOfWar2, RU}, - {0x2F123FD8, GodOfWar2, US}, - {0x44A8A22A, GodOfWar2, EU}, - {0x4340C7C6, GodOfWar2, Unknown}, - {0x5D482F18, JackieChanAdv, Unknown}, - {0xf0a6d880, HarvestMoon, US}, - {0x75c01a04, NamcoXCapcom, US}, - {0xBF6F101F, GiTS, US}, - {0xA5768F53, GiTS, JP}, - {0x6BF11378, Onimusha3, US}, - {0xF442260C, MajokkoALaMode2, JP}, - {0x14FE77F7, TalesOfAbyss, US}, - {0x045D77E9, TalesOfAbyss, US}, // undub - {0xAA5EC3A3, TalesOfAbyss, JP}, + {0x00000000, None, Unknown, 0}, + {0x2113EA2E, MetalSlug6, Unknown, 0}, + {0x42E05BAF, TomoyoAfter, JP, PointListPalette}, + {0x7800DC84, Clannad, JP, PointListPalette}, + {0xA6167B59, Lamune, JP, PointListPalette}, + {0xDDB59F46, KyuuketsuKitanMoonties, JP, PointListPalette}, + {0xC8EE2562, PiaCarroteYoukosoGPGakuenPrincess, JP, PointListPalette}, + {0x6CF94A43, KazokuKeikakuKokoroNoKizuna, JP, PointListPalette}, + {0xa39517ab, FFX, EU, 0}, + {0xa39517ae, FFX, FR, 0}, + {0x941bb7d9, FFX, DE, 0}, + {0xa39517a9, FFX, IT, 0}, + {0x941bb7de, FFX, ES, 0}, + {0xb4414ea1, FFX, RU, 0}, + {0xee97db5b, FFX, RU, 0}, + {0xaec495cc, FFX, RU, 0}, + {0xbb3d833a, FFX, US, 0}, + {0x6a4efe60, FFX, JP, 0}, + {0x3866ca7e, FFX, ASIA, 0}, // int. + {0x658597e2, FFX, JP, 0}, // int. + {0x9aac5309, FFX2, EU, 0}, + {0x9aac530c, FFX2, FR, 0}, + {0x9aac530a, FFX2, FR, 0}, // ? + {0x9aac530d, FFX2, DE, 0}, + {0x9aac530b, FFX2, IT, 0}, + {0x48fe0c71, FFX2, US, 0}, + {0xe1fd9a2d, FFX2, JP, 0}, // int. + {0x78da0252, FFXII, EU, 0}, + {0xc1274668, FFXII, EU, 0}, + {0xdc2a467e, FFXII, EU, 0}, + {0xca284668, FFXII, EU, 0}, + {0x280AD120, FFXII, JP, 0}, + {0x8BE3D7B2, ShadowHearts, Unknown, 0}, + {0xDEFA4763, ShadowHearts, US, 0}, + {0x21068223, Okami, US, 0}, + {0x891f223f, Okami, FR, 0}, + {0xC5DEFEA0, Okami, JP, 0}, + {0x053D2239, MetalGearSolid3, US, 0}, + {0x086273D2, MetalGearSolid3, FR, 0}, + {0x26A6E286, MetalGearSolid3, EU, 0}, + {0xAA31B5BF, MetalGearSolid3, Unknown, 0}, + {0x9F185CE1, MetalGearSolid3, Unknown, 0}, + {0x98D4BC93, MetalGearSolid3, EU, 0}, + {0x86BC3040, MetalGearSolid3, US, 0}, //Subsistance disc 1 + {0x0481AD8A, MetalGearSolid3, JP, 0}, + {0x79ED26AD, MetalGearSolid3, EU, 0}, + {0x5E31EA42, MetalGearSolid3, EU, 0}, + {0x278722BF, DBZBT2, US, 0}, + {0xFE961D28, DBZBT2, US, 0}, + {0x0393B6BE, DBZBT2, EU, 0}, + {0xE2F289ED, DBZBT2, JP, 0}, // Sparking Neo! + {0x35AA84D1, DBZBT2, Unknown, 0}, + {0x428113C2, DBZBT3, US, 0}, + {0xA422BB13, DBZBT3, EU, 0}, + {0x983C53D2, DBZBT3, Unknown, 0}, + {0x983C53D3, DBZBT3, Unknown, 0}, + {0x72B3802A, SFEX3, US, 0}, + {0x71521863, SFEX3, US, 0}, + {0x28703748, Bully, US, 0}, + {0xC78A495D, BullyCC, US, 0}, + {0xC19A374E, SoTC, US, 0}, + {0x7D8F539A, SoTC, EU, 0}, + {0x3122B508, OnePieceGrandAdventure, US, 0}, + {0x8DF14A24, OnePieceGrandAdventure, Unknown, 0}, + {0x6F8545DB, ICO, US, 0}, + {0xB01A4C95, ICO, JP, 0}, + {0x5C991F4E, ICO, Unknown, 0}, + {0x7ACF7E03, ICO, Unknown, 0}, + {0xAEAD1CA3, GT4, JP, 0}, + {0x44A61C8F, GT4, Unknown, 0}, + {0x0086E35B, GT4, Unknown, 0}, + {0x77E61C8A, GT4, Unknown, 0}, + {0xC164550A, WildArms5, JPUNDUB, 0}, + {0xC1640D2C, WildArms5, US, 0}, + {0x0FCF8FE4, WildArms5, EU, 0}, + {0x2294D322, WildArms5, JP, 0}, + {0x565B6170, WildArms5, JP, 0}, + {0x8B029334, Manhunt2, Unknown, 0}, + {0x09F49E37, CrashBandicootWoC, Unknown, 0}, + {0x013E349D, ResidentEvil4, US, 0}, + {0x6BA2F6B9, ResidentEvil4, Unknown, 0}, + {0x60FA8C69, ResidentEvil4, JP, 0}, + {0x72E1E60E, Spartan, Unknown, 0}, + {0x5ED8FB53, AceCombat4, JP, 0}, + {0x1B9B7563, AceCombat4, Unknown, 0}, + {0xEC432B24, Drakengard2, Unknown, 0}, + {0xFC46EA61, Tekken5, JP, 0}, + {0x1F88EE37, Tekken5, Unknown, 0}, + {0x652050D2, Tekken5, Unknown, 0}, + {0x9E98B8AE, IkkiTousen, JP, 0}, + {0xD6385328, GodOfWar, US, 0}, + {0xFB0E6D72, GodOfWar, EU, 0}, + {0xEB001875, GodOfWar, EU, 0}, + {0xA61A4C6D, GodOfWar, Unknown, 0}, + {0xE23D532B, GodOfWar, Unknown, 0}, + {0xDF1AF973, GodOfWar, Unknown, 0}, + {0xD6385328, GodOfWar, Unknown, 0}, + {0x2F123FD8, GodOfWar2, RU, 0}, + {0x2F123FD8, GodOfWar2, US, 0}, + {0x44A8A22A, GodOfWar2, EU, 0}, + {0x4340C7C6, GodOfWar2, Unknown, 0}, + {0x5D482F18, JackieChanAdv, Unknown, 0}, + {0xf0a6d880, HarvestMoon, US, 0}, + {0x75c01a04, NamcoXCapcom, US, 0}, + {0xBF6F101F, GiTS, US, 0}, + {0xA5768F53, GiTS, JP, 0}, + {0x6BF11378, Onimusha3, US, 0}, + {0xF442260C, MajokkoALaMode2, JP, 0}, + {0x14FE77F7, TalesOfAbyss, US, 0}, + {0x045D77E9, TalesOfAbyss, US, 0}, // undub + {0xAA5EC3A3, TalesOfAbyss, JP, 0}, + {0xFB236A46, SonicUnleashed, US, 0}, + {0x4C7BB3C8, SimpsonsGame, Unknown, 0}, + {0x4C94B32C, SimpsonsGame, Unknown, 0}, + {0xD71B57F4, Genji, Unknown, 0}, }; -CAtlMap CRC::m_map; +hash_map CRC::m_map; -CRC::Game CRC::Lookup(DWORD crc) +CRC::Game CRC::Lookup(uint32 crc) { - if(m_map.IsEmpty()) + if(m_map.empty()) { for(int i = 0; i < countof(m_games); i++) { @@ -142,9 +153,11 @@ CRC::Game CRC::Lookup(DWORD crc) } } - if(CAtlMap::CPair* pair = m_map.Lookup(crc)) + hash_map::iterator i = m_map.find(crc); + + if(i != m_map.end()) { - return *pair->m_value; + return *i->second; } return m_games[0]; diff --git a/plugins/GSdx/GSCrc.h b/plugins/GSdx/GSCrc.h index 12f41bd93f..06f6698d55 100644 --- a/plugins/GSdx/GSCrc.h +++ b/plugins/GSdx/GSCrc.h @@ -30,6 +30,10 @@ public: MetalSlug6, TomoyoAfter, Clannad, + Lamune, + KyuuketsuKitanMoonties, + PiaCarroteYoukosoGPGakuenPrincess, + KazokuKeikakuKokoroNoKizuna, FFX, FFX2, FFXII, @@ -63,7 +67,10 @@ public: Onimusha3, MajokkoALaMode2, TalesOfAbyss, - TitleCount + SonicUnleashed, + SimpsonsGame, + Genji, + TitleCount, }; enum Region @@ -81,17 +88,23 @@ public: ASIA }; + enum Flags + { + PointListPalette = 1, + }; + struct Game { - DWORD crc; + uint32 crc; Title title; Region region; + uint32 flags; }; private: static Game m_games[]; - static CAtlMap m_map; + static hash_map m_map; public: - static Game Lookup(DWORD crc); + static Game Lookup(uint32 crc); }; diff --git a/plugins/GSdx/GSDevice.cpp b/plugins/GSdx/GSDevice.cpp index fe40a0da83..12d757278e 100644 --- a/plugins/GSdx/GSDevice.cpp +++ b/plugins/GSdx/GSDevice.cpp @@ -21,3 +21,204 @@ #include "StdAfx.h" #include "GSDevice.h" + +GSDevice::GSDevice() + : m_wnd(NULL) + , m_backbuffer(NULL) + , m_merge(NULL) + , m_weavebob(NULL) + , m_blend(NULL) + , m_1x1(NULL) +{ +} + +GSDevice::~GSDevice() +{ +} + +bool GSDevice::Create(GSWnd* wnd, bool vsync) +{ + m_wnd = wnd; + m_vsync = vsync; + + return true; +} + +bool GSDevice::Reset(int w, int h, bool fs) +{ + for(list::iterator i = m_pool.begin(); i != m_pool.end(); i++) + { + delete *i; + } + + m_pool.clear(); + + delete m_backbuffer; + delete m_merge; + delete m_weavebob; + delete m_blend; + delete m_1x1; + + m_backbuffer = NULL; + m_merge = NULL; + m_weavebob = NULL; + m_blend = NULL; + m_1x1 = NULL; + + m_current = NULL; // current is special, points to other textures, no need to delete + + return true; +} + +void GSDevice::Present(const GSVector4i& r, int shader) +{ + GSVector4i cr = m_wnd->GetClientRect(); + + if(m_backbuffer->GetWidth() != cr.width() || m_backbuffer->GetHeight() != cr.height()) + { + Reset(cr.width(), cr.height(), false); + } + + ClearRenderTarget(m_backbuffer, 0); + + if(m_current) + { + static int s_shader[3] = {0, 5, 6}; // FIXME + + StretchRect(m_current, m_backbuffer, GSVector4(r), s_shader[shader]); + } + + Flip(); +} + +GSTexture* GSDevice::Fetch(int type, int w, int h, int format) +{ + GSVector2i size(w, h); + + for(list::iterator i = m_pool.begin(); i != m_pool.end(); i++) + { + GSTexture* t = *i; + + if(t->GetType() == type && t->GetFormat() == format && t->GetSize() == size) + { + m_pool.erase(i); + + return t; + } + } + + return Create(type, w, h, format); +} + +void GSDevice::Recycle(GSTexture* t) +{ + if(t) + { + m_pool.push_front(t); + + while(m_pool.size() > 200) + { + delete m_pool.back(); + + m_pool.pop_back(); + } + } +} + +GSTexture* GSDevice::CreateRenderTarget(int w, int h, int format) +{ + return Fetch(GSTexture::RenderTarget, w, h, format); +} + +GSTexture* GSDevice::CreateDepthStencil(int w, int h, int format) +{ + return Fetch(GSTexture::DepthStencil, w, h, format); +} + +GSTexture* GSDevice::CreateTexture(int w, int h, int format) +{ + return Fetch(GSTexture::Texture, w, h, format); +} + +GSTexture* GSDevice::CreateOffscreen(int w, int h, int format) +{ + return Fetch(GSTexture::Offscreen, w, h, format); +} + +void GSDevice::StretchRect(GSTexture* st, GSTexture* dt, const GSVector4& dr, int shader, bool linear) +{ + StretchRect(st, GSVector4(0, 0, 1, 1), dt, dr, shader, linear); +} + +GSTexture* GSDevice::GetCurrent() +{ + return m_current; +} + +void GSDevice::Merge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, const GSVector2i& fs, bool slbg, bool mmod, const GSVector4& c) +{ + if(!m_merge || !(m_merge->GetSize() == fs)) + { + m_merge = CreateRenderTarget(fs.x, fs.y); + } + + // TODO: m_1x1 + + // KH:COM crashes at startup when booting *through the bios* due to m_merge being NULL. + // (texture appears to be non-null, and is being re-created at a size around like 1700x340, + // dunno if that's relevant) -- air + + if(m_merge) + { + DoMerge(st, sr, dr, m_merge, slbg, mmod, c); + } + else + { + printf("GSdx: m_merge is NULL!\n"); + } + + m_current = m_merge; +} + +void GSDevice::Interlace(const GSVector2i& ds, int field, int mode, float yoffset) +{ + if(!m_weavebob || !(m_weavebob->GetSize() == ds)) + { + m_weavebob = CreateRenderTarget(ds.x, ds.y); + } + + if(mode == 0 || mode == 2) // weave or blend + { + // weave first + + DoInterlace(m_merge, m_weavebob, field, false, 0); + + if(mode == 2) + { + // blend + + if(!m_blend || !(m_blend->GetSize() == ds)) + { + m_blend = CreateRenderTarget(ds.x, ds.y); + } + + DoInterlace(m_weavebob, m_blend, 2, false, 0); + + m_current = m_blend; + } + else + { + m_current = m_weavebob; + } + } + else if(mode == 1) // bob + { + DoInterlace(m_merge, m_weavebob, 3, true, yoffset * field); + + m_current = m_weavebob; + } + else + { + m_current = m_merge; + } +} \ No newline at end of file diff --git a/plugins/GSdx/GSDevice.h b/plugins/GSdx/GSDevice.h index e21f5ffdc4..a5d36775a3 100644 --- a/plugins/GSdx/GSDevice.h +++ b/plugins/GSdx/GSDevice.h @@ -21,8 +21,10 @@ #pragma once +#include "GSWnd.h" #include "GSTexture.h" #include "GSVertex.h" +#include "GSAlignedClass.h" #pragma pack(push, 1) @@ -44,201 +46,84 @@ struct InterlaceConstantBuffer #pragma pack(pop) -template class GSDevice +class GSDevice : public GSAlignedClass<16> { - CAtlList m_pool; + list m_pool; + + GSTexture* Fetch(int type, int w, int h, int format); protected: - HWND m_hWnd; + GSWnd* m_wnd; bool m_vsync; - Texture m_backbuffer; - Texture m_merge; - Texture m_weavebob; - Texture m_blend; - Texture m_1x1; - Texture m_current; + GSTexture* m_backbuffer; + GSTexture* m_merge; + GSTexture* m_weavebob; + GSTexture* m_blend; + GSTexture* m_1x1; + GSTexture* m_current; - bool Fetch(int type, Texture& t, int w, int h, int format) - { - Recycle(t); + virtual GSTexture* Create(int type, int w, int h, int format) = 0; - for(POSITION pos = m_pool.GetHeadPosition(); pos; m_pool.GetNext(pos)) - { - const Texture& t2 = m_pool.GetAt(pos); - - if(t2.GetType() == type && t2.GetWidth() == w && t2.GetHeight() == h && t2.GetFormat() == format) - { - t = t2; - - m_pool.RemoveAt(pos); - - return true; - } - } - - return Create(type, t, w, h, format); - } - - virtual bool Create(int type, Texture& t, int w, int h, int format) = 0; - virtual void DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, bool slbg, bool mmod, GSVector4& c) = 0; - virtual void DoInterlace(Texture& st, Texture& dt, int shader, bool linear, float yoffset) = 0; + virtual void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c) = 0; + virtual void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset) = 0; public: - GSDevice() : m_hWnd(NULL) + GSDevice(); + virtual ~GSDevice(); + + void Recycle(GSTexture* t); + + virtual bool Create(GSWnd* wnd, bool vsync); + virtual bool Reset(int w, int h, bool fs); + + virtual bool IsLost() {return false;} + virtual void Present(const GSVector4i& r, int shader); + virtual void Flip() {} + + virtual void BeginScene() {} + virtual void DrawPrimitive() {}; + virtual void EndScene() {} + + virtual void ClearRenderTarget(GSTexture* t, const GSVector4& c) {} + virtual void ClearRenderTarget(GSTexture* t, uint32 c) {} + virtual void ClearDepth(GSTexture* t, float c) {} + virtual void ClearStencil(GSTexture* t, uint8 c) {} + + virtual GSTexture* CreateRenderTarget(int w, int h, int format = 0); + virtual GSTexture* CreateDepthStencil(int w, int h, int format = 0); + virtual GSTexture* CreateTexture(int w, int h, int format = 0); + virtual GSTexture* CreateOffscreen(int w, int h, int format = 0); + + virtual GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0) {return NULL;} + + virtual void StretchRect(GSTexture* st, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true); + virtual void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true) {} + + GSTexture* GetCurrent(); + virtual bool IsCurrentRGBA() {return true;} + + void Merge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, const GSVector2i& fs, bool slbg, bool mmod, const GSVector4& c); + void Interlace(const GSVector2i& ds, int field, int mode, float yoffset); + + template void PrepareShaderMacro(vector& dst, const T* src, const char* model) { - } + dst.clear(); - virtual ~GSDevice() - { - } - - virtual bool Create(HWND hWnd, bool vsync) - { - m_hWnd = hWnd; - m_vsync = vsync; - - return true; - } - - virtual bool Reset(int w, int h, bool fs) - { - m_pool.RemoveAll(); - m_backbuffer = Texture(); - m_merge = Texture(); - m_weavebob = Texture(); - m_blend = Texture(); - m_1x1 = Texture(); - m_current = Texture(); - - return true; - } - - virtual bool IsLost() = 0; - - virtual void Present(const CRect& r) = 0; - - virtual void BeginScene() = 0; - - virtual void EndScene() = 0; - - virtual void Draw(LPCTSTR str) = 0; - - virtual bool CopyOffscreen(Texture& src, const GSVector4& sr, Texture& dst, int w, int h, int format = 0) = 0; - - virtual void ClearRenderTarget(Texture& t, const GSVector4& c) = 0; - - virtual void ClearRenderTarget(Texture& t, DWORD c) = 0; - - virtual void ClearDepth(Texture& t, float c) = 0; - - virtual void ClearStencil(Texture& t, BYTE c) = 0; - - virtual bool CreateRenderTarget(Texture& t, int w, int h, int format = 0) - { - return Fetch(GSTexture::RenderTarget, t, w, h, format); - } - - virtual bool CreateDepthStencil(Texture& t, int w, int h, int format = 0) - { - return Fetch(GSTexture::DepthStencil, t, w, h, format); - } - - virtual bool CreateTexture(Texture& t, int w, int h, int format = 0) - { - return Fetch(GSTexture::Texture, t, w, h, format); - } - - virtual bool CreateOffscreen(Texture& t, int w, int h, int format = 0) - { - return Fetch(GSTexture::Offscreen, t, w, h, format); - } - - void Recycle(Texture& t) - { - if(t) + while(src && src->Definition && src->Name) { - m_pool.AddHead(t); - - while(m_pool.GetCount() > 200) - { - m_pool.RemoveTail(); - } - - t = Texture(); - } - } - - bool SaveCurrent(LPCTSTR fn) - { - return m_current.Save(fn); - } - - void GetCurrent(Texture& t) - { - t = m_current; - } - - void Merge(Texture* st, GSVector4* sr, GSVector4* dr, CSize fs, bool slbg, bool mmod, GSVector4& c) - { - if(!m_merge || m_merge.GetWidth() != fs.cx || m_merge.GetHeight() != fs.cy) - { - CreateRenderTarget(m_merge, fs.cx, fs.cy); + dst.push_back(*src++); } - // TODO: m_1x1 + T m; + + m.Name = "SHADER_MODEL"; + m.Definition = model; - DoMerge(st, sr, dr, m_merge, slbg, mmod, c); + dst.push_back(m); - m_current = m_merge; - } + m.Name = NULL; + m.Definition = NULL; - bool Interlace(CSize ds, int field, int mode, float yoffset) - { - if(!m_weavebob || m_weavebob.GetWidth() != ds.cx || m_weavebob.GetHeight() != ds.cy) - { - CreateRenderTarget(m_weavebob, ds.cx, ds.cy); - } - - if(mode == 0 || mode == 2) // weave or blend - { - // weave first - - DoInterlace(m_merge, m_weavebob, field, false, 0); - - if(mode == 2) - { - // blend - - if(!m_blend || m_blend.GetWidth() != ds.cx || m_blend.GetHeight() != ds.cy) - { - CreateRenderTarget(m_blend, ds.cx, ds.cy); - } - - DoInterlace(m_weavebob, m_blend, 2, false, 0); - - m_current = m_blend; - } - else - { - m_current = m_weavebob; - } - } - else if(mode == 1) // bob - { - DoInterlace(m_merge, m_weavebob, 3, true, yoffset * field); - - m_current = m_weavebob; - } - else - { - m_current = m_merge; - } - - return true; - } - - virtual bool IsCurrentRGBA() - { - return true; + dst.push_back(m); } }; diff --git a/plugins/GSdx/GSDevice10.cpp b/plugins/GSdx/GSDevice10.cpp index 5cd874a69d..6d7d2b73ec 100644 --- a/plugins/GSdx/GSDevice10.cpp +++ b/plugins/GSdx/GSDevice10.cpp @@ -20,6 +20,7 @@ */ #include "stdafx.h" +#include "GSdx.h" #include "GSDevice10.h" #include "resource.h" @@ -44,15 +45,20 @@ GSDevice10::GSDevice10() { memset(m_ps_srv, 0, sizeof(m_ps_srv)); memset(m_ps_ss, 0, sizeof(m_ps_ss)); + + m_vertices.stride = 0; + m_vertices.start = 0; + m_vertices.count = 0; + m_vertices.limit = 0; } GSDevice10::~GSDevice10() { } -bool GSDevice10::Create(HWND hWnd, bool vsync) +bool GSDevice10::Create(GSWnd* wnd, bool vsync) { - if(!__super::Create(hWnd, vsync)) + if(!__super::Create(wnd, vsync)) { return false; } @@ -75,12 +81,12 @@ bool GSDevice10::Create(HWND hWnd, bool vsync) //scd.BufferDesc.RefreshRate.Numerator = 60; //scd.BufferDesc.RefreshRate.Denominator = 1; scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - scd.OutputWindow = hWnd; + scd.OutputWindow = (HWND)m_wnd->GetHandle(); scd.SampleDesc.Count = 1; scd.SampleDesc.Quality = 0; scd.Windowed = TRUE; - UINT flags = 0; + uint32 flags = 0; #ifdef DEBUG flags |= D3D10_CREATE_DEVICE_DEBUG; @@ -90,16 +96,6 @@ bool GSDevice10::Create(HWND hWnd, bool vsync) if(FAILED(hr)) return false; - // font -/* - // TODO: the driver crashes on alt-enter when using a font... - - D3DX10_FONT_DESC fd; - memset(&fd, 0, sizeof(fd)); - _tcscpy(fd.FaceName, _T("Arial")); - fd.Height = 20; - D3DX10CreateFontIndirect(m_dev, &fd, &m_font); -*/ // convert D3D10_INPUT_ELEMENT_DESC il_convert[] = @@ -108,25 +104,13 @@ bool GSDevice10::Create(HWND hWnd, bool vsync) {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0}, }; - hr = CompileShader(IDR_CONVERT10_FX, "vs_main", NULL, &m_convert.vs, il_convert, countof(il_convert), &m_convert.il); + hr = CompileShader(IDR_CONVERT_FX, "vs_main", NULL, &m_convert.vs, il_convert, countof(il_convert), &m_convert.il); for(int i = 0; i < countof(m_convert.ps); i++) { - CStringA main; - main.Format("ps_main%d", i); - hr = CompileShader(IDR_CONVERT10_FX, main, NULL, &m_convert.ps[i]); + hr = CompileShader(IDR_CONVERT_FX, format("ps_main%d", i), NULL, &m_convert.ps[i]); } - memset(&bd, 0, sizeof(bd)); - - bd.Usage = D3D10_USAGE_DEFAULT; - bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; - bd.CPUAccessFlags = 0; - bd.MiscFlags = 0; - bd.ByteWidth = 4 * sizeof(GSVertexPT1); - - hr = m_dev->CreateBuffer(&bd, NULL, &m_convert.vb); - memset(&dsd, 0, sizeof(dsd)); dsd.DepthEnable = false; @@ -148,16 +132,12 @@ bool GSDevice10::Create(HWND hWnd, bool vsync) bd.ByteWidth = sizeof(MergeConstantBuffer); bd.Usage = D3D10_USAGE_DEFAULT; bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER; - bd.CPUAccessFlags = 0; - bd.MiscFlags = 0; hr = m_dev->CreateBuffer(&bd, NULL, &m_merge.cb); for(int i = 0; i < countof(m_merge.ps); i++) { - CStringA main; - main.Format("ps_main%d", i); - hr = CompileShader(IDR_MERGE10_FX, main, NULL, &m_merge.ps[i]); + hr = CompileShader(IDR_MERGE_FX, format("ps_main%d", i), NULL, &m_merge.ps[i]); } memset(&bsd, 0, sizeof(bsd)); @@ -180,16 +160,12 @@ bool GSDevice10::Create(HWND hWnd, bool vsync) bd.ByteWidth = sizeof(InterlaceConstantBuffer); bd.Usage = D3D10_USAGE_DEFAULT; bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER; - bd.CPUAccessFlags = 0; - bd.MiscFlags = 0; hr = m_dev->CreateBuffer(&bd, NULL, &m_interlace.cb); for(int i = 0; i < countof(m_interlace.ps); i++) { - CStringA main; - main.Format("ps_main%d", i); - hr = CompileShader(IDR_INTERLACE10_FX, main, NULL, &m_interlace.ps[i]); + hr = CompileShader(IDR_INTERLACE_FX, format("ps_main%d", i), NULL, &m_interlace.ps[i]); } // @@ -231,16 +207,9 @@ bool GSDevice10::Create(HWND hWnd, bool vsync) // - Reset(1, 1, true); + Reset(1, 1, false); // -/* - if(!m_mergefx.Create(this)) - { - return false; - } -*/ - // return true; } @@ -257,31 +226,13 @@ bool GSDevice10::Reset(int w, int h, bool fs) CComPtr backbuffer; m_swapchain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)&backbuffer); - m_backbuffer = Texture(backbuffer); + m_backbuffer = new GSTexture10(backbuffer); return true; } -void GSDevice10::Present(const CRect& r) +void GSDevice10::Flip() { - CRect cr; - - GetClientRect(m_hWnd, &cr); - - if(m_backbuffer.GetWidth() != cr.Width() || m_backbuffer.GetHeight() != cr.Height()) - { - Reset(cr.Width(), cr.Height(), false); - } - - float color[4] = {0, 0, 0, 0}; - - m_dev->ClearRenderTargetView(m_backbuffer, color); - - if(m_current) - { - StretchRect(m_current, m_backbuffer, GSVector4(r)); - } - m_swapchain->Present(m_vsync ? 1 : 0, 0); } @@ -289,6 +240,11 @@ void GSDevice10::BeginScene() { } +void GSDevice10::DrawPrimitive() +{ + m_dev->Draw(m_vertices.count, m_vertices.start); +} + void GSDevice10::EndScene() { PSSetShaderResources(NULL, NULL); @@ -296,94 +252,34 @@ void GSDevice10::EndScene() // not clearing the rt/ds gives a little fps boost in complex games (5-10%) // OMSetRenderTargets(NULL, NULL); + + m_vertices.start += m_vertices.count; + m_vertices.count = 0; } -void GSDevice10::Draw(LPCTSTR str) +void GSDevice10::ClearRenderTarget(GSTexture* t, const GSVector4& c) { - /* - BOOL fs; - CComPtr target; - - m_swapchain->GetFullscreenState(&fs, &target); - - if(fs) - { - BeginScene(); - - OMSetRenderTargets(m_backbuffer, NULL); - - CRect r(0, 0, m_backbuffer.GetWidth(), m_backbuffer.GetHeight()); - - D3DCOLOR c = D3DCOLOR_ARGB(255, 0, 255, 0); - - if(m_font->DrawText(NULL, str, -1, &r, DT_CALCRECT|DT_LEFT|DT_WORDBREAK, c)) - { - m_font->DrawText(NULL, str, -1, &r, DT_LEFT|DT_WORDBREAK, c); - } - - EndScene(); - } - */ + m_dev->ClearRenderTargetView(*(GSTexture10*)t, c.v); } -bool GSDevice10::CopyOffscreen(Texture& src, const GSVector4& sr, Texture& dst, int w, int h, int format) -{ - dst = Texture(); - - if(format == 0) - { - format = DXGI_FORMAT_R8G8B8A8_UNORM; - } - - if(format != DXGI_FORMAT_R8G8B8A8_UNORM && format != DXGI_FORMAT_R16_UINT) - { - ASSERT(0); - - return false; - } - - Texture rt; - - if(CreateRenderTarget(rt, w, h, format)) - { - GSVector4 dr(0, 0, w, h); - - StretchRect(src, sr, rt, dr, m_convert.ps[format == DXGI_FORMAT_R16_UINT ? 1 : 0], NULL); - - if(CreateOffscreen(dst, w, h, format)) - { - m_dev->CopyResource(dst, rt); - } - } - - Recycle(rt); - - return !!dst; -} - -void GSDevice10::ClearRenderTarget(Texture& t, const GSVector4& c) -{ - m_dev->ClearRenderTargetView(t, c.v); -} - -void GSDevice10::ClearRenderTarget(Texture& t, DWORD c) +void GSDevice10::ClearRenderTarget(GSTexture* t, uint32 c) { GSVector4 color = GSVector4(c) * (1.0f / 255); - m_dev->ClearRenderTargetView(t, color.v); + m_dev->ClearRenderTargetView(*(GSTexture10*)t, color.v); } -void GSDevice10::ClearDepth(Texture& t, float c) +void GSDevice10::ClearDepth(GSTexture* t, float c) { - m_dev->ClearDepthStencilView(t, D3D10_CLEAR_DEPTH, c, 0); + m_dev->ClearDepthStencilView(*(GSTexture10*)t, D3D10_CLEAR_DEPTH, c, 0); } -void GSDevice10::ClearStencil(Texture& t, BYTE c) +void GSDevice10::ClearStencil(GSTexture* t, uint8 c) { - m_dev->ClearDepthStencilView(t, D3D10_CLEAR_STENCIL, 0, c); + m_dev->ClearDepthStencilView(*(GSTexture10*)t, D3D10_CLEAR_STENCIL, 0, c); } -bool GSDevice10::Create(int type, Texture& t, int w, int h, int format) +GSTexture* GSDevice10::Create(int type, int w, int h, int format) { HRESULT hr; @@ -406,7 +302,7 @@ bool GSDevice10::Create(int type, Texture& t, int w, int h, int format) desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE; break; case GSTexture::DepthStencil: - desc.BindFlags = D3D10_BIND_DEPTH_STENCIL; + desc.BindFlags = D3D10_BIND_DEPTH_STENCIL;// | D3D10_BIND_SHADER_RESOURCE; break; case GSTexture::Texture: desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; @@ -417,13 +313,15 @@ bool GSDevice10::Create(int type, Texture& t, int w, int h, int format) break; } + GSTexture10* t = NULL; + CComPtr texture; hr = m_dev->CreateTexture2D(&desc, NULL, &texture); if(SUCCEEDED(hr)) { - t = Texture(texture); + t = new GSTexture10(texture); switch(type) { @@ -434,34 +332,135 @@ bool GSDevice10::Create(int type, Texture& t, int w, int h, int format) ClearDepth(t, 0); break; } - - return true; } - return false; + return t; } -bool GSDevice10::CreateRenderTarget(Texture& t, int w, int h, int format) +GSTexture* GSDevice10::CreateRenderTarget(int w, int h, int format) { - return __super::CreateRenderTarget(t, w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM); + return __super::CreateRenderTarget(w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM); } -bool GSDevice10::CreateDepthStencil(Texture& t, int w, int h, int format) +GSTexture* GSDevice10::CreateDepthStencil(int w, int h, int format) { - return __super::CreateDepthStencil(t, w, h, format ? format : DXGI_FORMAT_D32_FLOAT_S8X24_UINT); + return __super::CreateDepthStencil(w, h, format ? format : DXGI_FORMAT_D32_FLOAT_S8X24_UINT); // DXGI_FORMAT_R32G8X24_TYPELESS } -bool GSDevice10::CreateTexture(Texture& t, int w, int h, int format) +GSTexture* GSDevice10::CreateTexture(int w, int h, int format) { - return __super::CreateTexture(t, w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM); + return __super::CreateTexture(w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM); } -bool GSDevice10::CreateOffscreen(Texture& t, int w, int h, int format) +GSTexture* GSDevice10::CreateOffscreen(int w, int h, int format) { - return __super::CreateOffscreen(t, w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM); + return __super::CreateOffscreen(w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM); } -void GSDevice10::DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, bool slbg, bool mmod, GSVector4& c) +GSTexture* GSDevice10::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format) +{ + GSTexture* dst = NULL; + + if(format == 0) + { + format = DXGI_FORMAT_R8G8B8A8_UNORM; + } + + if(format != DXGI_FORMAT_R8G8B8A8_UNORM && format != DXGI_FORMAT_R16_UINT) + { + ASSERT(0); + + return false; + } + + if(GSTexture* rt = CreateRenderTarget(w, h, format)) + { + GSVector4 dr(0, 0, w, h); + + StretchRect(src, sr, rt, dr, m_convert.ps[format == DXGI_FORMAT_R16_UINT ? 1 : 0], NULL); + + dst = CreateOffscreen(w, h, format); + + if(dst) + { + m_dev->CopyResource(*(GSTexture10*)dst, *(GSTexture10*)rt); + } + + Recycle(rt); + } + + return dst; +} + +void GSDevice10::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear) +{ + StretchRect(st, sr, dt, dr, m_convert.ps[shader], NULL, linear); +} + +void GSDevice10::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, bool linear) +{ + StretchRect(st, sr, dt, dr, ps, ps_cb, m_convert.bs, linear); +} + +void GSDevice10::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, ID3D10BlendState* bs, bool linear) +{ + BeginScene(); + + GSVector2i ds = dt->GetSize(); + + // om + + OMSetDepthStencilState(m_convert.dss, 0); + OMSetBlendState(bs, 0); + OMSetRenderTargets(dt, NULL); + + // ia + + float left = dr.x * 2 / ds.x - 1.0f; + float top = 1.0f - dr.y * 2 / ds.y; + float right = dr.z * 2 / ds.x - 1.0f; + float bottom = 1.0f - dr.w * 2 / ds.y; + + GSVertexPT1 vertices[] = + { + {GSVector4(left, top, 0.5f, 1.0f), GSVector2(sr.x, sr.y)}, + {GSVector4(right, top, 0.5f, 1.0f), GSVector2(sr.z, sr.y)}, + {GSVector4(left, bottom, 0.5f, 1.0f), GSVector2(sr.x, sr.w)}, + {GSVector4(right, bottom, 0.5f, 1.0f), GSVector2(sr.z, sr.w)}, + }; + + IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); + IASetInputLayout(m_convert.il); + IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + // vs + + VSSetShader(m_convert.vs, NULL); + + // gs + + GSSetShader(NULL); + + // ps + + PSSetShader(ps, ps_cb); + PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, NULL); + PSSetShaderResources(st, NULL); + + // rs + + RSSet(ds.x, ds.y); + + // + + DrawPrimitive(); + + // + + EndScene(); +} + +void GSDevice10::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c) { ClearRenderTarget(dt, c); @@ -478,26 +477,83 @@ void GSDevice10::DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, } } -void GSDevice10::DoInterlace(Texture& st, Texture& dt, int shader, bool linear, float yoffset) +void GSDevice10::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset) { + GSVector4 s = GSVector4(dt->GetSize()); + GSVector4 sr(0, 0, 1, 1); - GSVector4 dr(0.0f, yoffset, (float)dt.GetWidth(), (float)dt.GetHeight() + yoffset); + GSVector4 dr(0.0f, yoffset, s.x, s.y + yoffset); InterlaceConstantBuffer cb; - cb.ZrH = GSVector2(0, 1.0f / dt.GetHeight()); - cb.hH = (float)dt.GetHeight() / 2; + cb.ZrH = GSVector2(0, 1.0f / s.y); + cb.hH = s.y / 2; m_dev->UpdateSubresource(m_interlace.cb, 0, NULL, &cb, 0, 0); StretchRect(st, sr, dt, dr, m_interlace.ps[shader], m_interlace.cb, linear); } -void GSDevice10::IASetVertexBuffer(ID3D10Buffer* vb, UINT stride) +void GSDevice10::IASetVertexBuffer(const void* vertices, size_t stride, size_t count) +{ + ASSERT(m_vertices.count == 0); + + if(count * stride > m_vertices.limit * m_vertices.stride) + { + m_vertices.vb_old = m_vertices.vb; + m_vertices.vb = NULL; + m_vertices.start = 0; + m_vertices.count = 0; + m_vertices.limit = max(count * 3 / 2, 10000); + } + + if(m_vertices.vb == NULL) + { + D3D10_BUFFER_DESC bd; + + memset(&bd, 0, sizeof(bd)); + + bd.Usage = D3D10_USAGE_DYNAMIC; + bd.ByteWidth = m_vertices.limit * stride; + bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; + bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + + HRESULT hr; + + hr = m_dev->CreateBuffer(&bd, NULL, &m_vertices.vb); + + if(FAILED(hr)) return; + } + + D3D10_MAP type = D3D10_MAP_WRITE_NO_OVERWRITE; + + if(m_vertices.start + count > m_vertices.limit || stride != m_vertices.stride) + { + m_vertices.start = 0; + + type = D3D10_MAP_WRITE_DISCARD; + } + + void* v = NULL; + + if(SUCCEEDED(m_vertices.vb->Map(type, 0, &v))) + { + GSVector4i::storent((uint8*)v + m_vertices.start * stride, vertices, count * stride); + + m_vertices.vb->Unmap(); + } + + m_vertices.count = count; + m_vertices.stride = stride; + + IASetVertexBuffer(m_vertices.vb, stride); +} + +void GSDevice10::IASetVertexBuffer(ID3D10Buffer* vb, size_t stride) { if(m_vb != vb || m_vb_stride != stride) { - UINT offset = 0; + uint32 offset = 0; m_dev->IASetVertexBuffers(0, 1, &vb, &stride, &offset); @@ -553,8 +609,14 @@ void GSDevice10::GSSetShader(ID3D10GeometryShader* gs) } } -void GSDevice10::PSSetShaderResources(ID3D10ShaderResourceView* srv0, ID3D10ShaderResourceView* srv1) +void GSDevice10::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1) { + ID3D10ShaderResourceView* srv0 = NULL; + ID3D10ShaderResourceView* srv1 = NULL; + + if(sr0) srv0 = *(GSTexture10*)sr0; + if(sr1) srv1 = *(GSTexture10*)sr1; + if(m_ps_srv[0] != srv0 || m_ps_srv[1] != srv1) { ID3D10ShaderResourceView* srvs[] = {srv0, srv1}; @@ -596,9 +658,9 @@ void GSDevice10::PSSetSamplerState(ID3D10SamplerState* ss0, ID3D10SamplerState* } } -void GSDevice10::RSSet(int width, int height, const RECT* scissor) +void GSDevice10::RSSet(int width, int height, const GSVector4i* scissor) { - if(m_viewport.cx != width || m_viewport.cy != height) + if(m_viewport.x != width || m_viewport.y != height) { D3D10_VIEWPORT vp; @@ -613,20 +675,20 @@ void GSDevice10::RSSet(int width, int height, const RECT* scissor) m_dev->RSSetViewports(1, &vp); - m_viewport = CSize(width, height); + m_viewport = GSVector2i(width, height); } - CRect r = scissor ? *scissor : CRect(0, 0, width, height); + GSVector4i r = scissor ? *scissor : GSVector4i(0, 0, width, height); - if(m_scissor != r) + if(!m_scissor.eq(r)) { - m_dev->RSSetScissorRects(1, &r); + m_dev->RSSetScissorRects(1, r); m_scissor = r; } } -void GSDevice10::OMSetDepthStencilState(ID3D10DepthStencilState* dss, UINT sref) +void GSDevice10::OMSetDepthStencilState(ID3D10DepthStencilState* dss, uint8 sref) { if(m_dss != dss || m_sref != sref) { @@ -650,8 +712,14 @@ void GSDevice10::OMSetBlendState(ID3D10BlendState* bs, float bf) } } -void GSDevice10::OMSetRenderTargets(ID3D10RenderTargetView* rtv, ID3D10DepthStencilView* dsv) +void GSDevice10::OMSetRenderTargets(GSTexture* rt, GSTexture* ds) { + ID3D10RenderTargetView* rtv = NULL; + ID3D10DepthStencilView* dsv = NULL; + + if(rt) rtv = *(GSTexture10*)rt; + if(ds) dsv = *(GSTexture10*)ds; + if(m_rtv != rtv || m_dsv != dsv) { m_dev->OMSetRenderTargets(1, &rtv, dsv); @@ -661,97 +729,21 @@ void GSDevice10::OMSetRenderTargets(ID3D10RenderTargetView* rtv, ID3D10DepthSten } } -void GSDevice10::DrawPrimitive(UINT count, UINT start) -{ - m_dev->Draw(count, start); -} - -void GSDevice10::StretchRect(Texture& st, Texture& dt, const GSVector4& dr, bool linear) -{ - StretchRect(st, GSVector4(0, 0, 1, 1), dt, dr, linear); -} - -void GSDevice10::StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, bool linear) -{ - StretchRect(st, sr, dt, dr, m_convert.ps[0], NULL, linear); -} - -void GSDevice10::StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, bool linear) -{ - StretchRect(st, sr, dt, dr, ps, ps_cb, m_convert.bs, linear); -} - -void GSDevice10::StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, ID3D10BlendState* bs, bool linear) -{ - BeginScene(); - - // om - - OMSetDepthStencilState(m_convert.dss, 0); - OMSetBlendState(bs, 0); - OMSetRenderTargets(dt, NULL); - - // ia - - float left = dr.x * 2 / dt.GetWidth() - 1.0f; - float top = 1.0f - dr.y * 2 / dt.GetHeight(); - float right = dr.z * 2 / dt.GetWidth() - 1.0f; - float bottom = 1.0f - dr.w * 2 / dt.GetHeight(); - - GSVertexPT1 vertices[] = - { - {GSVector4(left, top, 0.5f, 1.0f), GSVector2(sr.x, sr.y)}, - {GSVector4(right, top, 0.5f, 1.0f), GSVector2(sr.z, sr.y)}, - {GSVector4(left, bottom, 0.5f, 1.0f), GSVector2(sr.x, sr.w)}, - {GSVector4(right, bottom, 0.5f, 1.0f), GSVector2(sr.z, sr.w)}, - }; - - D3D10_BOX box = {0, 0, 0, sizeof(vertices), 1, 1}; - - m_dev->UpdateSubresource(m_convert.vb, 0, &box, vertices, 0, 0); - - IASetVertexBuffer(m_convert.vb, sizeof(vertices[0])); - IASetInputLayout(m_convert.il); - IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - // vs - - VSSetShader(m_convert.vs, NULL); - - // gs - - GSSetShader(NULL); - - // ps - - PSSetShader(ps, ps_cb); - PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, NULL); - PSSetShaderResources(st, NULL); - - // rs - - RSSet(dt.GetWidth(), dt.GetHeight()); - - // - - DrawPrimitive(countof(vertices)); - - // - - EndScene(); -} - -HRESULT GSDevice10::CompileShader(UINT id, LPCSTR entry, D3D10_SHADER_MACRO* macro, ID3D10VertexShader** ps, D3D10_INPUT_ELEMENT_DESC* layout, int count, ID3D10InputLayout** il) +HRESULT GSDevice10::CompileShader(uint32 id, const string& entry, D3D10_SHADER_MACRO* macro, ID3D10VertexShader** vs, D3D10_INPUT_ELEMENT_DESC* layout, int count, ID3D10InputLayout** il) { HRESULT hr; + vector m; + + PrepareShaderMacro(m, macro, "0x400"); + CComPtr shader, error; - hr = D3DX10CompileFromResource(AfxGetInstanceHandle(), MAKEINTRESOURCE(id), NULL, macro, NULL, entry, "vs_4_0", 0, 0, NULL, &shader, &error, NULL); + hr = D3DX10CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), "vs_4_0", 0, 0, NULL, &shader, &error, NULL); if(error) { - TRACE(_T("%s\n"), CString((LPCSTR)error->GetBufferPointer())); + printf("%s\n", (const char*)error->GetBufferPointer()); } if(FAILED(hr)) @@ -759,7 +751,7 @@ HRESULT GSDevice10::CompileShader(UINT id, LPCSTR entry, D3D10_SHADER_MACRO* mac return hr; } - hr = m_dev->CreateVertexShader((DWORD*)shader->GetBufferPointer(), shader->GetBufferSize(), ps); + hr = m_dev->CreateVertexShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(), vs); if(FAILED(hr)) { @@ -776,17 +768,21 @@ HRESULT GSDevice10::CompileShader(UINT id, LPCSTR entry, D3D10_SHADER_MACRO* mac return hr; } -HRESULT GSDevice10::CompileShader(UINT id, LPCSTR entry, D3D10_SHADER_MACRO* macro, ID3D10GeometryShader** gs) +HRESULT GSDevice10::CompileShader(uint32 id, const string& entry, D3D10_SHADER_MACRO* macro, ID3D10GeometryShader** gs) { HRESULT hr; + vector m; + + PrepareShaderMacro(m, macro, "0x400"); + CComPtr shader, error; - hr = D3DX10CompileFromResource(AfxGetInstanceHandle(), MAKEINTRESOURCE(id), NULL, macro, NULL, entry, "gs_4_0", 0, 0, NULL, &shader, &error, NULL); + hr = D3DX10CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), "gs_4_0", 0, 0, NULL, &shader, &error, NULL); if(error) { - TRACE(_T("%s\n"), CString((LPCSTR)error->GetBufferPointer())); + printf("%s\n", (const char*)error->GetBufferPointer()); } if(FAILED(hr)) @@ -794,7 +790,7 @@ HRESULT GSDevice10::CompileShader(UINT id, LPCSTR entry, D3D10_SHADER_MACRO* mac return hr; } - hr = m_dev->CreateGeometryShader((DWORD*)shader->GetBufferPointer(), shader->GetBufferSize(), gs); + hr = m_dev->CreateGeometryShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(), gs); if(FAILED(hr)) { @@ -804,17 +800,21 @@ HRESULT GSDevice10::CompileShader(UINT id, LPCSTR entry, D3D10_SHADER_MACRO* mac return hr; } -HRESULT GSDevice10::CompileShader(UINT id, LPCSTR entry, D3D10_SHADER_MACRO* macro, ID3D10PixelShader** ps) +HRESULT GSDevice10::CompileShader(uint32 id, const string& entry, D3D10_SHADER_MACRO* macro, ID3D10PixelShader** ps) { HRESULT hr; + vector m; + + PrepareShaderMacro(m, macro, "0x400"); + CComPtr shader, error; - hr = D3DX10CompileFromResource(AfxGetInstanceHandle(), MAKEINTRESOURCE(id), NULL, macro, NULL, entry, "ps_4_0", 0, 0, NULL, &shader, &error, NULL); + hr = D3DX10CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), "ps_4_0", 0, 0, NULL, &shader, &error, NULL); if(error) { - TRACE(_T("%s\n"), CString((LPCSTR)error->GetBufferPointer())); + printf("%s\n", (const char*)error->GetBufferPointer()); } if(FAILED(hr)) @@ -822,7 +822,7 @@ HRESULT GSDevice10::CompileShader(UINT id, LPCSTR entry, D3D10_SHADER_MACRO* mac return hr; } - hr = m_dev->CreatePixelShader((DWORD*)shader->GetBufferPointer(), shader->GetBufferSize(), ps); + hr = m_dev->CreatePixelShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(), ps); if(FAILED(hr)) { diff --git a/plugins/GSdx/GSDevice10.h b/plugins/GSdx/GSDevice10.h index 55124884de..5739532105 100644 --- a/plugins/GSdx/GSDevice10.h +++ b/plugins/GSdx/GSDevice10.h @@ -24,17 +24,10 @@ #include "GSDevice.h" #include "GSTexture10.h" -class GSDevice10 : public GSDevice +class GSDevice10 : public GSDevice { -public: - typedef GSTexture10 Texture; - -private: - // state cache - ID3D10Buffer* m_vb; - UINT m_vb_count; - UINT m_vb_stride; + size_t m_vb_stride; ID3D10InputLayout* m_layout; D3D10_PRIMITIVE_TOPOLOGY m_topology; ID3D10VertexShader* m_vs; @@ -44,10 +37,10 @@ private: ID3D10PixelShader* m_ps; ID3D10Buffer* m_ps_cb; ID3D10SamplerState* m_ps_ss[2]; - CSize m_viewport; - CRect m_scissor; + GSVector2i m_viewport; + GSVector4i m_scissor; ID3D10DepthStencilState* m_dss; - UINT m_sref; + uint8 m_sref; ID3D10BlendState* m_bs; float m_bf; ID3D10RenderTargetView* m_rtv; @@ -55,25 +48,30 @@ private: // - bool Create(int type, Texture& t, int w, int h, int format); - void DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, bool slbg, bool mmod, GSVector4& c); - void DoInterlace(Texture& st, Texture& dt, int shader, bool linear, float yoffset = 0); + GSTexture* Create(int type, int w, int h, int format); + + void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c); + void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0); // CComPtr m_dev; CComPtr m_swapchain; - CComPtr m_font; + + struct + { + CComPtr vb, vb_old; + size_t stride, start, count, limit; + } m_vertices; public: // TODO CComPtr m_rs; struct { - CComPtr vb; CComPtr il; CComPtr vs; - CComPtr ps[5]; + CComPtr ps[7]; CComPtr ln; CComPtr pt; CComPtr dss; @@ -97,51 +95,49 @@ public: GSDevice10(); virtual ~GSDevice10(); - bool Create(HWND hWnd, bool vsync); + bool Create(GSWnd* wnd, bool vsync); bool Reset(int w, int h, bool fs); - bool IsLost() {return false;} - void Present(const CRect& r); + + void Flip(); + void BeginScene(); + void DrawPrimitive(); void EndScene(); - void Draw(LPCTSTR str); - bool CopyOffscreen(Texture& src, const GSVector4& sr, Texture& dst, int w, int h, int format = 0); - void ClearRenderTarget(Texture& t, const GSVector4& c); - void ClearRenderTarget(Texture& t, DWORD c); - void ClearDepth(Texture& t, float c); - void ClearStencil(Texture& t, BYTE c); + void ClearRenderTarget(GSTexture* t, const GSVector4& c); + void ClearRenderTarget(GSTexture* t, uint32 c); + void ClearDepth(GSTexture* t, float c); + void ClearStencil(GSTexture* t, uint8 c); - bool CreateRenderTarget(Texture& t, int w, int h, int format = 0); - bool CreateDepthStencil(Texture& t, int w, int h, int format = 0); - bool CreateTexture(Texture& t, int w, int h, int format = 0); - bool CreateOffscreen(Texture& t, int w, int h, int format = 0); + GSTexture* CreateRenderTarget(int w, int h, int format = 0); + GSTexture* CreateDepthStencil(int w, int h, int format = 0); + GSTexture* CreateTexture(int w, int h, int format = 0); + GSTexture* CreateOffscreen(int w, int h, int format = 0); - ID3D10Device* operator->() {return m_dev;} - operator ID3D10Device*() {return m_dev;} + GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0); - void IASetVertexBuffer(ID3D10Buffer* vb, UINT stride); + void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true); + void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, bool linear = true); + void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, ID3D10BlendState* bs, bool linear = true); + + void IASetVertexBuffer(const void* vertices, size_t stride, size_t count); + void IASetVertexBuffer(ID3D10Buffer* vb, size_t stride); void IASetInputLayout(ID3D10InputLayout* layout); void IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY topology); void VSSetShader(ID3D10VertexShader* vs, ID3D10Buffer* vs_cb); void GSSetShader(ID3D10GeometryShader* gs); - void PSSetShaderResources(ID3D10ShaderResourceView* srv0, ID3D10ShaderResourceView* srv1); + void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1); void PSSetShader(ID3D10PixelShader* ps, ID3D10Buffer* ps_cb); void PSSetSamplerState(ID3D10SamplerState* ss0, ID3D10SamplerState* ss1); - void RSSet(int width, int height, const RECT* scissor = NULL); - void OMSetDepthStencilState(ID3D10DepthStencilState* dss, UINT sref); + void RSSet(int width, int height, const GSVector4i* scissor = NULL); + void OMSetDepthStencilState(ID3D10DepthStencilState* dss, uint8 sref); void OMSetBlendState(ID3D10BlendState* bs, float bf); - void OMSetRenderTargets(ID3D10RenderTargetView* rtv, ID3D10DepthStencilView* dsv); - void DrawPrimitive(UINT count, UINT start = 0); + void OMSetRenderTargets(GSTexture* rt, GSTexture* ds); - void StretchRect(Texture& st, Texture& dt, const GSVector4& dr, bool linear = true); - void StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, bool linear = true); - void StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, bool linear = true); - void StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, ID3D10BlendState* bs, bool linear = true); + ID3D10Device* operator->() {return m_dev;} + operator ID3D10Device*() {return m_dev;} - HRESULT CompileShader(UINT id, LPCSTR entry, D3D10_SHADER_MACRO* macro, ID3D10VertexShader** vs, D3D10_INPUT_ELEMENT_DESC* layout, int count, ID3D10InputLayout** il); - HRESULT CompileShader(UINT id, LPCSTR entry, D3D10_SHADER_MACRO* macro, ID3D10GeometryShader** gs); - HRESULT CompileShader(UINT id, LPCSTR entry, D3D10_SHADER_MACRO* macro, ID3D10PixelShader** ps); - - // TODO - bool SaveToFileD32S8X24(ID3D10Texture2D* ds, LPCTSTR fn); + HRESULT CompileShader(uint32 id, const string& entry, D3D10_SHADER_MACRO* macro, ID3D10VertexShader** vs, D3D10_INPUT_ELEMENT_DESC* layout, int count, ID3D10InputLayout** il); + HRESULT CompileShader(uint32 id, const string& entry, D3D10_SHADER_MACRO* macro, ID3D10GeometryShader** gs); + HRESULT CompileShader(uint32 id, const string& entry, D3D10_SHADER_MACRO* macro, ID3D10PixelShader** ps); }; diff --git a/plugins/GSdx/GSDevice11.cpp b/plugins/GSdx/GSDevice11.cpp new file mode 100644 index 0000000000..c31c0a8d92 --- /dev/null +++ b/plugins/GSdx/GSDevice11.cpp @@ -0,0 +1,870 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSdx.h" +#include "GSDevice11.h" +#include "resource.h" + +GSDevice11::GSDevice11() + : m_vb(NULL) + , m_vb_stride(0) + , m_layout(NULL) + , m_topology(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED) + , m_vs(NULL) + , m_vs_cb(NULL) + , m_gs(NULL) + , m_ps(NULL) + , m_ps_cb(NULL) + , m_scissor(0, 0, 0, 0) + , m_viewport(0, 0) + , m_dss(NULL) + , m_sref(0) + , m_bs(NULL) + , m_bf(-1) + , m_rtv(NULL) + , m_dsv(NULL) +{ + memset(m_ps_srv, 0, sizeof(m_ps_srv)); + memset(m_ps_ss, 0, sizeof(m_ps_ss)); + + m_vertices.stride = 0; + m_vertices.start = 0; + m_vertices.count = 0; + m_vertices.limit = 0; +} + +GSDevice11::~GSDevice11() +{ +} + +bool GSDevice11::Create(GSWnd* wnd, bool vsync) +{ + if(!__super::Create(wnd, vsync)) + { + return false; + } + + HRESULT hr; + + DXGI_SWAP_CHAIN_DESC scd; + D3D11_BUFFER_DESC bd; + D3D11_SAMPLER_DESC sd; + D3D11_DEPTH_STENCIL_DESC dsd; + D3D11_RASTERIZER_DESC rd; + D3D11_BLEND_DESC bsd; + + memset(&scd, 0, sizeof(scd)); + + scd.BufferCount = 2; + scd.BufferDesc.Width = 1; + scd.BufferDesc.Height = 1; + scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + //scd.BufferDesc.RefreshRate.Numerator = 60; + //scd.BufferDesc.RefreshRate.Denominator = 1; + scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + scd.OutputWindow = (HWND)m_wnd->GetHandle(); + scd.SampleDesc.Count = 1; + scd.SampleDesc.Quality = 0; + scd.Windowed = TRUE; + + uint32 flags = 0; + +#ifdef DEBUG + flags |= D3D11_CREATE_DEVICE_DEBUG; +#endif + + hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &m_level, &m_ctx); + // hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &m_level, &m_ctx); + + if(FAILED(hr)) return false; + + D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS options; + + hr = m_dev->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &options, sizeof(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS)); + + switch(m_level) + { + case D3D_FEATURE_LEVEL_9_1: + case D3D_FEATURE_LEVEL_9_2: + m_shader.model = "0x200"; + m_shader.vs = "vs_4_0_level_9_1"; + m_shader.ps = "ps_4_0_level_9_1"; + break; + case D3D_FEATURE_LEVEL_9_3: + m_shader.model = "0x300"; + m_shader.vs = "vs_4_0_level_9_3"; + m_shader.ps = "ps_4_0_level_9_3"; + break; + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_10_1: + m_shader.model = "0x400"; + m_shader.vs = "vs_4_0"; + m_shader.gs = "gs_4_0"; + m_shader.ps = "ps_4_0"; + break; + case D3D_FEATURE_LEVEL_11_0: + m_shader.model = "0x500"; + m_shader.vs = "vs_5_0"; + m_shader.gs = "gs_5_0"; + m_shader.ps = "ps_5_0"; + break; + } + + if(m_level < D3D_FEATURE_LEVEL_10_0) + { + return false; + } + + // convert + + D3D11_INPUT_ELEMENT_DESC il_convert[] = + { + {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }; + + hr = CompileShader(IDR_CONVERT_FX, "vs_main", NULL, &m_convert.vs, il_convert, countof(il_convert), &m_convert.il); + + for(int i = 0; i < countof(m_convert.ps); i++) + { + hr = CompileShader(IDR_CONVERT_FX, format("ps_main%d", i), NULL, &m_convert.ps[i]); + } + + memset(&dsd, 0, sizeof(dsd)); + + dsd.DepthEnable = false; + dsd.StencilEnable = false; + + hr = m_dev->CreateDepthStencilState(&dsd, &m_convert.dss); + + memset(&bsd, 0, sizeof(bsd)); + + bsd.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + hr = m_dev->CreateBlendState(&bsd, &m_convert.bs); + + // merge + + memset(&bd, 0, sizeof(bd)); + + bd.ByteWidth = sizeof(MergeConstantBuffer); + bd.Usage = D3D11_USAGE_DEFAULT; + bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + + hr = m_dev->CreateBuffer(&bd, NULL, &m_merge.cb); + + for(int i = 0; i < countof(m_merge.ps); i++) + { + hr = CompileShader(IDR_MERGE_FX, format("ps_main%d", i), NULL, &m_merge.ps[i]); + } + + memset(&bsd, 0, sizeof(bsd)); + + bsd.RenderTarget[0].BlendEnable = true; + bsd.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + bsd.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + bsd.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + bsd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + bsd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + bsd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + bsd.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + hr = m_dev->CreateBlendState(&bsd, &m_merge.bs); + + // interlace + + memset(&bd, 0, sizeof(bd)); + + bd.ByteWidth = sizeof(InterlaceConstantBuffer); + bd.Usage = D3D11_USAGE_DEFAULT; + bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + + hr = m_dev->CreateBuffer(&bd, NULL, &m_interlace.cb); + + for(int i = 0; i < countof(m_interlace.ps); i++) + { + hr = CompileShader(IDR_INTERLACE_FX, format("ps_main%d", i), NULL, &m_interlace.ps[i]); + } + + // + + memset(&rd, 0, sizeof(rd)); + + rd.FillMode = D3D11_FILL_SOLID; + rd.CullMode = D3D11_CULL_NONE; + rd.FrontCounterClockwise = false; + rd.DepthBias = false; + rd.DepthBiasClamp = 0; + rd.SlopeScaledDepthBias = 0; + rd.DepthClipEnable = false; // ??? + rd.ScissorEnable = true; + rd.MultisampleEnable = false; + rd.AntialiasedLineEnable = false; + + hr = m_dev->CreateRasterizerState(&rd, &m_rs); + + m_ctx->RSSetState(m_rs); + + // + + memset(&sd, 0, sizeof(sd)); + + sd.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + sd.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + sd.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + sd.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + sd.MaxLOD = FLT_MAX; + sd.MaxAnisotropy = 16; + sd.ComparisonFunc = D3D11_COMPARISON_NEVER; + + hr = m_dev->CreateSamplerState(&sd, &m_convert.ln); + + sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + + hr = m_dev->CreateSamplerState(&sd, &m_convert.pt); + + // + + Reset(1, 1, false); + + // + + return true; +} + +bool GSDevice11::Reset(int w, int h, bool fs) +{ + if(!__super::Reset(w, h, fs)) + return false; + + DXGI_SWAP_CHAIN_DESC scd; + memset(&scd, 0, sizeof(scd)); + m_swapchain->GetDesc(&scd); + m_swapchain->ResizeBuffers(scd.BufferCount, w, h, scd.BufferDesc.Format, 0); + + CComPtr backbuffer; + m_swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backbuffer); + m_backbuffer = new GSTexture11(backbuffer); + + return true; +} + +void GSDevice11::Flip() +{ + m_swapchain->Present(m_vsync ? 1 : 0, 0); +} + +void GSDevice11::BeginScene() +{ +} + +void GSDevice11::DrawPrimitive() +{ + m_ctx->Draw(m_vertices.count, m_vertices.start); +} + +void GSDevice11::EndScene() +{ + PSSetShaderResources(NULL, NULL); + + // not clearing the rt/ds gives a little fps boost in complex games (5-10%) + + // OMSetRenderTargets(NULL, NULL); + + m_vertices.start += m_vertices.count; + m_vertices.count = 0; +} + +void GSDevice11::ClearRenderTarget(GSTexture* t, const GSVector4& c) +{ + m_ctx->ClearRenderTargetView(*(GSTexture11*)t, c.v); +} + +void GSDevice11::ClearRenderTarget(GSTexture* t, uint32 c) +{ + GSVector4 color = GSVector4(c) * (1.0f / 255); + + m_ctx->ClearRenderTargetView(*(GSTexture11*)t, color.v); +} + +void GSDevice11::ClearDepth(GSTexture* t, float c) +{ + m_ctx->ClearDepthStencilView(*(GSTexture11*)t, D3D11_CLEAR_DEPTH, c, 0); +} + +void GSDevice11::ClearStencil(GSTexture* t, uint8 c) +{ + m_ctx->ClearDepthStencilView(*(GSTexture11*)t, D3D11_CLEAR_STENCIL, 0, c); +} + +GSTexture* GSDevice11::Create(int type, int w, int h, int format) +{ + HRESULT hr; + + D3D11_TEXTURE2D_DESC desc; + + memset(&desc, 0, sizeof(desc)); + + desc.Width = w; + desc.Height = h; + desc.Format = (DXGI_FORMAT)format; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + + switch(type) + { + case GSTexture::RenderTarget: + desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; + break; + case GSTexture::DepthStencil: + desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + break; + case GSTexture::Texture: + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + break; + case GSTexture::Offscreen: + desc.Usage = D3D11_USAGE_STAGING; + desc.CPUAccessFlags |= D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + break; + } + + GSTexture11* t = NULL; + + CComPtr texture; + + hr = m_dev->CreateTexture2D(&desc, NULL, &texture); + + if(SUCCEEDED(hr)) + { + t = new GSTexture11(texture); + + switch(type) + { + case GSTexture::RenderTarget: + ClearRenderTarget(t, 0); + break; + case GSTexture::DepthStencil: + ClearDepth(t, 0); + break; + } + } + + return t; +} + +GSTexture* GSDevice11::CreateRenderTarget(int w, int h, int format) +{ + return __super::CreateRenderTarget(w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM); +} + +GSTexture* GSDevice11::CreateDepthStencil(int w, int h, int format) +{ + return __super::CreateDepthStencil(w, h, format ? format : DXGI_FORMAT_D32_FLOAT_S8X24_UINT); +} + +GSTexture* GSDevice11::CreateTexture(int w, int h, int format) +{ + return __super::CreateTexture(w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM); +} + +GSTexture* GSDevice11::CreateOffscreen(int w, int h, int format) +{ + return __super::CreateOffscreen(w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM); +} + +GSTexture* GSDevice11::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format) +{ + GSTexture* dst = NULL; + + if(format == 0) + { + format = DXGI_FORMAT_R8G8B8A8_UNORM; + } + + if(format != DXGI_FORMAT_R8G8B8A8_UNORM && format != DXGI_FORMAT_R16_UINT) + { + ASSERT(0); + + return false; + } + + if(GSTexture* rt = CreateRenderTarget(w, h, format)) + { + GSVector4 dr(0, 0, w, h); + + StretchRect(src, sr, rt, dr, m_convert.ps[format == DXGI_FORMAT_R16_UINT ? 1 : 0], NULL); + + dst = CreateOffscreen(w, h, format); + + if(dst) + { + m_ctx->CopyResource(*(GSTexture11*)dst, *(GSTexture11*)rt); + } + + Recycle(rt); + } + + return dst; +} + +void GSDevice11::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear) +{ + StretchRect(st, sr, dt, dr, m_convert.ps[shader], NULL, linear); +} + +void GSDevice11::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear) +{ + StretchRect(st, sr, dt, dr, ps, ps_cb, m_convert.bs, linear); +} + +void GSDevice11::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear) +{ + BeginScene(); + + GSVector2i ds = dt->GetSize(); + + // om + + OMSetDepthStencilState(m_convert.dss, 0); + OMSetBlendState(bs, 0); + OMSetRenderTargets(dt, NULL); + + // ia + + float left = dr.x * 2 / ds.x - 1.0f; + float top = 1.0f - dr.y * 2 / ds.y; + float right = dr.z * 2 / ds.x - 1.0f; + float bottom = 1.0f - dr.w * 2 / ds.y; + + GSVertexPT1 vertices[] = + { + {GSVector4(left, top, 0.5f, 1.0f), GSVector2(sr.x, sr.y)}, + {GSVector4(right, top, 0.5f, 1.0f), GSVector2(sr.z, sr.y)}, + {GSVector4(left, bottom, 0.5f, 1.0f), GSVector2(sr.x, sr.w)}, + {GSVector4(right, bottom, 0.5f, 1.0f), GSVector2(sr.z, sr.w)}, + }; + + IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); + IASetInputLayout(m_convert.il); + IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + // vs + + VSSetShader(m_convert.vs, NULL); + + // gs + + GSSetShader(NULL); + + // ps + + PSSetShader(ps, ps_cb); + PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, NULL); + PSSetShaderResources(st, NULL); + + // rs + + RSSet(ds.x, ds.y); + + // + + DrawPrimitive(); + + // + + EndScene(); +} + +void GSDevice11::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c) +{ + ClearRenderTarget(dt, c); + + if(st[1] && !slbg) + { + StretchRect(st[1], sr[1], dt, dr[1], m_merge.ps[0], NULL, true); + } + + if(st[0]) + { + m_ctx->UpdateSubresource(m_merge.cb, 0, NULL, &c, 0, 0); + + StretchRect(st[0], sr[0], dt, dr[0], m_merge.ps[mmod ? 1 : 0], m_merge.cb, m_merge.bs, true); + } +} + +void GSDevice11::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset) +{ + GSVector4 s = GSVector4(dt->GetSize()); + + GSVector4 sr(0, 0, 1, 1); + GSVector4 dr(0.0f, yoffset, s.x, s.y + yoffset); + + InterlaceConstantBuffer cb; + + cb.ZrH = GSVector2(0, 1.0f / s.y); + cb.hH = s.y / 2; + + m_ctx->UpdateSubresource(m_interlace.cb, 0, NULL, &cb, 0, 0); + + StretchRect(st, sr, dt, dr, m_interlace.ps[shader], m_interlace.cb, linear); +} + +void GSDevice11::IASetVertexBuffer(const void* vertices, size_t stride, size_t count) +{ + ASSERT(m_vertices.count == 0); + + if(count * stride > m_vertices.limit * m_vertices.stride) + { + m_vertices.vb_old = m_vertices.vb; + m_vertices.vb = NULL; + m_vertices.start = 0; + m_vertices.count = 0; + m_vertices.limit = max(count * 3 / 2, 10000); + } + + if(m_vertices.vb == NULL) + { + D3D11_BUFFER_DESC bd; + + memset(&bd, 0, sizeof(bd)); + + bd.Usage = D3D11_USAGE_DYNAMIC; + bd.ByteWidth = m_vertices.limit * stride; + bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + HRESULT hr; + + hr = m_dev->CreateBuffer(&bd, NULL, &m_vertices.vb); + + if(FAILED(hr)) return; + } + + D3D11_MAP type = D3D11_MAP_WRITE_NO_OVERWRITE; + + if(m_vertices.start + count > m_vertices.limit || stride != m_vertices.stride) + { + m_vertices.start = 0; + + type = D3D11_MAP_WRITE_DISCARD; + } + + D3D11_MAPPED_SUBRESOURCE m; + + if(SUCCEEDED(m_ctx->Map(m_vertices.vb, 0, type, 0, &m))) + { + GSVector4i::storent((uint8*)m.pData + m_vertices.start * stride, vertices, count * stride); + + m_ctx->Unmap(m_vertices.vb, 0); + } + + m_vertices.count = count; + m_vertices.stride = stride; + + IASetVertexBuffer(m_vertices.vb, stride); +} + +void GSDevice11::IASetVertexBuffer(ID3D11Buffer* vb, size_t stride) +{ + if(m_vb != vb || m_vb_stride != stride) + { + uint32 offset = 0; + + m_ctx->IASetVertexBuffers(0, 1, &vb, &stride, &offset); + + m_vb = vb; + m_vb_stride = stride; + } +} + +void GSDevice11::IASetInputLayout(ID3D11InputLayout* layout) +{ + if(m_layout != layout) + { + m_ctx->IASetInputLayout(layout); + + m_layout = layout; + } +} + +void GSDevice11::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY topology) +{ + if(m_topology != topology) + { + m_ctx->IASetPrimitiveTopology(topology); + + m_topology = topology; + } +} + +void GSDevice11::VSSetShader(ID3D11VertexShader* vs, ID3D11Buffer* vs_cb) +{ + if(m_vs != vs) + { + m_ctx->VSSetShader(vs, NULL, 0); + + m_vs = vs; + } + + if(m_vs_cb != vs_cb) + { + m_ctx->VSSetConstantBuffers(0, 1, &vs_cb); + + m_vs_cb = vs_cb; + } +} + +void GSDevice11::GSSetShader(ID3D11GeometryShader* gs) +{ + if(m_gs != gs) + { + m_ctx->GSSetShader(gs, NULL, 0); + + m_gs = gs; + } +} + +void GSDevice11::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1) +{ + ID3D11ShaderResourceView* srv0 = NULL; + ID3D11ShaderResourceView* srv1 = NULL; + + if(sr0) srv0 = *(GSTexture11*)sr0; + if(sr1) srv1 = *(GSTexture11*)sr1; + + if(m_ps_srv[0] != srv0 || m_ps_srv[1] != srv1) + { + ID3D11ShaderResourceView* srvs[] = {srv0, srv1}; + + m_ctx->PSSetShaderResources(0, 2, srvs); + + m_ps_srv[0] = srv0; + m_ps_srv[1] = srv1; + } +} + +void GSDevice11::PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb) +{ + if(m_ps != ps) + { + m_ctx->PSSetShader(ps, NULL, 0); + + m_ps = ps; + } + + if(m_ps_cb != ps_cb) + { + m_ctx->PSSetConstantBuffers(0, 1, &ps_cb); + + m_ps_cb = ps_cb; + } +} + +void GSDevice11::PSSetSamplerState(ID3D11SamplerState* ss0, ID3D11SamplerState* ss1) +{ + if(m_ps_ss[0] != ss0 || m_ps_ss[1] != ss1) + { + ID3D11SamplerState* sss[] = {ss0, ss1}; + + m_ctx->PSSetSamplers(0, 2, sss); + + m_ps_ss[0] = ss0; + m_ps_ss[1] = ss1; + } +} + +void GSDevice11::RSSet(int width, int height, const GSVector4i* scissor) +{ + if(m_viewport.x != width || m_viewport.y != height) + { + D3D11_VIEWPORT vp; + + memset(&vp, 0, sizeof(vp)); + + vp.TopLeftX = 0; + vp.TopLeftY = 0; + vp.Width = width; + vp.Height = height; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + + m_ctx->RSSetViewports(1, &vp); + + m_viewport = GSVector2i(width, height); + } + + GSVector4i r = scissor ? *scissor : GSVector4i(0, 0, width, height); + + if(!m_scissor.eq(r)) + { + m_ctx->RSSetScissorRects(1, r); + + m_scissor = r; + } +} + +void GSDevice11::OMSetDepthStencilState(ID3D11DepthStencilState* dss, uint8 sref) +{ + if(m_dss != dss || m_sref != sref) + { + m_ctx->OMSetDepthStencilState(dss, sref); + + m_dss = dss; + m_sref = sref; + } +} + +void GSDevice11::OMSetBlendState(ID3D11BlendState* bs, float bf) +{ + if(m_bs != bs || m_bf != bf) + { + float BlendFactor[] = {bf, bf, bf, 0}; + + m_ctx->OMSetBlendState(bs, BlendFactor, 0xffffffff); + + m_bs = bs; + m_bf = bf; + } +} + +void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds) +{ + ID3D11RenderTargetView* rtv = NULL; + ID3D11DepthStencilView* dsv = NULL; + + if(rt) rtv = *(GSTexture11*)rt; + if(ds) dsv = *(GSTexture11*)ds; + + if(m_rtv != rtv || m_dsv != dsv) + { + m_ctx->OMSetRenderTargets(1, &rtv, dsv); + + m_rtv = rtv; + m_dsv = dsv; + } +} + +HRESULT GSDevice11::CompileShader(uint32 id, const string& entry, D3D11_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il) +{ + HRESULT hr; + + vector m; + + PrepareShaderMacro(m, macro, m_shader.model.c_str()); + + CComPtr shader, error; + + hr = D3DX11CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), m_shader.vs.c_str(), 0, 0, NULL, &shader, &error, NULL); + + if(error) + { + printf("%s\n", (const char*)error->GetBufferPointer()); + } + + if(FAILED(hr)) + { + return hr; + } + + hr = m_dev->CreateVertexShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(), NULL, vs); + + if(FAILED(hr)) + { + return hr; + } + + hr = m_dev->CreateInputLayout(layout, count, shader->GetBufferPointer(), shader->GetBufferSize(), il); + + if(FAILED(hr)) + { + return hr; + } + + return hr; +} + +HRESULT GSDevice11::CompileShader(uint32 id, const string& entry, D3D11_SHADER_MACRO* macro, ID3D11GeometryShader** gs) +{ + HRESULT hr; + + vector m; + + PrepareShaderMacro(m, macro, m_shader.model.c_str()); + + CComPtr shader, error; + + hr = D3DX11CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), m_shader.gs.c_str(), 0, 0, NULL, &shader, &error, NULL); + + if(error) + { + printf("%s\n", (const char*)error->GetBufferPointer()); + } + + if(FAILED(hr)) + { + return hr; + } + + hr = m_dev->CreateGeometryShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(), NULL, gs); + + if(FAILED(hr)) + { + return hr; + } + + return hr; +} + +HRESULT GSDevice11::CompileShader(uint32 id, const string& entry, D3D11_SHADER_MACRO* macro, ID3D11PixelShader** ps) +{ + HRESULT hr; + + vector m; + + PrepareShaderMacro(m, macro, m_shader.model.c_str()); + + CComPtr shader, error; + + hr = D3DX11CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), m_shader.ps.c_str(), 0, 0, NULL, &shader, &error, NULL); + + if(error) + { + printf("%s\n", (const char*)error->GetBufferPointer()); + } + + if(FAILED(hr)) + { + return hr; + } + + hr = m_dev->CreatePixelShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(),NULL, ps); + + if(FAILED(hr)) + { + return hr; + } + + return hr; +} diff --git a/plugins/GSdx/GSDevice11.h b/plugins/GSdx/GSDevice11.h new file mode 100644 index 0000000000..2fa406e941 --- /dev/null +++ b/plugins/GSdx/GSDevice11.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSDevice.h" +#include "GSTexture11.h" + +class GSDevice11 : public GSDevice +{ + ID3D11Buffer* m_vb; + size_t m_vb_stride; + ID3D11InputLayout* m_layout; + D3D11_PRIMITIVE_TOPOLOGY m_topology; + ID3D11VertexShader* m_vs; + ID3D11Buffer* m_vs_cb; + ID3D11GeometryShader* m_gs; + ID3D11ShaderResourceView* m_ps_srv[2]; + ID3D11PixelShader* m_ps; + ID3D11Buffer* m_ps_cb; + ID3D11SamplerState* m_ps_ss[2]; + GSVector2i m_viewport; + GSVector4i m_scissor; + ID3D11DepthStencilState* m_dss; + uint8 m_sref; + ID3D11BlendState* m_bs; + float m_bf; + ID3D11RenderTargetView* m_rtv; + ID3D11DepthStencilView* m_dsv; + + // + + GSTexture* Create(int type, int w, int h, int format); + + void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c); + void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0); + + // + + D3D_FEATURE_LEVEL m_level; + CComPtr m_dev; + CComPtr m_ctx; + CComPtr m_swapchain; + struct {string model, vs, gs, ps;} m_shader; + + struct + { + CComPtr vb, vb_old; + size_t stride, start, count, limit; + } m_vertices; + +public: // TODO + CComPtr m_rs; + + struct + { + CComPtr il; + CComPtr vs; + CComPtr ps[7]; + CComPtr ln; + CComPtr pt; + CComPtr dss; + CComPtr bs; + } m_convert; + + struct + { + CComPtr ps[2]; + CComPtr cb; + CComPtr bs; + } m_merge; + + struct + { + CComPtr ps[4]; + CComPtr cb; + } m_interlace; + +public: + GSDevice11(); + virtual ~GSDevice11(); + + bool Create(GSWnd* wnd, bool vsync); + bool Reset(int w, int h, bool fs); + + void Flip(); + + void BeginScene(); + void DrawPrimitive(); + void EndScene(); + + void ClearRenderTarget(GSTexture* t, const GSVector4& c); + void ClearRenderTarget(GSTexture* t, uint32 c); + void ClearDepth(GSTexture* t, float c); + void ClearStencil(GSTexture* t, uint8 c); + + GSTexture* CreateRenderTarget(int w, int h, int format = 0); + GSTexture* CreateDepthStencil(int w, int h, int format = 0); + GSTexture* CreateTexture(int w, int h, int format = 0); + GSTexture* CreateOffscreen(int w, int h, int format = 0); + + GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0); + + void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true); + void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear = true); + void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear = true); + + void IASetVertexBuffer(const void* vertices, size_t stride, size_t count); + void IASetVertexBuffer(ID3D11Buffer* vb, size_t stride); + void IASetInputLayout(ID3D11InputLayout* layout); + void IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY topology); + void VSSetShader(ID3D11VertexShader* vs, ID3D11Buffer* vs_cb); + void GSSetShader(ID3D11GeometryShader* gs); + void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1); + void PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb); + void PSSetSamplerState(ID3D11SamplerState* ss0, ID3D11SamplerState* ss1); + void RSSet(int width, int height, const GSVector4i* scissor = NULL); + void OMSetDepthStencilState(ID3D11DepthStencilState* dss, uint8 sref); + void OMSetBlendState(ID3D11BlendState* bs, float bf); + void OMSetRenderTargets(GSTexture* rt, GSTexture* ds); + + ID3D11Device* operator->() {return m_dev;} + operator ID3D11Device*() {return m_dev;} + operator ID3D11DeviceContext*() {return m_ctx;} + + HRESULT CompileShader(uint32 id, const string& entry, D3D11_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il); + HRESULT CompileShader(uint32 id, const string& entry, D3D11_SHADER_MACRO* macro, ID3D11GeometryShader** gs); + HRESULT CompileShader(uint32 id, const string& entry, D3D11_SHADER_MACRO* macro, ID3D11PixelShader** ps); +}; diff --git a/plugins/GSdx/GSDevice7.cpp b/plugins/GSdx/GSDevice7.cpp index 8ca5a59f36..2481fe5c0f 100644 --- a/plugins/GSdx/GSDevice7.cpp +++ b/plugins/GSdx/GSDevice7.cpp @@ -32,9 +32,9 @@ GSDevice7::~GSDevice7() { } -bool GSDevice7::Create(HWND hWnd, bool vsync) +bool GSDevice7::Create(GSWnd* wnd, bool vsync) { - if(!__super::Create(hWnd, vsync)) + if(!__super::Create(wnd, vsync)) { return false; } @@ -44,6 +44,8 @@ bool GSDevice7::Create(HWND hWnd, bool vsync) return false; } + HWND hWnd = (HWND)m_wnd->GetHandle(); + // TODO: fullscreen if(FAILED(m_dd->SetCooperativeLevel(hWnd, DDSCL_NORMAL))) @@ -73,7 +75,7 @@ bool GSDevice7::Create(HWND hWnd, bool vsync) return false; } - Reset(1, 1, true); + Reset(1, 1, false); return true; } @@ -83,8 +85,6 @@ bool GSDevice7::Reset(int w, int h, bool fs) if(!__super::Reset(w, h, fs)) return false; - m_backbuffer = NULL; - DDSURFACEDESC2 desc; memset(&desc, 0, sizeof(desc)); @@ -95,11 +95,15 @@ bool GSDevice7::Reset(int w, int h, bool fs) desc.dwWidth = w; desc.dwHeight = h; - if(FAILED(m_dd->CreateSurface(&desc, &m_backbuffer, NULL))) + CComPtr backbuffer; + + if(FAILED(m_dd->CreateSurface(&desc, &backbuffer, NULL))) { return false; } + m_backbuffer = new GSTexture7(GSTexture::RenderTarget, backbuffer); + CComPtr clipper; if(FAILED(m_dd->CreateClipper(0, &clipper, NULL))) @@ -112,7 +116,7 @@ bool GSDevice7::Reset(int w, int h, bool fs) HRGN hrgn = CreateRectRgn(0, 0, w, h); - BYTE buff[1024]; + uint8 buff[1024]; GetRegionData(hrgn, sizeof(buff), (RGNDATA*)buff); @@ -120,7 +124,7 @@ bool GSDevice7::Reset(int w, int h, bool fs) clipper->SetClipList((RGNDATA*)buff, 0); - if(FAILED(m_backbuffer->SetClipper(clipper))) + if(FAILED(backbuffer->SetClipper(clipper))) { return false; } @@ -129,24 +133,19 @@ bool GSDevice7::Reset(int w, int h, bool fs) return true; } -void GSDevice7::Present(const CRect& r) +void GSDevice7::Present(const GSVector4i& r, int shader) { HRESULT hr; - CRect cr; - GetClientRect(m_hWnd, &cr); + GSVector4i cr = m_wnd->GetClientRect(); - DDSURFACEDESC2 desc; - memset(&desc, 0, sizeof(desc)); - desc.dwSize = sizeof(desc); - - hr = m_backbuffer->GetSurfaceDesc(&desc); - - if(desc.dwWidth != cr.Width() || desc.dwHeight != cr.Height()) + if(m_backbuffer->GetWidth() != cr.width() || m_backbuffer->GetHeight() != cr.height()) { - Reset(cr.Width(), cr.Height(), false); + Reset(cr.width(), cr.height(), false); } + CComPtr backbuffer = *(GSTexture7*)m_backbuffer; + DDBLTFX fx; memset(&fx, 0, sizeof(fx)); @@ -154,22 +153,24 @@ void GSDevice7::Present(const CRect& r) fx.dwSize = sizeof(fx); fx.dwFillColor = 0; - hr = m_backbuffer->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &fx); + hr = backbuffer->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &fx); - CRect r2 = r; + GSVector4i r2 = r; - hr = m_backbuffer->Blt(&r2, m_merge, NULL, DDBLT_WAIT, NULL); + hr = backbuffer->Blt(r2, *(GSTexture7*)m_merge, NULL, DDBLT_WAIT, NULL); + + // if ClearRenderTarget was implemented the parent class could handle these tasks until this point r2 = cr; - MapWindowPoints(m_hWnd, HWND_DESKTOP, (POINT*)&r2, 2); + MapWindowPoints((HWND)m_wnd->GetHandle(), HWND_DESKTOP, (POINT*)&r2, 2); if(m_vsync) { hr = m_dd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL); } - hr = m_primary->Blt(&r2, m_backbuffer, &cr, DDBLT_WAIT, NULL); + hr = m_primary->Blt(r2, backbuffer, cr, DDBLT_WAIT, NULL); if(hr == DDERR_SURFACELOST) { @@ -183,12 +184,10 @@ void GSDevice7::Present(const CRect& r) } } -bool GSDevice7::Create(int type, Texture& t, int w, int h, int format) +GSTexture* GSDevice7::Create(int type, int w, int h, int format) { HRESULT hr; - t = Texture(); - DDSURFACEDESC2 desc; memset(&desc, 0, sizeof(desc)); @@ -206,6 +205,8 @@ bool GSDevice7::Create(int type, Texture& t, int w, int h, int format) desc.ddpfPixelFormat.dwGBitMask = 0x0000ff00; desc.ddpfPixelFormat.dwBBitMask = 0x000000ff; + GSTexture7* t = NULL; + CComPtr system, video; switch(type) @@ -217,25 +218,25 @@ bool GSDevice7::Create(int type, Texture& t, int w, int h, int format) if(FAILED(hr = m_dd->CreateSurface(&desc, &system, NULL))) return false; desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY; if(FAILED(hr = m_dd->CreateSurface(&desc, &video, NULL))) return false; - t = Texture(type, system, video); + t = new GSTexture7(type, system, video); break; case GSTexture::Offscreen: desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; if(FAILED(hr = m_dd->CreateSurface(&desc, &system, NULL))) return false; - t = Texture(type, system); + t = new GSTexture7(type, system); break; } - return !!t; + return t; } -void GSDevice7::DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, bool slbg, bool mmod, GSVector4& c) +void GSDevice7::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c) { HRESULT hr; - hr = dt->Blt(NULL, st[0], NULL, DDBLT_WAIT, NULL); + hr = (*(GSTexture7*)dt)->Blt(NULL, *(GSTexture7*)st[0], NULL, DDBLT_WAIT, NULL); } -void GSDevice7::DoInterlace(Texture& st, Texture& dt, int shader, bool linear, float yoffset) +void GSDevice7::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset) { } diff --git a/plugins/GSdx/GSDevice7.h b/plugins/GSdx/GSDevice7.h index 94823dbf88..3e6f4c37af 100644 --- a/plugins/GSdx/GSDevice7.h +++ b/plugins/GSdx/GSDevice7.h @@ -24,35 +24,23 @@ #include "GSDevice.h" #include "GSTexture7.h" -class GSDevice7 : public GSDevice +class GSDevice7 : public GSDevice { -public: - typedef GSTexture7 Texture; - private: CComPtr m_dd; CComPtr m_primary; - CComPtr m_backbuffer; - bool Create(int type, Texture& t, int w, int h, int format); - void DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, bool slbg, bool mmod, GSVector4& c); - void DoInterlace(Texture& st, Texture& dt, int shader, bool linear, float yoffset = 0); + GSTexture* Create(int type, int w, int h, int format); + + void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c); + void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0); public: GSDevice7(); virtual ~GSDevice7(); - bool Create(HWND hWnd, bool vsync); + bool Create(GSWnd* wnd, bool vsync); bool Reset(int w, int h, bool fs); - bool IsLost() {return false;} - void Present(const CRect& r); - void BeginScene() {} - void EndScene() {} - void Draw(LPCTSTR str) {} - bool CopyOffscreen(Texture& src, const GSVector4& sr, Texture& dst, int w, int h, int format = 0) {return false;} - void ClearRenderTarget(Texture& t, const GSVector4& c) {} - void ClearRenderTarget(Texture& t, DWORD c) {} - void ClearDepth(Texture& t, float c) {} - void ClearStencil(Texture& t, BYTE c) {} + void Present(const GSVector4i& r, int shader); }; diff --git a/plugins/GSdx/GSDevice9.cpp b/plugins/GSdx/GSDevice9.cpp index 03984fc848..37ef14415c 100644 --- a/plugins/GSdx/GSDevice9.cpp +++ b/plugins/GSdx/GSDevice9.cpp @@ -20,13 +20,12 @@ */ #include "stdafx.h" +#include "GSdx.h" #include "GSDevice9.h" #include "resource.h" GSDevice9::GSDevice9() : m_vb(NULL) - , m_vb_count(0) - , m_vb_vertices(NULL) , m_vb_stride(0) , m_layout(NULL) , m_topology((D3DPRIMITIVETYPE)0) @@ -39,7 +38,6 @@ GSDevice9::GSDevice9() , m_ps_ss(NULL) , m_scissor(0, 0, 0, 0) , m_dss(NULL) - , m_sref(0) , m_bs(NULL) , m_bf(0xffffffff) , m_rtv(NULL) @@ -49,6 +47,11 @@ GSDevice9::GSDevice9() memset(&m_ddcaps, 0, sizeof(m_ddcaps)); memset(&m_d3dcaps, 0, sizeof(m_d3dcaps)); memset(m_ps_srvs, 0, sizeof(m_ps_srvs)); + + m_vertices.stride = 0; + m_vertices.start = 0; + m_vertices.count = 0; + m_vertices.limit = 0; } GSDevice9::~GSDevice9() @@ -57,9 +60,9 @@ GSDevice9::~GSDevice9() if(m_ps_cb) _aligned_free(m_ps_cb); } -bool GSDevice9::Create(HWND hWnd, bool vsync) +bool GSDevice9::Create(GSWnd* wnd, bool vsync) { - if(!__super::Create(hWnd, vsync)) + if(!__super::Create(wnd, vsync)) { return false; } @@ -102,7 +105,7 @@ bool GSDevice9::Create(HWND hWnd, bool vsync) m_d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &m_d3dcaps); - bool fs = AfxGetApp()->GetProfileInt(_T("Settings"), _T("ModeWidth"), 0) > 0; + bool fs = theApp.GetConfig("ModeWidth", 0) > 0; if(!Reset(1, 1, fs)) return false; @@ -110,24 +113,17 @@ bool GSDevice9::Create(HWND hWnd, bool vsync) // shaders - DWORD psver = AfxGetApp()->GetProfileInt(_T("Settings"), _T("PixelShaderVersion2"), D3DPS_VERSION(2, 0)); - - if(psver > m_d3dcaps.PixelShaderVersion) + if(m_d3dcaps.PixelShaderVersion < D3DPS_VERSION(2, 0)) { - CString str; + string s = format( + "Supported pixel shader version is too low!\n\nSupported: %d.%d\nNeeded: 2.0 or higher", + D3DSHADER_VERSION_MAJOR(m_d3dcaps.PixelShaderVersion), D3DSHADER_VERSION_MINOR(m_d3dcaps.PixelShaderVersion)); - str.Format(_T("Supported pixel shader version is too low!\n\nSupported: %d.%d\nSelected: %d.%d"), - D3DSHADER_VERSION_MAJOR(m_d3dcaps.PixelShaderVersion), D3DSHADER_VERSION_MINOR(m_d3dcaps.PixelShaderVersion), - D3DSHADER_VERSION_MAJOR(psver), D3DSHADER_VERSION_MINOR(psver)); - - AfxMessageBox(str); + MessageBox(NULL, s.c_str(), "GSdx", MB_OK); return false; } - m_d3dcaps.PixelShaderVersion = min(psver, m_d3dcaps.PixelShaderVersion); - m_d3dcaps.VertexShaderVersion = m_d3dcaps.PixelShaderVersion & ~0x10000; - // convert static const D3DVERTEXELEMENT9 il_convert[] = @@ -137,13 +133,11 @@ bool GSDevice9::Create(HWND hWnd, bool vsync) D3DDECL_END() }; - CompileShader(IDR_CONVERT9_FX, "vs_main", NULL, &m_convert.vs, il_convert, countof(il_convert), &m_convert.il); + CompileShader(IDR_CONVERT_FX, "vs_main", NULL, &m_convert.vs, il_convert, countof(il_convert), &m_convert.il); for(int i = 0; i < countof(m_convert.ps); i++) { - CStringA main; - main.Format("ps_main%d", i); - CompileShader(IDR_CONVERT9_FX, main, NULL, &m_convert.ps[i]); + CompileShader(IDR_CONVERT_FX, format("ps_main%d", i), NULL, &m_convert.ps[i]); } m_convert.dss.DepthEnable = false; @@ -170,9 +164,7 @@ bool GSDevice9::Create(HWND hWnd, bool vsync) for(int i = 0; i < countof(m_merge.ps); i++) { - CStringA main; - main.Format("ps_main%d", i); - CompileShader(IDR_MERGE9_FX, main, NULL, &m_merge.ps[i]); + CompileShader(IDR_MERGE_FX, format("ps_main%d", i), NULL, &m_merge.ps[i]); } m_merge.bs.BlendEnable = true; @@ -188,9 +180,7 @@ bool GSDevice9::Create(HWND hWnd, bool vsync) for(int i = 0; i < countof(m_interlace.ps); i++) { - CStringA main; - main.Format("ps_main%d", i); - CompileShader(IDR_INTERLACE9_FX, main, NULL, &m_interlace.ps[i]); + CompileShader(IDR_INTERLACE_FX, format("ps_main%d", i), NULL, &m_interlace.ps[i]); } // @@ -220,16 +210,13 @@ bool GSDevice9::Reset(int w, int h, bool fs) CComPtr backbuffer; hr = m_swapchain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); - m_backbuffer = Texture(backbuffer); + m_backbuffer = new GSTexture9(backbuffer); return true; } m_swapchain = NULL; - m_backbuffer = Texture(); - if(m_font) m_font->OnLostDevice(); - m_font = NULL; - + if(m_vs_cb) _aligned_free(m_vs_cb); if(m_ps_cb) _aligned_free(m_ps_cb); @@ -243,9 +230,8 @@ bool GSDevice9::Reset(int w, int h, bool fs) m_ps_cb = NULL; m_ps_cb_len = 0; m_ps_ss = NULL; - m_scissor = CRect(0, 0, 0, 0); + m_scissor = GSVector4i::zero(); m_dss = NULL; - m_sref = 0; m_bs = NULL; m_bf = 0xffffffff; m_rtv = NULL; @@ -254,7 +240,7 @@ bool GSDevice9::Reset(int w, int h, bool fs) memset(&m_pp, 0, sizeof(m_pp)); m_pp.Windowed = TRUE; - m_pp.hDeviceWindow = m_hWnd; + m_pp.hDeviceWindow = (HWND)m_wnd->GetHandle(); m_pp.SwapEffect = D3DSWAPEFFECT_FLIP; m_pp.BackBufferFormat = D3DFMT_X8R8G8B8; m_pp.BackBufferWidth = 1; @@ -268,9 +254,9 @@ bool GSDevice9::Reset(int w, int h, bool fs) // m_pp.Flags |= D3DPRESENTFLAG_VIDEO; // enables tv-out (but I don't think anyone would still use a regular tv...) - int mw = AfxGetApp()->GetProfileInt(_T("Settings"), _T("ModeWidth"), 0); - int mh = AfxGetApp()->GetProfileInt(_T("Settings"), _T("ModeHeight"), 0); - int mrr = AfxGetApp()->GetProfileInt(_T("Settings"), _T("ModeRefreshRate"), 0); + int mw = theApp.GetConfig("ModeWidth", 0); + int mh = theApp.GetConfig("ModeHeight", 0); + int mrr = theApp.GetConfig("ModeRefreshRate", 0); if(fs && mw > 0 && mh > 0 && mrr >= 0) { @@ -279,16 +265,14 @@ bool GSDevice9::Reset(int w, int h, bool fs) m_pp.BackBufferHeight = mh; // m_pp.FullScreen_RefreshRateInHz = mrr; - ::SetWindowLong(m_hWnd, GWL_STYLE, ::GetWindowLong(m_hWnd, GWL_STYLE) & ~(WS_CAPTION|WS_THICKFRAME)); - ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); - ::SetMenu(m_hWnd, NULL); + m_wnd->HideFrame(); } if(!m_dev) { - UINT flags = D3DCREATE_MULTITHREADED | (m_d3dcaps.VertexProcessingCaps ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING); + uint32 flags = D3DCREATE_MULTITHREADED | (m_d3dcaps.VertexProcessingCaps ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING); - hr = m_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, flags, &m_pp, &m_dev); + hr = m_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, (HWND)m_wnd->GetHandle(), flags, &m_pp, &m_dev); if(FAILED(hr)) return false; } @@ -330,13 +314,7 @@ bool GSDevice9::Reset(int w, int h, bool fs) hr = m_dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); } - m_backbuffer = Texture(backbuffer); - - D3DXFONT_DESC fd; - memset(&fd, 0, sizeof(fd)); - _tcscpy(fd.FaceName, _T("Arial")); - fd.Height = 20; - D3DXCreateFontIndirect(m_dev, &fd, &m_font); + m_backbuffer = new GSTexture9(backbuffer); m_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); m_dev->SetRenderState(D3DRS_LIGHTING, FALSE); @@ -353,25 +331,9 @@ bool GSDevice9::IsLost() return hr == D3DERR_DEVICELOST || hr == D3DERR_DEVICENOTRESET; } -void GSDevice9::Present(const CRect& r) +void GSDevice9::Flip() { - CRect cr; - - GetClientRect(m_hWnd, &cr); - - if(m_backbuffer.GetWidth() != cr.Width() || m_backbuffer.GetHeight() != cr.Height()) - { - Reset(cr.Width(), cr.Height(), false); - } - - OMSetRenderTargets(m_backbuffer, NULL); - - m_dev->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0); - - if(m_current) - { - StretchRect(m_current, m_backbuffer, GSVector4(r)); - } + m_dev->EndScene(); if(m_swapchain) { @@ -381,109 +343,107 @@ void GSDevice9::Present(const CRect& r) { m_dev->Present(NULL, NULL, NULL, NULL); } + + m_dev->BeginScene(); } void GSDevice9::BeginScene() { - m_dev->BeginScene(); + // m_dev->BeginScene(); +} + +void GSDevice9::DrawPrimitive() +{ + int prims = 0; + + switch(m_topology) + { + case D3DPT_TRIANGLELIST: + prims = m_vertices.count / 3; + break; + case D3DPT_LINELIST: + prims = m_vertices.count / 2; + break; + case D3DPT_POINTLIST: + prims = m_vertices.count; + break; + case D3DPT_TRIANGLESTRIP: + case D3DPT_TRIANGLEFAN: + prims = m_vertices.count - 2; + break; + case D3DPT_LINESTRIP: + prims = m_vertices.count - 1; + break; + } + + m_dev->DrawPrimitive(m_topology, m_vertices.start, prims); } void GSDevice9::EndScene() { - m_dev->EndScene(); + // m_dev->EndScene(); + + m_vertices.start += m_vertices.count; + m_vertices.count = 0; } -void GSDevice9::Draw(LPCTSTR str) +void GSDevice9::ClearRenderTarget(GSTexture* t, const GSVector4& c) { - /* - if(!m_pp.Windowed) - { - BeginScene(); - - OMSetRenderTargets(m_backbuffer, NULL); - - CRect r(0, 0, m_backbuffer.GetWidth(), m_backbuffer.GetHeight()); - - D3DCOLOR c = D3DCOLOR_ARGB(255, 0, 255, 0); - - if(m_font->DrawText(NULL, str, -1, &r, DT_CALCRECT|DT_LEFT|DT_WORDBREAK, c)) - { - m_font->DrawText(NULL, str, -1, &r, DT_LEFT|DT_WORDBREAK, c); - } - - EndScene(); - } - */ + ClearRenderTarget(t, (c * 255 + 0.5f).zyxw().rgba32()); } -bool GSDevice9::CopyOffscreen(Texture& src, const GSVector4& sr, Texture& dst, int w, int h, int format) -{ - dst = Texture(); - - if(format == 0) - { - format = D3DFMT_A8R8G8B8; - } - - if(format != D3DFMT_A8R8G8B8) - { - ASSERT(0); - - return false; - } - - Texture rt; - - if(CreateRenderTarget(rt, w, h, format)) - { - GSVector4 dr(0, 0, w, h); - - StretchRect(src, sr, rt, dr, m_convert.ps[1], NULL, 0); - - if(CreateOffscreen(dst, w, h, format)) - { - m_dev->GetRenderTargetData(rt, dst); - } - } - - Recycle(rt); - - return !!dst; -} - -void GSDevice9::ClearRenderTarget(Texture& t, const GSVector4& c) -{ - ClearRenderTarget(t, D3DCOLOR_RGBA((BYTE)(c.r * 255 + 0.5f), (BYTE)(c.g * 255 + 0.5f), (BYTE)(c.b * 255 + 0.5f), (BYTE)(c.a * 255 + 0.5f))); -} - -void GSDevice9::ClearRenderTarget(Texture& t, DWORD c) +void GSDevice9::ClearRenderTarget(GSTexture* rt, uint32 c) { CComPtr surface; m_dev->GetRenderTarget(0, &surface); - m_dev->SetRenderTarget(0, t); + m_dev->SetRenderTarget(0, *(GSTexture9*)rt); m_dev->Clear(0, NULL, D3DCLEAR_TARGET, c, 0, 0); m_dev->SetRenderTarget(0, surface); } -void GSDevice9::ClearDepth(Texture& t, float c) +void GSDevice9::ClearDepth(GSTexture* t, float c) { - CComPtr surface; - m_dev->GetDepthStencilSurface(&surface); - m_dev->SetDepthStencilSurface(t); + GSTexture* rt = CreateRenderTarget(t->GetWidth(), t->GetHeight()); + + CComPtr rtsurface; + CComPtr dssurface; + + m_dev->GetRenderTarget(0, &rtsurface); + m_dev->GetDepthStencilSurface(&dssurface); + + m_dev->SetRenderTarget(0, *(GSTexture9*)rt); + m_dev->SetDepthStencilSurface(*(GSTexture9*)t); + m_dev->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, c, 0); - m_dev->SetDepthStencilSurface(surface); + + m_dev->SetRenderTarget(0, rtsurface); + m_dev->SetDepthStencilSurface(dssurface); + + Recycle(rt); } -void GSDevice9::ClearStencil(Texture& t, BYTE c) +void GSDevice9::ClearStencil(GSTexture* t, uint8 c) { - CComPtr surface; - m_dev->GetDepthStencilSurface(&surface); - m_dev->SetDepthStencilSurface(t); + GSTexture* rt = CreateRenderTarget(t->GetWidth(), t->GetHeight()); + + CComPtr rtsurface; + CComPtr dssurface; + + m_dev->GetRenderTarget(0, &rtsurface); + m_dev->GetDepthStencilSurface(&dssurface); + + m_dev->SetRenderTarget(0, *(GSTexture9*)rt); + m_dev->SetDepthStencilSurface(*(GSTexture9*)t); + m_dev->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 0, c); - m_dev->SetDepthStencilSurface(surface); + + m_dev->SetRenderTarget(0, rtsurface); + m_dev->SetDepthStencilSurface(dssurface); + + Recycle(rt); } -bool GSDevice9::Create(int type, Texture& t, int w, int h, int format) +GSTexture* GSDevice9::Create(int type, int w, int h, int format) { HRESULT hr; @@ -506,14 +466,16 @@ bool GSDevice9::Create(int type, Texture& t, int w, int h, int format) break; } + GSTexture9* t = NULL; + if(surface) { - t = Texture(surface); + t = new GSTexture9(surface); } if(texture) { - t = Texture(texture); + t = new GSTexture9(texture); } if(t) @@ -527,34 +489,138 @@ bool GSDevice9::Create(int type, Texture& t, int w, int h, int format) ClearDepth(t, 0); break; } - - return t; } - return false; + return t; } -bool GSDevice9::CreateRenderTarget(Texture& t, int w, int h, int format) +GSTexture* GSDevice9::CreateRenderTarget(int w, int h, int format) { - return __super::CreateRenderTarget(t, w, h, format ? format : D3DFMT_A8R8G8B8); + return __super::CreateRenderTarget(w, h, format ? format : D3DFMT_A8R8G8B8); } -bool GSDevice9::CreateDepthStencil(Texture& t, int w, int h, int format) +GSTexture* GSDevice9::CreateDepthStencil(int w, int h, int format) { - return __super::CreateDepthStencil(t, w, h, format ? format : D3DFMT_D24S8); + return __super::CreateDepthStencil(w, h, format ? format : D3DFMT_D24S8); + // return __super::CreateDepthStencil(w, h, format ? format : D3DFMT_D32F_LOCKABLE); } -bool GSDevice9::CreateTexture(Texture& t, int w, int h, int format) +GSTexture* GSDevice9::CreateTexture(int w, int h, int format) { - return __super::CreateTexture(t, w, h, format ? format : D3DFMT_A8R8G8B8); + return __super::CreateTexture(w, h, format ? format : D3DFMT_A8R8G8B8); } -bool GSDevice9::CreateOffscreen(Texture& t, int w, int h, int format) +GSTexture* GSDevice9::CreateOffscreen(int w, int h, int format) { - return __super::CreateOffscreen(t, w, h, format ? format : D3DFMT_A8R8G8B8); + return __super::CreateOffscreen(w, h, format ? format : D3DFMT_A8R8G8B8); } -void GSDevice9::DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, bool slbg, bool mmod, GSVector4& c) +GSTexture* GSDevice9::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format) +{ + GSTexture* dst = NULL; + + if(format == 0) + { + format = D3DFMT_A8R8G8B8; + } + + if(format != D3DFMT_A8R8G8B8) + { + ASSERT(0); + + return false; + } + + if(GSTexture* rt = CreateRenderTarget(w, h, format)) + { + GSVector4 dr(0, 0, w, h); + + StretchRect(src, sr, rt, dr, m_convert.ps[1], NULL, 0); + + dst = CreateOffscreen(w, h, format); + + if(dst) + { + m_dev->GetRenderTargetData(*(GSTexture9*)rt, *(GSTexture9*)dst); + } + + Recycle(rt); + } + + return dst; +} + +void GSDevice9::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear) +{ + StretchRect(st, sr, dt, dr, m_convert.ps[shader], NULL, 0, linear); +} + +void GSDevice9::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, bool linear) +{ + StretchRect(st, sr, dt, dr, ps, ps_cb, ps_cb_len, &m_convert.bs, linear); +} + +void GSDevice9::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, Direct3DBlendState9* bs, bool linear) +{ + BeginScene(); + + GSVector2i ds = dt->GetSize(); + + // om + + OMSetDepthStencilState(&m_convert.dss); + OMSetBlendState(bs, 0); + OMSetRenderTargets(dt, NULL); + + // ia + + float left = dr.x * 2 / ds.x - 1.0f; + float top = 1.0f - dr.y * 2 / ds.y; + float right = dr.z * 2 / ds.x - 1.0f; + float bottom = 1.0f - dr.w * 2 / ds.y; + + GSVertexPT1 vertices[] = + { + {GSVector4(left, top, 0.5f, 1.0f), GSVector2(sr.x, sr.y)}, + {GSVector4(right, top, 0.5f, 1.0f), GSVector2(sr.z, sr.y)}, + {GSVector4(left, bottom, 0.5f, 1.0f), GSVector2(sr.x, sr.w)}, + {GSVector4(right, bottom, 0.5f, 1.0f), GSVector2(sr.z, sr.w)}, + }; + + for(int i = 0; i < countof(vertices); i++) + { + vertices[i].p.x -= 1.0f / ds.x; + vertices[i].p.y += 1.0f / ds.y; + } + + IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); + IASetInputLayout(m_convert.il); + IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP); + + // vs + + VSSetShader(m_convert.vs, NULL, 0); + + // ps + + PSSetShader(ps, ps_cb, ps_cb_len); + PSSetSamplerState(linear ? &m_convert.ln : &m_convert.pt); + PSSetShaderResources(st, NULL); + + // rs + + RSSet(ds.x, ds.y); + + // + + DrawPrimitive(); + + // + + EndScene(); +} + +void GSDevice9::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c) { ClearRenderTarget(dt, c); @@ -573,30 +639,69 @@ void GSDevice9::DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, } } -void GSDevice9::DoInterlace(Texture& st, Texture& dt, int shader, bool linear, float yoffset) +void GSDevice9::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset) { + GSVector4 s = GSVector4(dt->GetSize()); + GSVector4 sr(0, 0, 1, 1); - GSVector4 dr(0.0f, yoffset, (float)dt.GetWidth(), (float)dt.GetHeight() + yoffset); + GSVector4 dr(0.0f, yoffset, s.x, s.y + yoffset); InterlaceConstantBuffer cb; - cb.ZrH = GSVector2(0, 1.0f / dt.GetHeight()); - cb.hH = (float)dt.GetHeight() / 2; + cb.ZrH = GSVector2(0, 1.0f / s.y); + cb.hH = (float)s.y / 2; StretchRect(st, sr, dt, dr, m_interlace.ps[shader], (const float*)&cb, 1, linear); } -/* -void GSDevice9::IASetVertexBuffer(IDirect3DVertexBuffer9* vb, UINT count, const void* vertices, UINT stride) + +void GSDevice9::IASetVertexBuffer(const void* vertices, size_t stride, size_t count) { - void* data = NULL; + ASSERT(m_vertices.count == 0); - if(SUCCEEDED(vb->Lock(0, count * stride, &data, D3DLOCK_DISCARD))) + if(count * stride > m_vertices.limit * m_vertices.stride) { - memcpy(data, vertices, count * stride); - - vb->Unlock(); + m_vertices.vb_old = m_vertices.vb; + m_vertices.vb = NULL; + m_vertices.start = 0; + m_vertices.count = 0; + m_vertices.limit = max(count * 3 / 2, 10000); } + if(m_vertices.vb == NULL) + { + HRESULT hr; + + hr = m_dev->CreateVertexBuffer(m_vertices.limit * stride, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertices.vb, NULL); + + if(FAILED(hr)) return; + } + + uint32 flags = D3DLOCK_NOOVERWRITE; + + if(m_vertices.start + count > m_vertices.limit || stride != m_vertices.stride) + { + m_vertices.start = 0; + + flags = D3DLOCK_DISCARD; + } + + void* v = NULL; + + if(SUCCEEDED(m_vertices.vb->Lock(m_vertices.start * stride, count * stride, &v, flags))) + { + GSVector4i::storent(v, vertices, count * stride); + + m_vertices.vb->Unlock(); + } + + m_vertices.count = count; + m_vertices.stride = stride; + + IASetVertexBuffer(m_vertices.vb, stride); +} + +void GSDevice9::IASetVertexBuffer(IDirect3DVertexBuffer9* vb, size_t stride) +{ if(m_vb != vb || m_vb_stride != stride) { m_dev->SetStreamSource(0, vb, 0, stride); @@ -605,23 +710,14 @@ void GSDevice9::IASetVertexBuffer(IDirect3DVertexBuffer9* vb, UINT count, const m_vb_stride = stride; } } -*/ -void GSDevice9::IASetVertexBuffer(UINT count, const void* vertices, UINT stride) -{ - m_vb_count = count; - m_vb_vertices = vertices; - m_vb_stride = stride; -} void GSDevice9::IASetInputLayout(IDirect3DVertexDeclaration9* layout) { - // TODO: get rid of all SetFVF before enabling this - - // if(m_layout != layout) + if(m_layout != layout) { m_dev->SetVertexDeclaration(layout); - // m_layout = layout; + m_layout = layout; } } @@ -661,8 +757,14 @@ void GSDevice9::VSSetShader(IDirect3DVertexShader9* vs, const float* vs_cb, int } } -void GSDevice9::PSSetShaderResources(IDirect3DTexture9* srv0, IDirect3DTexture9* srv1) +void GSDevice9::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1) { + IDirect3DTexture9* srv0 = NULL; + IDirect3DTexture9* srv1 = NULL; + + if(sr0) srv0 = *(GSTexture9*)sr0; + if(sr1) srv1 = *(GSTexture9*)sr1; + if(m_ps_srvs[0] != srv0) { m_dev->SetTexture(0, srv0); @@ -713,6 +815,7 @@ void GSDevice9::PSSetSamplerState(Direct3DSamplerState9* ss) { if(ss && m_ps_ss != ss) { + m_dev->SetSamplerState(0, D3DSAMP_ADDRESSU, ss->AddressU); m_dev->SetSamplerState(0, D3DSAMP_ADDRESSV, ss->AddressV); m_dev->SetSamplerState(1, D3DSAMP_ADDRESSU, ss->AddressU); @@ -734,21 +837,21 @@ void GSDevice9::PSSetSamplerState(Direct3DSamplerState9* ss) } } -void GSDevice9::RSSet(int width, int height, const RECT* scissor) +void GSDevice9::RSSet(int width, int height, const GSVector4i* scissor) { - CRect r = scissor ? *scissor : CRect(0, 0, width, height); + GSVector4i r = scissor ? *scissor : GSVector4i(0, 0, width, height); - if(m_scissor != r) + if(!m_scissor.eq(r)) { - m_dev->SetScissorRect(&r); + m_dev->SetScissorRect(r); m_scissor = r; } } -void GSDevice9::OMSetDepthStencilState(Direct3DDepthStencilState9* dss, UINT sref) +void GSDevice9::OMSetDepthStencilState(Direct3DDepthStencilState9* dss) { - if(m_dss != dss || m_sref != sref) + if(m_dss != dss) { m_dev->SetRenderState(D3DRS_ZENABLE, dss->DepthEnable); m_dev->SetRenderState(D3DRS_ZWRITEENABLE, dss->DepthWriteMask); @@ -768,15 +871,14 @@ void GSDevice9::OMSetDepthStencilState(Direct3DDepthStencilState9* dss, UINT sre m_dev->SetRenderState(D3DRS_STENCILPASS, dss->StencilPassOp); m_dev->SetRenderState(D3DRS_STENCILFAIL, dss->StencilFailOp); m_dev->SetRenderState(D3DRS_STENCILZFAIL, dss->StencilDepthFailOp); - m_dev->SetRenderState(D3DRS_STENCILREF, sref); + m_dev->SetRenderState(D3DRS_STENCILREF, dss->StencilRef); } m_dss = dss; - m_sref = sref; } } -void GSDevice9::OMSetBlendState(Direct3DBlendState9* bs, DWORD bf) +void GSDevice9::OMSetBlendState(Direct3DBlendState9* bs, uint32 bf) { if(m_bs != bs || m_bf != bf) { @@ -801,8 +903,14 @@ void GSDevice9::OMSetBlendState(Direct3DBlendState9* bs, DWORD bf) } } -void GSDevice9::OMSetRenderTargets(IDirect3DSurface9* rtv, IDirect3DSurface9* dsv) +void GSDevice9::OMSetRenderTargets(GSTexture* rt, GSTexture* ds) { + IDirect3DSurface9* rtv = NULL; + IDirect3DSurface9* dsv = NULL; + + if(rt) rtv = *(GSTexture9*)rt; + if(ds) dsv = *(GSTexture9*)ds; + if(m_rtv != rtv) { m_dev->SetRenderTarget(0, rtv); @@ -818,121 +926,21 @@ void GSDevice9::OMSetRenderTargets(IDirect3DSurface9* rtv, IDirect3DSurface9* ds } } -void GSDevice9::DrawPrimitive() -{ - int prims = 0; - - switch(m_topology) - { - case D3DPT_TRIANGLELIST: - prims = m_vb_count / 3; - break; - case D3DPT_LINELIST: - prims = m_vb_count / 2; - break; - case D3DPT_POINTLIST: - prims = m_vb_count; - break; - case D3DPT_TRIANGLESTRIP: - case D3DPT_TRIANGLEFAN: - prims = m_vb_count - 2; - break; - case D3DPT_LINESTRIP: - prims = m_vb_count - 1; - break; - } - - m_dev->DrawPrimitiveUP(m_topology, prims, m_vb_vertices, m_vb_stride); -} - -void GSDevice9::StretchRect(Texture& st, Texture& dt, const GSVector4& dr, bool linear) -{ - StretchRect(st, GSVector4(0, 0, 1, 1), dt, dr, linear); -} - -void GSDevice9::StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, bool linear) -{ - StretchRect(st, sr, dt, dr, m_convert.ps[0], NULL, 0, linear); -} - -void GSDevice9::StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, bool linear) -{ - StretchRect(st, sr, dt, dr, ps, ps_cb, ps_cb_len, &m_convert.bs, linear); -} - -void GSDevice9::StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, Direct3DBlendState9* bs, bool linear) -{ - BeginScene(); - - // om - - OMSetDepthStencilState(&m_convert.dss, 0); - OMSetBlendState(bs, 0); - OMSetRenderTargets(dt, NULL); - - // ia - - float left = dr.x * 2 / dt.GetWidth() - 1.0f; - float top = 1.0f - dr.y * 2 / dt.GetHeight(); - float right = dr.z * 2 / dt.GetWidth() - 1.0f; - float bottom = 1.0f - dr.w * 2 / dt.GetHeight(); - - GSVertexPT1 vertices[] = - { - {GSVector4(left, top, 0.5f, 1.0f), GSVector2(sr.x, sr.y)}, - {GSVector4(right, top, 0.5f, 1.0f), GSVector2(sr.z, sr.y)}, - {GSVector4(left, bottom, 0.5f, 1.0f), GSVector2(sr.x, sr.w)}, - {GSVector4(right, bottom, 0.5f, 1.0f), GSVector2(sr.z, sr.w)}, - }; - - for(int i = 0; i < countof(vertices); i++) - { - vertices[i].p.x -= 1.0f / dt.GetWidth(); - vertices[i].p.y += 1.0f / dt.GetHeight(); - } - - IASetVertexBuffer(4, vertices); - IASetInputLayout(m_convert.il); - IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP); - - // vs - - VSSetShader(m_convert.vs, NULL, 0); - - // ps - - PSSetShader(ps, ps_cb, ps_cb_len); - PSSetSamplerState(linear ? &m_convert.ln : &m_convert.pt); - PSSetShaderResources(st, NULL); - - // rs - - RSSet(dt.GetWidth(), dt.GetHeight()); - - // - - DrawPrimitive(); - - // - - EndScene(); -} - // FIXME: D3DXCompileShaderFromResource of d3dx9 v37 (march 2008) calls GetFullPathName on id for some reason and then crashes -static HRESULT LoadShader(UINT id, LPCSTR& data, DWORD& size) +static HRESULT LoadShader(uint32 id, LPCSTR& data, uint32& size) { CComPtr shader, error; - HRSRC hRes = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(id), RT_RCDATA); + HRSRC hRes = FindResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), RT_RCDATA); if(!hRes) return E_FAIL; - size = SizeofResource(AfxGetResourceHandle(), hRes); + size = SizeofResource(theApp.GetModuleHandle(), hRes); if(size == 0) return E_FAIL; - HGLOBAL hResData = LoadResource(AfxGetResourceHandle(), hRes); + HGLOBAL hResData = LoadResource(theApp.GetModuleHandle(), hRes); if(!hResData) return E_FAIL; @@ -941,37 +949,44 @@ static HRESULT LoadShader(UINT id, LPCSTR& data, DWORD& size) return S_OK; } -HRESULT GSDevice9::CompileShader(UINT id, LPCSTR entry, const D3DXMACRO* macro, IDirect3DVertexShader9** vs, const D3DVERTEXELEMENT9* layout, int count, IDirect3DVertexDeclaration9** il) +HRESULT GSDevice9::CompileShader(uint32 id, const string& entry, const D3DXMACRO* macro, IDirect3DVertexShader9** vs, const D3DVERTEXELEMENT9* layout, int count, IDirect3DVertexDeclaration9** il) { - LPCSTR target; + const char* target; + const char* model; if(m_d3dcaps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) { target = "vs_3_0"; + model = "0x300"; } else if(m_d3dcaps.VertexShaderVersion >= D3DVS_VERSION(2, 0)) { target = "vs_2_0"; + model = "0x200"; } else { return E_FAIL; } + vector m; + + PrepareShaderMacro(m, macro, model); + HRESULT hr; CComPtr shader, error; - // FIXME: hr = D3DXCompileShaderFromResource(AfxGetResourceHandle(), MAKEINTRESOURCE(id), macro, NULL, entry, target, 0, &shader, &error, NULL); + // FIXME: hr = D3DXCompileShaderFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), &m[0], NULL, entry.c_str(), target, 0, &shader, &error, NULL); LPCSTR data; - DWORD size; + uint32 size; hr = LoadShader(id, data, size); if(FAILED(hr)) return E_FAIL; - hr = D3DXCompileShader(data, size, macro, NULL, entry, target, 0, &shader, &error, NULL); + hr = D3DXCompileShader(data, size, &m[0], NULL, entry.c_str(), target, 0, &shader, &error, NULL); if(SUCCEEDED(hr)) { @@ -979,9 +994,7 @@ HRESULT GSDevice9::CompileShader(UINT id, LPCSTR entry, const D3DXMACRO* macro, } else if(error) { - LPCSTR msg = (LPCSTR)error->GetBufferPointer(); - - TRACE(_T("%s\n"), CString(msg)); + printf("%s\n", (const char*)error->GetBufferPointer()); } ASSERT(SUCCEEDED(hr)); @@ -1001,51 +1014,54 @@ HRESULT GSDevice9::CompileShader(UINT id, LPCSTR entry, const D3DXMACRO* macro, return S_OK; } -HRESULT GSDevice9::CompileShader(UINT id, LPCSTR entry, const D3DXMACRO* macro, IDirect3DPixelShader9** ps) +HRESULT GSDevice9::CompileShader(uint32 id, const string& entry, const D3DXMACRO* macro, IDirect3DPixelShader9** ps) { - LPCSTR target = NULL; - UINT flags = 0; + const char* target = NULL; + const char* model; + uint32 flags = 0; if(m_d3dcaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) { target = "ps_3_0"; + model = "0x300"; flags |= D3DXSHADER_AVOID_FLOW_CONTROL; } else if(m_d3dcaps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) { target = "ps_2_0"; + model = "0x200"; } else { return false; } + vector m; + + PrepareShaderMacro(m, macro, model); + HRESULT hr; CComPtr shader, error; - // FIXME: hr = D3DXCompileShaderFromResource(AfxGetResourceHandle(), MAKEINTRESOURCE(id), macro, NULL, entry, target, flags, &shader, &error, NULL); + // FIXME: hr = D3DXCompileShaderFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), &m[0], NULL, entry.c_str(), target, flags, &shader, &error, NULL); LPCSTR data; - DWORD size; + uint32 size; hr = LoadShader(id, data, size); if(FAILED(hr)) return E_FAIL; - hr = D3DXCompileShader(data, size, macro, NULL, entry, target, 0, &shader, &error, NULL); + hr = D3DXCompileShader(data, size, &m[0], NULL, entry.c_str(), target, 0, &shader, &error, NULL); if(SUCCEEDED(hr)) { hr = m_dev->CreatePixelShader((DWORD*)shader->GetBufferPointer(), ps); - - ASSERT(SUCCEEDED(hr)); } else if(error) { - LPCSTR msg = (LPCSTR)error->GetBufferPointer(); - - TRACE(_T("%s\n"), CString(msg)); + printf("%s\n", (const char*)error->GetBufferPointer()); } ASSERT(SUCCEEDED(hr)); diff --git a/plugins/GSdx/GSDevice9.h b/plugins/GSdx/GSDevice9.h index 5a16aa0106..741c4c4296 100644 --- a/plugins/GSdx/GSDevice9.h +++ b/plugins/GSdx/GSDevice9.h @@ -44,6 +44,7 @@ struct Direct3DDepthStencilState9 D3DSTENCILOP StencilDepthFailOp; D3DSTENCILOP StencilPassOp; D3DCMPFUNC StencilFunc; + uint32 StencilRef; }; struct Direct3DBlendState9 @@ -58,18 +59,11 @@ struct Direct3DBlendState9 UINT8 RenderTargetWriteMask; }; -class GSDevice9 : public GSDevice +class GSDevice9 : public GSDevice { -public: - typedef GSTexture9 Texture; - private: - // state cache - IDirect3DVertexBuffer9* m_vb; - UINT m_vb_count; - const void* m_vb_vertices; - UINT m_vb_stride; + size_t m_vb_stride; IDirect3DVertexDeclaration9* m_layout; D3DPRIMITIVETYPE m_topology; IDirect3DVertexShader9* m_vs; @@ -80,19 +74,19 @@ private: float* m_ps_cb; int m_ps_cb_len; Direct3DSamplerState9* m_ps_ss; - CRect m_scissor; + GSVector4i m_scissor; Direct3DDepthStencilState9* m_dss; - UINT m_sref; Direct3DBlendState9* m_bs; - DWORD m_bf; + uint32 m_bf; IDirect3DSurface9* m_rtv; IDirect3DSurface9* m_dsv; // - bool Create(int type, Texture& t, int w, int h, int format); - void DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, bool slbg, bool mmod, GSVector4& c); - void DoInterlace(Texture& st, Texture& dt, int shader, bool linear, float yoffset = 0); + GSTexture* Create(int type, int w, int h, int format); + + void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c); + void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0); // @@ -101,17 +95,21 @@ private: CComPtr m_d3d; CComPtr m_dev; CComPtr m_swapchain; - Texture m_backbuffer; - -public: // TODO - D3DPRESENT_PARAMETERS m_pp; - CComPtr m_font; struct { - CComPtr vs; + CComPtr vb, vb_old; + size_t stride, start, count, limit; + } m_vertices; + +public: // TODO + D3DPRESENT_PARAMETERS m_pp; + + struct + { CComPtr il; - CComPtr ps[5]; + CComPtr vs; + CComPtr ps[7]; Direct3DSamplerState9 ln; Direct3DSamplerState9 pt; Direct3DDepthStencilState9 dss; @@ -133,60 +131,50 @@ public: GSDevice9(); virtual ~GSDevice9(); - bool Create(HWND hWnd, bool vsync); + bool Create(GSWnd* wnd, bool vsync); bool Reset(int w, int h, bool fs); + bool IsLost(); - void Present(const CRect& r); + void Flip(); + void BeginScene(); + void DrawPrimitive(); void EndScene(); - void Draw(LPCTSTR str); - bool CopyOffscreen(Texture& src, const GSVector4& sr, Texture& dst, int w, int h, int format = 0); - void ClearRenderTarget(Texture& t, const GSVector4& c); - void ClearRenderTarget(Texture& t, DWORD c); - void ClearDepth(Texture& t, float c); - void ClearStencil(Texture& t, BYTE c); + void ClearRenderTarget(GSTexture* t, const GSVector4& c); + void ClearRenderTarget(GSTexture* t, uint32 c); + void ClearDepth(GSTexture* t, float c); + void ClearStencil(GSTexture* t, uint8 c); - bool CreateRenderTarget(Texture& t, int w, int h, int format = 0); - bool CreateDepthStencil(Texture& t, int w, int h, int format = 0); - bool CreateTexture(Texture& t, int w, int h, int format = 0); - bool CreateOffscreen(Texture& t, int w, int h, int format = 0); + GSTexture* CreateRenderTarget(int w, int h, int format = 0); + GSTexture* CreateDepthStencil(int w, int h, int format = 0); + GSTexture* CreateTexture(int w, int h, int format = 0); + GSTexture* CreateOffscreen(int w, int h, int format = 0); + + GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0); + + virtual bool IsCurrentRGBA() {return false;} + + void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true); + void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, bool linear = true); + void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, Direct3DBlendState9* bs, bool linear = true); + + void IASetVertexBuffer(const void* vertices, size_t stride, size_t count); + void IASetVertexBuffer(IDirect3DVertexBuffer9* vb, size_t stride); + void IASetInputLayout(IDirect3DVertexDeclaration9* layout); + void IASetPrimitiveTopology(D3DPRIMITIVETYPE topology); + void VSSetShader(IDirect3DVertexShader9* vs, const float* vs_cb, int vs_cb_len); + void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1); + void PSSetShader(IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len); + void PSSetSamplerState(Direct3DSamplerState9* ss); + void RSSet(int width, int height, const GSVector4i* scissor = NULL); + void OMSetDepthStencilState(Direct3DDepthStencilState9* dss); + void OMSetBlendState(Direct3DBlendState9* bs, uint32 bf); + void OMSetRenderTargets(GSTexture* rt, GSTexture* ds); IDirect3DDevice9* operator->() {return m_dev;} operator IDirect3DDevice9*() {return m_dev;} - // TODO: void IASetVertexBuffer(IDirect3DVertexBuffer9* vb, UINT count, const void* vertices, UINT stride); - void IASetVertexBuffer(UINT count, const void* vertices, UINT stride); - void IASetInputLayout(IDirect3DVertexDeclaration9* layout); - void IASetPrimitiveTopology(D3DPRIMITIVETYPE topology); - void VSSetShader(IDirect3DVertexShader9* vs, const float* vs_cb, int vs_cb_len); - void PSSetShaderResources(IDirect3DTexture9* srv0, IDirect3DTexture9* srv1); - void PSSetShader(IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len); - void PSSetSamplerState(Direct3DSamplerState9* ss); - void RSSet(int width, int height, const RECT* scissor = NULL); - void OMSetDepthStencilState(Direct3DDepthStencilState9* dss, UINT sref); - void OMSetBlendState(Direct3DBlendState9* bs, DWORD bf); - void OMSetRenderTargets(IDirect3DSurface9* rtv, IDirect3DSurface9* dsv); - void DrawPrimitive(); - - template void IASetVertexBuffer(UINT count, T* vertices) - { - IASetVertexBuffer(count, vertices, sizeof(T)); - } - - void StretchRect(Texture& st, Texture& dt, const GSVector4& dr, bool linear = true); - void StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, bool linear = true); - void StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, bool linear = true); - void StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, Direct3DBlendState9* bs, bool linear = true); - - HRESULT CompileShader(UINT id, LPCSTR entry, const D3DXMACRO* macro, IDirect3DVertexShader9** vs, const D3DVERTEXELEMENT9* layout, int count, IDirect3DVertexDeclaration9** il); - HRESULT CompileShader(UINT id, LPCSTR entry, const D3DXMACRO* macro, IDirect3DPixelShader9** ps); - - virtual bool IsCurrentRGBA() - { - return false; - } - - // TODO - bool SaveToFileD24S8(IDirect3DSurface9* ds, LPCTSTR fn); + HRESULT CompileShader(uint32 id, const string& entry, const D3DXMACRO* macro, IDirect3DVertexShader9** vs, const D3DVERTEXELEMENT9* layout, int count, IDirect3DVertexDeclaration9** il); + HRESULT CompileShader(uint32 id, const string& entry, const D3DXMACRO* macro, IDirect3DPixelShader9** ps); }; diff --git a/plugins/GSdx/GSDeviceNull.cpp b/plugins/GSdx/GSDeviceNull.cpp index 4d8aa3b8b3..a2bca4dd4f 100644 --- a/plugins/GSdx/GSDeviceNull.cpp +++ b/plugins/GSdx/GSDeviceNull.cpp @@ -22,14 +22,14 @@ #include "stdafx.h" #include "GSDeviceNull.h" -bool GSDeviceNull::Create(HWND hWnd, bool vsync) +bool GSDeviceNull::Create(GSWnd* wnd, bool vsync) { - if(!__super::Create(hWnd, vsync)) + if(!__super::Create(wnd, vsync)) { return false; } - Reset(1, 1, true); + Reset(1, 1, false); return true; } @@ -42,9 +42,7 @@ bool GSDeviceNull::Reset(int w, int h, bool fs) return true; } -bool GSDeviceNull::Create(int type, Texture& t, int w, int h, int format) +GSTexture* GSDeviceNull::Create(int type, int w, int h, int format) { - t = Texture(type, w, h, format); - - return true; + return new GSTextureNull(type, w, h, format); } diff --git a/plugins/GSdx/GSDeviceNull.h b/plugins/GSdx/GSDeviceNull.h index e2782f1228..3ce1c43885 100644 --- a/plugins/GSdx/GSDeviceNull.h +++ b/plugins/GSdx/GSDeviceNull.h @@ -24,30 +24,17 @@ #include "GSDevice.h" #include "GSTextureNull.h" -class GSDeviceNull : public GSDevice +class GSDeviceNull : public GSDevice { -public: - typedef GSTextureNull Texture; - private: - bool Create(int type, Texture& t, int w, int h, int format); - void DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, bool slbg, bool mmod, GSVector4& c) {} - void DoInterlace(Texture& st, Texture& dt, int shader, bool linear, float yoffset = 0) {} + GSTexture* Create(int type, int w, int h, int format); + + void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c) {} + void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0) {} public: GSDeviceNull() {} - bool Create(HWND hWnd, bool vsync); + bool Create(GSWnd* wnd, bool vsync); bool Reset(int w, int h, bool fs); - bool IsLost() {return false;} - void Present(const CRect& r) {} - void BeginScene() {} - void EndScene() {} - void Draw(LPCTSTR str) {} - bool CopyOffscreen(Texture& src, const GSVector4& sr, Texture& dst, int w, int h, int format = 0) {return false;} - - void ClearRenderTarget(Texture& t, const GSVector4& c) {} - void ClearRenderTarget(Texture& t, DWORD c) {} - void ClearDepth(Texture& t, float c) {} - void ClearStencil(Texture& t, BYTE c) {} }; diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp new file mode 100644 index 0000000000..fd36ded466 --- /dev/null +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -0,0 +1,530 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSdx.h" +#include "GSDeviceOGL.h" +#include "resource.h" + +GSDeviceOGL::GSDeviceOGL() + : m_hDC(NULL) + , m_hGLRC(NULL) + , m_vbo(0) + , m_fbo(0) + , m_context(0) + , m_topology(-1) + , m_ps_ss(NULL) + , m_scissor(0, 0, 0, 0) + , m_viewport(0, 0) + , m_dss(NULL) + , m_bs(NULL) + , m_bf(-1) + , m_rt((GLuint)-1) + , m_ds((GLuint)-1) +{ + m_vertices.stride = 0; + m_vertices.start = 0; + m_vertices.count = 0; + m_vertices.limit = 0; +} + +GSDeviceOGL::~GSDeviceOGL() +{ + if(m_context) cgDestroyContext(m_context); + if(m_vbo) glDeleteBuffers(1, &m_vbo); + if(m_fbo) glDeleteFramebuffers(1, &m_fbo); + + #ifdef _WINDOWS + + if(m_hGLRC) {wglMakeCurrent(NULL, NULL); wglDeleteContext(m_hGLRC);} + if(m_hDC) ReleaseDC((HWND)m_wnd->GetHandle(), m_hDC); + + #endif +} + +void GSDeviceOGL::OnCgError(CGcontext ctx, CGerror err) +{ + printf("%s\n", cgGetErrorString(err)); + printf("%s\n", cgGetLastListing(ctx)); // ? +} + +bool GSDeviceOGL::Create(GSWnd* wnd, bool vsync) +{ + if(!__super::Create(wnd, vsync)) + { + return false; + } + + cgSetErrorHandler(OnStaticCgError, this); + + #ifdef _WINDOWS + + PIXELFORMATDESCRIPTOR pfd; + + memset(&pfd, 0, sizeof(pfd)); + + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + pfd.cDepthBits = 32; // 24? + pfd.cStencilBits = 8; + pfd.iLayerType = PFD_MAIN_PLANE; + + m_hDC = GetDC((HWND)m_wnd->GetHandle()); + + if(!m_hDC) return false; + + if(!SetPixelFormat(m_hDC, ChoosePixelFormat(m_hDC, &pfd), &pfd)) + { + return false; + } + + m_hGLRC = wglCreateContext(m_hDC); + + if(!m_hGLRC) return false; + + if(!wglMakeCurrent(m_hDC, m_hGLRC)) + { + return false; + } + + #endif + + if(glewInit() != GLEW_OK) + { + return false; + } + + #ifdef _WINDOWS + + if(WGLEW_EXT_swap_control) + { + wglSwapIntervalEXT(vsync ? 1 : 0); + } + + #endif + + const char* vendor = (const char*)glGetString(GL_VENDOR); + const char* renderer = (const char*)glGetString(GL_RENDERER); + const char* version = (const char*)glGetString(GL_VERSION); + const char* exts = (const char*)glGetString(GL_EXTENSIONS); + + printf("%s, %s, OpenGL %s\n", vendor, renderer, version); + + const char* str = strstr(exts, "ARB_texture_non_power_of_two"); + + glGenBuffers(1, &m_vbo); CheckError(); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); CheckError(); + // TODO: setup layout? + + m_context = cgCreateContext(); + + // cgGLSetDebugMode(CG_FALSE); CheckCgError(); + + cgSetParameterSettingMode(m_context, CG_DEFERRED_PARAMETER_SETTING); CheckCgError(); +/* + struct {CGprofile vs, gs, ps;} m_profile; + m_profile.vs = cgGLGetLatestProfile(CG_GL_VERTEX); CheckCgError(); + m_profile.gs = cgGLGetLatestProfile(CG_GL_GEOMETRY); CheckCgError(); + m_profile.ps = cgGLGetLatestProfile(CG_GL_FRAGMENT); CheckCgError(); +*/ + GSVector4i r = wnd->GetClientRect(); + + Reset(r.width(), r.height(), false); + + return true; +} + +bool GSDeviceOGL::Reset(int w, int h, bool fs) +{ + if(!__super::Reset(w, h, fs)) + return false; + + glCullFace(GL_FRONT_AND_BACK); CheckError(); + glDisable(GL_LIGHTING); CheckError(); + glDisable(GL_ALPHA_TEST); CheckError(); + glEnable(GL_SCISSOR_TEST); CheckError(); + + glMatrixMode(GL_PROJECTION); CheckError(); + glLoadIdentity(); CheckError(); + glMatrixMode(GL_MODELVIEW); CheckError(); + glLoadIdentity(); CheckError(); + + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); CheckError(); + + // glViewport(0, 0, w, h); + + if(m_fbo) {glDeleteFramebuffersEXT(1, &m_fbo); m_fbo = 0;} + + glGenFramebuffers(1, &m_fbo); CheckError(); + + if(m_fbo == 0) return false; + + glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); CheckError(); + + return true; +} + +void GSDeviceOGL::Present(const GSVector4i& r, int shader) +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); CheckError(); + + // TODO: m_current => backbuffer + + Flip(); +} + +void GSDeviceOGL::Flip() +{ + #ifdef _WINDOWS + + SwapBuffers(m_hDC); + + #endif +} + +void GSDeviceOGL::BeginScene() +{ +} + +void GSDeviceOGL::DrawPrimitive() +{ + glDrawArrays(m_topology, m_vertices.count, m_vertices.start); CheckError(); +} + +void GSDeviceOGL::EndScene() +{ + m_vertices.start += m_vertices.count; + m_vertices.count = 0; +} + +void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c) +{ + GLuint texture = *(GSTextureOGL*)t; + + if(texture == 0) + { + // TODO: backbuffer + } + else + { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, texture); CheckError(); + } + + // TODO: disable scissor, color mask + + glClearColor(c.r, c.g, c.b, c.a); CheckError(); + glClear(GL_COLOR_BUFFER_BIT); CheckError(); +} + +void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c) +{ + ClearRenderTarget(t, GSVector4(c) * (1.0f / 255)); +} + +void GSDeviceOGL::ClearDepth(GSTexture* t, float c) +{ + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, *(GSTextureOGL*)t); CheckError(); + + // TODO: disable scissor, depth mask + + glClearDepth(c); CheckError(); + glClear(GL_DEPTH_BUFFER_BIT); CheckError(); +} + +void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c) +{ + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX, *(GSTextureOGL*)t); CheckError(); + + // TODO: disable scissor, depth (?) mask + + glClearStencil((GLint)c); CheckError(); + glClear(GL_STENCIL_BUFFER_BIT); CheckError(); +} + +GSTexture* GSDeviceOGL::Create(int type, int w, int h, int format) +{ + GLuint texture = 0; + + switch(type) + { + case GSTexture::RenderTarget: + glGenTextures(1, &texture); CheckError(); + glBindTexture(GL_TEXTURE_2D, texture); CheckError(); + glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); CheckError(); + break; + case GSTexture::DepthStencil: + glGenRenderbuffers(1, &texture); CheckError(); + glBindRenderbuffer(GL_RENDERBUFFER, texture); CheckError(); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH32F_STENCIL8, w, h); CheckError(); + // TODO: depth textures? + break; + case GSTexture::Texture: + glGenTextures(1, &texture); CheckError(); + glBindTexture(GL_TEXTURE_2D, texture); CheckError(); + glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); CheckError(); + break; + case GSTexture::Offscreen: + // TODO: ??? + break; + } + + if(!texture) return false; + + GSTextureOGL* t = new GSTextureOGL(texture, type, w, h, format); + + switch(type) + { + case GSTexture::RenderTarget: + ClearRenderTarget(t, 0); + break; + case GSTexture::DepthStencil: + ClearDepth(t, 0); + break; + } + + return t; +} + +GSTexture* GSDeviceOGL::CreateRenderTarget(int w, int h, int format) +{ + return __super::CreateRenderTarget(w, h, format ? format : GL_RGBA8); +} + +GSTexture* GSDeviceOGL::CreateDepthStencil(int w, int h, int format) +{ + return __super::CreateDepthStencil(w, h, format ? format : GL_DEPTH32F_STENCIL8); // TODO: GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8 +} + +GSTexture* GSDeviceOGL::CreateTexture(int w, int h, int format) +{ + return __super::CreateTexture(w, h, format ? format : GL_RGBA8); +} + +GSTexture* GSDeviceOGL::CreateOffscreen(int w, int h, int format) +{ + return __super::CreateOffscreen(w, h, format ? format : GL_RGBA8); +} + +GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format) +{ + // TODO + + return NULL; +} + +void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear) +{ + // TODO +} + +void GSDeviceOGL::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c) +{ + // TODO +} + +void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset) +{ + // TODO +} + +void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t stride, size_t count) +{ + ASSERT(m_vertices.count == 0); + + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); CheckError(); + + bool growbuffer = false; + bool discard = false; // in opengl 3.x this should be a flag to glMapBuffer, as I read somewhere + + if(count * stride > m_vertices.limit * m_vertices.stride) + { + m_vertices.start = 0; + m_vertices.count = 0; + m_vertices.limit = max(count * 3 / 2, 10000); + + growbuffer = true; + } + + if(m_vertices.start + count > m_vertices.limit || stride != m_vertices.stride) + { + m_vertices.start = 0; + + discard = true; + } + + if(growbuffer || discard) + { + glBufferData(GL_ARRAY_BUFFER, m_vertices.limit * stride, NULL, GL_DYNAMIC_DRAW); CheckError(); // GL_STREAM_DRAW? + } + + glBufferSubData(GL_ARRAY_BUFFER, m_vertices.start * stride, count * stride, vertices); CheckError(); +/* + if(GLvoid* v = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)) + { + GSVector4i::storent((uint8*)v + m_vertices.start * stride, vertices, count * stride); + + glUnmapBuffer(GL_ARRAY_BUFFER); CheckError(); + } +*/ + m_vertices.count = count; + m_vertices.stride = stride; +} + +void GSDeviceOGL::IASetInputLayout() +{ + // TODO +} + +void GSDeviceOGL::IASetPrimitiveTopology(int topology) +{ + m_topology = topology; +} + +void GSDeviceOGL::PSSetSamplerState(SamplerStateOGL* ss) +{ + if(ss && m_ps_ss != ss) + { + glActiveTexture(GL_TEXTURE0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ss->wrap.s); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ss->wrap.t); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ss->filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ss->filter); + + glActiveTexture(GL_TEXTURE1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ss->wrap.s); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ss->wrap.t); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ss->filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ss->filter); + + glActiveTexture(GL_TEXTURE2); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_POINT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_POINT); + + glActiveTexture(GL_TEXTURE3); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_POINT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_POINT); + + m_ps_ss = ss; + } +} + +void GSDeviceOGL::RSSet(int width, int height, const GSVector4i* scissor) +{ + if(m_viewport.x != width || m_viewport.y != height) + { + glViewport(0, 0, width, height); CheckError(); + + m_viewport = GSVector2i(width, height); + } + + GSVector4i r = scissor ? *scissor : GSVector4i(0, 0, width, height); + + if(!m_scissor.eq(r)) + { + glScissor(r.left, r.top, r.width(), r.height()); CheckError(); + + m_scissor = r; + } +} + +void GSDeviceOGL::OMSetDepthStencilState(DepthStencilStateOGL* dss) +{ + if(m_dss != dss) + { + if(dss->depth.enable) + { + glEnable(GL_DEPTH_TEST); CheckError(); + glDepthFunc(dss->depth.func); CheckError(); + glDepthMask(dss->depth.write); CheckError(); + } + else + { + glDisable(GL_DEPTH_TEST); CheckError(); + } + + if(dss->stencil.enable) + { + glEnable(GL_STENCIL_TEST); CheckError(); + glStencilFunc(dss->stencil.func, dss->stencil.ref, dss->stencil.mask); CheckError(); + glStencilOp(dss->stencil.sfail, dss->stencil.dpfail, dss->stencil.dppass); CheckError(); + glStencilMask(dss->stencil.wmask); CheckError(); + } + else + { + glDisable(GL_STENCIL_TEST); CheckError(); + } + + m_dss = dss; + } +} + +void GSDeviceOGL::OMSetBlendState(BlendStateOGL* bs, float bf) +{ + if(m_bs != bs || m_bf != bf) + { + if(bs->enable) + { + glEnable(GL_BLEND); CheckError(); + glBlendEquationSeparate(bs->modeRGB, bs->modeAlpha); CheckError(); + glBlendFuncSeparate(bs->srcRGB, bs->dstRGB, bs->srcAlpha, bs->dstAlpha); CheckError(); + glBlendColor(bf, bf, bf, 0); CheckError(); + } + else + { + glDisable(GL_BLEND); CheckError(); + } + + glColorMask(bs->mask.r, bs->mask.g, bs->mask.b, bs->mask.a); CheckError(); + + m_bs = bs; + m_bf = bf; + } +} + +void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds) +{ + GLuint rti = 0; + GLuint dsi = 0; + + if(rt) rti = *(GSTextureOGL*)rt; + if(ds) dsi = *(GSTextureOGL*)ds; + + if(m_rt != rti) + { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rti); CheckError(); + + m_rt = rti; + } + + if(m_ds != dsi) + { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, dsi); CheckError(); + + m_ds = dsi; + } +} diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h new file mode 100644 index 0000000000..850056120c --- /dev/null +++ b/plugins/GSdx/GSDeviceOGL.h @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSDevice.h" +#include "GSTextureOGL.h" + +struct SamplerStateOGL +{ + struct {GLenum s, t;} wrap; + GLenum filter; +}; + +struct DepthStencilStateOGL +{ + struct + { + bool enable; + bool write; + GLenum func; + } depth; + + struct + { + bool enable; + GLenum func; + GLint ref; + GLuint mask; + GLenum sfail; + GLenum dpfail; + GLenum dppass; + GLuint wmask; + } stencil; +}; + +struct BlendStateOGL +{ + bool enable; + GLenum srcRGB; + GLenum dstRGB; + GLenum srcAlpha; + GLenum dstAlpha; + GLenum modeRGB; + GLenum modeAlpha; + union {uint8 r:1, g:1, b:1, a:1;} mask; +}; + +class GSDeviceOGL : public GSDevice +{ + #ifdef _WINDOWS + + HDC m_hDC; + HGLRC m_hGLRC; + + #endif + + GLuint m_vbo; + GLuint m_fbo; + + struct + { + size_t stride, start, count, limit; + } m_vertices; + + int m_topology; + SamplerStateOGL* m_ps_ss; + GSVector4i m_scissor; + GSVector2i m_viewport; + DepthStencilStateOGL* m_dss; + BlendStateOGL* m_bs; + float m_bf; + GLuint m_rt; + GLuint m_ds; + + // + + CGcontext m_context; + + static void OnStaticCgError(CGcontext ctx, CGerror err, void* p) {((GSDeviceOGL*)p)->OnCgError(ctx, err);} + void OnCgError(CGcontext ctx, CGerror err); + + // + + GSTexture* Create(int type, int w, int h, int format); + + void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c); + void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0); + +public: + GSDeviceOGL(); + virtual ~GSDeviceOGL(); + + bool Create(GSWnd* wnd, bool vsync); + bool Reset(int w, int h, bool fs); + + void Present(const GSVector4i& r, int shader); + void Flip(); + + void BeginScene(); + void DrawPrimitive(); + void EndScene(); + + void ClearRenderTarget(GSTexture* t, const GSVector4& c); + void ClearRenderTarget(GSTexture* t, uint32 c); + void ClearDepth(GSTexture* t, float c); + void ClearStencil(GSTexture* t, uint8 c); + + GSTexture* CreateRenderTarget(int w, int h, int format = 0); + GSTexture* CreateDepthStencil(int w, int h, int format = 0); + GSTexture* CreateTexture(int w, int h, int format = 0); + GSTexture* CreateOffscreen(int w, int h, int format = 0); + + GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0); + + void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true); + + void IASetVertexBuffer(const void* vertices, size_t stride, size_t count); + void IASetInputLayout(); // TODO + void IASetPrimitiveTopology(int topology); + + void PSSetSamplerState(SamplerStateOGL* ss); + void RSSet(int width, int height, const GSVector4i* scissor); + void OMSetDepthStencilState(DepthStencilStateOGL* dss); + void OMSetBlendState(BlendStateOGL* bs, float bf); + void OMSetRenderTargets(GSTexture* rt, GSTexture* ds); + + static void CheckError() + { + #ifdef _DEBUG + + GLenum error = glGetError(); + + if(error != GL_NO_ERROR) + { + printf("%s\n", gluErrorString(error)); + } + + #endif + } + + static void CheckFrameBuffer() + { + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + if(status != GL_FRAMEBUFFER_COMPLETE) + { + printf("%d\n", status); + } + } + + void CheckCgError() + { + CGerror error; + + const char* s = cgGetLastErrorString(&error); + + if(error != CG_NO_ERROR) + { + printf("%s\n", s); + + if(error == CG_COMPILER_ERROR) + { + printf("%s\n", cgGetLastListing(m_context)); + } + } + } +}; diff --git a/plugins/GSdx/GSDialog.cpp b/plugins/GSdx/GSDialog.cpp new file mode 100644 index 0000000000..c47cc35973 --- /dev/null +++ b/plugins/GSdx/GSDialog.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "StdAfx.h" +#include "GSdx.h" +#include "GSDialog.h" +#include "GSVector.h" + +GSDialog::GSDialog(UINT id) + : m_id(id) + , m_hWnd(NULL) +{ +} + +INT_PTR GSDialog::DoModal() +{ + return DialogBoxParam(theApp.GetModuleHandle(), MAKEINTRESOURCE(m_id), NULL, DialogProc, (LPARAM)this); +} + +INT_PTR CALLBACK GSDialog::DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + GSDialog* dlg = NULL; + + if(message == WM_INITDIALOG) + { + dlg = (GSDialog*)lParam; + SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)dlg); + dlg->m_hWnd = hWnd; + + MONITORINFO mi; + mi.cbSize = sizeof(mi); + GetMonitorInfo(MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST), &mi); + + GSVector4i r; + GetWindowRect(hWnd, r); + + int x = (mi.rcWork.left + mi.rcWork.right - r.width()) / 2; + int y = (mi.rcWork.top + mi.rcWork.bottom - r.height()) / 2; + + SetWindowPos(hWnd, NULL, x, y, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + + dlg->OnInit(); + + return true; + } + + dlg = (GSDialog*)GetWindowLongPtr(hWnd, GWL_USERDATA); + + return dlg != NULL ? dlg->OnMessage(message, wParam, lParam) : FALSE; +} + +bool GSDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + return message == WM_COMMAND ? OnCommand((HWND)lParam, LOWORD(wParam), HIWORD(wParam)) : false; +} + +bool GSDialog::OnCommand(HWND hWnd, UINT id, UINT code) +{ + if(id == IDOK || id == IDCANCEL) + { + EndDialog(m_hWnd, id); + + return true; + } + + return false; +} + +string GSDialog::GetText(UINT id) +{ + string s; + + char* buff = NULL; + + for(int size = 256, limit = 65536; size < limit; size <<= 1) + { + buff = new char[size]; + + if(GetDlgItemText(m_hWnd, id, buff, size)) + { + s = buff; + size = limit; + } + + delete [] buff; + } + + return s; +} + +int GSDialog::GetTextAsInt(UINT id) +{ + return atoi(GetText(id).c_str()); +} + +void GSDialog::SetText(UINT id, const char* str) +{ + SetDlgItemText(m_hWnd, id, str); +} + +void GSDialog::SetTextAsInt(UINT id, int i) +{ + char buff[32] = {0}; + itoa(i, buff, 10); + SetText(id, buff); +} + +void GSDialog::ComboBoxInit(UINT id, const GSSetting* settings, int count, uint32 selid, uint32 maxid) +{ + HWND hWnd = GetDlgItem(m_hWnd, id); + + SendMessage(hWnd, CB_RESETCONTENT, 0, 0); + + for(int i = 0; i < count; i++) + { + if(settings[i].id <= maxid) + { + string str = settings[i].name; + + if(settings[i].note != NULL) + { + str = str + " (" + settings[i].note + ")"; + } + + ComboBoxAppend(id, str.c_str(), (LPARAM)settings[i].id, settings[i].id == selid); + } + } +} + +int GSDialog::ComboBoxAppend(UINT id, const char* str, LPARAM data, bool select) +{ + HWND hWnd = GetDlgItem(m_hWnd, id); + + int item = (int)SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)str); + + SendMessage(hWnd, CB_SETITEMDATA, item, (LPARAM)data); + + if(select) + { + SendMessage(hWnd, CB_SETCURSEL, item, 0); + } + + return item; +} + +bool GSDialog::ComboBoxGetSelData(UINT id, INT_PTR& data) +{ + HWND hWnd = GetDlgItem(m_hWnd, id); + + int item = SendMessage(hWnd, CB_GETCURSEL, 0, 0); + + if(item >= 0) + { + data = SendMessage(hWnd, CB_GETITEMDATA, item, 0); + + return true; + } + + return false; +} diff --git a/plugins/GSdx/GSDialog.h b/plugins/GSdx/GSDialog.h new file mode 100644 index 0000000000..0f1b913569 --- /dev/null +++ b/plugins/GSdx/GSDialog.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSSetting.h" + +class GSDialog +{ + int m_id; + + static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +protected: + HWND m_hWnd; + + virtual void OnInit() {} + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + virtual bool OnCommand(HWND hWnd, UINT id, UINT code); + +public: + GSDialog(UINT id); + virtual ~GSDialog() {} + + INT_PTR DoModal(); + + string GetText(UINT id); + int GetTextAsInt(UINT id); + + void SetText(UINT id, const char* str); + void SetTextAsInt(UINT id, int i); + + void ComboBoxInit(UINT id, const GSSetting* settings, int count, uint32 selid, uint32 maxid = ~0); + int ComboBoxAppend(UINT id, const char* str, LPARAM data = 0, bool select = false); + bool ComboBoxGetSelData(UINT id, INT_PTR& data); +}; diff --git a/plugins/GSdx/GSDirtyRect.cpp b/plugins/GSdx/GSDirtyRect.cpp index 1d8b7ff123..422fad5f22 100644 --- a/plugins/GSdx/GSDirtyRect.cpp +++ b/plugins/GSdx/GSDirtyRect.cpp @@ -23,36 +23,38 @@ #include "GSDirtyRect.h" GSDirtyRect::GSDirtyRect() - : m_psm(PSM_PSMCT32) - , m_rect(0, 0, 0, 0) + : psm(PSM_PSMCT32) { + left = top = right = bottom = 0; } -GSDirtyRect::GSDirtyRect(DWORD psm, CRect rect) +GSDirtyRect::GSDirtyRect(const GSVector4i& r, uint32 psm) + : psm(psm) { - m_psm = psm; - m_rect = rect; + left = r.left; + top = r.top; + right = r.right; + bottom = r.bottom; } -CRect GSDirtyRect::GetDirtyRect(const GIFRegTEX0& TEX0) +GSVector4i GSDirtyRect::GetDirtyRect(const GIFRegTEX0& TEX0) { - CRect r = m_rect; + GSVector4i r; - CSize src = GSLocalMemory::m_psm[m_psm].bs; + GSVector2i src = GSLocalMemory::m_psm[psm].bs; - r.left = (r.left) & ~(src.cx-1); - r.right = (r.right + (src.cx-1) /* + 1 */) & ~(src.cx-1); - r.top = (r.top) & ~(src.cy-1); - r.bottom = (r.bottom + (src.cy-1) /* + 1 */) & ~(src.cy-1); - - if(m_psm != TEX0.PSM) + if(psm != TEX0.PSM) { - CSize dst = GSLocalMemory::m_psm[TEX0.PSM].bs; + GSVector2i dst = GSLocalMemory::m_psm[TEX0.PSM].bs; - r.left = MulDiv(m_rect.left, dst.cx, src.cx); - r.right = MulDiv(m_rect.right, dst.cx, src.cx); - r.top = MulDiv(m_rect.top, dst.cy, src.cy); - r.bottom = MulDiv(m_rect.bottom, dst.cy, src.cy); + r.left = MulDiv(left, dst.x, src.x); + r.top = MulDiv(top, dst.y, src.y); + r.right = MulDiv(right, dst.x, src.x); + r.bottom = MulDiv(bottom, dst.y, src.y); + } + else + { + r = GSVector4i(left, top, right, bottom).ralign(src); } return r; @@ -60,11 +62,23 @@ CRect GSDirtyRect::GetDirtyRect(const GIFRegTEX0& TEX0) // -CRect GSDirtyRectList::GetDirtyRect(const GIFRegTEX0& TEX0, CSize size) +GSVector4i GSDirtyRectList::GetDirtyRectAndClear(const GIFRegTEX0& TEX0, const GSVector2i& size) { - if(IsEmpty()) return CRect(0, 0, 0, 0); - CRect r(INT_MAX, INT_MAX, 0, 0); - POSITION pos = GetHeadPosition(); - while(pos) r |= GetNext(pos).GetDirtyRect(TEX0); - return r & CRect(0, 0, size.cx, size.cy); + if(!empty()) + { + GSVector4i r(INT_MAX, INT_MAX, 0, 0); + + for(list::iterator i = begin(); i != end(); i++) + { + r = r.runion(i->GetDirtyRect(TEX0)); + } + + clear(); + + GSVector2i bs = GSLocalMemory::m_psm[TEX0.PSM].bs; + + return r.ralign(bs).rintersect(GSVector4i(0, 0, size.x, size.y)); + } + + return GSVector4i::zero(); } diff --git a/plugins/GSdx/GSDirtyRect.h b/plugins/GSdx/GSDirtyRect.h index 8e6f5734df..e9b7699055 100644 --- a/plugins/GSdx/GSDirtyRect.h +++ b/plugins/GSdx/GSDirtyRect.h @@ -25,18 +25,22 @@ class GSDirtyRect { - DWORD m_psm; - CRect m_rect; + int left; + int top; + int right; + int bottom; + + uint32 psm; public: GSDirtyRect(); - GSDirtyRect(DWORD psm, CRect rect); - CRect GetDirtyRect(const GIFRegTEX0& TEX0); + GSDirtyRect(const GSVector4i& r, uint32 psm); + GSVector4i GetDirtyRect(const GIFRegTEX0& TEX0); }; -class GSDirtyRectList : public CAtlList +class GSDirtyRectList : public list { public: GSDirtyRectList() {} - CRect GetDirtyRect(const GIFRegTEX0& TEX0, CSize size); + GSVector4i GetDirtyRectAndClear(const GIFRegTEX0& TEX0, const GSVector2i& size); }; \ No newline at end of file diff --git a/plugins/GSdx/GSDrawScanline.cpp b/plugins/GSdx/GSDrawScanline.cpp index ccdd34f4b7..05cf43b328 100644 --- a/plugins/GSdx/GSDrawScanline.cpp +++ b/plugins/GSdx/GSDrawScanline.cpp @@ -56,8 +56,8 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f) m_env.zm = GSVector4i(p->zm); m_env.aref = GSVector4i((int)context->TEST.AREF); m_env.afix = GSVector4i((int)context->ALPHA.FIX << 7).xxzzlh(); - m_env.frb = GSVector4i((int)env.FOGCOL.ai32[0] & 0x00ff00ff); - m_env.fga = GSVector4i((int)(env.FOGCOL.ai32[0] >> 8) & 0x00ff00ff); + m_env.frb = GSVector4i((int)env.FOGCOL.u32[0] & 0x00ff00ff); + m_env.fga = GSVector4i((int)(env.FOGCOL.u32[0] >> 8) & 0x00ff00ff); m_env.dimx = env.dimx; if(m_sel.fpsm == 1) @@ -163,7 +163,7 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f) // - f->ssl = m_ds.Lookup(m_sel); + f->ssl = m_ds[m_sel]; if(m_sel.aa1)// && (m_state->m_perfmon.GetFrame() & 0x40)) { @@ -173,7 +173,7 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f) sel.zwrite = 0; sel.edge = 1; - f->ssle = m_ds.Lookup(sel); + f->ssle = m_ds[sel]; } if(m_sel.IsSolidRect()) @@ -189,6 +189,7 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f) sel.iip = m_sel.iip; sel.tfx = m_sel.tfx; + sel.tcc = m_sel.tcc; sel.fst = m_sel.fst; sel.fge = m_sel.fge; sel.sprite = m_sel.sprite; @@ -196,7 +197,7 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f) sel.zb = m_sel.zb; sel.zoverflow = m_sel.zoverflow; - f->ssp = m_sp.Lookup(sel); + f->ssp = m_sp[sel]; } void GSDrawScanline::EndDraw(const GSRasterizerStats& stats) @@ -211,34 +212,34 @@ void GSDrawScanline::DrawSolidRect(const GSVector4i& r, const GSVertexSW& v) // FIXME: sometimes the frame and z buffer may overlap, the outcome is undefined - DWORD m; + uint32 m; m = m_env.zm.u32[0]; if(m != 0xffffffff) { - DWORD z = (DWORD)(float)v.p.z; + uint32 z = (uint32)v.p.z; if(m_sel.zpsm != 2) { if(m == 0) { - DrawSolidRectT(m_env.zbr, m_env.zbc[0], r, z, m); + DrawSolidRectT(m_env.zbr, m_env.zbc[0], r, z, m); } else { - DrawSolidRectT(m_env.zbr, m_env.zbc[0], r, z, m); + DrawSolidRectT(m_env.zbr, m_env.zbc[0], r, z, m); } } else { if(m == 0) { - DrawSolidRectT(m_env.zbr, m_env.zbc[0], r, z, m); + DrawSolidRectT(m_env.zbr, m_env.zbc[0], r, z, m); } else { - DrawSolidRectT(m_env.zbr, m_env.zbc[0], r, z, m); + DrawSolidRectT(m_env.zbr, m_env.zbc[0], r, z, m); } } } @@ -247,7 +248,7 @@ void GSDrawScanline::DrawSolidRect(const GSVector4i& r, const GSVertexSW& v) if(m != 0xffffffff) { - DWORD c = (GSVector4i(v.c) >> 7).rgba32(); + uint32 c = (GSVector4i(v.c) >> 7).rgba32(); if(m_state->m_context->FBA.FBA) { @@ -258,11 +259,11 @@ void GSDrawScanline::DrawSolidRect(const GSVector4i& r, const GSVertexSW& v) { if(m == 0) { - DrawSolidRectT(m_env.fbr, m_env.fbc[0], r, c, m); + DrawSolidRectT(m_env.fbr, m_env.fbc[0], r, c, m); } else { - DrawSolidRectT(m_env.fbr, m_env.fbc[0], r, c, m); + DrawSolidRectT(m_env.fbr, m_env.fbc[0], r, c, m); } } else @@ -271,25 +272,25 @@ void GSDrawScanline::DrawSolidRect(const GSVector4i& r, const GSVertexSW& v) if(m == 0) { - DrawSolidRectT(m_env.fbr, m_env.fbc[0], r, c, m); + DrawSolidRectT(m_env.fbr, m_env.fbc[0], r, c, m); } else { - DrawSolidRectT(m_env.fbr, m_env.fbc[0], r, c, m); + DrawSolidRectT(m_env.fbr, m_env.fbc[0], r, c, m); } } } } template -void GSDrawScanline::DrawSolidRectT(const GSVector4i* row, int* col, const GSVector4i& r, DWORD c, DWORD m) +void GSDrawScanline::DrawSolidRectT(const GSVector4i* row, int* col, const GSVector4i& r, uint32 c, uint32 m) { if(m == 0xffffffff) return; GSVector4i color((int)c); GSVector4i mask((int)m); - if(sizeof(T) == sizeof(WORD)) + if(sizeof(T) == sizeof(uint16)) { color = color.xxzzlh(); mask = mask.xxzzlh(); @@ -297,29 +298,35 @@ void GSDrawScanline::DrawSolidRectT(const GSVector4i* row, int* col, const GSVec color = color.andnot(mask); - GSVector4i bm(8 * 4 / sizeof(T) - 1, 8 - 1); - GSVector4i br = (r + bm).andnot(bm.xyxy()); + GSVector4i br = r.ralign(GSVector2i(8 * 4 / sizeof(T), 8)); - FillRect(row, col, GSVector4i(r.x, r.y, r.z, br.y), c, m); - FillRect(row, col, GSVector4i(r.x, br.w, r.z, r.w), c, m); - - if(r.x < br.x || br.z < r.z) + if(!br.rempty()) { - FillRect(row, col, GSVector4i(r.x, br.y, br.x, br.w), c, m); - FillRect(row, col, GSVector4i(br.z, br.y, r.z, br.w), c, m); - } + FillRect(row, col, GSVector4i(r.x, r.y, r.z, br.y), c, m); + FillRect(row, col, GSVector4i(r.x, br.w, r.z, r.w), c, m); - FillBlock(row, col, br, color, mask); + if(r.x < br.x || br.z < r.z) + { + FillRect(row, col, GSVector4i(r.x, br.y, br.x, br.w), c, m); + FillRect(row, col, GSVector4i(br.z, br.y, r.z, br.w), c, m); + } + + FillBlock(row, col, br, color, mask); + } + else + { + FillRect(row, col, r, c, m); + } } template -void GSDrawScanline::FillRect(const GSVector4i* row, int* col, const GSVector4i& r, DWORD c, DWORD m) +void GSDrawScanline::FillRect(const GSVector4i* row, int* col, const GSVector4i& r, uint32 c, uint32 m) { if(r.x >= r.z) return; for(int y = r.y; y < r.w; y++) { - DWORD base = row[y].x; + uint32 base = row[y].x; for(int x = r.x; x < r.z; x++) { @@ -337,7 +344,7 @@ void GSDrawScanline::FillBlock(const GSVector4i* row, int* col, const GSVector4i for(int y = r.y; y < r.w; y += 8) { - DWORD base = row[y].x; + uint32 base = row[y].x; for(int x = r.x; x < r.z; x += 8 * 4 / sizeof(T)) { @@ -362,7 +369,7 @@ GSDrawScanline::GSSetupPrimMap::GSSetupPrimMap(GSScanlineEnvironment& env) { } -GSSetupPrimCodeGenerator* GSDrawScanline::GSSetupPrimMap::Create(UINT64 key, void* ptr, size_t maxsize) +GSSetupPrimCodeGenerator* GSDrawScanline::GSSetupPrimMap::Create(uint64 key, void* ptr, size_t maxsize) { return new GSSetupPrimCodeGenerator(m_env, key, ptr, maxsize); } @@ -375,7 +382,7 @@ GSDrawScanline::GSDrawScanlineMap::GSDrawScanlineMap(GSScanlineEnvironment& env) { } -GSDrawScanlineCodeGenerator* GSDrawScanline::GSDrawScanlineMap::Create(UINT64 key, void* ptr, size_t maxsize) +GSDrawScanlineCodeGenerator* GSDrawScanline::GSDrawScanlineMap::Create(uint64 key, void* ptr, size_t maxsize) { return new GSDrawScanlineCodeGenerator(m_env, key, ptr, maxsize); } diff --git a/plugins/GSdx/GSDrawScanline.h b/plugins/GSdx/GSDrawScanline.h index 2221707dc8..9f9a1ea3d1 100644 --- a/plugins/GSdx/GSDrawScanline.h +++ b/plugins/GSdx/GSDrawScanline.h @@ -35,24 +35,24 @@ class GSDrawScanline : public GSAlignedClass<16>, public IDrawScanline // - class GSSetupPrimMap : public GSCodeGeneratorFunctionMap + class GSSetupPrimMap : public GSCodeGeneratorFunctionMap { GSScanlineEnvironment& m_env; public: GSSetupPrimMap(GSScanlineEnvironment& env); - GSSetupPrimCodeGenerator* Create(UINT64 key, void* ptr, size_t maxsize); + GSSetupPrimCodeGenerator* Create(uint64 key, void* ptr, size_t maxsize); } m_sp; // - class GSDrawScanlineMap : public GSCodeGeneratorFunctionMap + class GSDrawScanlineMap : public GSCodeGeneratorFunctionMap { GSScanlineEnvironment& m_env; public: GSDrawScanlineMap(GSScanlineEnvironment& env); - GSDrawScanlineCodeGenerator* Create(UINT64 key, void* ptr, size_t maxsize); + GSDrawScanlineCodeGenerator* Create(uint64 key, void* ptr, size_t maxsize); } m_ds; // @@ -60,10 +60,10 @@ class GSDrawScanline : public GSAlignedClass<16>, public IDrawScanline void DrawSolidRect(const GSVector4i& r, const GSVertexSW& v); template - void DrawSolidRectT(const GSVector4i* row, int* col, const GSVector4i& r, DWORD c, DWORD m); + void DrawSolidRectT(const GSVector4i* row, int* col, const GSVector4i& r, uint32 c, uint32 m); template - __forceinline void FillRect(const GSVector4i* row, int* col, const GSVector4i& r, DWORD c, DWORD m); + __forceinline void FillRect(const GSVector4i* row, int* col, const GSVector4i& r, uint32 c, uint32 m); template __forceinline void FillBlock(const GSVector4i* row, int* col, const GSVector4i& r, const GSVector4i& c, const GSVector4i& m); diff --git a/plugins/GSdx/GSDrawScanlineCodeGenerator.cpp b/plugins/GSdx/GSDrawScanlineCodeGenerator.cpp index 5b0c12411c..cb1d003a72 100644 --- a/plugins/GSdx/GSDrawScanlineCodeGenerator.cpp +++ b/plugins/GSdx/GSDrawScanlineCodeGenerator.cpp @@ -25,7 +25,7 @@ #include "StdAfx.h" #include "GSDrawScanlineCodeGenerator.h" -GSDrawScanlineCodeGenerator::GSDrawScanlineCodeGenerator(GSScanlineEnvironment& env, UINT64 key, void* ptr, size_t maxsize) +GSDrawScanlineCodeGenerator::GSDrawScanlineCodeGenerator(GSScanlineEnvironment& env, uint64 key, void* ptr, size_t maxsize) : CodeGenerator(maxsize, ptr) , m_env(env) { @@ -449,7 +449,7 @@ void GSDrawScanlineCodeGenerator::Init(int params) } } - if(m_sel.tfx != TFX_DECAL) + if(!(m_sel.tfx == TFX_DECAL && m_sel.tcc)) { if(m_sel.iip) { @@ -582,7 +582,7 @@ void GSDrawScanlineCodeGenerator::Step() } } - if(m_sel.tfx != TFX_DECAL) + if(!(m_sel.tfx == TFX_DECAL && m_sel.tcc)) { if(m_sel.iip) { @@ -707,18 +707,17 @@ void GSDrawScanlineCodeGenerator::TestZ(const Xmm& temp1, const Xmm& temp2) switch(m_sel.ztst) { case ZTST_GEQUAL: - // test |= zso < zdo; + // test |= zso < zdo; // ~(zso >= zdo) pcmpgtd(xmm1, xmm0); por(xmm7, xmm1); break; - case ZTST_GREATER: - // test |= zso <= zdo; - movdqa(xmm4, xmm1); - pcmpgtd(xmm1, xmm0); - por(xmm7, xmm1); - pcmpeqd(xmm4, xmm0); - por(xmm7, xmm1); + case ZTST_GREATER: // TODO: tidus hair and chocobo wings only appear fully when this is tested as ZTST_GEQUAL + // test |= zso <= zdo; // ~(zso > zdo) + pcmpgtd(xmm0, xmm1); + pcmpeqd(xmm4, xmm4); + pxor(xmm0, xmm4); + por(xmm7, xmm0); break; } @@ -870,10 +869,10 @@ void GSDrawScanlineCodeGenerator::SampleTexture() // xmm1, xmm4, xmm6 = free // xmm7 = used - // c00 = addr00.gather32_32((const DWORD/BYTE*)tex[, clut]); - // c01 = addr01.gather32_32((const DWORD/BYTE*)tex[, clut]); - // c10 = addr10.gather32_32((const DWORD/BYTE*)tex[, clut]); - // c11 = addr11.gather32_32((const DWORD/BYTE*)tex[, clut]); + // c00 = addr00.gather32_32((const uint32/uint8*)tex[, clut]); + // c01 = addr01.gather32_32((const uint32/uint8*)tex[, clut]); + // c10 = addr10.gather32_32((const uint32/uint8*)tex[, clut]); + // c11 = addr11.gather32_32((const uint32/uint8*)tex[, clut]); ReadTexel(xmm6, xmm5, xmm1, xmm4); @@ -989,7 +988,7 @@ void GSDrawScanlineCodeGenerator::SampleTexture() paddd(xmm2, xmm4); - // c00 = addr00.gather32_32((const DWORD/BYTE*)tex[, clut]); + // c00 = addr00.gather32_32((const uint32/uint8*)tex[, clut]); ReadTexel(xmm5, xmm2, xmm0, xmm1); @@ -1202,6 +1201,19 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() case TFX_DECAL: + // if(!tcc) gat = gat.mix16(ga.srl16(7)); + + if(!m_sel.tcc) + { + // GSVector4i ga = iip ? gaf : m_env.c.ga; + + movdqa(xmm4, xmmword[m_sel.iip ? &m_env.temp.ga : &m_env.c.ga]); + + psrlw(xmm4, 7); + + mix16(xmm6, xmm4, xmm3); + } + break; case TFX_HIGHLIGHT: diff --git a/plugins/GSdx/GSDrawScanlineCodeGenerator.h b/plugins/GSdx/GSDrawScanlineCodeGenerator.h index 2803037200..a131f8c678 100644 --- a/plugins/GSdx/GSDrawScanlineCodeGenerator.h +++ b/plugins/GSdx/GSDrawScanlineCodeGenerator.h @@ -73,5 +73,5 @@ class GSDrawScanlineCodeGenerator : public CodeGenerator void blendr(const Xmm& b, const Xmm& a, const Xmm& mask); public: - GSDrawScanlineCodeGenerator(GSScanlineEnvironment& env, UINT64 key, void* ptr, size_t maxsize); + GSDrawScanlineCodeGenerator(GSScanlineEnvironment& env, uint64 key, void* ptr, size_t maxsize); }; \ No newline at end of file diff --git a/plugins/GSdx/GSDrawingContext.h b/plugins/GSdx/GSDrawingContext.h index 0f72f2f930..75e4b73ce8 100644 --- a/plugins/GSdx/GSDrawingContext.h +++ b/plugins/GSdx/GSDrawingContext.h @@ -89,7 +89,7 @@ public: (int)SCISSOR.SCAX1 + 1, (int)SCISSOR.SCAY1 + 1); - scissor.ex = GSVector4i( + scissor.ex = GSVector4( (int)SCISSOR.SCAX0, (int)SCISSOR.SCAY0, (int)SCISSOR.SCAX1, diff --git a/plugins/GSdx/GSDump.cpp b/plugins/GSdx/GSDump.cpp index 70421b35db..4082e7823f 100644 --- a/plugins/GSdx/GSDump.cpp +++ b/plugins/GSdx/GSDump.cpp @@ -36,10 +36,10 @@ GSDump::~GSDump() Close(); } -void GSDump::Open(const CString& fn, DWORD crc, const GSFreezeData& fd, const GSPrivRegSet* regs) +void GSDump::Open(const string& fn, uint32 crc, const GSFreezeData& fd, const GSPrivRegSet* regs) { - m_gs = _tfopen(fn + _T(".gs"), _T("wb")); - m_obj = _tfopen(fn + _T(".obj"), _T("wt")); + m_gs = fopen((fn + ".gs").c_str(), "wb"); + m_obj = fopen((fn + ".obj").c_str(), "wt"); m_frames = 0; m_objects = 0; @@ -60,7 +60,7 @@ void GSDump::Close() if(m_obj) {fclose(m_obj); m_obj = NULL;} } -void GSDump::Transfer(int index, BYTE* mem, size_t size) +void GSDump::Transfer(int index, uint8* mem, size_t size) { if(m_gs && size > 0) { @@ -71,7 +71,7 @@ void GSDump::Transfer(int index, BYTE* mem, size_t size) } } -void GSDump::ReadFIFO(UINT32 size) +void GSDump::ReadFIFO(uint32 size) { if(m_gs && size > 0) { @@ -123,20 +123,20 @@ void GSDump::Object(GSVertexSW* vertices, int count, GS_PRIM_CLASS primclass) float y = vertices[i].p.y; float z = vertices[i].p.z; - _ftprintf(m_obj, _T("v %f %f %f\n"), x, y, z); + fprintf(m_obj, "v %f %f %f\n", x, y, z); } for(int i = 0; i < count; i++) { - _ftprintf(m_obj, _T("vt %f %f %f\n"), vertices[i].t.x, vertices[i].t.y, vertices[i].t.z); + fprintf(m_obj, "vt %f %f %f\n", vertices[i].t.x, vertices[i].t.y, vertices[i].t.z); } for(int i = 0; i < count; i++) { - _ftprintf(m_obj, _T("vn %f %f %f\n"), 0.0f, 0.0f, 0.0f); + fprintf(m_obj, "vn %f %f %f\n", 0.0f, 0.0f, 0.0f); } - _ftprintf(m_obj, _T("g f%d_o%d_p%d_v%d\n"), m_frames, m_objects, primclass, count); + fprintf(m_obj, "g f%d_o%d_p%d_v%d\n", m_frames, m_objects, primclass, count); for(int i = 0; i < count; i += 3) { @@ -144,7 +144,7 @@ void GSDump::Object(GSVertexSW* vertices, int count, GS_PRIM_CLASS primclass) int b = m_vertices + i + 2; int c = m_vertices + i + 3; - _ftprintf(m_obj, _T("f %d/%d/%d %d/%d/%d %d/%d/%d \n"), a, a, a, b, b, b, c, c, c); + fprintf(m_obj, "f %d/%d/%d %d/%d/%d %d/%d/%d\n", a, a, a, b, b, b, c, c, c); } m_vertices += count; diff --git a/plugins/GSdx/GSDump.h b/plugins/GSdx/GSDump.h index bfa2d0682b..5cc2c88104 100644 --- a/plugins/GSdx/GSDump.h +++ b/plugins/GSdx/GSDump.h @@ -55,10 +55,10 @@ public: GSDump(); virtual ~GSDump(); - void Open(const CString& fn, DWORD crc, const GSFreezeData& fd, const GSPrivRegSet* regs); + void Open(const string& fn, uint32 crc, const GSFreezeData& fd, const GSPrivRegSet* regs); void Close(); - void ReadFIFO(UINT32 size); - void Transfer(int index, BYTE* mem, size_t size); + void ReadFIFO(uint32 size); + void Transfer(int index, uint8* mem, size_t size); void VSync(int field, bool last, const GSPrivRegSet* regs); void Object(GSVertexSW* vertices, int count, GS_PRIM_CLASS primclass); operator bool() {return m_gs != NULL;} diff --git a/plugins/GSdx/GSFunctionMap.h b/plugins/GSdx/GSFunctionMap.h index a6fb5127d7..050e49a92a 100644 --- a/plugins/GSdx/GSFunctionMap.h +++ b/plugins/GSdx/GSFunctionMap.h @@ -22,10 +22,11 @@ #pragma once #include "GS.h" +#include "GSCodeBuffer.h" struct GSRasterizerStats { - __int64 ticks; + int64 ticks; int prims, pixels; GSRasterizerStats() @@ -45,13 +46,14 @@ template class GSFunctionMap protected: struct ActivePtr { - UINT64 frame, frames; - __int64 ticks, pixels; + uint64 frame, frames; + int64 ticks, pixels; VALUE f; }; - CRBMap m_map; - CRBMap m_map_active; + hash_map m_map; + hash_map m_map_active; + ActivePtr* m_active; virtual VALUE GetDefaultFunction(KEY key) = 0; @@ -64,38 +66,35 @@ public: virtual ~GSFunctionMap() { - POSITION pos = m_map_active.GetHeadPosition(); - - while(pos) + for(hash_map::iterator i = m_map_active.begin(); i != m_map_active.end(); i++) { - delete m_map_active.GetNextValue(pos); + delete i->second; } - - m_map_active.RemoveAll(); } - void SetAt(KEY key, VALUE f) - { - m_map.SetAt(key, f); - } - - VALUE Lookup(KEY key) + VALUE operator [] (KEY key) { m_active = NULL; - if(!m_map_active.Lookup(key, m_active)) + hash_map::iterator i = m_map_active.find(key); + + if(i != m_map_active.end()) { - CRBMap::CPair* pair = m_map.Lookup(key); + m_active = i->second; + } + else + { + hash_map::iterator i = m_map.find(key); ActivePtr* p = new ActivePtr(); memset(p, 0, sizeof(*p)); - p->frame = (UINT64)-1; + p->frame = (uint64)-1; - p->f = pair ? pair->m_value : GetDefaultFunction(key); + p->f = i != m_map.end() ? i->second : GetDefaultFunction(key); - m_map_active.SetAt(key, p); + m_map_active[key] = p; m_active = p; } @@ -103,7 +102,7 @@ public: return m_active->f; } - void UpdateStats(const GSRasterizerStats& stats, UINT64 frame) + void UpdateStats(const GSRasterizerStats& stats, uint64 frame) { if(m_active) { @@ -120,13 +119,11 @@ public: virtual void PrintStats() { - __int64 ttpf = 0; + int64 ttpf = 0; - POSITION pos = m_map_active.GetHeadPosition(); - - while(pos) + for(hash_map::iterator i = m_map_active.begin(); i != m_map_active.end(); i++) { - ActivePtr* p = m_map_active.GetNextValue(pos); + ActivePtr* p = i->second; if(p->frames) { @@ -134,23 +131,19 @@ public: } } - pos = m_map_active.GetHeadPosition(); - - while(pos) + for(hash_map::iterator i = m_map_active.begin(); i != m_map_active.end(); i++) { - KEY key; - ActivePtr* p; - - m_map_active.GetNextAssoc(pos, key, p); + KEY key = i->first; + ActivePtr* p = i->second; if(p->frames > 0) { - __int64 tpp = p->pixels > 0 ? p->ticks / p->pixels : 0; - __int64 tpf = p->frames > 0 ? p->ticks / p->frames : 0; - __int64 ppf = p->frames > 0 ? p->pixels / p->frames : 0; + int64 tpp = p->pixels > 0 ? p->ticks / p->pixels : 0; + int64 tpf = p->frames > 0 ? p->ticks / p->frames : 0; + int64 ppf = p->frames > 0 ? p->pixels / p->frames : 0; printf("[%012I64x]%c %6.2f%% | %5.2f%% | f %4I64d | p %10I64d | tpp %4I64d | tpf %9I64d | ppf %7I64d\n", - (UINT64)key, !m_map.Lookup(key) ? '*' : ' ', + (uint64)key, m_map.find(key) == m_map.end() ? '*' : ' ', (float)(tpf * 10000 / 50000000) / 100, (float)(tpf * 10000 / ttpf) / 100, p->frames, p->pixels, @@ -160,15 +153,14 @@ public: } }; -#include "GSCodeBuffer.h" #include "vtune/JITProfiling.h" template class GSCodeGeneratorFunctionMap : public GSFunctionMap { - DWORD m_id; - CStringA m_name; - CRBMap m_cgmap; + uint32 m_id; + string m_name; + hash_map m_cgmap; GSCodeBuffer m_cb; enum {MAX_SIZE = 4096}; @@ -177,7 +169,7 @@ protected: virtual CG* Create(KEY key, void* ptr, size_t maxsize = MAX_SIZE) = 0; public: - GSCodeGeneratorFunctionMap(LPCSTR name) + GSCodeGeneratorFunctionMap(const char* name) : m_id(0x100000) , m_name(name) { @@ -185,11 +177,9 @@ public: virtual ~GSCodeGeneratorFunctionMap() { - POSITION pos = m_cgmap.GetHeadPosition(); - - while(pos) + for(hash_map::iterator i = m_cgmap.begin(); i != m_cgmap.end(); i++) { - delete m_cgmap.GetNextValue(pos); + delete i->second; } } @@ -197,7 +187,13 @@ public: { CG* cg = NULL; - if(!m_cgmap.Lookup(key, cg)) + hash_map::iterator i = m_cgmap.find(key); + + if(i != m_cgmap.end()) + { + cg = i->second; + } + else { void* ptr = m_cb.GetBuffer(MAX_SIZE); @@ -207,20 +203,18 @@ public: m_cb.ReleaseBuffer(cg->getSize()); - m_cgmap.SetAt(key, cg); + m_cgmap[key] = cg; // vtune method registration - CStringA name; - - name.Format("%s<%016I64x>()", m_name, (UINT64)key); + string name = format("%s<%016I64x>()", m_name.c_str(), (uint64)key); iJIT_Method_Load ml; memset(&ml, 0, sizeof(ml)); ml.method_id = m_id++; - ml.method_name = (LPSTR)(LPCSTR)name; + ml.method_name = (char*)name.c_str(); ml.method_load_address = (void*)cg->getCode(); ml.method_size = cg->getSize(); diff --git a/plugins/GSdx/GSLocalMemory.cpp b/plugins/GSdx/GSLocalMemory.cpp index b86c6ce8b8..7d5a78fbed 100644 --- a/plugins/GSdx/GSLocalMemory.cpp +++ b/plugins/GSdx/GSLocalMemory.cpp @@ -28,29 +28,32 @@ #include "GSLocalMemory.h" #define ASSERT_BLOCK(r, w, h) \ - ASSERT((r).Width() >= w && (r).Height() >= h && !((r).left&(w-1)) && !((r).top&(h-1)) && !((r).right&(w-1)) && !((r).bottom&(h-1))); \ + ASSERT((r).width() >= w && (r).height() >= h && !((r).left&(w-1)) && !((r).top&(h-1)) && !((r).right&(w-1)) && !((r).bottom&(h-1))); \ -#define FOREACH_BLOCK_START(w, h, bpp) \ - DWORD bp = TEX0.TBP0; \ - DWORD bw = TEX0.TBW; \ - int offset = dstpitch * h - (r.right - r.left) * bpp / 8; \ - for(int y = r.top; y < r.bottom; y += h, dst += offset) \ +#define FOREACH_BLOCK_START(w, h, bpp, format) \ + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[format]; \ + uint32 bp = TEX0.TBP0; \ + uint32 bw = TEX0.TBW; \ + int offset = dstpitch * h - r.width() * bpp / 8; \ + for(int y = r.top, ye = r.bottom; y < ye; y += h, dst += offset) \ { ASSERT_BLOCK(r, w, h); \ - for(int x = r.left; x < r.right; x += w, dst += w * bpp / 8) \ + uint32 base = psm.bn(0, y, bp, bw); \ + for(int x = r.left, xe = r.right; x < xe; x += w, dst += w * bpp / 8) \ { \ + const uint8* src = BlockPtr(base + psm.blockOffset[x >> 3]); \ #define FOREACH_BLOCK_END }} // -DWORD GSLocalMemory::pageOffset32[32][32][64]; -DWORD GSLocalMemory::pageOffset32Z[32][32][64]; -DWORD GSLocalMemory::pageOffset16[32][64][64]; -DWORD GSLocalMemory::pageOffset16S[32][64][64]; -DWORD GSLocalMemory::pageOffset16Z[32][64][64]; -DWORD GSLocalMemory::pageOffset16SZ[32][64][64]; -DWORD GSLocalMemory::pageOffset8[32][64][128]; -DWORD GSLocalMemory::pageOffset4[32][128][128]; +uint32 GSLocalMemory::pageOffset32[32][32][64]; +uint32 GSLocalMemory::pageOffset32Z[32][32][64]; +uint32 GSLocalMemory::pageOffset16[32][64][64]; +uint32 GSLocalMemory::pageOffset16S[32][64][64]; +uint32 GSLocalMemory::pageOffset16Z[32][64][64]; +uint32 GSLocalMemory::pageOffset16SZ[32][64][64]; +uint32 GSLocalMemory::pageOffset8[32][64][128]; +uint32 GSLocalMemory::pageOffset4[32][128][128]; int GSLocalMemory::rowOffset32[2048]; int GSLocalMemory::rowOffset32Z[2048]; @@ -61,10 +64,14 @@ int GSLocalMemory::rowOffset16SZ[2048]; int GSLocalMemory::rowOffset8[2][2048]; int GSLocalMemory::rowOffset4[2][2048]; -// - -DWORD GSLocalMemory::m_xtbl[1024]; -DWORD GSLocalMemory::m_ytbl[1024]; +int GSLocalMemory::blockOffset32[256]; +int GSLocalMemory::blockOffset32Z[256]; +int GSLocalMemory::blockOffset16[256]; +int GSLocalMemory::blockOffset16S[256]; +int GSLocalMemory::blockOffset16Z[256]; +int GSLocalMemory::blockOffset16SZ[256]; +int GSLocalMemory::blockOffset8[256]; +int GSLocalMemory::blockOffset4[256]; // @@ -75,7 +82,7 @@ GSLocalMemory::psm_t GSLocalMemory::m_psm[64]; GSLocalMemory::GSLocalMemory() : m_clut(this) { - m_vm8 = (BYTE*)VirtualAlloc(NULL, m_vmsize * 2, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + m_vm8 = (uint8*)VirtualAlloc(NULL, m_vmsize * 2, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); memset(m_vm8, 0, m_vmsize); @@ -138,22 +145,60 @@ GSLocalMemory::GSLocalMemory() for(int x = 0; x < countof(rowOffset8[0]); x++) { - rowOffset8[0][x] = (int)PixelAddress8(x, 0, 0, 32) - (int)PixelAddress8(0, 0, 0, 32), + rowOffset8[0][x] = (int)PixelAddress8(x, 0, 0, 32) - (int)PixelAddress8(0, 0, 0, 32); rowOffset8[1][x] = (int)PixelAddress8(x, 2, 0, 32) - (int)PixelAddress8(0, 2, 0, 32); } for(int x = 0; x < countof(rowOffset4[0]); x++) { - rowOffset4[0][x] = (int)PixelAddress4(x, 0, 0, 32) - (int)PixelAddress4(0, 0, 0, 32), + rowOffset4[0][x] = (int)PixelAddress4(x, 0, 0, 32) - (int)PixelAddress4(0, 0, 0, 32); rowOffset4[1][x] = (int)PixelAddress4(x, 2, 0, 32) - (int)PixelAddress4(0, 2, 0, 32); } + for(int x = 0; x < countof(blockOffset32); x++) + { + blockOffset32[x] = (int)BlockNumber32(x << 3, 0, 0, 32) - (int)BlockNumber32(0, 0, 0, 32); + } + + for(int x = 0; x < countof(blockOffset32Z); x++) + { + blockOffset32Z[x] = (int)BlockNumber32Z(x << 3, 0, 0, 32) - (int)BlockNumber32Z(0, 0, 0, 32); + } + + for(int x = 0; x < countof(blockOffset16); x++) + { + blockOffset16[x] = (int)BlockNumber16(x << 3, 0, 0, 32) - (int)BlockNumber16(0, 0, 0, 32); + } + + for(int x = 0; x < countof(blockOffset16S); x++) + { + blockOffset16S[x] = (int)BlockNumber16S(x << 3, 0, 0, 32) - (int)BlockNumber16S(0, 0, 0, 32); + } + + for(int x = 0; x < countof(blockOffset16Z); x++) + { + blockOffset16Z[x] = (int)BlockNumber16Z(x << 3, 0, 0, 32) - (int)BlockNumber16Z(0, 0, 0, 32); + } + + for(int x = 0; x < countof(blockOffset16SZ); x++) + { + blockOffset16SZ[x] = (int)BlockNumber16SZ(x << 3, 0, 0, 32) - (int)BlockNumber16SZ(0, 0, 0, 32); + } + + for(int x = 0; x < countof(blockOffset8); x++) + { + blockOffset8[x] = (int)BlockNumber8(x << 3, 0, 0, 32) - (int)BlockNumber8(0, 0, 0, 32); + } + + for(int x = 0; x < countof(blockOffset4); x++) + { + blockOffset4[x] = (int)BlockNumber4(x << 3, 0, 0, 32) - (int)BlockNumber4(0, 0, 0, 32); + } + for(int i = 0; i < countof(m_psm); i++) { m_psm[i].pa = &GSLocalMemory::PixelAddress32; - m_psm[i].ba = &GSLocalMemory::BlockAddress32; - m_psm[i].pga = &GSLocalMemory::PageAddress32; - m_psm[i].pgn = &GSLocalMemory::PageNumber32; + m_psm[i].bn = &GSLocalMemory::BlockNumber32; m_psm[i].rp = &GSLocalMemory::ReadPixel32; m_psm[i].rpa = &GSLocalMemory::ReadPixel32; m_psm[i].wp = &GSLocalMemory::WritePixel32; @@ -167,11 +212,14 @@ GSLocalMemory::GSLocalMemory() m_psm[i].rtx = &GSLocalMemory::ReadTexture32; m_psm[i].rtxNP = &GSLocalMemory::ReadTexture32; m_psm[i].rtxP = &GSLocalMemory::ReadTexture32; + m_psm[i].rtxb = &GSLocalMemory::ReadTextureBlock32; + m_psm[i].rtxbP = &GSLocalMemory::ReadTextureBlock32; m_psm[i].bpp = m_psm[i].trbpp = 32; m_psm[i].pal = 0; - m_psm[i].bs = CSize(8, 8); - m_psm[i].pgs = CSize(64, 32); + m_psm[i].bs = GSVector2i(8, 8); + m_psm[i].pgs = GSVector2i(64, 32); for(int j = 0; j < 8; j++) m_psm[i].rowOffset[j] = rowOffset32; + m_psm[i].blockOffset = blockOffset32; } m_psm[PSM_PSMCT16].pa = &GSLocalMemory::PixelAddress16; @@ -183,28 +231,14 @@ GSLocalMemory::GSLocalMemory() m_psm[PSM_PSMZ16].pa = &GSLocalMemory::PixelAddress16Z; m_psm[PSM_PSMZ16S].pa = &GSLocalMemory::PixelAddress16SZ; - m_psm[PSM_PSMCT16].ba = &GSLocalMemory::BlockAddress16; - m_psm[PSM_PSMCT16S].ba = &GSLocalMemory::BlockAddress16S; - m_psm[PSM_PSMT8].ba = &GSLocalMemory::BlockAddress8; - m_psm[PSM_PSMT4].ba = &GSLocalMemory::BlockAddress4; - m_psm[PSM_PSMZ32].ba = &GSLocalMemory::BlockAddress32Z; - m_psm[PSM_PSMZ24].ba = &GSLocalMemory::BlockAddress32Z; - m_psm[PSM_PSMZ16].ba = &GSLocalMemory::BlockAddress16Z; - m_psm[PSM_PSMZ16S].ba = &GSLocalMemory::BlockAddress16SZ; - - m_psm[PSM_PSMCT16].pga = &GSLocalMemory::PageAddress16; - m_psm[PSM_PSMCT16S].pga = &GSLocalMemory::PageAddress16; - m_psm[PSM_PSMZ16].pga = &GSLocalMemory::PageAddress16; - m_psm[PSM_PSMZ16S].pga = &GSLocalMemory::PageAddress16; - m_psm[PSM_PSMT8].pga = &GSLocalMemory::PageAddress8; - m_psm[PSM_PSMT4].pga = &GSLocalMemory::PageAddress4; - - m_psm[PSM_PSMCT16].pgn = &GSLocalMemory::PageNumber16; - m_psm[PSM_PSMCT16S].pgn = &GSLocalMemory::PageNumber16; - m_psm[PSM_PSMZ16].pgn = &GSLocalMemory::PageNumber16; - m_psm[PSM_PSMZ16S].pgn = &GSLocalMemory::PageNumber16; - m_psm[PSM_PSMT8].pgn = &GSLocalMemory::PageNumber8; - m_psm[PSM_PSMT4].pgn = &GSLocalMemory::PageNumber4; + m_psm[PSM_PSMCT16].bn = &GSLocalMemory::BlockNumber16; + m_psm[PSM_PSMCT16S].bn = &GSLocalMemory::BlockNumber16S; + m_psm[PSM_PSMT8].bn = &GSLocalMemory::BlockNumber8; + m_psm[PSM_PSMT4].bn = &GSLocalMemory::BlockNumber4; + m_psm[PSM_PSMZ32].bn = &GSLocalMemory::BlockNumber32Z; + m_psm[PSM_PSMZ24].bn = &GSLocalMemory::BlockNumber32Z; + m_psm[PSM_PSMZ16].bn = &GSLocalMemory::BlockNumber16Z; + m_psm[PSM_PSMZ16S].bn = &GSLocalMemory::BlockNumber16SZ; m_psm[PSM_PSMCT24].rp = &GSLocalMemory::ReadPixel24; m_psm[PSM_PSMCT16].rp = &GSLocalMemory::ReadPixel16; @@ -342,11 +376,44 @@ GSLocalMemory::GSLocalMemory() m_psm[PSM_PSMZ16].rtxNP = &GSLocalMemory::ReadTexture16ZNP; m_psm[PSM_PSMZ16S].rtxNP = &GSLocalMemory::ReadTexture16SZNP; + m_psm[PSM_PSMCT24].rtxP = &GSLocalMemory::ReadTexture24; + m_psm[PSM_PSMCT16].rtxP = &GSLocalMemory::ReadTexture16; + m_psm[PSM_PSMCT16S].rtxP = &GSLocalMemory::ReadTexture16S; m_psm[PSM_PSMT8].rtxP = &GSLocalMemory::ReadTexture8P; m_psm[PSM_PSMT4].rtxP = &GSLocalMemory::ReadTexture4P; m_psm[PSM_PSMT8H].rtxP = &GSLocalMemory::ReadTexture8HP; m_psm[PSM_PSMT4HL].rtxP = &GSLocalMemory::ReadTexture4HLP; m_psm[PSM_PSMT4HH].rtxP = &GSLocalMemory::ReadTexture4HHP; + m_psm[PSM_PSMZ32].rtxP = &GSLocalMemory::ReadTexture32Z; + m_psm[PSM_PSMZ24].rtxP = &GSLocalMemory::ReadTexture24Z; + m_psm[PSM_PSMZ16].rtxP = &GSLocalMemory::ReadTexture16Z; + m_psm[PSM_PSMZ16S].rtxP = &GSLocalMemory::ReadTexture16SZ; + + m_psm[PSM_PSMCT24].rtxb = &GSLocalMemory::ReadTextureBlock24; + m_psm[PSM_PSMCT16].rtxb = &GSLocalMemory::ReadTextureBlock16; + m_psm[PSM_PSMCT16S].rtxb = &GSLocalMemory::ReadTextureBlock16S; + m_psm[PSM_PSMT8].rtxb = &GSLocalMemory::ReadTextureBlock8; + m_psm[PSM_PSMT4].rtxb = &GSLocalMemory::ReadTextureBlock4; + m_psm[PSM_PSMT8H].rtxb = &GSLocalMemory::ReadTextureBlock8H; + m_psm[PSM_PSMT4HL].rtxb = &GSLocalMemory::ReadTextureBlock4HL; + m_psm[PSM_PSMT4HH].rtxb = &GSLocalMemory::ReadTextureBlock4HH; + m_psm[PSM_PSMZ32].rtxb = &GSLocalMemory::ReadTextureBlock32Z; + m_psm[PSM_PSMZ24].rtxb = &GSLocalMemory::ReadTextureBlock24Z; + m_psm[PSM_PSMZ16].rtxb = &GSLocalMemory::ReadTextureBlock16Z; + m_psm[PSM_PSMZ16S].rtxb = &GSLocalMemory::ReadTextureBlock16SZ; + + m_psm[PSM_PSMCT24].rtxbP = &GSLocalMemory::ReadTextureBlock24; + m_psm[PSM_PSMCT16].rtxbP = &GSLocalMemory::ReadTextureBlock16; + m_psm[PSM_PSMCT16S].rtxbP = &GSLocalMemory::ReadTextureBlock16S; + m_psm[PSM_PSMT8].rtxbP = &GSLocalMemory::ReadTextureBlock8P; + m_psm[PSM_PSMT4].rtxbP = &GSLocalMemory::ReadTextureBlock4P; + m_psm[PSM_PSMT8H].rtxbP = &GSLocalMemory::ReadTextureBlock8HP; + m_psm[PSM_PSMT4HL].rtxbP = &GSLocalMemory::ReadTextureBlock4HLP; + m_psm[PSM_PSMT4HH].rtxbP = &GSLocalMemory::ReadTextureBlock4HHP; + m_psm[PSM_PSMZ32].rtxbP = &GSLocalMemory::ReadTextureBlock32Z; + m_psm[PSM_PSMZ24].rtxbP = &GSLocalMemory::ReadTextureBlock24Z; + m_psm[PSM_PSMZ16].rtxbP = &GSLocalMemory::ReadTextureBlock16Z; + m_psm[PSM_PSMZ16S].rtxbP = &GSLocalMemory::ReadTextureBlock16SZ; m_psm[PSM_PSMT8].pal = m_psm[PSM_PSMT8H].pal = 256; m_psm[PSM_PSMT4].pal = m_psm[PSM_PSMT4HL].pal = m_psm[PSM_PSMT4HH].pal = 16; @@ -363,15 +430,15 @@ GSLocalMemory::GSLocalMemory() m_psm[PSM_PSMZ24].trbpp = 24; m_psm[PSM_PSMZ16].trbpp = m_psm[PSM_PSMZ16S].trbpp = 16; - m_psm[PSM_PSMCT16].bs = m_psm[PSM_PSMCT16S].bs = CSize(16, 8); - m_psm[PSM_PSMT8].bs = CSize(16, 16); - m_psm[PSM_PSMT4].bs = CSize(32, 16); - m_psm[PSM_PSMZ16].bs = m_psm[PSM_PSMZ16S].bs = CSize(16, 8); + m_psm[PSM_PSMCT16].bs = m_psm[PSM_PSMCT16S].bs = GSVector2i(16, 8); + m_psm[PSM_PSMT8].bs = GSVector2i(16, 16); + m_psm[PSM_PSMT4].bs = GSVector2i(32, 16); + m_psm[PSM_PSMZ16].bs = m_psm[PSM_PSMZ16S].bs = GSVector2i(16, 8); - m_psm[PSM_PSMCT16].pgs = m_psm[PSM_PSMCT16S].pgs = CSize(64, 64); - m_psm[PSM_PSMT8].pgs = CSize(128, 64); - m_psm[PSM_PSMT4].pgs = CSize(128, 128); - m_psm[PSM_PSMZ16].pgs = m_psm[PSM_PSMZ16S].pgs = CSize(64, 64); + m_psm[PSM_PSMCT16].pgs = m_psm[PSM_PSMCT16S].pgs = GSVector2i(64, 64); + m_psm[PSM_PSMT8].pgs = GSVector2i(128, 64); + m_psm[PSM_PSMT4].pgs = GSVector2i(128, 128); + m_psm[PSM_PSMZ16].pgs = m_psm[PSM_PSMZ16S].pgs = GSVector2i(64, 64); for(int i = 0; i < 8; i++) m_psm[PSM_PSMCT16].rowOffset[i] = rowOffset16; for(int i = 0; i < 8; i++) m_psm[PSM_PSMCT16S].rowOffset[i] = rowOffset16S; @@ -381,49 +448,49 @@ GSLocalMemory::GSLocalMemory() for(int i = 0; i < 8; i++) m_psm[PSM_PSMZ24].rowOffset[i] = rowOffset32Z; for(int i = 0; i < 8; i++) m_psm[PSM_PSMZ16].rowOffset[i] = rowOffset16Z; for(int i = 0; i < 8; i++) m_psm[PSM_PSMZ16S].rowOffset[i] = rowOffset16SZ; + + m_psm[PSM_PSMCT16].blockOffset = blockOffset16; + m_psm[PSM_PSMCT16S].blockOffset = blockOffset16S; + m_psm[PSM_PSMT8].blockOffset = blockOffset8; + m_psm[PSM_PSMT4].blockOffset = blockOffset4; + m_psm[PSM_PSMZ32].blockOffset = blockOffset32Z; + m_psm[PSM_PSMZ24].blockOffset = blockOffset32Z; + m_psm[PSM_PSMZ16].blockOffset = blockOffset16Z; + m_psm[PSM_PSMZ16S].blockOffset = blockOffset16SZ; } GSLocalMemory::~GSLocalMemory() { VirtualFree(m_vm8, 0, MEM_RELEASE); - POSITION pos = m_omap.GetHeadPosition(); - - while(pos) + for(hash_map::iterator i = m_omap.begin(); i != m_omap.end(); i++) { - Offset* o = m_omap.GetNextValue(pos); - - for(int i = 0; i < countof(o->col); i++) - { - _aligned_free(o->col); - } + Offset* o = i->second; + + _aligned_free(o->col[0]); _aligned_free(o); } - m_omap.RemoveAll(); - - pos = m_o4map.GetHeadPosition(); - - while(pos) + for(hash_map::iterator i = m_o4map.begin(); i != m_o4map.end(); i++) { - _aligned_free(m_o4map.GetNextValue(pos)); + _aligned_free(i->second); } - - m_o4map.RemoveAll(); } -GSLocalMemory::Offset* GSLocalMemory::GetOffset(DWORD bp, DWORD bw, DWORD psm) +GSLocalMemory::Offset* GSLocalMemory::GetOffset(uint32 bp, uint32 bw, uint32 psm) { if(bw == 0) {ASSERT(0); return NULL;} ASSERT(m_psm[psm].bpp > 8); // only for 16/24/32/8h/4hh/4hl formats where all columns are the same - DWORD hash = bp | (bw << 14) | (psm << 20); + uint32 hash = bp | (bw << 14) | (psm << 20); - if(CRBMap::CPair* pair = m_omap.Lookup(hash)) + hash_map::iterator i = m_omap.find(hash); + + if(i != m_omap.end()) { - return pair->m_value; + return i->second; } Offset* o = (Offset*)_aligned_malloc(sizeof(Offset), 16); @@ -446,31 +513,33 @@ GSLocalMemory::Offset* GSLocalMemory::GetOffset(DWORD bp, DWORD bw, DWORD psm) memcpy(o->col[i], m_psm[psm].rowOffset[0], sizeof(int) * 2048); } - m_omap.SetAt(hash, o); + m_omap[hash] = o; return o; } GSLocalMemory::Offset4* GSLocalMemory::GetOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF) { - DWORD fbp = FRAME.Block(); - DWORD zbp = ZBUF.Block(); - DWORD fpsm = FRAME.PSM; - DWORD zpsm = ZBUF.PSM; - DWORD bw = FRAME.FBW; + uint32 fbp = FRAME.Block(); + uint32 zbp = ZBUF.Block(); + uint32 fpsm = FRAME.PSM; + uint32 zpsm = ZBUF.PSM; + uint32 bw = FRAME.FBW; ASSERT(m_psm[fpsm].trbpp > 8 || m_psm[zpsm].trbpp > 8); // "(psm & 0x0f) ^ ((psm & 0xf0) >> 2)" creates 4 bit unique identifiers for render target formats (only) - DWORD fpsm_hash = (fpsm & 0x0f) ^ ((fpsm & 0x30) >> 2); - DWORD zpsm_hash = (zpsm & 0x0f) ^ ((zpsm & 0x30) >> 2); + uint32 fpsm_hash = (fpsm & 0x0f) ^ ((fpsm & 0x30) >> 2); + uint32 zpsm_hash = (zpsm & 0x0f) ^ ((zpsm & 0x30) >> 2); - DWORD hash = (FRAME.FBP << 0) | (ZBUF.ZBP << 9) | (bw << 18) | (fpsm_hash << 24) | (zpsm_hash << 28); + uint32 hash = (FRAME.FBP << 0) | (ZBUF.ZBP << 9) | (bw << 18) | (fpsm_hash << 24) | (zpsm_hash << 28); - if(CRBMap::CPair* pair = m_o4map.Lookup(hash)) + hash_map::iterator i = m_o4map.find(hash); + + if(i != m_o4map.end()) { - return pair->m_value; + return i->second; } Offset4* o = (Offset4*)_aligned_malloc(sizeof(Offset4), 16); @@ -495,172 +564,18 @@ GSLocalMemory::Offset4* GSLocalMemory::GetOffset4(const GIFRegFRAME& FRAME, cons o->col[i].y = m_psm[zpsm].rowOffset[0][i * 4] << zs; } - m_o4map.SetAt(hash, o); + m_o4map[hash] = o; return o; } -bool GSLocalMemory::FillRect(const GSVector4i& r, DWORD c, DWORD psm, DWORD bp, DWORD bw) -{ - const psm_t& tbl = m_psm[psm]; - - writePixel wp = tbl.wp; - pixelAddress ba = tbl.ba; - - int w = tbl.bs.cx; - int h = tbl.bs.cy; - int bpp = tbl.bpp; - - int shift = 0; - - switch(bpp) - { - case 32: shift = 0; break; - case 16: shift = 1; c = (c & 0xffff) * 0x00010001; break; - case 8: shift = 2; c = (c & 0xff) * 0x01010101; break; - case 4: shift = 3; c = (c & 0xf) * 0x11111111; break; - } - - CRect clip; - - clip.left = (r.x + (w - 1)) & ~(w - 1); - clip.top = (r.y + (h - 1)) & ~(h - 1); - clip.right = r.z & ~(w - 1); - clip.bottom = r.w & ~(h - 1); - - for(int y = r.y; y < clip.top; y++) - { - for(int x = r.x; x < r.z; x++) - { - (this->*wp)(x, y, c, bp, bw); - } - } - - for(int y = clip.bottom; y < r.w; y++) - { - for(int x = r.x; x < r.z; x++) - { - (this->*wp)(x, y, c, bp, bw); - } - } - - if(r.x < clip.left || clip.right < r.z) - { - for(int y = clip.top; y < clip.bottom; y += h) - { - for(int ys = y, ye = y + h; ys < ye; ys++) - { - for(int x = r.x; x < clip.left; x++) - { - (this->*wp)(x, ys, c, bp, bw); - } - - for(int x = clip.right; x < r.z; x++) - { - (this->*wp)(x, ys, c, bp, bw); - } - } - } - } - - if(psm == PSM_PSMCT24 || psm == PSM_PSMZ24) - { - #if _M_SSE >= 0x200 - - GSVector4i c128(c); - GSVector4i mask(0x00ffffff); - - for(int y = clip.top; y < clip.bottom; y += h) - { - for(int x = clip.left; x < clip.right; x += w) - { - GSVector4i* p = (GSVector4i*)&m_vm8[ba(x, y, bp, bw) << 2 >> shift]; - - for(int i = 0; i < 16; i += 4) - { - p[i + 0] = p[i + 0].blend8(c128, mask); - p[i + 1] = p[i + 1].blend8(c128, mask); - p[i + 2] = p[i + 2].blend8(c128, mask); - p[i + 3] = p[i + 3].blend8(c128, mask); - } - } - } - - #else - - c &= 0x00ffffff; - - for(int y = clip.top; y < clip.bottom; y += h) - { - for(int x = clip.left; x < clip.right; x += w) - { - DWORD* p = &m_vm32[ba(x, y, bp, bw)]; - - for(int i = 0; i < 64; i += 4) - { - p[i + 0] = (p[i + 0] & 0xff000000) | c; - p[i + 1] = (p[i + 1] & 0xff000000) | c; - p[i + 2] = (p[i + 2] & 0xff000000) | c; - p[i + 3] = (p[i + 3] & 0xff000000) | c; - } - } - } - - #endif - } - else - { - #if _M_SSE >= 0x200 - - GSVector4i c128(c); - - for(int y = clip.top; y < clip.bottom; y += h) - { - for(int x = clip.left; x < clip.right; x += w) - { - GSVector4i* p = (GSVector4i*)&m_vm8[ba(x, y, bp, bw) << 2 >> shift]; - - for(int i = 0; i < 16; i += 4) - { - p[i + 0] = c128; - p[i + 1] = c128; - p[i + 2] = c128; - p[i + 3] = c128; - } - } - } - - #else - - for(int y = clip.top; y < clip.bottom; y += h) - { - for(int x = clip.left; x < clip.right; x += w) - { - DWORD* p = (DWORD*)&m_vm8[ba(x, y, bp, bw) << 2 >> shift]; - - for(int i = 0; i < 64; i += 4) - { - p[i + 0] = c; - p[i + 1] = c; - p[i + 2] = c; - p[i + 3] = c; - } - } - } - - #endif - } - - return true; -} - //////////////////// template -void GSLocalMemory::WriteImageColumn(int l, int r, int y, int h, BYTE* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF) +void GSLocalMemory::WriteImageColumn(int l, int r, int y, int h, uint8* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF) { - DWORD bp = BITBLTBUF.DBP; - DWORD bw = BITBLTBUF.DBW; + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; const int csy = bsy / 4; @@ -670,14 +585,14 @@ void GSLocalMemory::WriteImageColumn(int l, int r, int y, int h, BYTE* src, int { switch(psm) { - case PSM_PSMCT32: WriteColumn32(y, (BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], &src[x * 4], srcpitch); break; - case PSM_PSMCT16: WriteColumn16(y, (BYTE*)&m_vm16[BlockAddress16(x, y, bp, bw)], &src[x * 2], srcpitch); break; - case PSM_PSMCT16S: WriteColumn16(y, (BYTE*)&m_vm16[BlockAddress16S(x, y, bp, bw)], &src[x * 2], srcpitch); break; - case PSM_PSMT8: WriteColumn8(y, (BYTE*)&m_vm8[BlockAddress8(x, y, bp, bw)], &src[x], srcpitch); break; - case PSM_PSMT4: WriteColumn4(y, (BYTE*)&m_vm8[BlockAddress4(x, y, bp, bw) >> 1], &src[x >> 1], srcpitch); break; - case PSM_PSMZ32: WriteColumn32(y, (BYTE*)&m_vm32[BlockAddress32Z(x, y, bp, bw)], &src[x * 4], srcpitch); break; - case PSM_PSMZ16: WriteColumn16(y, (BYTE*)&m_vm16[BlockAddress16Z(x, y, bp, bw)], &src[x * 2], srcpitch); break; - case PSM_PSMZ16S: WriteColumn16(y, (BYTE*)&m_vm16[BlockAddress16SZ(x, y, bp, bw)], &src[x * 2], srcpitch); break; + case PSM_PSMCT32: WriteColumn32(y, BlockPtr32(x, y, bp, bw), &src[x * 4], srcpitch); break; + case PSM_PSMCT16: WriteColumn16(y, BlockPtr16(x, y, bp, bw), &src[x * 2], srcpitch); break; + case PSM_PSMCT16S: WriteColumn16(y, BlockPtr16S(x, y, bp, bw), &src[x * 2], srcpitch); break; + case PSM_PSMT8: WriteColumn8(y, BlockPtr8(x, y, bp, bw), &src[x], srcpitch); break; + case PSM_PSMT4: WriteColumn4(y, BlockPtr4(x, y, bp, bw), &src[x >> 1], srcpitch); break; + case PSM_PSMZ32: WriteColumn32(y, BlockPtr32Z(x, y, bp, bw), &src[x * 4], srcpitch); break; + case PSM_PSMZ16: WriteColumn16(y, BlockPtr16Z(x, y, bp, bw), &src[x * 2], srcpitch); break; + case PSM_PSMZ16S: WriteColumn16(y, BlockPtr16SZ(x, y, bp, bw), &src[x * 2], srcpitch); break; // TODO default: __assume(0); } @@ -686,10 +601,10 @@ void GSLocalMemory::WriteImageColumn(int l, int r, int y, int h, BYTE* src, int } template -void GSLocalMemory::WriteImageBlock(int l, int r, int y, int h, BYTE* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF) +void GSLocalMemory::WriteImageBlock(int l, int r, int y, int h, uint8* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF) { - DWORD bp = BITBLTBUF.DBP; - DWORD bw = BITBLTBUF.DBW; + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; for(int offset = srcpitch * bsy; h >= bsy; h -= bsy, y += bsy, src += offset) { @@ -697,14 +612,14 @@ void GSLocalMemory::WriteImageBlock(int l, int r, int y, int h, BYTE* src, int s { switch(psm) { - case PSM_PSMCT32: WriteBlock32((BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], &src[x * 4], srcpitch); break; - case PSM_PSMCT16: WriteBlock16((BYTE*)&m_vm16[BlockAddress16(x, y, bp, bw)], &src[x * 2], srcpitch); break; - case PSM_PSMCT16S: WriteBlock16((BYTE*)&m_vm16[BlockAddress16S(x, y, bp, bw)], &src[x * 2], srcpitch); break; - case PSM_PSMT8: WriteBlock8((BYTE*)&m_vm8[BlockAddress8(x, y, bp, bw)], &src[x], srcpitch); break; - case PSM_PSMT4: WriteBlock4((BYTE*)&m_vm8[BlockAddress4(x, y, bp, bw) >> 1], &src[x >> 1], srcpitch); break; - case PSM_PSMZ32: WriteBlock32((BYTE*)&m_vm32[BlockAddress32Z(x, y, bp, bw)], &src[x * 4], srcpitch); break; - case PSM_PSMZ16: WriteBlock16((BYTE*)&m_vm16[BlockAddress16Z(x, y, bp, bw)], &src[x * 2], srcpitch); break; - case PSM_PSMZ16S: WriteBlock16((BYTE*)&m_vm16[BlockAddress16SZ(x, y, bp, bw)], &src[x * 2], srcpitch); break; + case PSM_PSMCT32: WriteBlock32(BlockPtr32(x, y, bp, bw), &src[x * 4], srcpitch); break; + case PSM_PSMCT16: WriteBlock16(BlockPtr16(x, y, bp, bw), &src[x * 2], srcpitch); break; + case PSM_PSMCT16S: WriteBlock16(BlockPtr16S(x, y, bp, bw), &src[x * 2], srcpitch); break; + case PSM_PSMT8: WriteBlock8(BlockPtr8(x, y, bp, bw), &src[x], srcpitch); break; + case PSM_PSMT4: WriteBlock4(BlockPtr4(x, y, bp, bw), &src[x >> 1], srcpitch); break; + case PSM_PSMZ32: WriteBlock32(BlockPtr32Z(x, y, bp, bw), &src[x * 4], srcpitch); break; + case PSM_PSMZ16: WriteBlock16(BlockPtr16Z(x, y, bp, bw), &src[x * 2], srcpitch); break; + case PSM_PSMZ16S: WriteBlock16(BlockPtr16SZ(x, y, bp, bw), &src[x * 2], srcpitch); break; // TODO default: __assume(0); } @@ -713,10 +628,10 @@ void GSLocalMemory::WriteImageBlock(int l, int r, int y, int h, BYTE* src, int s } template -void GSLocalMemory::WriteImageLeftRight(int l, int r, int y, int h, BYTE* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF) +void GSLocalMemory::WriteImageLeftRight(int l, int r, int y, int h, uint8* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF) { - DWORD bp = BITBLTBUF.DBP; - DWORD bw = BITBLTBUF.DBW; + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; for(; h > 0; y++, h--, src += srcpitch) { @@ -724,14 +639,14 @@ void GSLocalMemory::WriteImageLeftRight(int l, int r, int y, int h, BYTE* src, i { switch(psm) { - case PSM_PSMCT32: WritePixel32(x, y, *(DWORD*)&src[x * 4], bp, bw); break; - case PSM_PSMCT16: WritePixel16(x, y, *(WORD*)&src[x * 2], bp, bw); break; - case PSM_PSMCT16S: WritePixel16S(x, y, *(WORD*)&src[x * 2], bp, bw); break; + case PSM_PSMCT32: WritePixel32(x, y, *(uint32*)&src[x * 4], bp, bw); break; + case PSM_PSMCT16: WritePixel16(x, y, *(uint16*)&src[x * 2], bp, bw); break; + case PSM_PSMCT16S: WritePixel16S(x, y, *(uint16*)&src[x * 2], bp, bw); break; case PSM_PSMT8: WritePixel8(x, y, src[x], bp, bw); break; case PSM_PSMT4: WritePixel4(x, y, src[x >> 1] >> ((x & 1) << 2), bp, bw); break; - case PSM_PSMZ32: WritePixel32Z(x, y, *(DWORD*)&src[x * 4], bp, bw); break; - case PSM_PSMZ16: WritePixel16Z(x, y, *(WORD*)&src[x * 2], bp, bw); break; - case PSM_PSMZ16S: WritePixel16SZ(x, y, *(WORD*)&src[x * 2], bp, bw); break; + case PSM_PSMZ32: WritePixel32Z(x, y, *(uint32*)&src[x * 4], bp, bw); break; + case PSM_PSMZ16: WritePixel16Z(x, y, *(uint16*)&src[x * 2], bp, bw); break; + case PSM_PSMZ16S: WritePixel16SZ(x, y, *(uint16*)&src[x * 2], bp, bw); break; // TODO default: __assume(0); } @@ -740,12 +655,12 @@ void GSLocalMemory::WriteImageLeftRight(int l, int r, int y, int h, BYTE* src, i } template -void GSLocalMemory::WriteImageTopBottom(int l, int r, int y, int h, BYTE* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF) +void GSLocalMemory::WriteImageTopBottom(int l, int r, int y, int h, uint8* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF) { - __declspec(align(16)) BYTE buff[64]; // merge buffer for one column + __declspec(align(16)) uint8 buff[64]; // merge buffer for one column - DWORD bp = BITBLTBUF.DBP; - DWORD bw = BITBLTBUF.DBW; + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; const int csy = bsy / 4; @@ -759,18 +674,18 @@ void GSLocalMemory::WriteImageTopBottom(int l, int r, int y, int h, BYTE* src, i for(int x = l; x < r; x += bsx) { - BYTE* dst = NULL; + uint8* dst = NULL; switch(psm) { - case PSM_PSMCT32: dst = (BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)]; break; - case PSM_PSMCT16: dst = (BYTE*)&m_vm16[BlockAddress16(x, y, bp, bw)]; break; - case PSM_PSMCT16S: dst = (BYTE*)&m_vm16[BlockAddress16S(x, y, bp, bw)]; break; - case PSM_PSMT8: dst = (BYTE*)&m_vm8[BlockAddress8(x, y, bp, bw)]; break; - case PSM_PSMT4: dst = (BYTE*)&m_vm8[BlockAddress4(x, y, bp, bw) >> 1]; break; - case PSM_PSMZ32: dst = (BYTE*)&m_vm32[BlockAddress32Z(x, y, bp, bw)]; break; - case PSM_PSMZ16: dst = (BYTE*)&m_vm16[BlockAddress16Z(x, y, bp, bw)]; break; - case PSM_PSMZ16S: dst = (BYTE*)&m_vm16[BlockAddress16SZ(x, y, bp, bw)]; break; + case PSM_PSMCT32: dst = BlockPtr32(x, y, bp, bw); break; + case PSM_PSMCT16: dst = BlockPtr16(x, y, bp, bw); break; + case PSM_PSMCT16S: dst = BlockPtr16S(x, y, bp, bw); break; + case PSM_PSMT8: dst = BlockPtr8(x, y, bp, bw); break; + case PSM_PSMT4: dst = BlockPtr4(x, y, bp, bw); break; + case PSM_PSMZ32: dst = BlockPtr32Z(x, y, bp, bw); break; + case PSM_PSMZ16: dst = BlockPtr16Z(x, y, bp, bw); break; + case PSM_PSMZ16S: dst = BlockPtr16SZ(x, y, bp, bw); break; // TODO default: __assume(0); } @@ -793,12 +708,12 @@ void GSLocalMemory::WriteImageTopBottom(int l, int r, int y, int h, BYTE* src, i break; case PSM_PSMT8: ReadColumn8(y, dst, buff, 16); - memcpy(&buff[y2 * 16], &src[x], h2 * 16); + for(int i = 0, j = y2; i < h2; i++, j++) memcpy(&buff[j * 16], &src[i * srcpitch + x], 16); WriteColumn8(y, dst, buff, 16); break; case PSM_PSMT4: ReadColumn4(y, dst, buff, 16); - memcpy(&buff[y2 * 16], &src[x >> 1], h2 * 16); + for(int i = 0, j = y2; i < h2; i++, j++) memcpy(&buff[j * 16], &src[i * srcpitch + (x >> 1)], 16); WriteColumn4(y, dst, buff, 16); break; // TODO @@ -840,18 +755,18 @@ void GSLocalMemory::WriteImageTopBottom(int l, int r, int y, int h, BYTE* src, i { for(int x = l; x < r; x += bsx) { - BYTE* dst = NULL; + uint8* dst = NULL; switch(psm) { - case PSM_PSMCT32: dst = (BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)]; break; - case PSM_PSMCT16: dst = (BYTE*)&m_vm16[BlockAddress16(x, y, bp, bw)]; break; - case PSM_PSMCT16S: dst = (BYTE*)&m_vm16[BlockAddress16S(x, y, bp, bw)]; break; - case PSM_PSMT8: dst = (BYTE*)&m_vm8[BlockAddress8(x, y, bp, bw)]; break; - case PSM_PSMT4: dst = (BYTE*)&m_vm8[BlockAddress4(x, y, bp, bw) >> 1]; break; - case PSM_PSMZ32: dst = (BYTE*)&m_vm32[BlockAddress32Z(x, y, bp, bw)]; break; - case PSM_PSMZ16: dst = (BYTE*)&m_vm16[BlockAddress16Z(x, y, bp, bw)]; break; - case PSM_PSMZ16S: dst = (BYTE*)&m_vm16[BlockAddress16SZ(x, y, bp, bw)]; break; + case PSM_PSMCT32: dst = BlockPtr32(x, y, bp, bw); break; + case PSM_PSMCT16: dst = BlockPtr16(x, y, bp, bw); break; + case PSM_PSMCT16S: dst = BlockPtr16S(x, y, bp, bw); break; + case PSM_PSMT8: dst = BlockPtr8(x, y, bp, bw); break; + case PSM_PSMT4: dst = BlockPtr4(x, y, bp, bw); break; + case PSM_PSMZ32: dst = BlockPtr32Z(x, y, bp, bw); break; + case PSM_PSMZ16: dst = BlockPtr16Z(x, y, bp, bw); break; + case PSM_PSMZ16S: dst = BlockPtr16SZ(x, y, bp, bw); break; // TODO default: __assume(0); } @@ -874,12 +789,12 @@ void GSLocalMemory::WriteImageTopBottom(int l, int r, int y, int h, BYTE* src, i break; case PSM_PSMT8: ReadColumn8(y, dst, buff, 16); - memcpy(&buff[0], &src[x], h * 16); + for(int i = 0; i < h; i++) memcpy(&buff[i * 16], &src[i * srcpitch + x], 16); WriteColumn8(y, dst, buff, 16); break; case PSM_PSMT4: ReadColumn4(y, dst, buff, 16); - memcpy(&buff[0], &src[x >> 1], h * 16); + for(int i = 0; i < h; i++) memcpy(&buff[i * 16], &src[i * srcpitch + (x >> 1)], 16); WriteColumn4(y, dst, buff, 16); break; // TODO @@ -891,7 +806,7 @@ void GSLocalMemory::WriteImageTopBottom(int l, int r, int y, int h, BYTE* src, i } template -void GSLocalMemory::WriteImage(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) +void GSLocalMemory::WriteImage(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) { if(TRXREG.RRW == 0) return; @@ -915,7 +830,7 @@ void GSLocalMemory::WriteImage(int& tx, int& ty, BYTE* src, int len, GIFRegBITBL if(ra - la >= bsx && h > 0) // "transfer width" >= "block width" && there is at least one full row { - BYTE* s = &src[-l * trbpp >> 3]; + uint8* s = &src[-l * trbpp >> 3]; src += srcpitch * h; len -= srcpitch * h; @@ -1000,12 +915,12 @@ void GSLocalMemory::WriteImage(int& tx, int& ty, BYTE* src, int len, GIFRegBITBL #define IsTopLeftAligned(dsax, tx, ty, bw, bh) \ ((((int)dsax) & ((bw)-1)) == 0 && ((tx) & ((bw)-1)) == 0 && ((int)dsax) == (tx) && ((ty) & ((bh)-1)) == 0) -void GSLocalMemory::WriteImage24(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) +void GSLocalMemory::WriteImage24(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) { if(TRXREG.RRW == 0) return; - DWORD bp = BITBLTBUF.DBP; - DWORD bw = BITBLTBUF.DBW; + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; int tw = TRXPOS.DSAX + TRXREG.RRW, srcpitch = TRXREG.RRW * 3; int th = len / srcpitch; @@ -1026,7 +941,7 @@ void GSLocalMemory::WriteImage24(int& tx, int& ty, BYTE* src, int len, GIFRegBIT { for(int x = tx; x < tw; x += 8) { - UnpackAndWriteBlock24(src + (x - tx) * 3, srcpitch, (BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)]); + UnpackAndWriteBlock24(src + (x - tx) * 3, srcpitch, BlockPtr32(x, y, bp, bw)); } } @@ -1034,12 +949,12 @@ void GSLocalMemory::WriteImage24(int& tx, int& ty, BYTE* src, int len, GIFRegBIT } } -void GSLocalMemory::WriteImage8H(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) +void GSLocalMemory::WriteImage8H(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) { if(TRXREG.RRW == 0) return; - DWORD bp = BITBLTBUF.DBP; - DWORD bw = BITBLTBUF.DBW; + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; int tw = TRXPOS.DSAX + TRXREG.RRW, srcpitch = TRXREG.RRW; int th = len / srcpitch; @@ -1060,7 +975,7 @@ void GSLocalMemory::WriteImage8H(int& tx, int& ty, BYTE* src, int len, GIFRegBIT { for(int x = tx; x < tw; x += 8) { - UnpackAndWriteBlock8H(src + (x - tx), srcpitch, (BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)]); + UnpackAndWriteBlock8H(src + (x - tx), srcpitch, BlockPtr32(x, y, bp, bw)); } } @@ -1068,12 +983,12 @@ void GSLocalMemory::WriteImage8H(int& tx, int& ty, BYTE* src, int len, GIFRegBIT } } -void GSLocalMemory::WriteImage4HL(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) +void GSLocalMemory::WriteImage4HL(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) { if(TRXREG.RRW == 0) return; - DWORD bp = BITBLTBUF.DBP; - DWORD bw = BITBLTBUF.DBW; + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; int tw = TRXPOS.DSAX + TRXREG.RRW, srcpitch = TRXREG.RRW / 2; int th = len / srcpitch; @@ -1094,7 +1009,7 @@ void GSLocalMemory::WriteImage4HL(int& tx, int& ty, BYTE* src, int len, GIFRegBI { for(int x = tx; x < tw; x += 8) { - UnpackAndWriteBlock4HL(src + (x - tx) / 2, srcpitch, (BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)]); + UnpackAndWriteBlock4HL(src + (x - tx) / 2, srcpitch, BlockPtr32(x, y, bp, bw)); } } @@ -1102,12 +1017,12 @@ void GSLocalMemory::WriteImage4HL(int& tx, int& ty, BYTE* src, int len, GIFRegBI } } -void GSLocalMemory::WriteImage4HH(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) +void GSLocalMemory::WriteImage4HH(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) { if(TRXREG.RRW == 0) return; - DWORD bp = BITBLTBUF.DBP; - DWORD bw = BITBLTBUF.DBW; + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; int tw = TRXPOS.DSAX + TRXREG.RRW, srcpitch = TRXREG.RRW / 2; int th = len / srcpitch; @@ -1128,19 +1043,19 @@ void GSLocalMemory::WriteImage4HH(int& tx, int& ty, BYTE* src, int len, GIFRegBI { for(int x = tx; x < tw; x += 8) { - UnpackAndWriteBlock4HH(src + (x - tx) / 2, srcpitch, (BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)]); + UnpackAndWriteBlock4HH(src + (x - tx) / 2, srcpitch, BlockPtr32(x, y, bp, bw)); } } ty = th; } } -void GSLocalMemory::WriteImage24Z(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) +void GSLocalMemory::WriteImage24Z(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) { if(TRXREG.RRW == 0) return; - DWORD bp = BITBLTBUF.DBP; - DWORD bw = BITBLTBUF.DBW; + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; int tw = TRXPOS.DSAX + TRXREG.RRW, srcpitch = TRXREG.RRW * 3; int th = len / srcpitch; @@ -1161,23 +1076,23 @@ void GSLocalMemory::WriteImage24Z(int& tx, int& ty, BYTE* src, int len, GIFRegBI { for(int x = tx; x < tw; x += 8) { - UnpackAndWriteBlock24(src + (x - tx) * 3, srcpitch, (BYTE*)&m_vm32[BlockAddress32Z(x, y, bp, bw)]); + UnpackAndWriteBlock24(src + (x - tx) * 3, srcpitch, BlockPtr32Z(x, y, bp, bw)); } } ty = th; } } -void GSLocalMemory::WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) +void GSLocalMemory::WriteImageX(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) { if(len <= 0) return; - BYTE* pb = (BYTE*)src; - WORD* pw = (WORD*)src; - DWORD* pd = (DWORD*)src; + uint8* pb = (uint8*)src; + uint16* pw = (uint16*)src; + uint32* pd = (uint32*)src; - DWORD bp = BITBLTBUF.DBP; - DWORD bw = BITBLTBUF.DBW; + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; psm_t* psm = &m_psm[BITBLTBUF.DPSM]; int x = tx; @@ -1194,7 +1109,7 @@ void GSLocalMemory::WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITB while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x++, pd++) @@ -1214,12 +1129,12 @@ void GSLocalMemory::WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITB while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x++, pb += 3) { - WritePixel24(addr + offset[x], *(DWORD*)pb); + WritePixel24(addr + offset[x], *(uint32*)pb); } if(x == ex) {x = sx; y++;} @@ -1236,7 +1151,7 @@ void GSLocalMemory::WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITB while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x++, pw++) @@ -1253,7 +1168,7 @@ void GSLocalMemory::WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITB while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x++, pb++) @@ -1270,7 +1185,7 @@ void GSLocalMemory::WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITB while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x += 2, pb++) @@ -1288,7 +1203,7 @@ void GSLocalMemory::WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITB while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x++, pb++) @@ -1305,7 +1220,7 @@ void GSLocalMemory::WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITB while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x += 2, pb++) @@ -1323,7 +1238,7 @@ void GSLocalMemory::WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITB while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x += 2, pb++) @@ -1344,16 +1259,16 @@ void GSLocalMemory::WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITB // -void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) const +void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) const { if(len <= 0) return; - BYTE* pb = (BYTE*)dst; - WORD* pw = (WORD*)dst; - DWORD* pd = (DWORD*)dst; + uint8* pb = (uint8*)dst; + uint16* pw = (uint16*)dst; + uint32* pd = (uint32*)dst; - DWORD bp = BITBLTBUF.SBP; - DWORD bw = BITBLTBUF.SBW; + uint32 bp = BITBLTBUF.SBP; + uint32 bw = BITBLTBUF.SBW; psm_t* psm = &m_psm[BITBLTBUF.SPSM]; int x = tx; @@ -1370,7 +1285,7 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBL while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x++, pd++) @@ -1390,16 +1305,16 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBL while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x++, pb += 3) { - DWORD dw = ReadPixel32(addr + offset[x]); + uint32 c = ReadPixel32(addr + offset[x]); - pb[0] = ((BYTE*)&dw)[0]; - pb[1] = ((BYTE*)&dw)[1]; - pb[2] = ((BYTE*)&dw)[2]; + pb[0] = ((uint8*)&c)[0]; + pb[1] = ((uint8*)&c)[1]; + pb[2] = ((uint8*)&c)[2]; } if(x == ex) {x = sx; y++;} @@ -1416,7 +1331,7 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBL while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x++, pw++) @@ -1433,7 +1348,7 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBL while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x++, pb++) @@ -1450,7 +1365,7 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBL while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x += 2, pb++) @@ -1467,7 +1382,7 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBL while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x++, pb++) @@ -1484,7 +1399,7 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBL while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x += 2, pb++) @@ -1501,7 +1416,7 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBL while(len > 0) { - DWORD addr = psm->pa(0, y, bp, bw); + uint32 addr = psm->pa(0, y, bp, bw); int* offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x += 2, pb++) @@ -1521,166 +1436,165 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBL /////////////////// -void GSLocalMemory::ReadTexture32(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture32(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMCT32) { - ReadBlock32((BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], dst, dstpitch); + ReadBlock32(src, dst, dstpitch); } FOREACH_BLOCK_END - } -void GSLocalMemory::ReadTexture24(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { if(TEXA.AEM) { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMCT24) { - ReadAndExpandBlock24((BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], dst, dstpitch, TEXA); + ReadAndExpandBlock24(src, dst, dstpitch, TEXA); } FOREACH_BLOCK_END } else { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMCT24) { - ReadAndExpandBlock24((BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], dst, dstpitch, TEXA); + ReadAndExpandBlock24(src, dst, dstpitch, TEXA); } FOREACH_BLOCK_END } } -void GSLocalMemory::ReadTexture16(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture16(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - __declspec(align(16)) WORD block[16 * 8]; + __declspec(align(16)) uint16 block[16 * 8]; - FOREACH_BLOCK_START(16, 8, 32) + FOREACH_BLOCK_START(16, 8, 32, PSM_PSMCT16) { - ReadBlock16((BYTE*)&m_vm16[BlockAddress16(x, y, bp, bw)], (BYTE*)block, sizeof(block) / 8); + ReadBlock16(src, (uint8*)block, sizeof(block) / 8); ExpandBlock16(block, dst, dstpitch, TEXA); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture16S(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture16S(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - __declspec(align(16)) WORD block[16 * 8]; + __declspec(align(16)) uint16 block[16 * 8]; - FOREACH_BLOCK_START(16, 8, 32) + FOREACH_BLOCK_START(16, 8, 32, PSM_PSMCT16S) { - ReadBlock16((BYTE*)&m_vm16[BlockAddress16S(x, y, bp, bw)], (BYTE*)block, sizeof(block) / 8); + ReadBlock16(src, (uint8*)block, sizeof(block) / 8); ExpandBlock16(block, dst, dstpitch, TEXA); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture8(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture8(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - const DWORD* pal = m_clut; + const uint32* pal = m_clut; - FOREACH_BLOCK_START(16, 16, 32) + FOREACH_BLOCK_START(16, 16, 32, PSM_PSMT8) { - ReadAndExpandBlock8_32((BYTE*)&m_vm8[BlockAddress8(x, y, bp, bw)], dst, dstpitch, pal); + ReadAndExpandBlock8_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture4(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture4(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - const UINT64* pal = m_clut; + const uint64* pal = m_clut; - FOREACH_BLOCK_START(32, 16, 32) + FOREACH_BLOCK_START(32, 16, 32, PSM_PSMT4) { - ReadAndExpandBlock4_32((BYTE*)&m_vm8[BlockAddress4(x, y, bp, bw) >> 1], dst, dstpitch, pal); + ReadAndExpandBlock4_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture8H(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture8H(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - const DWORD* pal = m_clut; + const uint32* pal = m_clut; - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT8H) { - ReadAndExpandBlock8H_32((BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], dst, dstpitch, pal); + ReadAndExpandBlock8H_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture4HL(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture4HL(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - const DWORD* pal = m_clut; + const uint32* pal = m_clut; - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT4HL) { - ReadAndExpandBlock4HL_32((BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], dst, dstpitch, pal); + ReadAndExpandBlock4HL_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture4HH(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture4HH(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - const DWORD* pal = m_clut; + const uint32* pal = m_clut; - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT4HH) { - ReadAndExpandBlock4HH_32((BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], dst, dstpitch, pal); + ReadAndExpandBlock4HH_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture32Z(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture32Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMZ32) { - ReadBlock32((BYTE*)&m_vm32[BlockAddress32Z(x, y, bp, bw)], dst, dstpitch); + ReadBlock32(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture24Z(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { if(TEXA.AEM) { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMZ24) { - ReadAndExpandBlock24((BYTE*)&m_vm32[BlockAddress32Z(x, y, bp, bw)], dst, dstpitch, TEXA); + ReadAndExpandBlock24(src, dst, dstpitch, TEXA); } FOREACH_BLOCK_END } else { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMZ24) { - ReadAndExpandBlock24((BYTE*)&m_vm32[BlockAddress32Z(x, y, bp, bw)], dst, dstpitch, TEXA); + ReadAndExpandBlock24(src, dst, dstpitch, TEXA); } FOREACH_BLOCK_END } } -void GSLocalMemory::ReadTexture16Z(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture16Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - __declspec(align(16)) WORD block[16 * 8]; + __declspec(align(16)) uint16 block[16 * 8]; - FOREACH_BLOCK_START(16, 8, 32) + FOREACH_BLOCK_START(16, 8, 32, PSM_PSMZ16) { - ReadBlock16((BYTE*)&m_vm16[BlockAddress16Z(x, y, bp, bw)], (BYTE*)block, sizeof(block) / 8); + ReadBlock16(src, (uint8*)block, sizeof(block) / 8); ExpandBlock16(block, dst, dstpitch, TEXA); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture16SZ(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture16SZ(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - __declspec(align(16)) WORD block[16 * 8]; + __declspec(align(16)) uint16 block[16 * 8]; - FOREACH_BLOCK_START(16, 8, 32) + FOREACH_BLOCK_START(16, 8, 32, PSM_PSMZ16S) { - ReadBlock16((BYTE*)&m_vm16[BlockAddress16SZ(x, y, bp, bw)], (BYTE*)block, sizeof(block) / 8); + ReadBlock16(src, (uint8*)block, sizeof(block) / 8); ExpandBlock16(block, dst, dstpitch, TEXA); } @@ -1689,36 +1603,132 @@ void GSLocalMemory::ReadTexture16SZ(const CRect& r, BYTE* dst, int dstpitch, con /////////////////// -void GSLocalMemory::ReadTexture(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP) +void GSLocalMemory::ReadTextureBlock32(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const { - readTexture rtx = m_psm[TEX0.PSM].rtx; - readTexel rt = m_psm[TEX0.PSM].rt; - CSize bs = m_psm[TEX0.PSM].bs; + ALIGN_STACK(16); - if(r.Width() < bs.cx || r.Height() < bs.cy - || (r.left & (bs.cx-1)) || (r.top & (bs.cy-1)) - || (r.right & (bs.cx-1)) || (r.bottom & (bs.cy-1)) - || (CLAMP.WMS == 3) || (CLAMP.WMT == 3)) + ReadBlock32(BlockPtr(bp), dst, dstpitch); +} + +void GSLocalMemory::ReadTextureBlock24(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + ALIGN_STACK(16); + + if(TEXA.AEM) { - ReadTexture(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, rtx); + ReadAndExpandBlock24(BlockPtr(bp), dst, dstpitch, TEXA); } else { - (this->*rtx)(r, dst, dstpitch, TEX0, TEXA); + ReadAndExpandBlock24(BlockPtr(bp), dst, dstpitch, TEXA); } } -void GSLocalMemory::ReadTextureNC(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP) +void GSLocalMemory::ReadTextureBlock16(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + __declspec(align(16)) uint16 block[16 * 8]; + + ReadBlock16(BlockPtr(bp), (uint8*)block, sizeof(block) / 8); + + ExpandBlock16(block, dst, dstpitch, TEXA); +} + +void GSLocalMemory::ReadTextureBlock16S(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + __declspec(align(16)) uint16 block[16 * 8]; + + ReadBlock16(BlockPtr(bp), (uint8*)block, sizeof(block) / 8); + + ExpandBlock16(block, dst, dstpitch, TEXA); +} + +void GSLocalMemory::ReadTextureBlock8(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + ALIGN_STACK(16); + + ReadAndExpandBlock8_32(BlockPtr(bp), dst, dstpitch, m_clut); +} + +void GSLocalMemory::ReadTextureBlock4(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + ALIGN_STACK(16); + + ReadAndExpandBlock4_32(BlockPtr(bp), dst, dstpitch, m_clut); +} + +void GSLocalMemory::ReadTextureBlock8H(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + ALIGN_STACK(16); + + ReadAndExpandBlock8H_32(BlockPtr(bp), dst, dstpitch, m_clut); +} + +void GSLocalMemory::ReadTextureBlock4HL(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + ALIGN_STACK(16); + + ReadAndExpandBlock4HL_32(BlockPtr(bp), dst, dstpitch, m_clut); +} + +void GSLocalMemory::ReadTextureBlock4HH(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + ALIGN_STACK(16); + + ReadAndExpandBlock4HH_32(BlockPtr(bp), dst, dstpitch, m_clut); +} + +void GSLocalMemory::ReadTextureBlock32Z(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + ALIGN_STACK(16); + + ReadBlock32(BlockPtr(bp), dst, dstpitch); +} + +void GSLocalMemory::ReadTextureBlock24Z(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + ALIGN_STACK(16); + + if(TEXA.AEM) + { + ReadAndExpandBlock24(BlockPtr(bp), dst, dstpitch, TEXA); + } + else + { + ReadAndExpandBlock24(BlockPtr(bp), dst, dstpitch, TEXA); + } +} + +void GSLocalMemory::ReadTextureBlock16Z(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + __declspec(align(16)) uint16 block[16 * 8]; + + ReadBlock16(BlockPtr(bp), (uint8*)block, sizeof(block) / 8); + + ExpandBlock16(block, dst, dstpitch, TEXA); +} + +void GSLocalMemory::ReadTextureBlock16SZ(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + __declspec(align(16)) uint16 block[16 * 8]; + + ReadBlock16(BlockPtr(bp), (uint8*)block, sizeof(block) / 8); + + ExpandBlock16(block, dst, dstpitch, TEXA); +} + +/////////////////// + +void GSLocalMemory::ReadTexture(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) { readTexture rtx = m_psm[TEX0.PSM].rtx; readTexel rt = m_psm[TEX0.PSM].rt; - CSize bs = m_psm[TEX0.PSM].bs; + GSVector2i bs = m_psm[TEX0.PSM].bs; - if(r.Width() < bs.cx || r.Height() < bs.cy - || (r.left & (bs.cx-1)) || (r.top & (bs.cy-1)) - || (r.right & (bs.cx-1)) || (r.bottom & (bs.cy-1))) + if(r.width() < bs.x || r.height() < bs.y + || (r.left & (bs.x - 1)) || (r.top & (bs.y - 1)) + || (r.right & (bs.x - 1)) || (r.bottom & (bs.y - 1))) { - ReadTextureNC(r, dst, dstpitch, TEX0, TEXA, rt, rtx); + ReadTexture(r, dst, dstpitch, TEX0, TEXA, rt, rtx); } else { @@ -1727,33 +1737,33 @@ void GSLocalMemory::ReadTextureNC(const CRect& r, BYTE* dst, int dstpitch, const } /////////////////// -void GSLocalMemory::ReadTexture16NP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture16NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(16, 8, 16) + FOREACH_BLOCK_START(16, 8, 16, PSM_PSMCT16) { - ReadBlock16((BYTE*)&m_vm16[BlockAddress16(x, y, bp, bw)], dst, dstpitch); + ReadBlock16(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture16SNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture16SNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(16, 8, 16) + FOREACH_BLOCK_START(16, 8, 16, PSM_PSMCT16S) { - ReadBlock16((BYTE*)&m_vm16[BlockAddress16S(x, y, bp, bw)], dst, dstpitch); + ReadBlock16(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture8NP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture8NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - const DWORD* pal = m_clut; + const uint32* pal = m_clut; if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) { - FOREACH_BLOCK_START(16, 16, 32) + FOREACH_BLOCK_START(16, 16, 32, PSM_PSMT8) { - ReadAndExpandBlock8_32((BYTE*)&m_vm8[BlockAddress8(x, y, bp, bw)], dst, dstpitch, pal); + ReadAndExpandBlock8_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1761,11 +1771,11 @@ void GSLocalMemory::ReadTexture8NP(const CRect& r, BYTE* dst, int dstpitch, cons { ASSERT(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S); - __declspec(align(16)) BYTE block[16 * 16]; + __declspec(align(16)) uint8 block[16 * 16]; - FOREACH_BLOCK_START(16, 16, 16) + FOREACH_BLOCK_START(16, 16, 16, PSM_PSMT8) { - ReadBlock8(&m_vm8[BlockAddress8(x, y, bp, bw)], (BYTE*)block, sizeof(block) / 16); + ReadBlock8(src, (uint8*)block, sizeof(block) / 16); ExpandBlock8_16(block, dst, dstpitch, pal); } @@ -1773,15 +1783,15 @@ void GSLocalMemory::ReadTexture8NP(const CRect& r, BYTE* dst, int dstpitch, cons } } -void GSLocalMemory::ReadTexture4NP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture4NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - const UINT64* pal = m_clut; + const uint64* pal = m_clut; if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) { - FOREACH_BLOCK_START(32, 16, 32) + FOREACH_BLOCK_START(32, 16, 32, PSM_PSMT4) { - ReadAndExpandBlock4_32(&m_vm8[BlockAddress4(x, y, bp, bw) >> 1], dst, dstpitch, pal); + ReadAndExpandBlock4_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1789,11 +1799,11 @@ void GSLocalMemory::ReadTexture4NP(const CRect& r, BYTE* dst, int dstpitch, cons { ASSERT(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S); - __declspec(align(16)) BYTE block[(32 / 2) * 16]; + __declspec(align(16)) uint8 block[(32 / 2) * 16]; - FOREACH_BLOCK_START(32, 16, 16) + FOREACH_BLOCK_START(32, 16, 16, PSM_PSMT4) { - ReadBlock4(&m_vm8[BlockAddress4(x, y, bp, bw)>>1], (BYTE*)block, sizeof(block) / 16); + ReadBlock4(src, (uint8*)block, sizeof(block) / 16); ExpandBlock4_16(block, dst, dstpitch, pal); } @@ -1801,15 +1811,15 @@ void GSLocalMemory::ReadTexture4NP(const CRect& r, BYTE* dst, int dstpitch, cons } } -void GSLocalMemory::ReadTexture8HNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture8HNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - const DWORD* pal = m_clut; + const uint32* pal = m_clut; if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT8H) { - ReadAndExpandBlock8H_32((const BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], dst, dstpitch, pal); + ReadAndExpandBlock8H_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1817,11 +1827,11 @@ void GSLocalMemory::ReadTexture8HNP(const CRect& r, BYTE* dst, int dstpitch, con { ASSERT(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S); - __declspec(align(16)) DWORD block[8 * 8]; + __declspec(align(16)) uint32 block[8 * 8]; - FOREACH_BLOCK_START(8, 8, 16) + FOREACH_BLOCK_START(8, 8, 16, PSM_PSMT8H) { - ReadBlock32((const BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], (BYTE*)block, sizeof(block) / 8); + ReadBlock32(src, (uint8*)block, sizeof(block) / 8); ExpandBlock8H_16(block, dst, dstpitch, pal); } @@ -1829,15 +1839,15 @@ void GSLocalMemory::ReadTexture8HNP(const CRect& r, BYTE* dst, int dstpitch, con } } -void GSLocalMemory::ReadTexture4HLNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture4HLNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - const DWORD* pal = m_clut; + const uint32* pal = m_clut; if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT4HL) { - ReadAndExpandBlock4HL_32((const BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], dst, dstpitch, pal); + ReadAndExpandBlock4HL_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1845,11 +1855,11 @@ void GSLocalMemory::ReadTexture4HLNP(const CRect& r, BYTE* dst, int dstpitch, co { ASSERT(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S); - __declspec(align(16)) DWORD block[8 * 8]; + __declspec(align(16)) uint32 block[8 * 8]; - FOREACH_BLOCK_START(8, 8, 16) + FOREACH_BLOCK_START(8, 8, 16, PSM_PSMT4HL) { - ReadBlock32((const BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], (BYTE*)block, sizeof(block) / 8); + ReadBlock32(src, (uint8*)block, sizeof(block) / 8); ExpandBlock4HL_16(block, dst, dstpitch, pal); } @@ -1857,15 +1867,15 @@ void GSLocalMemory::ReadTexture4HLNP(const CRect& r, BYTE* dst, int dstpitch, co } } -void GSLocalMemory::ReadTexture4HHNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - const DWORD* pal = m_clut; + const uint32* pal = m_clut; if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT4HH) { - ReadAndExpandBlock4HH_32((const BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], dst, dstpitch, pal); + ReadAndExpandBlock4HH_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1873,11 +1883,11 @@ void GSLocalMemory::ReadTexture4HHNP(const CRect& r, BYTE* dst, int dstpitch, co { ASSERT(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S); - __declspec(align(16)) DWORD block[8 * 8]; + __declspec(align(16)) uint32 block[8 * 8]; - FOREACH_BLOCK_START(8, 8, 16) + FOREACH_BLOCK_START(8, 8, 16, PSM_PSMT4HH) { - ReadBlock32((const BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], (BYTE*)block, sizeof(block) / 8); + ReadBlock32(src, (uint8*)block, sizeof(block) / 8); ExpandBlock4HH_16(block, dst, dstpitch, pal); } @@ -1885,38 +1895,37 @@ void GSLocalMemory::ReadTexture4HHNP(const CRect& r, BYTE* dst, int dstpitch, co } } -void GSLocalMemory::ReadTexture16ZNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture16ZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(16, 8, 16) + FOREACH_BLOCK_START(16, 8, 16, PSM_PSMZ16) { - ReadBlock16((const BYTE*)&m_vm16[BlockAddress16Z(x, y, bp, bw)], dst, dstpitch); + ReadBlock16(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture16SZNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture16SZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(16, 8, 16) + FOREACH_BLOCK_START(16, 8, 16, PSM_PSMZ16S) { - ReadBlock16((const BYTE*)&m_vm16[BlockAddress16SZ(x, y, bp, bw)], dst, dstpitch); + ReadBlock16(src, dst, dstpitch); } FOREACH_BLOCK_END } /////////////////// -void GSLocalMemory::ReadTextureNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP) +void GSLocalMemory::ReadTextureNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) { readTexture rtx = m_psm[TEX0.PSM].rtxNP; readTexel rt = m_psm[TEX0.PSM].rtNP; - CSize bs = m_psm[TEX0.PSM].bs; + GSVector2i bs = m_psm[TEX0.PSM].bs; - if(r.Width() < bs.cx || r.Height() < bs.cy - || (r.left & (bs.cx-1)) || (r.top & (bs.cy-1)) - || (r.right & (bs.cx-1)) || (r.bottom & (bs.cy-1)) - || (CLAMP.WMS == 3) || (CLAMP.WMT == 3)) + if(r.width() < bs.x || r.height() < bs.y + || (r.left & (bs.x - 1)) || (r.top & (bs.y - 1)) + || (r.right & (bs.x - 1)) || (r.bottom & (bs.y - 1))) { - DWORD psm = TEX0.PSM; + uint32 psm = TEX0.PSM; switch(psm) { @@ -1934,53 +1943,11 @@ void GSLocalMemory::ReadTextureNP(const CRect& r, BYTE* dst, int dstpitch, const default: case PSM_PSMCT32: case PSM_PSMCT24: - ReadTexture(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, rtx); + ReadTexture(r, dst, dstpitch, TEX0, TEXA, rt, rtx); break; case PSM_PSMCT16: case PSM_PSMCT16S: - ReadTexture(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, rtx); - break; - } - } - else - { - (this->*rtx)(r, dst, dstpitch, TEX0, TEXA); - } -} - -void GSLocalMemory::ReadTextureNPNC(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP) -{ - readTexture rtx = m_psm[TEX0.PSM].rtxNP; - readTexel rt = m_psm[TEX0.PSM].rtNP; - CSize bs = m_psm[TEX0.PSM].bs; - - if(r.Width() < bs.cx || r.Height() < bs.cy - || (r.left & (bs.cx-1)) || (r.top & (bs.cy-1)) - || (r.right & (bs.cx-1)) || (r.bottom & (bs.cy-1))) - { - DWORD psm = TEX0.PSM; - - switch(psm) - { - case PSM_PSMT8: - case PSM_PSMT8H: - case PSM_PSMT4: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - psm = TEX0.CPSM; - break; - } - - switch(psm) - { - default: - case PSM_PSMCT32: - case PSM_PSMCT24: - ReadTextureNC(r, dst, dstpitch, TEX0, TEXA, rt, rtx); - break; - case PSM_PSMCT16: - case PSM_PSMCT16S: - ReadTextureNC(r, dst, dstpitch, TEX0, TEXA, rt, rtx); + ReadTexture(r, dst, dstpitch, TEX0, TEXA, rt, rtx); break; } } @@ -1992,320 +1959,101 @@ void GSLocalMemory::ReadTextureNPNC(const CRect& r, BYTE* dst, int dstpitch, con // 32/8 -void GSLocalMemory::ReadTexture8P(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture8P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(16, 16, 8) + FOREACH_BLOCK_START(16, 16, 8, PSM_PSMT8) { - ReadBlock8(&m_vm8[BlockAddress8(x, y, bp, bw)], dst, dstpitch); + ReadBlock8(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture4P(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture4P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(32, 16, 8) + FOREACH_BLOCK_START(32, 16, 8, PSM_PSMT4) { - ReadBlock4P(&m_vm8[BlockAddress4(x, y, bp, bw) >> 1], dst, dstpitch); + ReadBlock4P(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture8HP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture8HP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(8, 8, 8) + FOREACH_BLOCK_START(8, 8, 8, PSM_PSMT8H) { - ReadBlock8HP((BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], dst, dstpitch); + ReadBlock8HP(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture4HLP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture4HLP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(8, 8, 8) + FOREACH_BLOCK_START(8, 8, 8, PSM_PSMT4HL) { - ReadBlock4HLP((BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], dst, dstpitch); + ReadBlock4HLP(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture4HHP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const +void GSLocalMemory::ReadTexture4HHP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(8, 8, 8) + FOREACH_BLOCK_START(8, 8, 8, PSM_PSMT4HH) { - ReadBlock4HHP((BYTE*)&m_vm32[BlockAddress32(x, y, bp, bw)], dst, dstpitch); + ReadBlock4HHP(src, dst, dstpitch); } FOREACH_BLOCK_END } // -template -void GSLocalMemory::ReadTexture(CRect r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, readTexel rt, readTexture rtx) +void GSLocalMemory::ReadTextureBlock8P(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const { - // TODO: this is a mess, make it more simple - - DWORD wms = CLAMP.WMS, wmt = CLAMP.WMT; - DWORD minu = CLAMP.MINU, maxu = CLAMP.MAXU; - DWORD minv = CLAMP.MINV, maxv = CLAMP.MAXV; - - CSize bs = m_psm[TEX0.PSM].bs; - - int bsxm = bs.cx - 1; - int bsym = bs.cy - 1; - - if(wms == 3 || wmt == 3) - { - if(wms == 3 && wmt == 3) - { - int w = minu + 1; - int h = minv + 1; - - w = (w + bsxm) & ~bsxm; - h = (h + bsym) & ~bsym; - - if(w % bs.cx == 0 && maxu % bs.cx == 0 && h % bs.cy == 0 && maxv % bs.cy == 0) - { -// printf("!!! 1 wms = %d, wmt = %d, %3x %3x %3x %3x, %d %d - %d %d\n", wms, wmt, minu, maxu, minv, maxv, r.left, r.top, r.right, r.bottom); - - T* buff = (T*)_aligned_malloc(w * h * sizeof(T), 16); - - (this->*rtx)(CRect(CPoint(maxu, maxv), CSize(w, h)), (BYTE*)buff, w * sizeof(T), TEX0, TEXA); - - dst -= r.left * sizeof(T); - -// int left = (r.left + minu) & ~minu; -// int right = r.right & ~minu; - - for(int y = r.top; y < r.bottom; y++, dst += dstpitch) - { - T* src = &buff[(y & minv) * w]; - - int x = r.left; -/* - for(; x < left; x++) - { - ((T*)dst)[x] = src[x & minu]; - } - - for(; x < right; x += minu + 1) - { - memcpy(&((T*)dst)[x], src, sizeof(T) * (minu + 1)); - } -*/ - for(; x < r.right; x++) - { - ((T*)dst)[x] = src[x & minu]; - } - } - - _aligned_free(buff); - - return; - } - } - - if(wms == 2) - { - int left = r.left; - r.left = min(r.right, max(r.left, (int)minu)); - r.right = max(r.left, min(r.right, (int)maxu + 1)); - dst += (r.left - left) * sizeof(T); - } - - if(wmt == 2) - { - int top = r.top; - r.top = min(r.bottom, max(r.top, (int)minv)); - r.bottom = max(r.top, min(r.bottom, (int)maxv + 1)); - dst += (r.top - top) * dstpitch; - } - - if(wms == 3 && wmt != 3) - { - int w = ((minu + 1) + bsxm) & ~bsxm; - - if(w % bs.cx == 0 && maxu % bs.cx == 0) - { -// printf("!!! 2 wms = %d, wmt = %d, %3x %3x %3x %3x, %d %d - %d %d\n", wms, wmt, minu, maxu, minv, maxv, r.left, r.top, r.right, r.bottom); - int top = r.top & ~bsym; - int bottom = (r.bottom + bsym) & ~bsym; - - int h = bottom - top; - - T* buff = (T*)_aligned_malloc(w * h * sizeof(T), 16); - - (this->*rtx)(CRect(CPoint(maxu, top), CSize(w, h)), (BYTE*)buff, w * sizeof(T), TEX0, TEXA); - - dst -= r.left * sizeof(T); - -// int left = (r.left + minu) & ~minu; -// int right = r.right & ~minu; - - for(int y = r.top; y < r.bottom; y++, dst += dstpitch) - { - T* src = &buff[(y - top) * w]; - - int x = r.left; -/* - for(; x < left; x++) - { - ((T*)dst)[x] = src[x & minu]; - } - - for(; x < right; x += minu + 1) - { - memcpy(&((T*)dst)[x], src, sizeof(T) * (minu + 1)); - } -*/ - for(; x < r.right; x++) - { - ((T*)dst)[x] = src[x & minu]; - } - } - - _aligned_free(buff); - - return; - } - } - - if(wms != 3 && wmt == 3) - { - int h = (minv + 1 + bsym) & ~bsym; - - if(h % bs.cy == 0 && maxv % bs.cy == 0) - { -// printf("!!! 3 wms = %d, wmt = %d, %3x %3x %3x %3x, %d %d - %d %d\n", wms, wmt, minu, maxu, minv, maxv, r.left, r.top, r.right, r.bottom); - int left = r.left & ~bsxm; - int right = (r.right + bsxm) & ~bsxm; - - int w = right - left; - - T* buff = (T*)_aligned_malloc(w * h * sizeof(T), 16); - - (this->*rtx)(CRect(CPoint(left, maxv), CSize(w, h)), (BYTE*)buff, w * sizeof(T), TEX0, TEXA); - - for(int y = r.top; y < r.bottom; y++, dst += dstpitch) - { - T* src = &buff[(y & minv) * w + (r.left - left)]; - - memcpy(dst, src, sizeof(T) * r.Width()); - } - - _aligned_free(buff); - - return; - } - } - - switch(wms) - { - default: for(int x = r.left; x < r.right; x++) m_xtbl[x] = x; break; - case 3: for(int x = r.left; x < r.right; x++) m_xtbl[x] = (x & minu) | maxu; break; - } - - switch(wmt) - { - default: for(int y = r.top; y < r.bottom; y++) m_ytbl[y] = y; break; - case 3: for(int y = r.top; y < r.bottom; y++) m_ytbl[y] = (y & minv) | maxv; break; - } - -// printf("!!! 4 wms = %d, wmt = %d, %3x %3x %3x %3x, %d %d - %d %d\n", wms, wmt, minu, maxu, minv, maxv, r.left, r.top, r.right, r.bottom); - - for(int y = r.top; y < r.bottom; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((T*)dst)[i] = (T)(this->*rt)(m_xtbl[x], m_ytbl[y], TEX0, TEXA); - } - else - { - // find a block-aligned rect that fits between r and the region clamped area (if any) - - CRect r1 = r; - CRect r2 = r; - - r1.left = (r1.left + bsxm) & ~bsxm; - r1.top = (r1.top + bsym) & ~bsym; - r1.right = r1.right & ~bsxm; - r1.bottom = r1.bottom & ~bsym; - - if(wms == 2 && minu < maxu) - { - r2.left = minu & ~bsxm; - r2.right = (maxu + bsxm) & ~bsxm; - } - - if(wmt == 2 && minv < maxv) - { - r2.top = minv & ~bsym; - r2.bottom = (maxv + bsym) & ~bsym; - } - - CRect cr = r1 & r2; - - bool aligned = ((DWORD_PTR)(dst + (cr.left - r.left) * sizeof(T)) & 0xf) == 0; - - if(cr.left >= cr.right && cr.top >= cr.bottom || !aligned) - { - // TODO: expand r to block size, read into temp buffer, copy to r (like above) - -if(!aligned) printf("unaligned memory pointer passed to ReadTexture\n"); - -// printf("!!! 5 wms = %d, wmt = %d, %3x %3x %3x %3x, %d %d - %d %d\n", wms, wmt, minu, maxu, minv, maxv, r.left, r.top, r.right, r.bottom); - - for(int y = r.top; y < r.bottom; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA); - } - else - { -// printf("!!! 6 wms = %d, wmt = %d, %3x %3x %3x %3x, %d %d - %d %d\n", wms, wmt, minu, maxu, minv, maxv, r.left, r.top, r.right, r.bottom); - - for(int y = r.top; y < cr.top; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA); - - if(!cr.IsRectEmpty()) - { - (this->*rtx)(cr, dst + (cr.left - r.left) * sizeof(T), dstpitch, TEX0, TEXA); - } - - for(int y = cr.top; y < cr.bottom; y++, dst += dstpitch) - { - for(int x = r.left, i = 0; x < cr.left; x++, i++) - ((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA); - for(int x = cr.right, i = x - r.left; x < r.right; x++, i++) - ((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA); - } - - for(int y = cr.bottom; y < r.bottom; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA); - } - } + ReadBlock8(BlockPtr(bp), dst, dstpitch); } -template -void GSLocalMemory::ReadTextureNC(CRect r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, readTexel rt, readTexture rtx) +void GSLocalMemory::ReadTextureBlock4P(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const { - CSize bs = m_psm[TEX0.PSM].bs; + ALIGN_STACK(16); - int bsxm = bs.cx - 1; - int bsym = bs.cy - 1; + ReadBlock4P(BlockPtr(bp), dst, dstpitch); +} - CRect cr; +void GSLocalMemory::ReadTextureBlock8HP(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + ALIGN_STACK(16); - cr.left = (r.left + bsxm) & ~bsxm; - cr.top = (r.top + bsym) & ~bsym; - cr.right = r.right & ~bsxm; - cr.bottom = r.bottom & ~bsym; + ReadBlock8HP(BlockPtr(bp), dst, dstpitch); +} + +void GSLocalMemory::ReadTextureBlock4HLP(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + ALIGN_STACK(16); + + ReadBlock4HLP(BlockPtr(bp), dst, dstpitch); +} + +void GSLocalMemory::ReadTextureBlock4HHP(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const +{ + ALIGN_STACK(16); + + ReadBlock4HHP(BlockPtr(bp), dst, dstpitch); +} + +// + +template +void GSLocalMemory::ReadTexture(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, readTexel rt, readTexture rtx) +{ + GSVector4i cr = r.ralign(m_psm[TEX0.PSM].bs); bool aligned = ((DWORD_PTR)(dst + (cr.left - r.left) * sizeof(T)) & 0xf) == 0; - if(cr.left >= cr.right && cr.top >= cr.bottom || !aligned) + if(cr.rempty() || !aligned) { // TODO: expand r to block size, read into temp buffer, copy to r (like above) -if(!aligned) printf("unaligned memory pointer passed to ReadTexture\n"); +if(!aligned) +printf("unaligned memory pointer passed to ReadTexture\n"); for(int y = r.top; y < r.bottom; y++, dst += dstpitch) for(int x = r.left, i = 0; x < r.right; x++, i++) @@ -2317,7 +2065,7 @@ if(!aligned) printf("unaligned memory pointer passed to ReadTexture\n"); for(int x = r.left, i = 0; x < r.right; x++, i++) ((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA); - if(!cr.IsRectEmpty()) + if(!cr.rempty()) (this->*rtx)(cr, dst + (cr.left - r.left) * sizeof(T), dstpitch, TEX0, TEXA); for(int y = cr.top; y < cr.bottom; y++, dst += dstpitch) @@ -2334,7 +2082,7 @@ if(!aligned) printf("unaligned memory pointer passed to ReadTexture\n"); } } -HRESULT GSLocalMemory::SaveBMP(LPCTSTR fn, DWORD bp, DWORD bw, DWORD psm, int w, int h) +HRESULT GSLocalMemory::SaveBMP(const string& fn, uint32 bp, uint32 bw, uint32 psm, int w, int h) { int pitch = w * 4; int size = pitch * h; @@ -2352,17 +2100,15 @@ HRESULT GSLocalMemory::SaveBMP(LPCTSTR fn, DWORD bp, DWORD bw, DWORD psm, int w, TEXA.TA0 = 0; TEXA.TA1 = 0x80; - // (this->*m_psm[TEX0.PSM].rtx)(CRect(0, 0, w, h), bits, pitch, TEX0, TEXA); - readPixel rp = m_psm[psm].rp; - BYTE* p = (BYTE*)bits; + uint8* p = (uint8*)bits; for(int j = h-1; j >= 0; j--, p += pitch) for(int i = 0; i < w; i++) - ((DWORD*)p)[i] = (this->*rp)(i, j, TEX0.TBP0, TEX0.TBW); + ((uint32*)p)[i] = (this->*rp)(i, j, TEX0.TBP0, TEX0.TBW); - if(FILE* fp = _tfopen(fn, _T("wb"))) + if(FILE* fp = fopen(fn.c_str(), "wb")) { BITMAPINFOHEADER bih; memset(&bih, 0, sizeof(bih)); diff --git a/plugins/GSdx/GSLocalMemory.h b/plugins/GSdx/GSLocalMemory.h index bcc18e5a6f..a09e972c8d 100644 --- a/plugins/GSdx/GSLocalMemory.h +++ b/plugins/GSdx/GSLocalMemory.h @@ -32,24 +32,25 @@ class GSLocalMemory : public GSBlock { public: - typedef DWORD (*pixelAddress)(int x, int y, DWORD bp, DWORD bw); - typedef void (GSLocalMemory::*writePixel)(int x, int y, DWORD c, DWORD bp, DWORD bw); - typedef void (GSLocalMemory::*writeFrame)(int x, int y, DWORD c, DWORD bp, DWORD bw); - typedef DWORD (GSLocalMemory::*readPixel)(int x, int y, DWORD bp, DWORD bw) const; - typedef DWORD (GSLocalMemory::*readTexel)(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - typedef void (GSLocalMemory::*writePixelAddr)(DWORD addr, DWORD c); - typedef void (GSLocalMemory::*writeFrameAddr)(DWORD addr, DWORD c); - typedef DWORD (GSLocalMemory::*readPixelAddr)(DWORD addr) const; - typedef DWORD (GSLocalMemory::*readTexelAddr)(DWORD addr, const GIFRegTEXA& TEXA) const; - typedef void (GSLocalMemory::*writeImage)(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - typedef void (GSLocalMemory::*readImage)(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) const; - typedef void (GSLocalMemory::*readTexture)(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + typedef uint32 (*pixelAddress)(int x, int y, uint32 bp, uint32 bw); + typedef void (GSLocalMemory::*writePixel)(int x, int y, uint32 c, uint32 bp, uint32 bw); + typedef void (GSLocalMemory::*writeFrame)(int x, int y, uint32 c, uint32 bp, uint32 bw); + typedef uint32 (GSLocalMemory::*readPixel)(int x, int y, uint32 bp, uint32 bw) const; + typedef uint32 (GSLocalMemory::*readTexel)(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + typedef void (GSLocalMemory::*writePixelAddr)(uint32 addr, uint32 c); + typedef void (GSLocalMemory::*writeFrameAddr)(uint32 addr, uint32 c); + typedef uint32 (GSLocalMemory::*readPixelAddr)(uint32 addr) const; + typedef uint32 (GSLocalMemory::*readTexelAddr)(uint32 addr, const GIFRegTEXA& TEXA) const; + typedef void (GSLocalMemory::*writeImage)(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); + typedef void (GSLocalMemory::*readImage)(int& tx, int& ty, uint8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) const; + typedef void (GSLocalMemory::*readTexture)(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + typedef void (GSLocalMemory::*readTextureBlock)(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; typedef union { struct { - pixelAddress pa, ba, pga, pgn; + pixelAddress pa, bn; readPixel rp; readPixelAddr rpa; writePixel wp; @@ -60,18 +61,23 @@ public: writeImage wi; readImage ri; readTexture rtx, rtxNP, rtxP; - DWORD bpp, pal, trbpp; - CSize bs, pgs; + readTextureBlock rtxb, rtxbP; + short bpp, trbpp; + int pal; + GSVector2i bs, pgs; int* rowOffset[8]; + int* blockOffset; }; - BYTE dummy[128]; + + uint8 dummy[128]; + } psm_t; static psm_t m_psm[64]; static const int m_vmsize = 1024 * 1024 * 4; - union {BYTE* m_vm8; WORD* m_vm16; DWORD* m_vm32;}; + union {uint8* m_vm8; uint16* m_vm16; uint32* m_vm32;}; GSClut m_clut; @@ -79,7 +85,7 @@ public: { GSVector4i row[2048]; // 0 | 0 | 0 | 0 int* col[4]; // x | x+1 | x+2 | x+3 - DWORD hash; + uint32 hash; }; struct Offset4 @@ -88,18 +94,18 @@ public: GSVector2i row[2048]; // f yn | z yn (n = 0 1 2 ...) GSVector2i col[512]; // f xn | z xn (n = 0 4 8 ...) - DWORD hash; + uint32 hash; }; protected: - static DWORD pageOffset32[32][32][64]; - static DWORD pageOffset32Z[32][32][64]; - static DWORD pageOffset16[32][64][64]; - static DWORD pageOffset16S[32][64][64]; - static DWORD pageOffset16Z[32][64][64]; - static DWORD pageOffset16SZ[32][64][64]; - static DWORD pageOffset8[32][64][128]; - static DWORD pageOffset4[32][128][128]; + static uint32 pageOffset32[32][32][64]; + static uint32 pageOffset32Z[32][32][64]; + static uint32 pageOffset16[32][64][64]; + static uint32 pageOffset16S[32][64][64]; + static uint32 pageOffset16Z[32][64][64]; + static uint32 pageOffset16SZ[32][64][64]; + static uint32 pageOffset8[32][64][128]; + static uint32 pageOffset4[32][128][128]; static int rowOffset32[2048]; static int rowOffset32Z[2048]; @@ -110,12 +116,21 @@ protected: static int rowOffset8[2][2048]; static int rowOffset4[2][2048]; - __forceinline static DWORD Expand24To32(DWORD c, const GIFRegTEXA& TEXA) + static int blockOffset32[256]; + static int blockOffset32Z[256]; + static int blockOffset16[256]; + static int blockOffset16S[256]; + static int blockOffset16Z[256]; + static int blockOffset16SZ[256]; + static int blockOffset8[256]; + static int blockOffset4[256]; + + __forceinline static uint32 Expand24To32(uint32 c, const GIFRegTEXA& TEXA) { return (((!TEXA.AEM | (c & 0xffffff)) ? TEXA.TA0 : 0) << 24) | (c & 0xffffff); } - __forceinline static DWORD Expand16To32(WORD c, const GIFRegTEXA& TEXA) + __forceinline static uint32 Expand16To32(uint16 c, const GIFRegTEXA& TEXA) { return (((c & 0x8000) ? TEXA.TA1 : (!TEXA.AEM | c) ? TEXA.TA0 : 0) << 24) | ((c & 0x7c00) << 9) | ((c & 0x03e0) << 6) | ((c & 0x001f) << 3); } @@ -126,884 +141,711 @@ protected: // - CRBMapC m_omap; - CRBMapC m_o4map; + hash_map m_omap; + hash_map m_o4map; public: GSLocalMemory(); virtual ~GSLocalMemory(); - Offset* GetOffset(DWORD bp, DWORD bw, DWORD psm); + Offset* GetOffset(uint32 bp, uint32 bw, uint32 psm); Offset4* GetOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF); // address - static DWORD PageNumber32(int x, int y, DWORD bp, DWORD bw) + static uint32 BlockNumber32(int x, int y, uint32 bp, uint32 bw) { - return (bp >> 5) + (y >> 5) * bw + (x >> 6); + return bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable32[(y >> 3) & 3][(x >> 3) & 7]; } - static DWORD PageNumber16(int x, int y, DWORD bp, DWORD bw) + static uint32 BlockNumber16(int x, int y, uint32 bp, uint32 bw) { - return (bp >> 5) + (y >> 6) * bw + (x >> 6); + return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16[(y >> 3) & 7][(x >> 4) & 3]; } - static DWORD PageNumber8(int x, int y, DWORD bp, DWORD bw) + static uint32 BlockNumber16S(int x, int y, uint32 bp, uint32 bw) + { + return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16S[(y >> 3) & 7][(x >> 4) & 3]; + } + + static uint32 BlockNumber8(int x, int y, uint32 bp, uint32 bw) { ASSERT((bw & 1) == 0); - return (bp >> 5) + (y >> 6) * (bw >> 1) + (x >> 7); + return bp + ((y >> 1) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f) + blockTable8[(y >> 4) & 3][(x >> 4) & 7]; } - static DWORD PageNumber4(int x, int y, DWORD bp, DWORD bw) + static uint32 BlockNumber4(int x, int y, uint32 bp, uint32 bw) { ASSERT((bw & 1) == 0); - return (bp >> 5) + (y >> 7) * (bw >> 1) + (x >> 7); + return bp + ((y >> 2) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f) + blockTable4[(y >> 4) & 7][(x >> 5) & 3]; } - static DWORD PageAddress32(int x, int y, DWORD bp, DWORD bw) + static uint32 BlockNumber32Z(int x, int y, uint32 bp, uint32 bw) { - return PageNumber32(x, y, bp, bw) << 11; + return bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable32Z[(y >> 3) & 3][(x >> 3) & 7]; } - static DWORD PageAddress16(int x, int y, DWORD bp, DWORD bw) + static uint32 BlockNumber16Z(int x, int y, uint32 bp, uint32 bw) { - return PageNumber16(x, y, bp, bw) << 12; + return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16Z[(y >> 3) & 7][(x >> 4) & 3]; } - static DWORD PageAddress8(int x, int y, DWORD bp, DWORD bw) + static uint32 BlockNumber16SZ(int x, int y, uint32 bp, uint32 bw) { - return PageNumber8(x, y, bp, bw) << 13; + return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16SZ[(y >> 3) & 7][(x >> 4) & 3]; } - static DWORD PageAddress4(int x, int y, DWORD bp, DWORD bw) + uint8* BlockPtr(uint32 bp) const { - return PageNumber4(x, y, bp, bw) << 14; + ASSERT(bp < 16384); + + return &m_vm8[bp << 8]; } - static DWORD BlockAddress32(int x, int y, DWORD bp, DWORD bw) + uint8* BlockPtr32(int x, int y, uint32 bp, uint32 bw) const { - DWORD page = bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable32[(y >> 3) & 3][(x >> 3) & 7]; - return (page + block) << 6; + return &m_vm8[BlockNumber32(x, y, bp, bw) << 8]; } - static DWORD BlockAddress16(int x, int y, DWORD bp, DWORD bw) + uint8* BlockPtr16(int x, int y, uint32 bp, uint32 bw) const { - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16[(y >> 3) & 7][(x >> 4) & 3]; - return (page + block) << 7; + return &m_vm8[BlockNumber16(x, y, bp, bw) << 8]; } - static DWORD BlockAddress16S(int x, int y, DWORD bp, DWORD bw) + uint8* BlockPtr16S(int x, int y, uint32 bp, uint32 bw) const { - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16S[(y >> 3) & 7][(x >> 4) & 3]; - return (page + block) << 7; + return &m_vm8[BlockNumber16S(x, y, bp, bw) << 8]; } - static DWORD BlockAddress8(int x, int y, DWORD bp, DWORD bw) + uint8* BlockPtr8(int x, int y, uint32 bp, uint32 bw) const + { + return &m_vm8[BlockNumber8(x, y, bp, bw) << 8]; + } + + uint8* BlockPtr4(int x, int y, uint32 bp, uint32 bw) const + { + return &m_vm8[BlockNumber4(x, y, bp, bw) << 8]; + } + + uint8* BlockPtr32Z(int x, int y, uint32 bp, uint32 bw) const + { + return &m_vm8[BlockNumber32Z(x, y, bp, bw) << 8]; + } + + uint8* BlockPtr16Z(int x, int y, uint32 bp, uint32 bw) const + { + return &m_vm8[BlockNumber16Z(x, y, bp, bw) << 8]; + } + + uint8* BlockPtr16SZ(int x, int y, uint32 bp, uint32 bw) const + { + return &m_vm8[BlockNumber16SZ(x, y, bp, bw) << 8]; + } + + static uint32 PixelAddressOrg32(int x, int y, uint32 bp, uint32 bw) + { + return (BlockNumber32(x, y, bp, bw) << 6) + columnTable32[y & 7][x & 7]; + } + + static uint32 PixelAddressOrg16(int x, int y, uint32 bp, uint32 bw) + { + return (BlockNumber16(x, y, bp, bw) << 7) + columnTable16[y & 7][x & 15]; + } + + static uint32 PixelAddressOrg16S(int x, int y, uint32 bp, uint32 bw) + { + return (BlockNumber16S(x, y, bp, bw) << 7) + columnTable16[y & 7][x & 15]; + } + + static uint32 PixelAddressOrg8(int x, int y, uint32 bp, uint32 bw) + { + return (BlockNumber8(x, y, bp, bw) << 8) + columnTable8[y & 15][x & 15]; + } + + static uint32 PixelAddressOrg4(int x, int y, uint32 bp, uint32 bw) + { + return (BlockNumber4(x, y, bp, bw) << 9) + columnTable4[y & 15][x & 31]; + } + + static uint32 PixelAddressOrg32Z(int x, int y, uint32 bp, uint32 bw) + { + return (BlockNumber32Z(x, y, bp, bw) << 6) + columnTable32[y & 7][x & 7]; + } + + static uint32 PixelAddressOrg16Z(int x, int y, uint32 bp, uint32 bw) + { + return (BlockNumber16Z(x, y, bp, bw) << 7) + columnTable16[y & 7][x & 15]; + } + + static uint32 PixelAddressOrg16SZ(int x, int y, uint32 bp, uint32 bw) + { + return (BlockNumber16SZ(x, y, bp, bw) << 7) + columnTable16[y & 7][x & 15]; + } + + static __forceinline uint32 PixelAddress32(int x, int y, uint32 bp, uint32 bw) + { + uint32 page = (bp >> 5) + (y >> 5) * bw + (x >> 6); + uint32 word = (page << 11) + pageOffset32[bp & 0x1f][y & 0x1f][x & 0x3f]; + return word; + } + + static __forceinline uint32 PixelAddress16(int x, int y, uint32 bp, uint32 bw) + { + uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6); + uint32 word = (page << 12) + pageOffset16[bp & 0x1f][y & 0x3f][x & 0x3f]; + return word; + } + + static __forceinline uint32 PixelAddress16S(int x, int y, uint32 bp, uint32 bw) + { + uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6); + uint32 word = (page << 12) + pageOffset16S[bp & 0x1f][y & 0x3f][x & 0x3f]; + return word; + } + + static __forceinline uint32 PixelAddress8(int x, int y, uint32 bp, uint32 bw) { ASSERT((bw & 1) == 0); - DWORD page = bp + ((y >> 1) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f); - DWORD block = blockTable8[(y >> 4) & 3][(x >> 4) & 7]; - return (page + block) << 8; + uint32 page = (bp >> 5) + (y >> 6) * (bw >> 1) + (x >> 7); + uint32 word = (page << 13) + pageOffset8[bp & 0x1f][y & 0x3f][x & 0x7f]; + return word; } - static DWORD BlockAddress4(int x, int y, DWORD bp, DWORD bw) + static __forceinline uint32 PixelAddress4(int x, int y, uint32 bp, uint32 bw) { ASSERT((bw & 1) == 0); - DWORD page = bp + ((y >> 2) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f); - DWORD block = blockTable4[(y >> 4) & 7][(x >> 5) & 3]; - return (page + block) << 9; - } - - static DWORD BlockAddress32Z(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable32Z[(y >> 3) & 3][(x >> 3) & 7]; - return (page + block) << 6; - } - - static DWORD BlockAddress16Z(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16Z[(y >> 3) & 7][(x >> 4) & 3]; - return (page + block) << 7; - } - - static DWORD BlockAddress16SZ(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16SZ[(y >> 3) & 7][(x >> 4) & 3]; - return (page + block) << 7; - } - - static DWORD PixelAddressOrg32(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable32[(y >> 3) & 3][(x >> 3) & 7]; - DWORD word = ((page + block) << 6) + columnTable32[y & 7][x & 7]; - ASSERT(word < 1024*1024); + uint32 page = (bp >> 5) + (y >> 7) * (bw >> 1) + (x >> 7); + uint32 word = (page << 14) + pageOffset4[bp & 0x1f][y & 0x7f][x & 0x7f]; return word; } - static DWORD PixelAddressOrg16(int x, int y, DWORD bp, DWORD bw) + static __forceinline uint32 PixelAddress32Z(int x, int y, uint32 bp, uint32 bw) { - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16[(y >> 3) & 7][(x >> 4) & 3]; - DWORD word = ((page + block) << 7) + columnTable16[y & 7][x & 15]; - ASSERT(word < 1024*1024*2); + uint32 page = (bp >> 5) + (y >> 5) * bw + (x >> 6); + uint32 word = (page << 11) + pageOffset32Z[bp & 0x1f][y & 0x1f][x & 0x3f]; return word; } - static DWORD PixelAddressOrg16S(int x, int y, DWORD bp, DWORD bw) + static __forceinline uint32 PixelAddress16Z(int x, int y, uint32 bp, uint32 bw) { - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16S[(y >> 3) & 7][(x >> 4) & 3]; - DWORD word = ((page + block) << 7) + columnTable16[y & 7][x & 15]; - ASSERT(word < 1024*1024*2); + uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6); + uint32 word = (page << 12) + pageOffset16Z[bp & 0x1f][y & 0x3f][x & 0x3f]; return word; } - static DWORD PixelAddressOrg8(int x, int y, DWORD bp, DWORD bw) + static __forceinline uint32 PixelAddress16SZ(int x, int y, uint32 bp, uint32 bw) { - ASSERT((bw & 1) == 0); - DWORD page = bp + ((y >> 1) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f); - DWORD block = blockTable8[(y >> 4) & 3][(x >> 4) & 7]; - DWORD word = ((page + block) << 8) + columnTable8[y & 15][x & 15]; - ASSERT(word < 1024*1024*4); - return word; - } - - static DWORD PixelAddressOrg4(int x, int y, DWORD bp, DWORD bw) - { - ASSERT((bw & 1) == 0); - DWORD page = bp + ((y >> 2) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f); - DWORD block = blockTable4[(y >> 4) & 7][(x >> 5) & 3]; - DWORD word = ((page + block) << 9) + columnTable4[y & 15][x & 31]; - ASSERT(word < 1024*1024*8); - return word; - } - - static DWORD PixelAddressOrg32Z(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable32Z[(y >> 3) & 3][(x >> 3) & 7]; - DWORD word = ((page + block) << 6) + columnTable32[y & 7][x & 7]; - ASSERT(word < 1024*1024); - return word; - } - - static DWORD PixelAddressOrg16Z(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16Z[(y >> 3) & 7][(x >> 4) & 3]; - DWORD word = ((page + block) << 7) + columnTable16[y & 7][x & 15]; - ASSERT(word < 1024*1024*2); - return word; - } - - static DWORD PixelAddressOrg16SZ(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16SZ[(y >> 3) & 7][(x >> 4) & 3]; - DWORD word = ((page + block) << 7) + columnTable16[y & 7][x & 15]; - ASSERT(word < 1024*1024*2); - return word; - } - - static __forceinline DWORD PixelAddress32(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = (bp >> 5) + (y >> 5) * bw + (x >> 6); - DWORD word = (page << 11) + pageOffset32[bp & 0x1f][y & 0x1f][x & 0x3f]; - return word; - } - - static __forceinline DWORD PixelAddress16(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = (bp >> 5) + (y >> 6) * bw + (x >> 6); - DWORD word = (page << 12) + pageOffset16[bp & 0x1f][y & 0x3f][x & 0x3f]; - return word; - } - - static __forceinline DWORD PixelAddress16S(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = (bp >> 5) + (y >> 6) * bw + (x >> 6); - DWORD word = (page << 12) + pageOffset16S[bp & 0x1f][y & 0x3f][x & 0x3f]; - return word; - } - - static __forceinline DWORD PixelAddress8(int x, int y, DWORD bp, DWORD bw) - { - ASSERT((bw & 1) == 0); - DWORD page = (bp >> 5) + (y >> 6) * (bw >> 1) + (x >> 7); - DWORD word = (page << 13) + pageOffset8[bp & 0x1f][y & 0x3f][x & 0x7f]; - return word; - } - - static __forceinline DWORD PixelAddress4(int x, int y, DWORD bp, DWORD bw) - { - ASSERT((bw & 1) == 0); - DWORD page = (bp >> 5) + (y >> 7) * (bw >> 1) + (x >> 7); - DWORD word = (page << 14) + pageOffset4[bp & 0x1f][y & 0x7f][x & 0x7f]; - return word; - } - - static __forceinline DWORD PixelAddress32Z(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = (bp >> 5) + (y >> 5) * bw + (x >> 6); - DWORD word = (page << 11) + pageOffset32Z[bp & 0x1f][y & 0x1f][x & 0x3f]; - return word; - } - - static __forceinline DWORD PixelAddress16Z(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = (bp >> 5) + (y >> 6) * bw + (x >> 6); - DWORD word = (page << 12) + pageOffset16Z[bp & 0x1f][y & 0x3f][x & 0x3f]; - return word; - } - - static __forceinline DWORD PixelAddress16SZ(int x, int y, DWORD bp, DWORD bw) - { - DWORD page = (bp >> 5) + (y >> 6) * bw + (x >> 6); - DWORD word = (page << 12) + pageOffset16SZ[bp & 0x1f][y & 0x3f][x & 0x3f]; + uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6); + uint32 word = (page << 12) + pageOffset16SZ[bp & 0x1f][y & 0x3f][x & 0x3f]; return word; } // pixel R/W - __forceinline DWORD ReadPixel32(DWORD addr) const + __forceinline uint32 ReadPixel32(uint32 addr) const { return m_vm32[addr]; } - __forceinline DWORD ReadPixel24(DWORD addr) const + __forceinline uint32 ReadPixel24(uint32 addr) const { return m_vm32[addr] & 0x00ffffff; } - __forceinline DWORD ReadPixel16(DWORD addr) const + __forceinline uint32 ReadPixel16(uint32 addr) const { - return (DWORD)m_vm16[addr]; + return (uint32)m_vm16[addr]; } - __forceinline DWORD ReadPixel8(DWORD addr) const + __forceinline uint32 ReadPixel8(uint32 addr) const { - return (DWORD)m_vm8[addr]; + return (uint32)m_vm8[addr]; } - __forceinline DWORD ReadPixel4(DWORD addr) const + __forceinline uint32 ReadPixel4(uint32 addr) const { return (m_vm8[addr >> 1] >> ((addr & 1) << 2)) & 0x0f; } - __forceinline DWORD ReadPixel8H(DWORD addr) const + __forceinline uint32 ReadPixel8H(uint32 addr) const { return m_vm32[addr] >> 24; } - __forceinline DWORD ReadPixel4HL(DWORD addr) const + __forceinline uint32 ReadPixel4HL(uint32 addr) const { return (m_vm32[addr] >> 24) & 0x0f; } - __forceinline DWORD ReadPixel4HH(DWORD addr) const + __forceinline uint32 ReadPixel4HH(uint32 addr) const { return (m_vm32[addr] >> 28) & 0x0f; } - __forceinline DWORD ReadFrame24(DWORD addr) const + __forceinline uint32 ReadFrame24(uint32 addr) const { return 0x80000000 | (m_vm32[addr] & 0xffffff); } - __forceinline DWORD ReadFrame16(DWORD addr) const + __forceinline uint32 ReadFrame16(uint32 addr) const { - DWORD c = (DWORD)m_vm16[addr]; + uint32 c = (uint32)m_vm16[addr]; return ((c & 0x8000) << 16) | ((c & 0x7c00) << 9) | ((c & 0x03e0) << 6) | ((c & 0x001f) << 3); } - __forceinline DWORD ReadPixel32(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel32(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel32(PixelAddress32(x, y, bp, bw)); } - __forceinline DWORD ReadPixel24(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel24(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel24(PixelAddress32(x, y, bp, bw)); } - __forceinline DWORD ReadPixel16(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel16(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel16(PixelAddress16(x, y, bp, bw)); } - __forceinline DWORD ReadPixel16S(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel16S(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel16(PixelAddress16S(x, y, bp, bw)); } - __forceinline DWORD ReadPixel8(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel8(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel8(PixelAddress8(x, y, bp, bw)); } - __forceinline DWORD ReadPixel4(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel4(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel4(PixelAddress4(x, y, bp, bw)); } - __forceinline DWORD ReadPixel8H(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel8H(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel8H(PixelAddress32(x, y, bp, bw)); } - __forceinline DWORD ReadPixel4HL(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel4HL(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel4HL(PixelAddress32(x, y, bp, bw)); } - __forceinline DWORD ReadPixel4HH(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel4HH(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel4HH(PixelAddress32(x, y, bp, bw)); } - __forceinline DWORD ReadPixel32Z(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel32Z(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel32(PixelAddress32Z(x, y, bp, bw)); } - __forceinline DWORD ReadPixel24Z(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel24Z(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel24(PixelAddress32Z(x, y, bp, bw)); } - __forceinline DWORD ReadPixel16Z(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel16Z(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel16(PixelAddress16Z(x, y, bp, bw)); } - __forceinline DWORD ReadPixel16SZ(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadPixel16SZ(int x, int y, uint32 bp, uint32 bw) const { return ReadPixel16(PixelAddress16SZ(x, y, bp, bw)); } - __forceinline DWORD ReadFrame24(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadFrame24(int x, int y, uint32 bp, uint32 bw) const { return ReadFrame24(PixelAddress32(x, y, bp, bw)); } - __forceinline DWORD ReadFrame16(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadFrame16(int x, int y, uint32 bp, uint32 bw) const { return ReadFrame16(PixelAddress16(x, y, bp, bw)); } - __forceinline DWORD ReadFrame16S(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadFrame16S(int x, int y, uint32 bp, uint32 bw) const { return ReadFrame16(PixelAddress16S(x, y, bp, bw)); } - __forceinline DWORD ReadFrame24Z(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadFrame24Z(int x, int y, uint32 bp, uint32 bw) const { return ReadFrame24(PixelAddress32Z(x, y, bp, bw)); } - __forceinline DWORD ReadFrame16Z(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadFrame16Z(int x, int y, uint32 bp, uint32 bw) const { return ReadFrame16(PixelAddress16Z(x, y, bp, bw)); } - __forceinline DWORD ReadFrame16SZ(int x, int y, DWORD bp, DWORD bw) const + __forceinline uint32 ReadFrame16SZ(int x, int y, uint32 bp, uint32 bw) const { return ReadFrame16(PixelAddress16SZ(x, y, bp, bw)); } - __forceinline void WritePixel32(DWORD addr, DWORD c) + __forceinline void WritePixel32(uint32 addr, uint32 c) { m_vm32[addr] = c; } - __forceinline void WritePixel24(DWORD addr, DWORD c) + __forceinline void WritePixel24(uint32 addr, uint32 c) { m_vm32[addr] = (m_vm32[addr] & 0xff000000) | (c & 0x00ffffff); } - __forceinline void WritePixel16(DWORD addr, DWORD c) + __forceinline void WritePixel16(uint32 addr, uint32 c) { - m_vm16[addr] = (WORD)c; + m_vm16[addr] = (uint16)c; } - __forceinline void WritePixel8(DWORD addr, DWORD c) + __forceinline void WritePixel8(uint32 addr, uint32 c) { - m_vm8[addr] = (BYTE)c; + m_vm8[addr] = (uint8)c; } - __forceinline void WritePixel4(DWORD addr, DWORD c) + __forceinline void WritePixel4(uint32 addr, uint32 c) { int shift = (addr & 1) << 2; addr >>= 1; - m_vm8[addr] = (BYTE)((m_vm8[addr] & (0xf0 >> shift)) | ((c & 0x0f) << shift)); + m_vm8[addr] = (uint8)((m_vm8[addr] & (0xf0 >> shift)) | ((c & 0x0f) << shift)); } - __forceinline void WritePixel8H(DWORD addr, DWORD c) + __forceinline void WritePixel8H(uint32 addr, uint32 c) { m_vm32[addr] = (m_vm32[addr] & 0x00ffffff) | (c << 24); } - __forceinline void WritePixel4HL(DWORD addr, DWORD c) + __forceinline void WritePixel4HL(uint32 addr, uint32 c) { m_vm32[addr] = (m_vm32[addr] & 0xf0ffffff) | ((c & 0x0f) << 24); } - __forceinline void WritePixel4HH(DWORD addr, DWORD c) + __forceinline void WritePixel4HH(uint32 addr, uint32 c) { m_vm32[addr] = (m_vm32[addr] & 0x0fffffff) | ((c & 0x0f) << 28); } - __forceinline void WriteFrame16(DWORD addr, DWORD c) + __forceinline void WriteFrame16(uint32 addr, uint32 c) { - DWORD rb = c & 0x00f800f8; - DWORD ga = c & 0x8000f800; + uint32 rb = c & 0x00f800f8; + uint32 ga = c & 0x8000f800; WritePixel16(addr, (ga >> 16) | (rb >> 9) | (ga >> 6) | (rb >> 3)); } - __forceinline void WritePixel32(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel32(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel32(PixelAddress32(x, y, bp, bw), c); } - __forceinline void WritePixel24(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel24(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel24(PixelAddress32(x, y, bp, bw), c); } - __forceinline void WritePixel16(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel16(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel16(PixelAddress16(x, y, bp, bw), c); } - __forceinline void WritePixel16S(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel16S(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel16(PixelAddress16S(x, y, bp, bw), c); } - __forceinline void WritePixel8(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel8(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel8(PixelAddress8(x, y, bp, bw), c); } - __forceinline void WritePixel4(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel4(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel4(PixelAddress4(x, y, bp, bw), c); } - __forceinline void WritePixel8H(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel8H(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel8H(PixelAddress32(x, y, bp, bw), c); } - __forceinline void WritePixel4HL(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel4HL(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel4HL(PixelAddress32(x, y, bp, bw), c); } - __forceinline void WritePixel4HH(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel4HH(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel4HH(PixelAddress32(x, y, bp, bw), c); } - __forceinline void WritePixel32Z(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel32Z(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel32(PixelAddress32Z(x, y, bp, bw), c); } - __forceinline void WritePixel24Z(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel24Z(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel24(PixelAddress32Z(x, y, bp, bw), c); } - __forceinline void WritePixel16Z(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel16Z(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel16(PixelAddress16Z(x, y, bp, bw), c); } - __forceinline void WritePixel16SZ(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WritePixel16SZ(int x, int y, uint32 c, uint32 bp, uint32 bw) { WritePixel16(PixelAddress16SZ(x, y, bp, bw), c); } - __forceinline void WriteFrame16(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WriteFrame16(int x, int y, uint32 c, uint32 bp, uint32 bw) { WriteFrame16(PixelAddress16(x, y, bp, bw), c); } - __forceinline void WriteFrame16S(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WriteFrame16S(int x, int y, uint32 c, uint32 bp, uint32 bw) { WriteFrame16(PixelAddress16S(x, y, bp, bw), c); } - __forceinline void WriteFrame16Z(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WriteFrame16Z(int x, int y, uint32 c, uint32 bp, uint32 bw) { WriteFrame16(PixelAddress16Z(x, y, bp, bw), c); } - __forceinline void WriteFrame16SZ(int x, int y, DWORD c, DWORD bp, DWORD bw) + __forceinline void WriteFrame16SZ(int x, int y, uint32 c, uint32 bp, uint32 bw) { WriteFrame16(PixelAddress16SZ(x, y, bp, bw), c); } - __forceinline DWORD ReadTexel32(DWORD addr, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel32(uint32 addr, const GIFRegTEXA& TEXA) const { return m_vm32[addr]; } - __forceinline DWORD ReadTexel24(DWORD addr, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel24(uint32 addr, const GIFRegTEXA& TEXA) const { return Expand24To32(m_vm32[addr], TEXA); } - __forceinline DWORD ReadTexel16(DWORD addr, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel16(uint32 addr, const GIFRegTEXA& TEXA) const { return Expand16To32(m_vm16[addr], TEXA); } - __forceinline DWORD ReadTexel8(DWORD addr, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel8(uint32 addr, const GIFRegTEXA& TEXA) const { return m_clut[ReadPixel8(addr)]; } - __forceinline DWORD ReadTexel4(DWORD addr, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel4(uint32 addr, const GIFRegTEXA& TEXA) const { return m_clut[ReadPixel4(addr)]; } - __forceinline DWORD ReadTexel8H(DWORD addr, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel8H(uint32 addr, const GIFRegTEXA& TEXA) const { return m_clut[ReadPixel8H(addr)]; } - __forceinline DWORD ReadTexel4HL(DWORD addr, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel4HL(uint32 addr, const GIFRegTEXA& TEXA) const { return m_clut[ReadPixel4HL(addr)]; } - __forceinline DWORD ReadTexel4HH(DWORD addr, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel4HH(uint32 addr, const GIFRegTEXA& TEXA) const { return m_clut[ReadPixel4HH(addr)]; } - __forceinline DWORD ReadTexel32(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel32(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel32(PixelAddress32(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel24(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel24(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel24(PixelAddress32(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel16(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel16(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel16(PixelAddress16(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel16S(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel16S(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel16(PixelAddress16S(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel8(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel8(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel8(PixelAddress8(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel4(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel4(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel4(PixelAddress4(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel8H(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel8H(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel8H(PixelAddress32(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel4HL(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel4HL(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel4HL(PixelAddress32(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel4HH(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel4HH(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel4HH(PixelAddress32(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel32Z(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel32Z(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel32(PixelAddress32Z(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel24Z(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel24Z(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel24(PixelAddress32Z(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel16Z(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel16Z(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel16(PixelAddress16Z(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel16SZ(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel16SZ(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadTexel16(PixelAddress16SZ(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline DWORD ReadTexel16NP(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel16NP(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadPixel16(x, y, TEX0.TBP0, TEX0.TBW); } - __forceinline DWORD ReadTexel16SNP(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel16SNP(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadPixel16S(x, y, TEX0.TBP0, TEX0.TBW); } - __forceinline DWORD ReadTexel16ZNP(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel16ZNP(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadPixel16Z(x, y, TEX0.TBP0, TEX0.TBW); } - __forceinline DWORD ReadTexel16SZNP(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const + __forceinline uint32 ReadTexel16SZNP(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { return ReadPixel16SZ(x, y, TEX0.TBP0, TEX0.TBW); } // - __forceinline DWORD PixelAddressX(int PSM, int x, int y, DWORD bp, DWORD bw) - { - switch(PSM) - { - case PSM_PSMCT32: return PixelAddress32(x, y, bp, bw); - case PSM_PSMCT24: return PixelAddress32(x, y, bp, bw); - case PSM_PSMCT16: return PixelAddress16(x, y, bp, bw); - case PSM_PSMCT16S: return PixelAddress16S(x, y, bp, bw); - case PSM_PSMT8: return PixelAddress8(x, y, bp, bw); - case PSM_PSMT4: return PixelAddress4(x, y, bp, bw); - case PSM_PSMT8H: return PixelAddress32(x, y, bp, bw); - case PSM_PSMT4HL: return PixelAddress32(x, y, bp, bw); - case PSM_PSMT4HH: return PixelAddress32(x, y, bp, bw); - case PSM_PSMZ32: return PixelAddress32Z(x, y, bp, bw); - case PSM_PSMZ24: return PixelAddress32Z(x, y, bp, bw); - case PSM_PSMZ16: return PixelAddress16Z(x, y, bp, bw); - case PSM_PSMZ16S: return PixelAddress16SZ(x, y, bp, bw); - default: ASSERT(0); return PixelAddress32(x, y, bp, bw); - } - } - - __forceinline DWORD ReadPixelX(int PSM, DWORD addr) const - { - switch(PSM) - { - case PSM_PSMCT32: return ReadPixel32(addr); - case PSM_PSMCT24: return ReadPixel24(addr); - case PSM_PSMCT16: return ReadPixel16(addr); - case PSM_PSMCT16S: return ReadPixel16(addr); - case PSM_PSMT8: return ReadPixel8(addr); - case PSM_PSMT4: return ReadPixel4(addr); - case PSM_PSMT8H: return ReadPixel8H(addr); - case PSM_PSMT4HL: return ReadPixel4HL(addr); - case PSM_PSMT4HH: return ReadPixel4HH(addr); - case PSM_PSMZ32: return ReadPixel32(addr); - case PSM_PSMZ24: return ReadPixel24(addr); - case PSM_PSMZ16: return ReadPixel16(addr); - case PSM_PSMZ16S: return ReadPixel16(addr); - default: ASSERT(0); return ReadPixel32(addr); - } - } - - __forceinline DWORD ReadFrameX(int PSM, DWORD addr) const - { - switch(PSM) - { - case PSM_PSMCT32: return ReadPixel32(addr); - case PSM_PSMCT24: return ReadFrame24(addr); - case PSM_PSMCT16: return ReadFrame16(addr); - case PSM_PSMCT16S: return ReadFrame16(addr); - case PSM_PSMZ32: return ReadPixel32(addr); - case PSM_PSMZ24: return ReadFrame24(addr); - case PSM_PSMZ16: return ReadFrame16(addr); - case PSM_PSMZ16S: return ReadFrame16(addr); - default: ASSERT(0); return ReadPixel32(addr); - } - } - - __forceinline DWORD ReadTexelX(int PSM, DWORD addr, const GIFRegTEXA& TEXA) const - { - switch(PSM) - { - case PSM_PSMCT32: return ReadTexel32(addr, TEXA); - case PSM_PSMCT24: return ReadTexel24(addr, TEXA); - case PSM_PSMCT16: return ReadTexel16(addr, TEXA); - case PSM_PSMCT16S: return ReadTexel16(addr, TEXA); - case PSM_PSMT8: return ReadTexel8(addr, TEXA); - case PSM_PSMT4: return ReadTexel4(addr, TEXA); - case PSM_PSMT8H: return ReadTexel8H(addr, TEXA); - case PSM_PSMT4HL: return ReadTexel4HL(addr, TEXA); - case PSM_PSMT4HH: return ReadTexel4HH(addr, TEXA); - case PSM_PSMZ32: return ReadTexel32(addr, TEXA); - case PSM_PSMZ24: return ReadTexel24(addr, TEXA); - case PSM_PSMZ16: return ReadTexel16(addr, TEXA); - case PSM_PSMZ16S: return ReadTexel16(addr, TEXA); - default: ASSERT(0); return ReadTexel32(addr, TEXA); - } - } - - __forceinline DWORD ReadTexelX(int PSM, int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const - { - switch(PSM) - { - case PSM_PSMCT32: return ReadTexel32(x, y, TEX0, TEXA); - case PSM_PSMCT24: return ReadTexel24(x, y, TEX0, TEXA); - case PSM_PSMCT16: return ReadTexel16(x, y, TEX0, TEXA); - case PSM_PSMCT16S: return ReadTexel16(x, y, TEX0, TEXA); - case PSM_PSMT8: return ReadTexel8(x, y, TEX0, TEXA); - case PSM_PSMT4: return ReadTexel4(x, y, TEX0, TEXA); - case PSM_PSMT8H: return ReadTexel8H(x, y, TEX0, TEXA); - case PSM_PSMT4HL: return ReadTexel4HL(x, y, TEX0, TEXA); - case PSM_PSMT4HH: return ReadTexel4HH(x, y, TEX0, TEXA); - case PSM_PSMZ32: return ReadTexel32Z(x, y, TEX0, TEXA); - case PSM_PSMZ24: return ReadTexel24Z(x, y, TEX0, TEXA); - case PSM_PSMZ16: return ReadTexel16Z(x, y, TEX0, TEXA); - case PSM_PSMZ16S: return ReadTexel16Z(x, y, TEX0, TEXA); - default: ASSERT(0); return ReadTexel32(x, y, TEX0, TEXA); - } - } - - __forceinline void WritePixelX(int PSM, DWORD addr, DWORD c) - { - switch(PSM) - { - case PSM_PSMCT32: WritePixel32(addr, c); break; - case PSM_PSMCT24: WritePixel24(addr, c); break; - case PSM_PSMCT16: WritePixel16(addr, c); break; - case PSM_PSMCT16S: WritePixel16(addr, c); break; - case PSM_PSMT8: WritePixel8(addr, c); break; - case PSM_PSMT4: WritePixel4(addr, c); break; - case PSM_PSMT8H: WritePixel8H(addr, c); break; - case PSM_PSMT4HL: WritePixel4HL(addr, c); break; - case PSM_PSMT4HH: WritePixel4HH(addr, c); break; - case PSM_PSMZ32: WritePixel32(addr, c); break; - case PSM_PSMZ24: WritePixel24(addr, c); break; - case PSM_PSMZ16: WritePixel16(addr, c); break; - case PSM_PSMZ16S: WritePixel16(addr, c); break; - default: ASSERT(0); WritePixel32(addr, c); break; - } - } - - __forceinline void WriteFrameX(int PSM, DWORD addr, DWORD c) - { - switch(PSM) - { - case PSM_PSMCT32: WritePixel32(addr, c); break; - case PSM_PSMCT24: WritePixel24(addr, c); break; - case PSM_PSMCT16: WriteFrame16(addr, c); break; - case PSM_PSMCT16S: WriteFrame16(addr, c); break; - case PSM_PSMZ32: WritePixel32(addr, c); break; - case PSM_PSMZ24: WritePixel24(addr, c); break; - case PSM_PSMZ16: WriteFrame16(addr, c); break; - case PSM_PSMZ16S: WriteFrame16(addr, c); break; - default: ASSERT(0); WritePixel32(addr, c); break; - } - } - - // FillRect - - bool FillRect(const GSVector4i& r, DWORD c, DWORD psm, DWORD bp, DWORD bw); - - // + template + void WriteImageColumn(int l, int r, int y, int h, uint8* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF); template - void WriteImageColumn(int l, int r, int y, int h, BYTE* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF); - - template - void WriteImageBlock(int l, int r, int y, int h, BYTE* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF); + void WriteImageBlock(int l, int r, int y, int h, uint8* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF); template - void WriteImageLeftRight(int l, int r, int y, int h, BYTE* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF); + void WriteImageLeftRight(int l, int r, int y, int h, uint8* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF); template - void WriteImageTopBottom(int l, int r, int y, int h, BYTE* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF); + void WriteImageTopBottom(int l, int r, int y, int h, uint8* src, int srcpitch, const GIFRegBITBLTBUF& BITBLTBUF); template - void WriteImage(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); + void WriteImage(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void WriteImage24(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void WriteImage8H(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void WriteImage4HL(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void WriteImage4HH(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void WriteImage24Z(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); + void WriteImage24(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); + void WriteImage8H(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); + void WriteImage4HL(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); + void WriteImage4HH(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); + void WriteImage24Z(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); + void WriteImageX(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); // TODO: ReadImage32/24/... - void ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) const; + void ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) const; + + // * => 32 + + void ReadTexture32(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture16(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture16S(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture8(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture4(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture8H(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture4HL(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture4HH(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture32Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture16Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture16SZ(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + + void ReadTexture(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); + + void ReadTextureBlock32(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock24(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock16(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock16S(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock8(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock4(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock8H(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock4HL(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock4HH(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock32Z(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock24Z(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock16Z(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock16SZ(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + + // * => 32/16 + + void ReadTexture16NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture16SNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture8NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture4NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture8HNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture4HLNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture16ZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture16SZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + + void ReadTextureNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); + + // pal ? 8 : 32 + + void ReadTexture8P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture4P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture8HP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture4HLP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + void ReadTexture4HHP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + + void ReadTextureBlock8P(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock4P(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock8HP(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock4HLP(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; + void ReadTextureBlock4HHP(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; // - void ReadTexture32(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture24(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture16(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture16S(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture8(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture4(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture8H(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture4HL(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture4HH(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture32Z(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture24Z(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture16Z(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture16SZ(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - - void ReadTexture(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP); - void ReadTextureNC(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP); - - // 32/16 - - void ReadTexture16NP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture16SNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture8NP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture4NP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture8HNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture4HLNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture4HHNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture16ZNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture16SZNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - - void ReadTextureNP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP); - void ReadTextureNPNC(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP); - - // 32/8 - - void ReadTexture8P(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture4P(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture8HP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture4HLP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; - void ReadTexture4HHP(const CRect& r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const; + template void ReadTexture(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, readTexel rt, readTexture rtx); // - static DWORD m_xtbl[1024], m_ytbl[1024]; - - template void ReadTexture(CRect r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, readTexel rt, readTexture rtx); - template void ReadTextureNC(CRect r, BYTE* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, readTexel rt, readTexture rtx); - - // - - HRESULT SaveBMP(LPCTSTR fn, DWORD bp, DWORD bw, DWORD psm, int w, int h); + HRESULT SaveBMP(const string& fn, uint32 bp, uint32 bw, uint32 psm, int w, int h); }; #pragma warning(default: 4244) \ No newline at end of file diff --git a/plugins/GSdx/GSPerfMon.cpp b/plugins/GSdx/GSPerfMon.cpp index ba3aa1a809..82c044c361 100644 --- a/plugins/GSdx/GSPerfMon.cpp +++ b/plugins/GSdx/GSPerfMon.cpp @@ -22,8 +22,6 @@ #include "stdafx.h" #include "GSPerfMon.h" -extern "C" unsigned __int64 __rdtsc(); - GSPerfMon::GSPerfMon() : m_total(0) , m_begin(0) @@ -33,7 +31,6 @@ GSPerfMon::GSPerfMon() { memset(m_counters, 0, sizeof(m_counters)); memset(m_stats, 0, sizeof(m_stats)); - memset(m_warnings, 0, sizeof(m_warnings)); } void GSPerfMon::Put(counter_t c, double val) diff --git a/plugins/GSdx/GSPerfMon.h b/plugins/GSdx/GSPerfMon.h index 1c9b94921d..e6d97e338c 100644 --- a/plugins/GSdx/GSPerfMon.h +++ b/plugins/GSdx/GSPerfMon.h @@ -25,13 +25,11 @@ class GSPerfMon { public: enum counter_t {Frame, Prim, Draw, Swizzle, Unswizzle, Fillrate, Quad, CounterLast}; - enum warning_t {DATE, PABE, ABE, COLCLAMP, DepthTexture, WarningLast}; protected: double m_counters[CounterLast]; double m_stats[CounterLast]; - bool m_warnings[WarningLast]; - UINT64 m_begin, m_total, m_start, m_frame; + uint64 m_begin, m_total, m_start, m_frame; clock_t m_lastframe; int m_count; @@ -43,12 +41,10 @@ protected: public: GSPerfMon(); - void SetFrame(UINT64 frame) {m_frame = frame;} - UINT64 GetFrame() {return m_frame;} + void SetFrame(uint64 frame) {m_frame = frame;} + uint64 GetFrame() {return m_frame;} void Put(counter_t c, double val = 0); double Get(counter_t c) {return m_stats[c];} - void Put(warning_t c) {m_warnings[c] = true;} - bool Get(warning_t c) {bool b = m_warnings[c]; m_warnings[c] = false; return b;} void Update(); int CPU(); }; diff --git a/plugins/GSdx/GSRasterizer.cpp b/plugins/GSdx/GSRasterizer.cpp index 053e789084..abd730281a 100644 --- a/plugins/GSdx/GSRasterizer.cpp +++ b/plugins/GSdx/GSRasterizer.cpp @@ -51,7 +51,7 @@ void GSRasterizer::Draw(const GSRasterizerData* data) m_stats.Reset(); - __int64 start = __rdtsc(); + int64 start = __rdtsc(); switch(data->primclass) { @@ -94,7 +94,7 @@ void GSRasterizer::DrawPoint(const GSVertexSW* v, const GSVector4i& scissor) GSVector4i p(v->p); - if(scissor.x <= p.x && p.x < scissor.z && scissor.y <= p.y && p.y < scissor.w) + if(scissor.left <= p.x && p.x < scissor.right && scissor.top <= p.y && p.y < scissor.bottom) { if((p.y % m_threads) == m_id) { @@ -153,7 +153,7 @@ void GSRasterizer::DrawLine(const GSVertexSW* v, const GSVector4i& scissor) GSVector4i p(l.p); - if(scissor.y <= p.y && p.y < scissor.w) + if(scissor.top <= p.y && p.y < scissor.bottom) { GSVertexSW dscan = dv / dv.p.xxxx(); @@ -277,7 +277,7 @@ void GSRasterizer::DrawTriangleTop(GSVertexSW* v, const GSVector4i& scissor) longest.p = v[2].p - v[1].p; - int i = (longest.p > GSVector4::zero()).upl(longest.p == GSVector4::zero()).mask(); + int i = longest.p.upl(longest.p == GSVector4::zero()).mask(); if(i & 2) return; @@ -305,8 +305,8 @@ void GSRasterizer::DrawTriangleTop(GSVertexSW* v, const GSVector4i& scissor) GSVertexSW dscan = longest * longest.p.xxxx().rcp(); - GSVertexSW vl = v[2 - i] - l; - GSVector4 vr = v[1 + i].p - r; + GSVertexSW vl = v[1 + i] - l; + GSVector4 vr = v[2 - i].p - r; GSVertexSW dl = vl / vl.p.yyyy(); GSVector4 dr = vr / vr.yyyy(); @@ -329,14 +329,14 @@ void GSRasterizer::DrawTriangleBottom(GSVertexSW* v, const GSVector4i& scissor) longest.p = v[1].p - v[0].p; - int i = (longest.p > GSVector4::zero()).upl(longest.p == GSVector4::zero()).mask(); + int i = longest.p.upl(longest.p == GSVector4::zero()).mask(); if(i & 2) return; i &= 1; - GSVertexSW& l = v[1 - i]; - GSVector4& r = v[i].p; + GSVertexSW& l = v[i]; + GSVector4& r = v[1 - i].p; GSVector4 fscissor(scissor); @@ -384,7 +384,7 @@ void GSRasterizer::DrawTriangleTopBottom(GSVertexSW* v, const GSVector4i& scisso GSVertexSW longest = dv[1] * (dv[0].p / dv[1].p).yyyy() - dv[0]; - int i = (longest.p > GSVector4::zero()).upl(longest.p == GSVector4::zero()).mask(); + int i = longest.p.upl(longest.p == GSVector4::zero()).mask(); if(i & 2) return; @@ -409,8 +409,8 @@ void GSRasterizer::DrawTriangleTopBottom(GSVertexSW* v, const GSVector4i& scisso GSVertexSW& l = v[0]; GSVector4 r = v[0].p; - GSVertexSW dl = dv[1 - i] / dv[1 - i].p.yyyy(); - GSVector4 dr = dv[i].p / dv[i].p.yyyy(); + GSVertexSW dl = dv[i] / dv[i].p.yyyy(); + GSVector4 dr = dv[1 - i].p / dv[1 - i].p.yyyy(); GSVector4 dy = tbmax.xxxx() - l.p.yyyy(); @@ -427,7 +427,7 @@ void GSRasterizer::DrawTriangleTopBottom(GSVertexSW* v, const GSVector4i& scisso if(top < bottom) { - if(i) + if(i == 0) { l = v[1]; dv[2] = v[2] - v[1]; @@ -546,29 +546,9 @@ void GSRasterizer::DrawSprite(const GSVertexSW* vertices, const GSVector4i& scis GSVector4i r(v[0].p.xyxy(v[1].p).ceil()); - int& top = r.y; - int& bottom = r.w; - - int& left = r.x; - int& right = r.z; - - #if _M_SSE >= 0x401 - - r = r.sat_i32(scissor); + r = r.rintersect(scissor); - if((r < r.zwzw()).mask() != 0x00ff) return; - - #else - - if(top < scissor.y) top = scissor.y; - if(bottom > scissor.w) bottom = scissor.w; - if(top >= bottom) return; - - if(left < scissor.x) left = scissor.x; - if(right > scissor.z) right = scissor.z; - if(left >= right) return; - - #endif + if(r.rempty()) return; GSVertexSW scan = v[0]; @@ -578,7 +558,7 @@ void GSRasterizer::DrawSprite(const GSVertexSW* vertices, const GSVector4i& scis { (m_ds->*m_dsf.sr)(r, scan); - m_stats.pixels += (r.z - r.x) * (r.w - r.y); + m_stats.pixels += r.width() * r.height(); } return; @@ -599,18 +579,18 @@ void GSRasterizer::DrawSprite(const GSVertexSW* vertices, const GSVector4i& scis dedge.t = (dv.t / dv.p.yyyy()).xyxy(zero).wyww(); dscan.t = (dv.t / dv.p.xxxx()).xyxy(zero).xwww(); - if(scan.p.y < (float)top) scan.t += dedge.t * ((float)top - scan.p.y); - if(scan.p.x < (float)left) scan.t += dscan.t * ((float)left - scan.p.x); + if(scan.p.y < (float)r.top) scan.t += dedge.t * ((float)r.top - scan.p.y); + if(scan.p.x < (float)r.left) scan.t += dscan.t * ((float)r.left - scan.p.x); m_dsf.ssp(v, dscan); - for(; top < bottom; top++, scan.t += dedge.t) + for(; r.top < r.bottom; r.top++, scan.t += dedge.t) { - if((top % m_threads) == m_id) + if((r.top % m_threads) == m_id) { - m_dsf.ssl(right, left, top, scan); + m_dsf.ssl(r.right, r.left, r.top, scan); - m_stats.pixels += right - left; + m_stats.pixels += r.width(); } } } @@ -681,7 +661,7 @@ void GSRasterizer::DrawEdge(const GSVertexSW& v0, const GSVertexSW& v1, const GS int xi = x >> 16; int xf = x & 0xffff; - if(scissor.x <= xi && xi < scissor.z && (xi % m_threads) == m_id) + if(scissor.left <= xi && xi < scissor.right && (xi % m_threads) == m_id) { m_stats.pixels++; @@ -709,7 +689,7 @@ void GSRasterizer::DrawEdge(const GSVertexSW& v0, const GSVertexSW& v1, const GS int xi = (x >> 16) + 1; int xf = x & 0xffff; - if(scissor.x <= xi && xi < scissor.z && (xi % m_threads) == m_id) + if(scissor.left <= xi && xi < scissor.right && (xi % m_threads) == m_id) { m_stats.pixels++; @@ -779,7 +759,7 @@ void GSRasterizer::DrawEdge(const GSVertexSW& v0, const GSVertexSW& v1, const GS int yi = y >> 16; int yf = y & 0xffff; - if(scissor.y <= yi && yi < scissor.w && (yi % m_threads) == m_id) + if(scissor.top <= yi && yi < scissor.bottom && (yi % m_threads) == m_id) { m_stats.pixels++; @@ -807,7 +787,7 @@ void GSRasterizer::DrawEdge(const GSVertexSW& v0, const GSVertexSW& v1, const GS int yi = (y >> 16) + 1; int yf = y & 0xffff; - if(scissor.y <= yi && yi < scissor.w && (yi % m_threads) == m_id) + if(scissor.top <= yi && yi < scissor.bottom && (yi % m_threads) == m_id) { m_stats.pixels++; @@ -835,29 +815,17 @@ GSRasterizerMT::GSRasterizerMT(IDrawScanline* ds, int id, int threads, long* syn : GSRasterizer(ds, id, threads) , m_sync(sync) , m_exit(false) - , m_ThreadId(0) - , m_hThread(NULL) , m_data(NULL) { if(id > 0) { - m_hThread = CreateThread(NULL, 0, StaticThreadProc, (LPVOID)this, 0, &m_ThreadId); + CreateThread(); } } GSRasterizerMT::~GSRasterizerMT() { - if(m_hThread != NULL) - { - m_exit = true; - - if(WaitForSingleObject(m_hThread, 5000) != WAIT_OBJECT_0) - { - TerminateThread(m_hThread, 1); - } - - CloseHandle(m_hThread); - } + m_exit = true; } void GSRasterizerMT::Draw(const GSRasterizerData* data) @@ -870,16 +838,11 @@ void GSRasterizerMT::Draw(const GSRasterizerData* data) { m_data = data; - InterlockedBitTestAndSet(m_sync, m_id); + _interlockedbittestandset(m_sync, m_id); } } -DWORD WINAPI GSRasterizerMT::StaticThreadProc(LPVOID lpParam) -{ - return ((GSRasterizerMT*)lpParam)->ThreadProc(); -} - -DWORD GSRasterizerMT::ThreadProc() +void GSRasterizerMT::ThreadProc() { // _mm_setcsr(MXCSR); @@ -889,15 +852,13 @@ DWORD GSRasterizerMT::ThreadProc() { __super::Draw(m_data); - InterlockedBitTestAndReset(m_sync, m_id); + _interlockedbittestandreset(m_sync, m_id); } else { _mm_pause(); } } - - return 0; } // @@ -915,17 +876,19 @@ GSRasterizerList::GSRasterizerList() GSRasterizerList::~GSRasterizerList() { - _aligned_free(m_sync); - FreeRasterizers(); + + _aligned_free(m_sync); } void GSRasterizerList::FreeRasterizers() { - while(!IsEmpty()) + for(list::iterator i = begin(); i != end(); i++) { - delete RemoveHead(); + delete *i; } + + clear(); } void GSRasterizerList::Draw(const GSRasterizerData* data) @@ -934,13 +897,11 @@ void GSRasterizerList::Draw(const GSRasterizerData* data) m_stats.Reset(); - __int64 start = __rdtsc(); + int64 start = __rdtsc(); - POSITION pos = GetTailPosition(); - - while(pos) + for(list::reverse_iterator i = rbegin(); i != rend(); i++) { - GetPrev(pos)->Draw(data); + (*i)->Draw(data); } while(*m_sync) @@ -950,13 +911,11 @@ void GSRasterizerList::Draw(const GSRasterizerData* data) m_stats.ticks = __rdtsc() - start; - pos = GetHeadPosition(); - - while(pos) + for(list::iterator i = begin(); i != end(); i++) { GSRasterizerStats s; - GetNext(pos)->GetStats(s); + (*i)->GetStats(s); m_stats.pixels += s.pixels; m_stats.prims = max(m_stats.prims, s.prims); @@ -970,8 +929,8 @@ void GSRasterizerList::GetStats(GSRasterizerStats& stats) void GSRasterizerList::PrintStats() { - if(!IsEmpty()) + if(!empty()) { - GetHead()->PrintStats(); + front()->PrintStats(); } } diff --git a/plugins/GSdx/GSRasterizer.h b/plugins/GSdx/GSRasterizer.h index 0f24c794f2..00a2009baf 100644 --- a/plugins/GSdx/GSRasterizer.h +++ b/plugins/GSdx/GSRasterizer.h @@ -24,6 +24,7 @@ #include "GS.h" #include "GSVertexSW.h" #include "GSFunctionMap.h" +#include "GSThread.h" __declspec(align(16)) class GSRasterizerData { @@ -102,17 +103,13 @@ public: void PrintStats() {m_ds->PrintStats();} }; -class GSRasterizerMT : public GSRasterizer +class GSRasterizerMT : public GSRasterizer, private GSThread { long* m_sync; bool m_exit; - DWORD m_ThreadId; - HANDLE m_hThread; const GSRasterizerData* m_data; - static DWORD WINAPI StaticThreadProc(LPVOID lpParam); - - DWORD ThreadProc(); + void ThreadProc(); public: GSRasterizerMT(IDrawScanline* ds, int id, int threads, long* sync); @@ -123,7 +120,7 @@ public: void Draw(const GSRasterizerData* data); }; -class GSRasterizerList : protected CAtlList, public IRasterizer +class GSRasterizerList : protected list, public IRasterizer { long* m_sync; GSRasterizerStats m_stats; @@ -142,7 +139,7 @@ public: for(int i = 0; i < threads; i++) { - AddTail(new GSRasterizerMT(new DS(parent, i), i, threads, m_sync)); + push_back(new GSRasterizerMT(new DS(parent, i), i, threads, m_sync)); } } diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index 8d4460dc03..b83f9cdcf9 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -21,3 +21,734 @@ #include "StdAfx.h" #include "GSRenderer.h" + +GSRenderer::GSRenderer(uint8* base, bool mt, void (*irq)(), GSDevice* dev) + : GSState(base, mt, irq) + , m_dev(dev) + , m_shader(0) +{ + m_interlace = theApp.GetConfig("interlace", 0); + m_aspectratio = theApp.GetConfig("aspectratio", 1); + m_filter = theApp.GetConfig("filter", 1); + m_vsync = !!theApp.GetConfig("vsync", 0); + m_nativeres = !!theApp.GetConfig("nativeres", 0); + m_aa1 = !!theApp.GetConfig("aa1", 0); + m_blur = !!theApp.GetConfig("blur", 0); + + if(m_nativeres) m_filter = 2; + + s_n = 0; + s_dump = !!theApp.GetConfig("dump", 0); + s_save = !!theApp.GetConfig("save", 0); + s_savez = !!theApp.GetConfig("savez", 0); +} + +GSRenderer::~GSRenderer() +{ + delete m_dev; +} + +bool GSRenderer::Create(const string& title) +{ + if(!m_wnd.Create(title.c_str())) + { + return false; + } + + ASSERT(m_dev); + + if(!m_dev->Create(&m_wnd, m_vsync)) + { + return false; + } + + Reset(); + + return true; +} + +bool GSRenderer::Merge(int field) +{ + bool en[2]; + + GSVector4i fr[2]; + GSVector4i dr[2]; + + int baseline = INT_MAX; + + for(int i = 0; i < 2; i++) + { + en[i] = IsEnabled(i); + + if(en[i]) + { + fr[i] = GetFrameRect(i); + dr[i] = GetDisplayRect(i); + + baseline = min(dr[i].top, baseline); + + // printf("[%d]: %d %d %d %d, %d %d %d %d\n", i, fr[i], dr[i]); + } + } + + if(!en[0] && !en[1]) + { + return false; + } + + // try to avoid fullscreen blur, could be nice on tv but on a monitor it's like double vision, hurts my eyes (persona 4, guitar hero) + // + // NOTE: probably the technique explained in graphtip.pdf (Antialiasing by Supersampling / 4. Reading Odd/Even Scan Lines Separately with the PCRTC then Blending) + + bool samesrc = + en[0] && en[1] && + m_regs->DISP[0].DISPFB.FBP == m_regs->DISP[1].DISPFB.FBP && + m_regs->DISP[0].DISPFB.FBW == m_regs->DISP[1].DISPFB.FBW && + m_regs->DISP[0].DISPFB.PSM == m_regs->DISP[1].DISPFB.PSM; + + bool blurdetected = false; + + if(samesrc && m_regs->PMODE.SLBG == 0 && m_regs->PMODE.MMOD == 1 && m_regs->PMODE.ALP == 0x80) + { + if(fr[0].eq(fr[1] + GSVector4i(0, -1, 0, 0)) && dr[0].eq(dr[1] + GSVector4i(0, 0, 0, 1)) + || fr[1].eq(fr[0] + GSVector4i(0, -1, 0, 0)) && dr[1].eq(dr[0] + GSVector4i(0, 0, 0, 1))) + { + // persona 4: + // + // fr[0] = 0 0 640 448 + // fr[1] = 0 1 640 448 + // dr[0] = 159 50 779 498 + // dr[1] = 159 50 779 497 + // + // second image shifted up by 1 pixel and blended over itself + // + // god of war: + // + // fr[0] = 0 1 512 448 + // fr[1] = 0 0 512 448 + // dr[0] = 127 50 639 497 + // dr[1] = 127 50 639 498 + // + // same just the first image shifted + + int top = min(fr[0].top, fr[1].top); + int bottom = max(dr[0].bottom, dr[1].bottom); + + fr[0].top = top; + fr[1].top = top; + dr[0].bottom = bottom; + dr[1].bottom = bottom; + + blurdetected = true; + } + else if(dr[0].eq(dr[1]) && (fr[0].eq(fr[1] + GSVector4i(0, 1, 0, 1)) || fr[1].eq(fr[0] + GSVector4i(0, 1, 0, 1)))) + { + // dq5: + // + // fr[0] = 0 1 512 445 + // fr[1] = 0 0 512 444 + // dr[0] = 127 50 639 494 + // dr[1] = 127 50 639 494 + + int top = min(fr[0].top, fr[1].top); + int bottom = min(fr[0].bottom, fr[1].bottom); + + fr[0].top = fr[1].top = top; + fr[0].bottom = fr[1].bottom = bottom; + + blurdetected = true; + } + } + + GSVector2i fs(0, 0); + GSVector2i ds(0, 0); + + GSTexture* tex[2] = {NULL, NULL}; + + if(samesrc && fr[0].bottom == fr[1].bottom) + { + tex[0] = GetOutput(0); + tex[1] = tex[0]; // saves one texture fetch + } + else + { + if(en[0]) tex[0] = GetOutput(0); + if(en[1]) tex[1] = GetOutput(1); + } + + GSVector4 src[2]; + GSVector4 dst[2]; + + for(int i = 0; i < 2; i++) + { + if(!en[i] || !tex[i]) continue; + + GSVector4i r = fr[i]; + + // overscan hack + + if(dr[i].height() > 512) // hmm + { + int y = GetDeviceSize(i).y; + if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD) y /= 2; + r.bottom = r.top + y; + } + + // + + if(m_blur && blurdetected && i == 1) + { + r += GSVector4i(0, 1).xyxy(); + } + + GSVector4 scale = GSVector4(tex[i]->m_scale).xyxy(); + + src[i] = GSVector4(r) * scale / GSVector4(tex[i]->GetSize()).xyxy(); + + GSVector2 o(0, 0); + + if(dr[i].top - baseline >= 4) // 2? + { + o.y = tex[i]->m_scale.y * (dr[i].top - baseline); + + if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD) + { + o.y /= 2; + } + } + + dst[i] = GSVector4(o).xyxy() + scale * GSVector4(r.rsize()); + + fs.x = max(fs.x, (int)(dst[i].z + 0.5f)); + fs.y = max(fs.y, (int)(dst[i].w + 0.5f)); + } + + ds = fs; + + if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD) + { + ds.y *= 2; + } + + bool slbg = m_regs->PMODE.SLBG; + bool mmod = m_regs->PMODE.MMOD; + + if(tex[0] || tex[1]) + { + GSVector4 c = GSVector4((int)m_regs->BGCOLOR.R, (int)m_regs->BGCOLOR.G, (int)m_regs->BGCOLOR.B, (int)m_regs->PMODE.ALP) / 255; + + m_dev->Merge(tex, src, dst, fs, slbg, mmod, c); + + if(m_regs->SMODE2.INT && m_interlace > 0) + { + int field2 = 1 - ((m_interlace - 1) & 1); + int mode = (m_interlace - 1) >> 1; + + m_dev->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->m_scale.y : tex[0]->m_scale.y); + } + } + + return true; +} + +void GSRenderer::VSync(int field) +{ + GSPerfMonAutoTimer pmat(m_perfmon); + + m_perfmon.Put(GSPerfMon::Frame); + + Flush(); + + field = field ? 1 : 0; + + if(!Merge(field)) return; + + // osd + + if((m_perfmon.GetFrame() & 0x1f) == 0) + { + m_perfmon.Update(); + + double fps = 1000.0f / m_perfmon.Get(GSPerfMon::Frame); + + string s2 = m_regs->SMODE2.INT ? (string("Interlaced ") + (m_regs->SMODE2.FFMD ? "(frame)" : "(field)")) : "Progressive"; + + GSVector4i r = GetDisplayRect(); + + string s = format( + "%I64d | %d x %d | %.2f fps (%d%%) | %s - %s | %s | %d/%d/%d | %d%% CPU | %.2f | %.2f", + m_perfmon.GetFrame(), r.width(), r.height(), fps, (int)(100.0 * fps / GetFPS()), + s2.c_str(), + GSSettingsDlg::g_interlace[m_interlace].name, + GSSettingsDlg::g_aspectratio[m_aspectratio].name, + (int)m_perfmon.Get(GSPerfMon::Quad), + (int)m_perfmon.Get(GSPerfMon::Prim), + (int)m_perfmon.Get(GSPerfMon::Draw), + m_perfmon.CPU(), + m_perfmon.Get(GSPerfMon::Swizzle) / 1024, + m_perfmon.Get(GSPerfMon::Unswizzle) / 1024 + ); + + double fillrate = m_perfmon.Get(GSPerfMon::Fillrate); + + if(fillrate > 0) + { + s += format(" | %.2f mpps", fps * fillrate / (1024 * 1024)); + } + + if(m_capture.IsCapturing()) + { + s += " | Recording..."; + } + + m_wnd.SetWindowText(s.c_str()); + } + + if(m_frameskip) + { + return; + } + + // present + + if(m_dev->IsLost()) + { + ResetDevice(); + } + + m_dev->Present(m_wnd.GetClientRect().fit(m_aspectratio), m_shader); + + // snapshot + + if(!m_snapshot.empty()) + { + if(!m_dump && (::GetAsyncKeyState(VK_SHIFT) & 0x8000)) + { + GSFreezeData fd; + fd.size = 0; + fd.data = NULL; + Freeze(&fd, true); + fd.data = new uint8[fd.size]; + Freeze(&fd, false); + + m_dump.Open(m_snapshot, m_crc, fd, m_regs); + + delete [] fd.data; + } + + if(GSTexture* t = m_dev->GetCurrent()) + { + t->Save(m_snapshot + ".bmp"); + } + + m_snapshot.clear(); + } + else + { + if(m_dump) + { + m_dump.VSync(field, !(::GetAsyncKeyState(VK_CONTROL) & 0x8000), m_regs); + } + } + + // capture + + if(m_capture.IsCapturing()) + { + if(GSTexture* current = m_dev->GetCurrent()) + { + GSVector2i size = m_capture.GetSize(); + + if(GSTexture* offscreen = m_dev->CopyOffscreen(current, GSVector4(0, 0, 1, 1), size.x, size.y)) + { + GSTexture::GSMap m; + + if(offscreen->Map(m)) + { + m_capture.DeliverFrame(m.bits, m.pitch, m_dev->IsCurrentRGBA()); + + offscreen->Unmap(); + } + + m_dev->Recycle(offscreen); + } + } + } +} + +bool GSRenderer::MakeSnapshot(const string& path) +{ + if(m_snapshot.empty()) + { + time_t t = time(NULL); + + char buff[16]; + + if(strftime(buff, sizeof(buff), "%Y%m%d%H%M%S", localtime(&t))) + { + m_snapshot = format("%s_%s", path.c_str(), buff); + } + } + + return true; +} + +void GSRenderer::KeyEvent(GSKeyEventData* e) +{ + if(e->type == KEYPRESS) + { + // TODO: linux + + int step = (::GetAsyncKeyState(VK_SHIFT) & 0x8000) ? -1 : 1; + + switch(e->key) + { + case VK_F5: + m_interlace = (m_interlace + 7 + step) % 7; + return; + case VK_F6: + m_aspectratio = (m_aspectratio + 3 + step) % 3; + return; + case VK_F7: + m_shader = (m_shader + 3 + step) % 3; + return; + case VK_F12: + if(m_capture.IsCapturing()) m_capture.EndCapture(); + else m_capture.BeginCapture(GetFPS()); + return; + case VK_DELETE: + m_aa1 = !m_aa1; + return; + case VK_END: + m_blur = !m_blur; + return; + } + } +} + +void GSRenderer::GetTextureMinMax(GSVector4i& r, bool linear) +{ + const GSDrawingContext* context = m_context; + + int tw = context->TEX0.TW; + int th = context->TEX0.TH; + + int w = 1 << tw; + int h = 1 << th; + + GSVector4i tr(0, 0, w, h); + + int wms = context->CLAMP.WMS; + int wmt = context->CLAMP.WMT; + + int minu = (int)context->CLAMP.MINU; + int minv = (int)context->CLAMP.MINV; + int maxu = (int)context->CLAMP.MAXU; + int maxv = (int)context->CLAMP.MAXV; + + GSVector4i vr = tr; + + switch(wms) + { + case CLAMP_REPEAT: + break; + case CLAMP_CLAMP: + break; + case CLAMP_REGION_CLAMP: + if(vr.x < minu) vr.x = minu; + if(vr.z > maxu + 1) vr.z = maxu + 1; + break; + case CLAMP_REGION_REPEAT: + vr.x = maxu; + vr.z = vr.x + (minu + 1); + break; + default: + __assume(0); + } + + switch(wmt) + { + case CLAMP_REPEAT: + break; + case CLAMP_CLAMP: + break; + case CLAMP_REGION_CLAMP: + if(vr.y < minv) vr.y = minv; + if(vr.w > maxv + 1) vr.w = maxv + 1; + break; + case CLAMP_REGION_REPEAT: + vr.y = maxv; + vr.w = vr.y + (minv + 1); + break; + default: + __assume(0); + } + + if(wms + wmt < 6) + { + GSVector4 st = m_vt.m_min.t.xyxy(m_vt.m_max.t); + + if(linear) + { + st += GSVector4(-0x8000, 0x8000).xxyy(); + } + + GSVector4i uv = GSVector4i(st).sra32(16); + + GSVector4i u, v; + + int mask = 0; + + if(wms == CLAMP_REPEAT || wmt == CLAMP_REPEAT) + { + u = uv & GSVector4i::xffffffff().srl32(32 - tw); + v = uv & GSVector4i::xffffffff().srl32(32 - th); + + GSVector4i uu = uv.sra32(tw); + GSVector4i vv = uv.sra32(th); + + mask = (uu.upl32(vv) == uu.uph32(vv)).mask(); + } + + uv = uv.rintersect(tr); + + switch(wms) + { + case CLAMP_REPEAT: + if(mask & 0x000f) {if(vr.x < u.x) vr.x = u.x; if(vr.z > u.z + 1) vr.z = u.z + 1;} + break; + case CLAMP_CLAMP: + case CLAMP_REGION_CLAMP: + if(vr.x < uv.x) vr.x = uv.x; + if(vr.z > uv.z + 1) vr.z = uv.z + 1; + break; + case CLAMP_REGION_REPEAT: // TODO + break; + default: + __assume(0); + } + + switch(wmt) + { + case CLAMP_REPEAT: + if(mask & 0xf000) {if(vr.y < v.y) vr.y = v.y; if(vr.w > v.w + 1) vr.w = v.w + 1;} + break; + case CLAMP_CLAMP: + case CLAMP_REGION_CLAMP: + if(vr.y < uv.y) vr.y = uv.y; + if(vr.w > uv.w + 1) vr.w = uv.w + 1; + break; + case CLAMP_REGION_REPEAT: // TODO + break; + default: + __assume(0); + } + } + + GSVector2i bs = GSLocalMemory::m_psm[context->TEX0.PSM].bs; + + r = vr.ralign(bs).rintersect(tr); +} + +void GSRenderer::GetAlphaMinMax() +{ + if(m_vt.m_alpha.valid) + { + return; + } + + const GSDrawingEnvironment& env = m_env; + const GSDrawingContext* context = m_context; + + GSVector4i a = m_vt.m_min.c.uph32(m_vt.m_max.c).zzww(); + + if(PRIM->TME && context->TEX0.TCC) + { + uint32 bpp = GSLocalMemory::m_psm[context->TEX0.PSM].trbpp; + uint32 cbpp = GSLocalMemory::m_psm[context->TEX0.CPSM].trbpp; + uint32 pal = GSLocalMemory::m_psm[context->TEX0.PSM].pal; + + if(bpp == 32) + { + a.y = 0; + a.w = 0xff; + } + else if(bpp == 24) + { + a.y = env.TEXA.AEM ? 0 : env.TEXA.TA0; + a.w = env.TEXA.TA0; + } + else if(bpp == 16) + { + a.y = env.TEXA.AEM ? 0 : min(env.TEXA.TA0, env.TEXA.TA1); + a.w = max(env.TEXA.TA0, env.TEXA.TA1); + } + else + { + m_mem.m_clut.GetAlphaMinMax32(a.y, a.w); + } + + switch(context->TEX0.TFX) + { + case TFX_MODULATE: + a.x = (a.x * a.y) >> 7; + a.z = (a.z * a.w) >> 7; + if(a.x > 0xff) a.x = 0xff; + if(a.z > 0xff) a.z = 0xff; + break; + case TFX_DECAL: + a.x = a.y; + a.z = a.w; + break; + case TFX_HIGHLIGHT: + a.x = a.x + a.y; + a.z = a.z + a.w; + if(a.x > 0xff) a.x = 0xff; + if(a.z > 0xff) a.z = 0xff; + break; + case TFX_HIGHLIGHT2: + a.x = a.y; + a.z = a.w; + break; + default: + __assume(0); + } + } + + m_vt.m_alpha.min = a.x; + m_vt.m_alpha.max = a.z; + m_vt.m_alpha.valid = true; +} + +bool GSRenderer::TryAlphaTest(uint32& fm, uint32& zm) +{ + const GSDrawingContext* context = m_context; + + bool pass = true; + + if(context->TEST.ATST == ATST_NEVER) + { + pass = false; + } + else if(context->TEST.ATST != ATST_ALWAYS) + { + GetAlphaMinMax(); + + int amin = m_vt.m_alpha.min; + int amax = m_vt.m_alpha.max; + + int aref = context->TEST.AREF; + + switch(context->TEST.ATST) + { + case ATST_NEVER: + pass = false; + break; + case ATST_ALWAYS: + pass = true; + break; + case ATST_LESS: + if(amax < aref) pass = true; + else if(amin >= aref) pass = false; + else return false; + break; + case ATST_LEQUAL: + if(amax <= aref) pass = true; + else if(amin > aref) pass = false; + else return false; + break; + case ATST_EQUAL: + if(amin == aref && amax == aref) pass = true; + else if(amin > aref || amax < aref) pass = false; + else return false; + break; + case ATST_GEQUAL: + if(amin >= aref) pass = true; + else if(amax < aref) pass = false; + else return false; + break; + case ATST_GREATER: + if(amin > aref) pass = true; + else if(amax <= aref) pass = false; + else return false; + break; + case ATST_NOTEQUAL: + if(amin == aref && amax == aref) pass = false; + else if(amin > aref || amax < aref) pass = true; + else return false; + break; + default: + __assume(0); + } + } + + if(!pass) + { + switch(context->TEST.AFAIL) + { + case AFAIL_KEEP: fm = zm = 0xffffffff; break; + case AFAIL_FB_ONLY: zm = 0xffffffff; break; + case AFAIL_ZB_ONLY: fm = 0xffffffff; break; + case AFAIL_RGB_ONLY: fm |= 0xff000000; zm = 0xffffffff; break; + default: __assume(0); + } + } + + return true; +} + +bool GSRenderer::IsLinear() +{ + float qmin = m_vt.m_min.t.z; + float qmax = m_vt.m_max.t.z; + + if(PRIM->FST) + { + // assume Q = 1.0f => LOD > 0 (should not, but Q is very often bogus, 0 or DEN) + + qmin = qmax = 1.0f; + } + + return m_context->TEX1.IsLinear(qmin, qmax); +} + +bool GSRenderer::IsOpaque() +{ + if(PRIM->AA1) + { + return false; + } + + if(!PRIM->ABE) + { + return true; + } + + const GSDrawingContext* context = m_context; + + int amin = 0, amax = 0xff; + + if(context->ALPHA.A != context->ALPHA.B) + { + if(context->ALPHA.C == 0) + { + GetAlphaMinMax(); + + amin = m_vt.m_alpha.min; + amax = m_vt.m_alpha.max; + } + else if(context->ALPHA.C == 1) + { + if(context->FRAME.PSM == PSM_PSMCT24 || context->FRAME.PSM == PSM_PSMZ24) + { + amin = amax = 0x80; + } + } + else if(context->ALPHA.C == 1) + { + amin = amax = context->ALPHA.FIX; + } + } + + return context->ALPHA.IsOpaque(amin, amax); +} diff --git a/plugins/GSdx/GSRenderer.h b/plugins/GSdx/GSRenderer.h index 56bd999fb7..1817ce0786 100644 --- a/plugins/GSdx/GSRenderer.h +++ b/plugins/GSdx/GSRenderer.h @@ -21,14 +21,23 @@ #pragma once +#include "GSdx.h" #include "GSWnd.h" #include "GSState.h" +#include "GSVertexTrace.h" #include "GSVertexList.h" #include "GSSettingsDlg.h" #include "GSCapture.h" -struct GSRendererSettings +class GSRenderer : public GSState { + GSCapture m_capture; + string m_snapshot; + int m_shader; + + bool Merge(int field); + +protected: int m_interlace; int m_aspectratio; int m_filter; @@ -36,520 +45,45 @@ struct GSRendererSettings bool m_nativeres; bool m_aa1; bool m_blur; -}; -class GSRendererBase : public GSState, protected GSRendererSettings -{ -protected: - bool m_osd; + virtual void ResetDevice() {} + virtual GSTexture* GetOutput(int i) = 0; - void ProcessWindowMessages() - { - MSG msg; + GSVertexTrace m_vt; - memset(&msg, 0, sizeof(msg)); + // following functions need m_vt to be initialized - while(msg.message != WM_QUIT && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - if(OnMessage(msg)) - { - continue; - } - - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - virtual bool OnMessage(const MSG& msg) - { - if(msg.message == WM_KEYDOWN) - { - int step = (::GetAsyncKeyState(VK_SHIFT) & 0x8000) ? -1 : 1; - - switch(msg.wParam) - { - case VK_F5: - m_interlace = (m_interlace + 7 + step) % 7; - return true; - case VK_F6: - m_aspectratio = (m_aspectratio + 3 + step) % 3; - return true; - case VK_F7: - m_wnd.SetWindowText(_T("PCSX2")); - m_osd = !m_osd; - return true; - case VK_DELETE: - m_aa1 = !m_aa1; - return true; - case VK_END: - m_blur = !m_blur; - return true; - } - } - - return false; - } + void GetTextureMinMax(GSVector4i& r, bool linear); + void GetAlphaMinMax(); + bool TryAlphaTest(uint32& fm, uint32& zm); + bool IsLinear(); + bool IsOpaque(); public: GSWnd m_wnd; - -public: - GSRendererBase(BYTE* base, bool mt, void (*irq)(), const GSRendererSettings& rs) - : GSState(base, mt, irq) - , m_osd(true) - { - m_interlace = rs.m_interlace; - m_aspectratio = rs.m_aspectratio; - m_filter = rs.m_filter; - m_vsync = rs.m_vsync; - m_nativeres = rs.m_nativeres; - m_aa1 = rs.m_aa1; - m_blur = rs.m_blur; - }; - - virtual bool Create(LPCTSTR title) = 0; - virtual void VSync(int field) = 0; - virtual bool MakeSnapshot(LPCTSTR path) = 0; -}; - -template class GSRenderer : public GSRendererBase -{ -protected: - typedef typename Device::Texture Texture; - - virtual void ResetDevice() {} - virtual bool GetOutput(int i, Texture& t) = 0; - - bool Merge(int field) - { - bool en[2]; - - CRect fr[2]; - CRect dr[2]; - - int baseline = INT_MAX; - - for(int i = 0; i < 2; i++) - { - en[i] = IsEnabled(i); - - if(en[i]) - { - fr[i] = GetFrameRect(i); - dr[i] = GetDisplayRect(i); - - baseline = min(dr[i].top, baseline); - - // printf("[%d]: %d %d %d %d, %d %d %d %d\n", i, fr[i], dr[i]); - } - } - - if(!en[0] && !en[1]) - { - return false; - } - - // try to avoid fullscreen blur, could be nice on tv but on a monitor it's like double vision, hurts my eyes (persona 4, guitar hero) - // - // NOTE: probably the technique explained in graphtip.pdf (Antialiasing by Supersampling / 4. Reading Odd/Even Scan Lines Separately with the PCRTC then Blending) - - bool samesrc = - en[0] && en[1] && - m_regs->DISP[0].DISPFB.FBP == m_regs->DISP[1].DISPFB.FBP && - m_regs->DISP[0].DISPFB.FBW == m_regs->DISP[1].DISPFB.FBW && - m_regs->DISP[0].DISPFB.PSM == m_regs->DISP[1].DISPFB.PSM; - - bool blurdetected = false; - - if(samesrc && m_regs->PMODE.SLBG == 0 && m_regs->PMODE.MMOD == 1 && m_regs->PMODE.ALP == 0x80) - { - if(fr[0] == fr[1] + CRect(0, 1, 0, 0) && dr[0] == dr[1] + CRect(0, 0, 0, 1) - || fr[1] == fr[0] + CRect(0, 1, 0, 0) && dr[1] == dr[0] + CRect(0, 0, 0, 1)) - { - // persona 4: - // - // fr[0] = 0 0 640 448 - // fr[1] = 0 1 640 448 - // dr[0] = 159 50 779 498 - // dr[1] = 159 50 779 497 - // - // second image shifted up by 1 pixel and blended over itself - // - // god of war: - // - // fr[0] = 0 1 512 448 - // fr[1] = 0 0 512 448 - // dr[0] = 127 50 639 497 - // dr[1] = 127 50 639 498 - // - // same just the first image shifted - - int top = min(fr[0].top, fr[1].top); - int bottom = max(dr[0].bottom, dr[1].bottom); - - fr[0].top = top; - fr[1].top = top; - dr[0].bottom = bottom; - dr[1].bottom = bottom; - - blurdetected = true; - } - else if(dr[0] == dr[1] && (fr[0] == fr[1] + CPoint(0, 1) || fr[1] == fr[0] + CPoint(0, 1))) - { - // dq5: - // - // fr[0] = 0 1 512 445 - // fr[1] = 0 0 512 444 - // dr[0] = 127 50 639 494 - // dr[1] = 127 50 639 494 - - int top = min(fr[0].top, fr[1].top); - int bottom = min(fr[0].bottom, fr[1].bottom); - - fr[0].top = fr[1].top = top; - fr[0].bottom = fr[1].bottom = bottom; - - blurdetected = true; - } - } - - CSize fs(0, 0); - CSize ds(0, 0); - - Texture tex[2]; - - if(samesrc && fr[0].bottom == fr[1].bottom) - { - GetOutput(0, tex[0]); - - tex[1] = tex[0]; // saves one texture fetch - } - else - { - if(en[0]) GetOutput(0, tex[0]); - if(en[1]) GetOutput(1, tex[1]); - } - - GSVector4 src[2]; - GSVector4 dst[2]; - - for(int i = 0; i < 2; i++) - { - if(!en[i] || !tex[i]) continue; - - CRect r = fr[i]; - - // overscan hack - - if(dr[i].Height() > 512) // hmm - { - int y = GetDeviceSize(i).cy; - if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD) y /= 2; - r.bottom = r.top + y; - } - - // - - if(m_blur && blurdetected && i == 1) - { - src[i].x = tex[i].m_scale.x * r.left / tex[i].GetWidth(); - src[i].y = (tex[i].m_scale.y * r.top + 1) / tex[i].GetHeight(); - src[i].z = tex[i].m_scale.x * r.right / tex[i].GetWidth(); - src[i].w = (tex[i].m_scale.y * r.bottom + 1) / tex[i].GetHeight(); - } - else - { - src[i].x = tex[i].m_scale.x * r.left / tex[i].GetWidth(); - src[i].y = tex[i].m_scale.y * r.top / tex[i].GetHeight(); - src[i].z = tex[i].m_scale.x * r.right / tex[i].GetWidth(); - src[i].w = tex[i].m_scale.y * r.bottom / tex[i].GetHeight(); - } - - GSVector2 o; - - o.x = 0; - o.y = 0; - - if(dr[i].top - baseline >= 4) // 2? - { - o.y = tex[i].m_scale.y * (dr[i].top - baseline); - } - - if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD) o.y /= 2; - - dst[i].x = o.x; - dst[i].y = o.y; - dst[i].z = o.x + tex[i].m_scale.x * r.Width(); - dst[i].w = o.y + tex[i].m_scale.y * r.Height(); - - fs.cx = max(fs.cx, (int)(dst[i].z + 0.5f)); - fs.cy = max(fs.cy, (int)(dst[i].w + 0.5f)); - } - - ds.cx = fs.cx; - ds.cy = fs.cy; - - if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD) ds.cy *= 2; - - bool slbg = m_regs->PMODE.SLBG; - bool mmod = m_regs->PMODE.MMOD; - - if(tex[0] || tex[1]) - { - GSVector4 c; - - c.r = (float)m_regs->BGCOLOR.R / 255; - c.g = (float)m_regs->BGCOLOR.G / 255; - c.b = (float)m_regs->BGCOLOR.B / 255; - c.a = (float)m_regs->PMODE.ALP / 255; - - m_dev.Merge(tex, src, dst, fs, slbg, mmod, c); - - if(m_regs->SMODE2.INT && m_interlace > 0) - { - int field2 = 1 - ((m_interlace - 1) & 1); - int mode = (m_interlace - 1) >> 1; - - if(!m_dev.Interlace(ds, field ^ field2, mode, tex[1].m_scale.y)) - { - return false; - } - } - } - - return true; - } - - void DoSnapshot(int field) - { - if(!m_snapshot.IsEmpty()) - { - if(!m_dump && (::GetAsyncKeyState(VK_SHIFT) & 0x8000)) - { - GSFreezeData fd; - fd.size = 0; - fd.data = NULL; - Freeze(&fd, true); - fd.data = new BYTE[fd.size]; - Freeze(&fd, false); - - m_dump.Open(m_snapshot, m_crc, fd, m_regs); - - delete [] fd.data; - } - - m_dev.SaveCurrent(m_snapshot + _T(".bmp")); - - m_snapshot.Empty(); - } - else - { - if(m_dump) - { - m_dump.VSync(field, !(::GetAsyncKeyState(VK_CONTROL) & 0x8000), m_regs); - } - } - } - - void DoCapture() - { - if(!m_capture.IsCapturing()) - { - return; - } - - CSize size = m_capture.GetSize(); - - Texture current; - - m_dev.GetCurrent(current); - - Texture offscreen; - - if(m_dev.CopyOffscreen(current, GSVector4(0, 0, 1, 1), offscreen, size.cx, size.cy)) - { - BYTE* bits = NULL; - int pitch = 0; - - if(offscreen.Map(&bits, pitch)) - { - m_capture.DeliverFrame(bits, pitch, m_dev.IsCurrentRGBA()); - - offscreen.Unmap(); - } - - m_dev.Recycle(offscreen); - } - } - - virtual bool OnMessage(const MSG& msg) - { - if(msg.message == WM_KEYDOWN) - { - switch(msg.wParam) - { - case VK_F12: - if(m_capture.IsCapturing()) m_capture.EndCapture(); - else m_capture.BeginCapture(GetFPS()); - return true; - } - } - - return __super::OnMessage(msg); - } - -public: - Device m_dev; - bool m_psrr; + GSDevice* m_dev; int s_n; bool s_dump; bool s_save; bool s_savez; - CString m_snapshot; - GSCapture m_capture; - public: - GSRenderer(BYTE* base, bool mt, void (*irq)(), const GSRendererSettings& rs, bool psrr) - : GSRendererBase(base, mt, irq, rs) - , m_psrr(psrr) + GSRenderer(uint8* base, bool mt, void (*irq)(), GSDevice* dev); + virtual ~GSRenderer(); + + virtual bool Create(const string& title); + virtual void VSync(int field); + virtual bool MakeSnapshot(const string& path); + virtual void KeyEvent(GSKeyEventData* e); + + virtual bool CanUpscale() { - s_n = 0; - s_dump = !!AfxGetApp()->GetProfileInt(_T("Debug"), _T("dump"), 0); - s_save = !!AfxGetApp()->GetProfileInt(_T("Debug"), _T("save"), 0); - s_savez = !!AfxGetApp()->GetProfileInt(_T("Debug"), _T("savez"), 0); + return !m_nativeres; } - - bool Create(LPCTSTR title) - { - if(!m_wnd.Create(title)) - { - return false; - } - - if(!m_dev.Create(m_wnd, m_vsync)) - { - return false; - } - - Reset(); - - return true; - } - - void VSync(int field) - { - GSPerfMonAutoTimer pmat(m_perfmon); - - Flush(); - - m_perfmon.Put(GSPerfMon::Frame); - - ProcessWindowMessages(); - - field = field ? 1 : 0; - - if(!Merge(field)) return; - - // osd - - static UINT64 s_frame = 0; - static CString s_stats; - - if(m_perfmon.GetFrame() - s_frame >= 30) - { - m_perfmon.Update(); - - s_frame = m_perfmon.GetFrame(); - - double fps = 1000.0f / m_perfmon.Get(GSPerfMon::Frame); - - s_stats.Format( - _T("%I64d | %d x %d | %.2f fps (%d%%) | %s - %s | %s | %d/%d/%d | %d%% CPU | %.2f | %.2f"), - m_perfmon.GetFrame(), GetDisplaySize().cx, GetDisplaySize().cy, fps, (int)(100.0 * fps / GetFPS()), - m_regs->SMODE2.INT ? (CString(_T("Interlaced ")) + (m_regs->SMODE2.FFMD ? _T("(frame)") : _T("(field)"))) : _T("Progressive"), - GSSettingsDlg::g_interlace[m_interlace].name, - GSSettingsDlg::g_aspectratio[m_aspectratio].name, - (int)m_perfmon.Get(GSPerfMon::Quad), - (int)m_perfmon.Get(GSPerfMon::Prim), - (int)m_perfmon.Get(GSPerfMon::Draw), - m_perfmon.CPU(), - m_perfmon.Get(GSPerfMon::Swizzle) / 1024, - m_perfmon.Get(GSPerfMon::Unswizzle) / 1024 - ); - - double fillrate = m_perfmon.Get(GSPerfMon::Fillrate); - - if(fillrate > 0) - { - s_stats.Format(_T("%s | %.2f mpps"), CString(s_stats), fps * fillrate / (1024 * 1024)); - } - - if(m_capture.IsCapturing()) - { - s_stats += _T(" | Recording..."); - } - - if(m_perfmon.Get(GSPerfMon::COLCLAMP)) _tprintf(_T("*** NOT SUPPORTED: color wrap ***\n")); - if(m_perfmon.Get(GSPerfMon::PABE)) _tprintf(_T("*** NOT SUPPORTED: per pixel alpha blend ***\n")); - if(m_perfmon.Get(GSPerfMon::DATE)) _tprintf(_T("*** PERFORMANCE WARNING: destination alpha test used ***\n")); - if(m_perfmon.Get(GSPerfMon::ABE)) _tprintf(_T("*** NOT SUPPORTED: alpha blending mode ***\n")); - if(m_perfmon.Get(GSPerfMon::DepthTexture)) _tprintf(_T("*** NOT SUPPORTED: depth texture ***\n")); - - m_wnd.SetWindowText(s_stats); - } - - if(m_osd) - { - m_dev.Draw(s_stats + _T("\n\nF5: interlace mode\nF6: aspect ratio\nF7: OSD")); - } - - if(m_frameskip) - { - return; - } - - // - - if(m_dev.IsLost()) - { - ResetDevice(); - } - - // - - CRect r; - - m_wnd.GetClientRect(&r); - - GSUtil::FitRect(r, m_aspectratio); - - m_dev.Present(r); - - // - - DoSnapshot(field); - - DoCapture(); - } - - bool MakeSnapshot(LPCTSTR path) - { - if(m_snapshot.IsEmpty()) - { - m_snapshot.Format(_T("%s_%s"), path, CTime::GetCurrentTime().Format(_T("%Y%m%d%H%M%S"))); - } - - return true; - } - - virtual void MinMaxUV(int w, int h, CRect& r) {r = CRect(0, 0, w, h);} - virtual bool CanUpscale() {return !m_nativeres;} }; -template class GSRendererT : public GSRenderer +template class GSRendererT : public GSRenderer { protected: Vertex* m_vertices; @@ -594,6 +128,8 @@ protected: // FIXME: berserk fpsm = 27 (8H) Draw(); + + m_perfmon.Put(GSPerfMon::Draw, 1); } m_count = 0; @@ -607,7 +143,7 @@ protected: m_maxcount -= 100; } - template __forceinline Vertex* DrawingKick(bool skip, DWORD& count) + template __forceinline Vertex* DrawingKick(bool skip, int& count) { switch(prim) { @@ -687,15 +223,15 @@ protected: virtual void Draw() = 0; public: - GSRendererT(BYTE* base, bool mt, void (*irq)(), const GSRendererSettings& rs, bool psrr = true) - : GSRenderer(base, mt, irq, rs, psrr) + GSRendererT(uint8* base, bool mt, void (*irq)(), GSDevice* dev) + : GSRenderer(base, mt, irq, dev) + , m_vertices(NULL) , m_count(0) , m_maxcount(0) - , m_vertices(NULL) { } - ~GSRendererT() + virtual ~GSRendererT() { if(m_vertices) _aligned_free(m_vertices); } diff --git a/plugins/GSdx/GSRendererDX.cpp b/plugins/GSdx/GSRendererDX.cpp new file mode 100644 index 0000000000..77f6bfd198 --- /dev/null +++ b/plugins/GSdx/GSRendererDX.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSRendererDX.h" \ No newline at end of file diff --git a/plugins/GSdx/GSRendererDX.h b/plugins/GSdx/GSRendererDX.h new file mode 100644 index 0000000000..14a6fde4e0 --- /dev/null +++ b/plugins/GSdx/GSRendererDX.h @@ -0,0 +1,338 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSRendererHW.h" +#include "GSTextureFX.h" + +template +class GSRendererDX : public GSRendererHW +{ + GSTextureFX* m_tfx; + bool m_logz; + bool m_fba; + +protected: + int m_topology; + GSVector2 m_pixelcenter; + + virtual void SetupDATE(GSTexture* rt, GSTexture* ds) {} + virtual void UpdateFBA(GSTexture* rt) {} + +public: + GSRendererDX(uint8* base, bool mt, void (*irq)(), GSDevice* dev, GSTextureCache* tc, GSTextureFX* tfx) + : GSRendererHW(base, mt, irq, dev, tc) + , m_tfx(tfx) + , m_topology(-1) + , m_pixelcenter(0, 0) + { + m_logz = !!theApp.GetConfig("logz", 0); + m_fba = !!theApp.GetConfig("fba", 1); + } + + virtual ~GSRendererDX() + { + delete m_tfx; + } + + bool Create(const string& title) + { + if(!__super::Create(title)) + return false; + + if(!m_tfx->Create(m_dev)) + return false; + + return true; + } + + void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) + { + GSDrawingEnvironment& env = m_env; + GSDrawingContext* context = m_context; + + // + + SetupDATE(rt, ds); + + // + + m_dev->BeginScene(); + + // om + + GSTextureFX::OMDepthStencilSelector om_dssel; + + om_dssel.zte = context->TEST.ZTE; + om_dssel.ztst = context->TEST.ZTST; + om_dssel.zwe = !context->ZBUF.ZMSK; + om_dssel.date = context->FRAME.PSM != PSM_PSMCT24 ? context->TEST.DATE : 0; + om_dssel.fba = m_fba ? context->FBA.FBA : 0; + + GSTextureFX::OMBlendSelector om_bsel; + + om_bsel.abe = !IsOpaque(); + om_bsel.a = context->ALPHA.A; + om_bsel.b = context->ALPHA.B; + om_bsel.c = context->ALPHA.C; + om_bsel.d = context->ALPHA.D; + om_bsel.wr = (context->FRAME.FBMSK & 0x000000ff) != 0x000000ff; + om_bsel.wg = (context->FRAME.FBMSK & 0x0000ff00) != 0x0000ff00; + om_bsel.wb = (context->FRAME.FBMSK & 0x00ff0000) != 0x00ff0000; + om_bsel.wa = (context->FRAME.FBMSK & 0xff000000) != 0xff000000; + + // vs + + GSTextureFX::VSSelector vs_sel; + + vs_sel.bppz = 0; + vs_sel.tme = PRIM->TME; + vs_sel.fst = PRIM->FST; + vs_sel.logz = m_logz ? 1 : 0; + vs_sel.prim = primclass; + + if(om_dssel.zte && om_dssel.ztst > 0 && om_dssel.zwe) + { + if(context->ZBUF.PSM == PSM_PSMZ24) + { + if(m_vt.m_max.p.z > 0xffffff) + { + ASSERT(m_vt.m_min.p.z > 0xffffff); + + vs_sel.bppz = 1; + om_dssel.ztst = 1; + } + } + else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S) + { + if(m_vt.m_max.p.z > 0xffff) + { + ASSERT(m_vt.m_min.p.z > 0xffff); // sfex capcom logo + + vs_sel.bppz = 2; + om_dssel.ztst = 1; + } + } + } + + GSTextureFX::VSConstantBuffer vs_cb; + + float sx = 2.0f * rt->m_scale.x / (rt->GetWidth() * 16); + float sy = 2.0f * rt->m_scale.y / (rt->GetHeight() * 16); + float ox = (float)(int)context->XYOFFSET.OFX; + float oy = (float)(int)context->XYOFFSET.OFY; + float ox2 = 2.0f * m_pixelcenter.x / rt->GetWidth(); + float oy2 = 2.0f * m_pixelcenter.y / rt->GetHeight(); + + vs_cb.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f); + vs_cb.VertexOffset = GSVector4(ox * sx + ox2 + 1, -(oy * sy + oy2 + 1), 0.0f, -1.0f); + + if(PRIM->TME) + { + if(PRIM->FST) + { + vs_cb.TextureScale.x = 1.0f / (16 << context->TEX0.TW); + vs_cb.TextureScale.y = 1.0f / (16 << context->TEX0.TH); + } + else + { + vs_cb.TextureScale = GSVector2(1.0f, 1.0f); + } + } + + // gs + + GSTextureFX::GSSelector gs_sel; + + gs_sel.iip = PRIM->IIP; + gs_sel.prim = primclass; + + // ps + + GSTextureFX::PSSelector ps_sel; + + ps_sel.fst = PRIM->FST; + ps_sel.wms = context->CLAMP.WMS; + ps_sel.wmt = context->CLAMP.WMT; + ps_sel.bpp = 0; + ps_sel.aem = env.TEXA.AEM; + ps_sel.tfx = context->TEX0.TFX; + ps_sel.tcc = context->TEX0.TCC; + ps_sel.ate = context->TEST.ATE; + ps_sel.atst = context->TEST.ATST; + ps_sel.fog = PRIM->FGE; + ps_sel.clr1 = om_bsel.abe && om_bsel.a == 1 && om_bsel.b == 2 && om_bsel.d == 1; + ps_sel.fba = context->FBA.FBA; + ps_sel.aout = context->FRAME.PSM == PSM_PSMCT16 || context->FRAME.PSM == PSM_PSMCT16S || (context->FRAME.FBMSK & 0xff000000) == 0x7f000000 ? 1 : 0; + ps_sel.ltf = m_filter == 2 ? IsLinear() : m_filter; + + GSTextureFX::PSSamplerSelector ps_ssel; + + ps_ssel.tau = 0; + ps_ssel.tav = 0; + ps_ssel.ltf = ps_sel.ltf; + + GSTextureFX::PSConstantBuffer ps_cb; + + ps_cb.FogColor_AREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255; + + if(ps_sel.atst == 2 || ps_sel.atst == 5) + { + ps_cb.FogColor_AREF.a -= 0.9f / 255; + } + else if(ps_sel.atst == 3 || ps_sel.atst == 6) + { + ps_cb.FogColor_AREF.a += 0.9f / 255; + } + + if(tex) + { + ps_sel.bpp = tex->m_bpp; + + int w = tex->m_texture->GetWidth(); + int h = tex->m_texture->GetHeight(); + + ps_cb.WH = GSVector4((int)(1 << context->TEX0.TW), (int)(1 << context->TEX0.TH), w, h); + ps_cb.HalfTexel = GSVector4(-0.5f, 0.5f).xxyy() / GSVector4(w, h).xyxy(); + ps_cb.MinF_TA.z = (float)(int)env.TEXA.TA0 / 255; + ps_cb.MinF_TA.w = (float)(int)env.TEXA.TA1 / 255; + + switch(context->CLAMP.WMS) + { + case 0: + ps_ssel.tau = 1; + break; + case 1: + ps_ssel.tau = 0; + break; + case 2: + ps_cb.MinMax.x = ((float)(int)context->CLAMP.MINU) / (1 << context->TEX0.TW); + ps_cb.MinMax.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW); + ps_cb.MinF_TA.x = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW); + ps_ssel.tau = 0; + break; + case 3: + ps_cb.MskFix.x = context->CLAMP.MINU; + ps_cb.MskFix.z = context->CLAMP.MAXU; + ps_ssel.tau = 1; + break; + default: + __assume(0); + } + + switch(context->CLAMP.WMT) + { + case 0: + ps_ssel.tav = 1; + break; + case 1: + ps_ssel.tav = 0; + break; + case 2: + ps_cb.MinMax.y = ((float)(int)context->CLAMP.MINV) / (1 << context->TEX0.TH); + ps_cb.MinMax.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH); + ps_cb.MinF_TA.y = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH); + ps_ssel.tav = 0; + break; + case 3: + ps_cb.MskFix.y = context->CLAMP.MINV; + ps_cb.MskFix.w = context->CLAMP.MAXV; + ps_ssel.tav = 1; + break; + default: + __assume(0); + } + } + else + { + ps_sel.tfx = 4; + } + + // rs + + int w = rt->GetWidth(); + int h = rt->GetHeight(); + + GSVector4i scissor = GSVector4i(GSVector4(rt->m_scale).xyxy() * context->scissor.in).rintersect(GSVector4i(0, 0, w, h)); + + // + + uint8 afix = context->ALPHA.FIX; + + m_tfx->SetupOM(om_dssel, om_bsel, afix, rt, ds); + m_tfx->SetupIA(m_vertices, m_count, m_topology); + m_tfx->SetupVS(vs_sel, &vs_cb); + m_tfx->SetupGS(gs_sel); + m_tfx->SetupPS(ps_sel, &ps_cb, ps_ssel, tex ? tex->m_texture : NULL, tex ? tex->m_palette : NULL); + m_tfx->SetupRS(w, h, scissor); + + // draw + + if(context->TEST.DoFirstPass()) + { + m_dev->DrawPrimitive(); + } + + if(context->TEST.DoSecondPass()) + { + ASSERT(!env.PABE.PABE); + + static const uint32 iatst[] = {1, 0, 5, 6, 7, 2, 3, 4}; + + ps_sel.atst = iatst[ps_sel.atst]; + + m_tfx->UpdatePS(ps_sel, &ps_cb, ps_ssel); + + bool z = om_dssel.zwe; + bool r = om_bsel.wr; + bool g = om_bsel.wg; + bool b = om_bsel.wb; + bool a = om_bsel.wa; + + switch(context->TEST.AFAIL) + { + case 0: z = r = g = b = a = false; break; // none + case 1: z = false; break; // rgba + case 2: r = g = b = a = false; break; // z + case 3: z = a = false; break; // rgb + default: __assume(0); + } + + if(z || r || g || b || a) + { + om_dssel.zwe = z; + om_bsel.wr = r; + om_bsel.wg = g; + om_bsel.wb = b; + om_bsel.wa = a; + + m_tfx->UpdateOM(om_dssel, om_bsel, afix); + + m_dev->DrawPrimitive(); + } + } + + m_dev->EndScene(); + + if(om_dssel.fba) UpdateFBA(rt); + } +}; \ No newline at end of file diff --git a/plugins/GSdx/GSRendererDX10.cpp b/plugins/GSdx/GSRendererDX10.cpp new file mode 100644 index 0000000000..0bc018f78b --- /dev/null +++ b/plugins/GSdx/GSRendererDX10.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSRendererDX10.h" +#include "GSCrc.h" +#include "resource.h" + +GSRendererDX10::GSRendererDX10(uint8* base, bool mt, void (*irq)()) + : GSRendererDX(base, mt, irq, new GSDevice10(), new GSTextureCache10(this), new GSTextureFX10()) +{ + InitVertexKick(); + + m_pixelcenter = GSVector2(-0.5f, -0.5f); +} + +bool GSRendererDX10::Create(const string& title) +{ + if(!__super::Create(title)) + return false; + + // + + D3D10_DEPTH_STENCIL_DESC dsd; + + memset(&dsd, 0, sizeof(dsd)); + + dsd.DepthEnable = false; + dsd.StencilEnable = true; + dsd.StencilReadMask = 1; + dsd.StencilWriteMask = 1; + dsd.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS; + dsd.FrontFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE; + dsd.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; + dsd.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP; + dsd.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS; + dsd.BackFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE; + dsd.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; + dsd.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP; + + (*(GSDevice10*)m_dev)->CreateDepthStencilState(&dsd, &m_date.dss); + + D3D10_BLEND_DESC bd; + + memset(&bd, 0, sizeof(bd)); + + (*(GSDevice10*)m_dev)->CreateBlendState(&bd, &m_date.bs); + + // + + return true; +} + +template +void GSRendererDX10::VertexKick(bool skip) +{ + GSVertexHW10& dst = m_vl.AddTail(); + + dst.vi[0] = m_v.vi[0]; + dst.vi[1] = m_v.vi[1]; + + if(tme && fst) + { + GSVector4::storel(&dst.ST, m_v.GetUV()); + } + + int count = 0; + + if(GSVertexHW10* v = DrawingKick(skip, count)) + { + GSVector4i scissor = m_context->scissor.dx10; + + #if _M_SSE >= 0x401 + + GSVector4i pmin, pmax, v0, v1, v2; + + switch(prim) + { + case GS_POINTLIST: + v0 = GSVector4i::load((int)v[0].p.xy).upl16(); + pmin = v0; + pmax = v0; + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + v0 = GSVector4i::load((int)v[0].p.xy); + v1 = GSVector4i::load((int)v[1].p.xy); + pmin = v0.min_u16(v1).upl16(); + pmax = v0.max_u16(v1).upl16(); + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + v0 = GSVector4i::load((int)v[0].p.xy); + v1 = GSVector4i::load((int)v[1].p.xy); + v2 = GSVector4i::load((int)v[2].p.xy); + pmin = v0.min_u16(v1).min_u16(v2).upl16(); + pmax = v0.max_u16(v1).max_u16(v2).upl16(); + break; + } + + GSVector4i test = (pmax < scissor) | (pmin > scissor.zwxy()); + + if(test.mask() & 0xff) + { + return; + } + + #else + + switch(prim) + { + case GS_POINTLIST: + if(v[0].p.x < scissor.x + || v[0].p.x > scissor.z + || v[0].p.y < scissor.y + || v[0].p.y > scissor.w) + { + return; + } + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + if(v[0].p.x < scissor.x && v[1].p.x < scissor.x + || v[0].p.x > scissor.z && v[1].p.x > scissor.z + || v[0].p.y < scissor.y && v[1].p.y < scissor.y + || v[0].p.y > scissor.w && v[1].p.y > scissor.w) + { + return; + } + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + if(v[0].p.x < scissor.x && v[1].p.x < scissor.x && v[2].p.x < scissor.x + || v[0].p.x > scissor.z && v[1].p.x > scissor.z && v[2].p.x > scissor.z + || v[0].p.y < scissor.y && v[1].p.y < scissor.y && v[2].p.y < scissor.y + || v[0].p.y > scissor.w && v[1].p.y > scissor.w && v[2].p.y > scissor.w) + { + return; + } + break; + } + + #endif + + m_count += count; + } +} + +void GSRendererDX10::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) +{ + switch(primclass) + { + case GS_POINT_CLASS: + m_topology = D3D10_PRIMITIVE_TOPOLOGY_POINTLIST; + m_perfmon.Put(GSPerfMon::Prim, m_count); + break; + case GS_LINE_CLASS: + case GS_SPRITE_CLASS: + m_topology = D3D10_PRIMITIVE_TOPOLOGY_LINELIST; + m_perfmon.Put(GSPerfMon::Prim, m_count / 2); + break; + case GS_TRIANGLE_CLASS: + m_topology = D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + m_perfmon.Put(GSPerfMon::Prim, m_count / 3); + break; + default: + __assume(0); + } + + __super::Draw(primclass, rt, ds, tex); +} + +void GSRendererDX10::SetupDATE(GSTexture* rt, GSTexture* ds) +{ + if(!m_context->TEST.DATE) return; // || (::GetAsyncKeyState(VK_CONTROL) & 0x8000) + + GSDevice10* dev = (GSDevice10*)m_dev; + + int w = rt->GetWidth(); + int h = rt->GetHeight(); + + if(GSTexture* t = dev->CreateRenderTarget(w, h)) + { + // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows + + dev->BeginScene(); + + dev->ClearStencil(ds, 0); + + // om + + dev->OMSetDepthStencilState(m_date.dss, 1); + dev->OMSetBlendState(m_date.bs, 0); + dev->OMSetRenderTargets(t, ds); + + // ia + + GSVector4 s = GSVector4(rt->m_scale.x / w, rt->m_scale.y / h); + GSVector4 o = GSVector4(-1.0f, 1.0f); + + GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); + GSVector4 dst = src * 2.0f + o.xxxx(); + + GSVertexPT1 vertices[] = + { + {GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(src.x, src.y)}, + {GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(src.z, src.y)}, + {GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)}, + {GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)}, + }; + + dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); + dev->IASetInputLayout(dev->m_convert.il); + dev->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + // vs + + dev->VSSetShader(dev->m_convert.vs, NULL); + + // gs + + dev->GSSetShader(NULL); + + // ps + + dev->PSSetShaderResources(rt, NULL); + dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL); + dev->PSSetSamplerState(dev->m_convert.pt, NULL); + + // rs + + dev->RSSet(w, h); + + // set + + dev->DrawPrimitive(); + + // + + dev->EndScene(); + + dev->Recycle(t); + } +} diff --git a/plugins/GSdx/GSRendererHW10.h b/plugins/GSdx/GSRendererDX10.h similarity index 64% rename from plugins/GSdx/GSRendererHW10.h rename to plugins/GSdx/GSRendererDX10.h index a9985dfc0f..1465fff56e 100644 --- a/plugins/GSdx/GSRendererHW10.h +++ b/plugins/GSdx/GSRendererDX10.h @@ -21,36 +21,27 @@ #pragma once -#include "GSRendererHW.h" +#include "GSRendererDX.h" #include "GSVertexHW.h" #include "GSTextureCache10.h" #include "GSTextureFX10.h" -class GSRendererHW10 : public GSRendererHW +class GSRendererDX10 : public GSRendererDX { - typedef GSDevice10 Device; - typedef GSVertexHW10 Vertex; - typedef GSTextureCache10 TextureCache; - - bool WrapZ(DWORD maxz); - protected: - GSTextureFX10 m_tfx; - - void Draw(int prim, Texture& rt, Texture& ds, GSTextureCache::GSTexture* tex); - struct { CComPtr dss; CComPtr bs; } m_date; - void SetupDATE(Texture& rt, Texture& ds); + void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); + void SetupDATE(GSTexture* rt, GSTexture* ds); public: - GSRendererHW10(BYTE* base, bool mt, void (*irq)(), const GSRendererSettings& rs); + GSRendererDX10(uint8* base, bool mt, void (*irq)()); - bool Create(LPCTSTR title); + bool Create(const string& title); - template void VertexKick(bool skip); + template void VertexKick(bool skip); }; \ No newline at end of file diff --git a/plugins/GSdx/GSRendererDX11.cpp b/plugins/GSdx/GSRendererDX11.cpp new file mode 100644 index 0000000000..063c513a8e --- /dev/null +++ b/plugins/GSdx/GSRendererDX11.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSRendererDX11.h" +#include "GSCrc.h" +#include "resource.h" + +GSRendererDX11::GSRendererDX11(uint8* base, bool mt, void (*irq)()) + : GSRendererDX(base, mt, irq, new GSDevice11(), new GSTextureCache11(this), new GSTextureFX11()) +{ + InitVertexKick(); + + m_pixelcenter = GSVector2(-0.5f, -0.5f); +} + +bool GSRendererDX11::Create(const string& title) +{ + if(!__super::Create(title)) + return false; + + // + + D3D11_DEPTH_STENCIL_DESC dsd; + + memset(&dsd, 0, sizeof(dsd)); + + dsd.DepthEnable = false; + dsd.StencilEnable = true; + dsd.StencilReadMask = 1; + dsd.StencilWriteMask = 1; + dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; + dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + dsd.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsd.BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; + dsd.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + + (*(GSDevice11*)m_dev)->CreateDepthStencilState(&dsd, &m_date.dss); + + D3D11_BLEND_DESC bd; + + memset(&bd, 0, sizeof(bd)); + + (*(GSDevice11*)m_dev)->CreateBlendState(&bd, &m_date.bs); + + // + + return true; +} + +template +void GSRendererDX11::VertexKick(bool skip) +{ + GSVertexHW11& dst = m_vl.AddTail(); + + dst.vi[0] = m_v.vi[0]; + dst.vi[1] = m_v.vi[1]; + + if(tme && fst) + { + GSVector4::storel(&dst.ST, m_v.GetUV()); + } + + int count = 0; + + if(GSVertexHW11* v = DrawingKick(skip, count)) + { + GSVector4i scissor = m_context->scissor.dx10; + + #if _M_SSE >= 0x401 + + GSVector4i pmin, pmax, v0, v1, v2; + + switch(prim) + { + case GS_POINTLIST: + v0 = GSVector4i::load((int)v[0].p.xy).upl16(); + pmin = v0; + pmax = v0; + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + v0 = GSVector4i::load((int)v[0].p.xy); + v1 = GSVector4i::load((int)v[1].p.xy); + pmin = v0.min_u16(v1).upl16(); + pmax = v0.max_u16(v1).upl16(); + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + v0 = GSVector4i::load((int)v[0].p.xy); + v1 = GSVector4i::load((int)v[1].p.xy); + v2 = GSVector4i::load((int)v[2].p.xy); + pmin = v0.min_u16(v1).min_u16(v2).upl16(); + pmax = v0.max_u16(v1).max_u16(v2).upl16(); + break; + } + + GSVector4i test = (pmax < scissor) | (pmin > scissor.zwxy()); + + if(test.mask() & 0xff) + { + return; + } + + #else + + switch(prim) + { + case GS_POINTLIST: + if(v[0].p.x < scissor.x + || v[0].p.x > scissor.z + || v[0].p.y < scissor.y + || v[0].p.y > scissor.w) + { + return; + } + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + if(v[0].p.x < scissor.x && v[1].p.x < scissor.x + || v[0].p.x > scissor.z && v[1].p.x > scissor.z + || v[0].p.y < scissor.y && v[1].p.y < scissor.y + || v[0].p.y > scissor.w && v[1].p.y > scissor.w) + { + return; + } + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + if(v[0].p.x < scissor.x && v[1].p.x < scissor.x && v[2].p.x < scissor.x + || v[0].p.x > scissor.z && v[1].p.x > scissor.z && v[2].p.x > scissor.z + || v[0].p.y < scissor.y && v[1].p.y < scissor.y && v[2].p.y < scissor.y + || v[0].p.y > scissor.w && v[1].p.y > scissor.w && v[2].p.y > scissor.w) + { + return; + } + break; + } + + #endif + + m_count += count; + } +} + +void GSRendererDX11::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) +{ + switch(primclass) + { + case GS_POINT_CLASS: + m_topology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; + m_perfmon.Put(GSPerfMon::Prim, m_count); + break; + case GS_LINE_CLASS: + case GS_SPRITE_CLASS: + m_topology = D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + m_perfmon.Put(GSPerfMon::Prim, m_count / 2); + break; + case GS_TRIANGLE_CLASS: + m_topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + m_perfmon.Put(GSPerfMon::Prim, m_count / 3); + break; + default: + __assume(0); + } + + __super::Draw(primclass, rt, ds, tex); +} + +void GSRendererDX11::SetupDATE(GSTexture* rt, GSTexture* ds) +{ + if(!m_context->TEST.DATE) return; // || (::GetAsyncKeyState(VK_CONTROL) & 0x8000) + + GSDevice11* dev = (GSDevice11*)m_dev; + + int w = rt->GetWidth(); + int h = rt->GetHeight(); + + if(GSTexture* t = dev->CreateRenderTarget(w, h)) + { + // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows + + dev->BeginScene(); + + dev->ClearStencil(ds, 0); + + // om + + dev->OMSetDepthStencilState(m_date.dss, 1); + dev->OMSetBlendState(m_date.bs, 0); + dev->OMSetRenderTargets(t, ds); + + // ia + + GSVector4 s = GSVector4(rt->m_scale.x / w, rt->m_scale.y / h); + GSVector4 o = GSVector4(-1.0f, 1.0f); + + GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); + GSVector4 dst = src * 2.0f + o.xxxx(); + + GSVertexPT1 vertices[] = + { + {GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(src.x, src.y)}, + {GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(src.z, src.y)}, + {GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)}, + {GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)}, + }; + + dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); + dev->IASetInputLayout(dev->m_convert.il); + dev->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + // vs + + dev->VSSetShader(dev->m_convert.vs, NULL); + + // gs + + dev->GSSetShader(NULL); + + // ps + + dev->PSSetShaderResources(rt, NULL); + dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL); + dev->PSSetSamplerState(dev->m_convert.pt, NULL); + + // rs + + dev->RSSet(w, h); + + // set + + dev->DrawPrimitive(); + + // + + dev->EndScene(); + + dev->Recycle(t); + } +} diff --git a/plugins/GSdx/GSRendererDX11.h b/plugins/GSdx/GSRendererDX11.h new file mode 100644 index 0000000000..e30f2e7c07 --- /dev/null +++ b/plugins/GSdx/GSRendererDX11.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSRendererDX.h" +#include "GSVertexHW.h" +#include "GSTextureCache11.h" +#include "GSTextureFX11.h" + +class GSRendererDX11 : public GSRendererDX +{ +protected: + void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); + + struct + { + CComPtr dss; + CComPtr bs; + } m_date; + + void SetupDATE(GSTexture* rt, GSTexture* ds); + +public: + GSRendererDX11(uint8* base, bool mt, void (*irq)()); + + bool Create(const string& title); + + template void VertexKick(bool skip); +}; \ No newline at end of file diff --git a/plugins/GSdx/GSRendererDX9.cpp b/plugins/GSdx/GSRendererDX9.cpp new file mode 100644 index 0000000000..c6e4be5a4f --- /dev/null +++ b/plugins/GSdx/GSRendererDX9.cpp @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSRendererDX9.h" +#include "GSCrc.h" +#include "resource.h" + +GSRendererDX9::GSRendererDX9(uint8* base, bool mt, void (*irq)()) + : GSRendererDX(base, mt, irq, new GSDevice9(), new GSTextureCache9(this), new GSTextureFX9()) +{ + InitVertexKick(); +} + +bool GSRendererDX9::Create(const string& title) +{ + if(!__super::Create(title)) + return false; + + // + + memset(&m_date.dss, 0, sizeof(m_date.dss)); + + m_date.dss.StencilEnable = true; + m_date.dss.StencilReadMask = 1; + m_date.dss.StencilWriteMask = 1; + m_date.dss.StencilFunc = D3DCMP_ALWAYS; + m_date.dss.StencilPassOp = D3DSTENCILOP_REPLACE; + m_date.dss.StencilRef = 1; + + memset(&m_date.bs, 0, sizeof(m_date.bs)); + + // + + memset(&m_fba.dss, 0, sizeof(m_fba.dss)); + + m_fba.dss.StencilEnable = true; + m_fba.dss.StencilReadMask = 2; + m_fba.dss.StencilWriteMask = 2; + m_fba.dss.StencilFunc = D3DCMP_EQUAL; + m_fba.dss.StencilPassOp = D3DSTENCILOP_ZERO; + m_fba.dss.StencilFailOp = D3DSTENCILOP_ZERO; + m_fba.dss.StencilDepthFailOp = D3DSTENCILOP_ZERO; + m_fba.dss.StencilRef = 2; + + memset(&m_fba.bs, 0, sizeof(m_fba.bs)); + + m_fba.bs.RenderTargetWriteMask = D3DCOLORWRITEENABLE_ALPHA; + + // + + return true; +} + +template +void GSRendererDX9::VertexKick(bool skip) +{ + GSVertexHW9 v; + + v.p = GSVector4(((GSVector4i)m_v.XYZ).upl16()); + + if(tme && !fst) + { + v.p = v.p.xyxy(GSVector4((float)m_v.XYZ.Z, m_v.RGBAQ.Q)); + } + else + { + v.p = v.p.xyxy(GSVector4::load((float)m_v.XYZ.Z)); + } + + if(tme) + { + if(fst) + { + v.t = m_v.GetUV(); + } + else + { + v.t = GSVector4::loadl(&m_v.ST); + } + } + + GSVertexHW9& dst = m_vl.AddTail(); + + dst = v; + + dst.c0 = m_v.RGBAQ.u32[0]; + dst.c1 = m_v.FOG.u32[1]; + + int count = 0; + + if(GSVertexHW9* v = DrawingKick(skip, count)) + { + GSVector4 scissor = m_context->scissor.dx9; + + GSVector4 pmin, pmax; + + switch(prim) + { + case GS_POINTLIST: + pmin = v[0].p; + pmax = v[0].p; + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + pmin = v[0].p.minv(v[1].p); + pmax = v[0].p.maxv(v[1].p); + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + pmin = v[0].p.minv(v[1].p).minv(v[2].p); + pmax = v[0].p.maxv(v[1].p).maxv(v[2].p); + break; + } + + GSVector4 test = (pmax < scissor) | (pmin > scissor.zwxy()); + + if(test.mask() & 3) + { + return; + } + + switch(prim) + { + case GS_POINTLIST: + break; + case GS_LINELIST: + case GS_LINESTRIP: + if(PRIM->IIP == 0) {v[0].c0 = v[1].c0;} + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + if(PRIM->IIP == 0) {v[0].c0 = v[1].c0 = v[2].c0;} + break; + case GS_SPRITE: + if(PRIM->IIP == 0) {v[0].c0 = v[1].c0;} + v[0].p.z = v[1].p.z; + v[0].p.w = v[1].p.w; + v[0].c1 = v[1].c1; + v[2] = v[1]; + v[3] = v[1]; + v[1].p.y = v[0].p.y; + v[1].t.y = v[0].t.y; + v[2].p.x = v[0].p.x; + v[2].t.x = v[0].t.x; + v[4] = v[1]; + v[5] = v[2]; + count += 4; + break; + } + + m_count += count; + } +} + +void GSRendererDX9::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) +{ + switch(primclass) + { + case GS_POINT_CLASS: + m_topology = D3DPT_POINTLIST; + m_perfmon.Put(GSPerfMon::Prim, m_count); + break; + case GS_LINE_CLASS: + m_topology = D3DPT_LINELIST; + m_perfmon.Put(GSPerfMon::Prim, m_count / 2); + break; + case GS_TRIANGLE_CLASS: + case GS_SPRITE_CLASS: + m_topology = D3DPT_TRIANGLELIST; + m_perfmon.Put(GSPerfMon::Prim, m_count / 3); + break; + default: + __assume(0); + } + + (*(GSDevice9*)m_dev)->SetRenderState(D3DRS_SHADEMODE, PRIM->IIP ? D3DSHADE_GOURAUD : D3DSHADE_FLAT); // TODO + + __super::Draw(primclass, rt, ds, tex); +} + +void GSRendererDX9::SetupDATE(GSTexture* rt, GSTexture* ds) +{ + if(!m_context->TEST.DATE) return; // || (::GetAsyncKeyState(VK_CONTROL) & 0x8000) + + GSDevice9* dev = (GSDevice9*)m_dev; + + int w = rt->GetWidth(); + int h = rt->GetHeight(); + + if(GSTexture* t = dev->CreateRenderTarget(w, h)) + { + // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows + + dev->BeginScene(); + + dev->ClearStencil(ds, 0); + + // om + + dev->OMSetDepthStencilState(&m_date.dss); + dev->OMSetBlendState(&m_date.bs, 0); + dev->OMSetRenderTargets(t, ds); + + // ia + + GSVector4 s = GSVector4(rt->m_scale.x / w, rt->m_scale.y / h); + GSVector4 o = GSVector4(-1.0f, 1.0f); + + GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); + GSVector4 dst = src * 2.0f + o.xxxx(); + + GSVertexPT1 vertices[] = + { + {GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(src.x, src.y)}, + {GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(src.z, src.y)}, + {GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)}, + {GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)}, + }; + + dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); + dev->IASetInputLayout(dev->m_convert.il); + dev->IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP); + + // vs + + dev->VSSetShader(dev->m_convert.vs, NULL, 0); + + // ps + + dev->PSSetShaderResources(rt, NULL); + dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL, 0); + dev->PSSetSamplerState(&dev->m_convert.pt); + + // rs + + dev->RSSet(w, h); + + // + + dev->DrawPrimitive(); + + // + + dev->EndScene(); + + dev->Recycle(t); + } +} + +void GSRendererDX9::UpdateFBA(GSTexture* rt) +{ + GSDevice9* dev = (GSDevice9*)m_dev; + + dev->BeginScene(); + + // om + + dev->OMSetDepthStencilState(&m_fba.dss); + dev->OMSetBlendState(&m_fba.bs, 0); + + // ia + + GSVector4 s = GSVector4(rt->m_scale.x / rt->GetWidth(), rt->m_scale.y / rt->GetHeight()); + GSVector4 o = GSVector4(-1.0f, 1.0f); + + GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); + GSVector4 dst = src * 2.0f + o.xxxx(); + + GSVertexPT1 vertices[] = + { + {GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(0, 0)}, + {GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(0, 0)}, + {GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(0, 0)}, + {GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(0, 0)}, + }; + + dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); + dev->IASetInputLayout(dev->m_convert.il); + dev->IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP); + + // vs + + dev->VSSetShader(dev->m_convert.vs, NULL, 0); + + // ps + + dev->PSSetShader(dev->m_convert.ps[4], NULL, 0); + + // rs + + dev->RSSet(rt->GetWidth(), rt->GetHeight()); + + // + + dev->DrawPrimitive(); + + // + + dev->EndScene(); +} diff --git a/plugins/GSdx/GSRendererHW9.h b/plugins/GSdx/GSRendererDX9.h similarity index 63% rename from plugins/GSdx/GSRendererHW9.h rename to plugins/GSdx/GSRendererDX9.h index c91a0cb42d..1bebe4e490 100644 --- a/plugins/GSdx/GSRendererHW9.h +++ b/plugins/GSdx/GSRendererDX9.h @@ -21,25 +21,14 @@ #pragma once -#include "GSRendererHW.h" +#include "GSRendererDX.h" #include "GSVertexHW.h" #include "GSTextureCache9.h" #include "GSTextureFX9.h" -class GSRendererHW9 : public GSRendererHW +class GSRendererDX9 : public GSRendererDX { - typedef GSDevice9 Device; - typedef GSVertexHW9 Vertex; - typedef GSTextureCache9 TextureCache; - - bool WrapZ(float maxz); - protected: - GSTextureFX9 m_tfx; - bool m_logz; - - void Draw(int prim, Texture& rt, Texture& ds, GSTextureCache::GSTexture* tex); - struct { Direct3DDepthStencilState9 dss; @@ -48,18 +37,18 @@ protected: struct { - bool enabled; Direct3DDepthStencilState9 dss; Direct3DBlendState9 bs; } m_fba; - void SetupDATE(Texture& rt, Texture& ds); - void UpdateFBA(Texture& rt); + void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); + void SetupDATE(GSTexture* rt, GSTexture* ds); + void UpdateFBA(GSTexture* rt); public: - GSRendererHW9(BYTE* base, bool mt, void (*irq)(), const GSRendererSettings& rs); + GSRendererDX9(uint8* base, bool mt, void (*irq)()); - bool Create(LPCTSTR title); + bool Create(const string& title); - template void VertexKick(bool skip); + template void VertexKick(bool skip); }; diff --git a/plugins/GSdx/GSRendererHW.h b/plugins/GSdx/GSRendererHW.h index e0d1818d25..536755108d 100644 --- a/plugins/GSdx/GSRendererHW.h +++ b/plugins/GSdx/GSRendererHW.h @@ -25,16 +25,17 @@ #include "GSTextureCache.h" #include "GSCrc.h" -template -class GSRendererHW : public GSRendererT +template +class GSRendererHW : public GSRendererT { - TextureCache* m_tc; int m_width; int m_height; int m_skip; bool m_reset; protected: + GSTextureCache* m_tc; + void Reset() { // TODO: GSreset can come from the main thread too => crash @@ -45,183 +46,6 @@ protected: __super::Reset(); } - void MinMaxUV(int w, int h, CRect& r) - { - int wms = m_context->CLAMP.WMS; - int wmt = m_context->CLAMP.WMT; - - int minu = (int)m_context->CLAMP.MINU; - int minv = (int)m_context->CLAMP.MINV; - int maxu = (int)m_context->CLAMP.MAXU; - int maxv = (int)m_context->CLAMP.MAXV; - - GSVector4i vr = GSVector4i(0, 0, w, h); - - GSVector4i wm[3]; - - if(wms + wmt < 6) - { - GSVector4 mm; - - if(m_count < 100) - { - Vertex* v = m_vertices; - - GSVector4 minv(+1e10f); - GSVector4 maxv(-1e10f); - - int i = 0; - - if(PRIM->FST) - { - for(int j = m_count - 3; i < j; i += 4) - { - GSVector4 v0 = GSVector4(v[i + 0].m128[0]); - GSVector4 v1 = GSVector4(v[i + 1].m128[0]); - GSVector4 v2 = GSVector4(v[i + 2].m128[0]); - GSVector4 v3 = GSVector4(v[i + 3].m128[0]); - - minv = minv.minv((v0.minv(v1)).minv(v2.minv(v3))); - maxv = maxv.maxv((v0.maxv(v1)).maxv(v2.maxv(v3))); - } - - for(int j = m_count; i < j; i++) - { - GSVector4 v0 = GSVector4(v[i + 0].m128[0]); - - minv = minv.minv(v0); - maxv = maxv.maxv(v0); - } - - mm = minv.xyxy(maxv) * GSVector4(16 << m_context->TEX0.TW, 16 << m_context->TEX0.TH, 16 << m_context->TEX0.TW, 16 << m_context->TEX0.TH).rcpnr(); - } - else - { - /* - for(int j = m_count - 3; i < j; i += 4) - { - GSVector4 v0 = GSVector4(v[i + 0].m128[0]) / GSVector4(v[i + 0].GetQ()); - GSVector4 v1 = GSVector4(v[i + 1].m128[0]) / GSVector4(v[i + 1].GetQ()); - GSVector4 v2 = GSVector4(v[i + 2].m128[0]) / GSVector4(v[i + 2].GetQ()); - GSVector4 v3 = GSVector4(v[i + 3].m128[0]) / GSVector4(v[i + 3].GetQ()); - - minv = minv.minv((v0.minv(v1)).minv(v2.minv(v3))); - maxv = maxv.maxv((v0.maxv(v1)).maxv(v2.maxv(v3))); - } - - for(int j = m_count; i < j; i++) - { - GSVector4 v0 = GSVector4(v[i + 0].m128[0]) / GSVector4(v[i + 0].GetQ());; - - minv = minv.minv(v0); - maxv = maxv.maxv(v0); - } - - mm = minv.xyxy(maxv); - */ - - // just can't beat the compiler generated scalar sse code with packed div or rcp - - mm.x = mm.y = +1e10; - mm.z = mm.w = -1e10; - - for(int j = m_count; i < j; i++) - { - float w = 1.0f / v[i].GetQ(); - - float x = v[i].t.x * w; - - if(x < mm.x) mm.x = x; - if(x > mm.z) mm.z = x; - - float y = v[i].t.y * w; - - if(y < mm.y) mm.y = y; - if(y > mm.w) mm.w = y; - } - } - } - else - { - mm = GSVector4(0.0f, 0.0f, 1.0f, 1.0f); - } - - GSVector4 v0 = GSVector4(vr); - GSVector4 v1 = v0.zwzw(); - - GSVector4 mmf = mm.floor(); - GSVector4 mask = mmf.xyxy() == mmf.zwzw(); - - wm[0] = GSVector4i(v0.blend8((mm - mmf) * v1, mask)); - - mm *= v1; - - wm[1] = GSVector4i(mm.sat(GSVector4::zero(), v1)); - wm[2] = GSVector4i(mm.sat(GSVector4(minu, minv, maxu, maxv))); - } - - GSVector4i v; - - switch(wms) - { - case CLAMP_REPEAT: - v = wm[0]; - if(v.x == 0 && v.z != w) v.z = w; // FIXME - vr.x = v.x; - vr.z = v.z; - break; - case CLAMP_CLAMP: - case CLAMP_REGION_CLAMP: - v = wm[wms]; - if(v.x > v.z) v.x = v.z; - vr.x = v.x; - vr.z = v.z; - break; - case CLAMP_REGION_REPEAT: - if(m_psrr) {vr.x = maxu; vr.z = vr.x + (minu + 1);} - //else {vr.x = 0; vr.z = w;} - break; - default: - __assume(0); - } - - switch(wmt) - { - case CLAMP_REPEAT: - v = wm[0]; - if(v.y == 0 && v.w != h) v.w = h; // FIXME - vr.y = v.y; - vr.w = v.w; - break; - case CLAMP_CLAMP: - case CLAMP_REGION_CLAMP: - v = wm[wmt]; - if(v.y > v.w) v.y = v.w; - vr.y = v.y; - vr.w = v.w; - break; - case CLAMP_REGION_REPEAT: - if(m_psrr) {vr.y = maxv; vr.w = vr.y + (minv + 1);} - //else {r.y = 0; r.w = w;} - break; - default: - __assume(0); - } - - r = vr; - - r.InflateRect(1, 1); // one more pixel because of bilinear filtering - - CSize bs = GSLocalMemory::m_psm[m_context->TEX0.PSM].bs; - CSize bsm(bs.cx - 1, bs.cy - 1); - - r.left = max(r.left & ~bsm.cx, 0); - r.right = min((r.right + bsm.cx) & ~bsm.cx, w); - - r.top = max(r.top & ~bsm.cy, 0); - r.bottom = min((r.bottom + bsm.cy) & ~bsm.cy, h); - } - void VSync(int field) { __super::VSync(field); @@ -243,7 +67,7 @@ protected: m_tc->RemoveAll(); } - bool GetOutput(int i, Texture& t) + GSTexture* GetOutput(int i) { const GSRegDISPFB& DISPFB = m_regs->DISP[i].DISPFB; @@ -253,45 +77,47 @@ protected: TEX0.TBW = DISPFB.FBW; TEX0.PSM = DISPFB.PSM; - TRACE(_T("[%d] GetOutput %d %05x (%d)\n"), (int)m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM); + // TRACE(_T("[%d] GetOutput %d %05x (%d)\n"), (int)m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM); - if(GSTextureCache::GSRenderTarget* rt = m_tc->GetRenderTarget(TEX0, m_width, m_height, true)) + GSTexture* t = NULL; + + if(GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true, true)) { t = rt->m_texture; if(s_dump) { - CString str; - str.Format(_T("c:\\temp2\\_%05d_f%I64d_fr%d_%05x_%d.bmp"), s_n++, m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM); - if(s_save) rt->m_texture.Save(str); - } + if(s_save) + { + t->Save(format("c:\\temp2\\_%05d_f%I64d_fr%d_%05x_%d.bmp", s_n, m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM)); + } - return true; + s_n++; + } } - return false; + return t; } - void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, CRect r) + void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) { - TRACE(_T("[%d] InvalidateVideoMem %d,%d - %d,%d %05x (%d)\n"), (int)m_perfmon.GetFrame(), r.left, r.top, r.right, r.bottom, (int)BITBLTBUF.DBP, (int)BITBLTBUF.DPSM); + // printf("[%d] InvalidateVideoMem %d,%d - %d,%d %05x (%d)\n", (int)m_perfmon.GetFrame(), r.left, r.top, r.right, r.bottom, (int)BITBLTBUF.DBP, (int)BITBLTBUF.DPSM); m_tc->InvalidateVideoMem(BITBLTBUF, r); } - void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, CRect r) + void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) { - TRACE(_T("[%d] InvalidateLocalMem %d,%d - %d,%d %05x (%d)\n"), (int)m_perfmon.GetFrame(), r.left, r.top, r.right, r.bottom, (int)BITBLTBUF.SBP, (int)BITBLTBUF.SPSM); + // printf("[%d] InvalidateLocalMem %d,%d - %d,%d %05x (%d)\n", (int)m_perfmon.GetFrame(), r.left, r.top, r.right, r.bottom, (int)BITBLTBUF.SBP, (int)BITBLTBUF.SPSM); m_tc->InvalidateLocalMem(BITBLTBUF, r); } void Draw() { - if(IsBadFrame(m_skip)) - { - return; - } + if(IsBadFrame(m_skip)) return; + + m_vt.Update(m_vertices, m_count, GSUtil::GetPrimClass(PRIM->PRIM), PRIM, m_context); GSDrawingEnvironment& env = m_env; GSDrawingContext* context = m_context; @@ -302,84 +128,181 @@ protected: TEX0.TBW = context->FRAME.FBW; TEX0.PSM = context->FRAME.PSM; - GSTextureCache::GSRenderTarget* rt = m_tc->GetRenderTarget(TEX0, m_width, m_height); + GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true); TEX0.TBP0 = context->ZBUF.Block(); TEX0.TBW = context->FRAME.FBW; TEX0.PSM = context->ZBUF.PSM; - GSTextureCache::GSDepthStencil* ds = m_tc->GetDepthStencil(TEX0, m_width, m_height); + GSTextureCache::Target* ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, m_context->DepthWrite()); - GSTextureCache::GSTexture* tex = NULL; + GSTextureCache::Source* tex = NULL; if(PRIM->TME) { - tex = m_tc->GetTexture(); + m_mem.m_clut.Read32(context->TEX0, env.TEXA); + + GSVector4i r; + + GetTextureMinMax(r, IsLinear()); + + tex = m_tc->LookupSource(context->TEX0, env.TEXA, r); if(!tex) return; } if(s_dump) { - CString str; - str.Format(_T("c:\\temp2\\_%05d_f%I64d_tex_%05x_%d_%d%d_%02x_%02x_%02x_%02x.dds"), - s_n++, m_perfmon.GetFrame(), (int)context->TEX0.TBP0, (int)context->TEX0.PSM, - (int)context->CLAMP.WMS, (int)context->CLAMP.WMT, - (int)context->CLAMP.MINU, (int)context->CLAMP.MAXU, - (int)context->CLAMP.MINV, (int)context->CLAMP.MAXV); - if(PRIM->TME) if(s_save) tex->m_texture.Save(str, true); - str.Format(_T("c:\\temp2\\_%05d_f%I64d_tpx_%05x_%d.dds"), s_n-1, m_perfmon.GetFrame(), context->TEX0.CBP, context->TEX0.CPSM); - if(PRIM->TME && tex->m_palette) if(s_save) tex->m_palette.Save(str, true); - str.Format(_T("c:\\temp2\\_%05d_f%I64d_rt0_%05x_%d.bmp"), s_n++, m_perfmon.GetFrame(), context->FRAME.Block(), context->FRAME.PSM); - if(s_save) rt->m_texture.Save(str); - str.Format(_T("c:\\temp2\\_%05d_f%I64d_rz0_%05x_%d.bmp"), s_n-1, m_perfmon.GetFrame(), context->ZBUF.Block(), context->ZBUF.PSM); - if(s_savez) ds->m_texture.Save(str); + uint64 frame = m_perfmon.GetFrame(); + + string s; + + if(s_save && tex) + { + s = format("c:\\temp2\\_%05d_f%I64d_tex_%05x_%d_%d%d_%02x_%02x_%02x_%02x.dds", + s_n, frame, (int)context->TEX0.TBP0, (int)context->TEX0.PSM, + (int)context->CLAMP.WMS, (int)context->CLAMP.WMT, + (int)context->CLAMP.MINU, (int)context->CLAMP.MAXU, + (int)context->CLAMP.MINV, (int)context->CLAMP.MAXV); + + tex->m_texture->Save(s, true); + + if(tex->m_palette) + { + s = format("c:\\temp2\\_%05d_f%I64d_tpx_%05x_%d.dds", s_n, frame, context->TEX0.CBP, context->TEX0.CPSM); + + tex->m_palette->Save(s, true); + } + } + + s_n++; + + if(s_save) + { + s = format("c:\\temp2\\_%05d_f%I64d_rt0_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM); + + rt->m_texture->Save(s); + } + + if(s_savez) + { + s = format("c:\\temp2\\_%05d_f%I64d_rz0_%05x_%d.bmp", s_n, frame, context->ZBUF.Block(), context->ZBUF.PSM); + + ds->m_texture->Save(s); + } + + s_n++; } int prim = PRIM->PRIM; - if(!OverrideInput(prim, rt->m_texture, ds->m_texture, tex ? &tex->m_texture : NULL)) + if(!OverrideInput(prim, rt->m_texture, ds->m_texture, tex)) { return; } - Draw(prim, rt->m_texture, ds->m_texture, tex); + // skip alpha test if possible + + GIFRegTEST TEST = context->TEST; + GIFRegFRAME FRAME = context->FRAME; + GIFRegZBUF ZBUF = context->ZBUF; + + uint32 fm = context->FRAME.FBMSK; + uint32 zm = context->ZBUF.ZMSK || context->TEST.ZTE == 0 ? 0xffffffff : 0; + + if(context->TEST.ATE && context->TEST.ATST != ATST_ALWAYS) + { + if(TryAlphaTest(fm, zm)) + { + context->TEST.ATE = 0; + } + } + + context->FRAME.FBMSK = fm; + context->ZBUF.ZMSK = zm != 0; + + // + + Draw(GSUtil::GetPrimClass(prim), rt->m_texture, ds->m_texture, tex); + + // + + context->TEST = TEST; + context->FRAME = FRAME; + context->ZBUF = ZBUF; + + // + + GSVector4i r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in)); + + GIFRegBITBLTBUF BITBLTBUF; + + BITBLTBUF.DBW = context->FRAME.FBW; + + if(fm != 0xffffffff) + { + BITBLTBUF.DBP = context->FRAME.Block(); + BITBLTBUF.DPSM = context->FRAME.PSM; + + m_tc->InvalidateVideoMem(BITBLTBUF, r, false); + } + + if(zm != 0xffffffff) + { + BITBLTBUF.DBP = context->ZBUF.Block(); + BITBLTBUF.DPSM = context->ZBUF.PSM; + + m_tc->InvalidateVideoMem(BITBLTBUF, r, false); + } + + // OverrideOutput(); if(s_dump) { - CString str; - str.Format(_T("c:\\temp2\\_%05d_f%I64d_rt1_%05x_%d.bmp"), s_n++, m_perfmon.GetFrame(), context->FRAME.Block(), context->FRAME.PSM); - if(s_save) rt->m_texture.Save(str); - str.Format(_T("c:\\temp2\\_%05d_f%I64d_rz1_%05x_%d.bmp"), s_n-1, m_perfmon.GetFrame(), context->ZBUF.Block(), context->ZBUF.PSM); - if(s_savez) ds->m_texture.Save(str); - // if(s_savez) m_dev.SaveToFileD32S8X24(ds->m_texture, str); // TODO - } + uint64 frame = m_perfmon.GetFrame(); - m_tc->InvalidateTextures(context->FRAME, context->ZBUF); + string s; + + if(s_save) + { + s = format("c:\\temp2\\_%05d_f%I64d_rt1_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM); + + rt->m_texture->Save(s); + } + + if(s_savez) + { + s = format("c:\\temp2\\_%05d_f%I64d_rz1_%05x_%d.bmp", s_n, frame, context->ZBUF.Block(), context->ZBUF.PSM); + + ds->m_texture->Save(s); + } + + s_n++; + } } - virtual void Draw(int prim, Texture& rt, Texture& ds, typename GSTextureCache::GSTexture* tex) = 0; + virtual void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) = 0; - virtual bool OverrideInput(int& prim, Texture& rt, Texture& ds, Texture* t) + virtual bool OverrideInput(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) { #pragma region ffxii pal video conversion if(m_game.title == CRC::FFXII && m_game.region == CRC::EU) { - static DWORD* video = NULL; + static uint32* video = NULL; static bool ok = false; - if(prim == GS_POINTLIST && m_count >= 448*448 && m_count <= 448*512) + if(prim == GS_POINTLIST && m_count >= 448 * 448 && m_count <= 448 * 512) { // incoming pixels are stored in columns, one column is 16x512, total res 448x512 or 448x454 - if(!video) video = new DWORD[512*512]; + if(!video) video = new uint32[512 * 512]; for(int x = 0, i = 0, rows = m_count / 448; x < 448; x += 16) { - DWORD* dst = &video[x]; + uint32* dst = &video[x]; for(int y = 0; y < rows; y++, dst += 512) { @@ -394,16 +317,18 @@ protected: return false; } - else if(prim == GS_LINELIST && m_count == 512*2 && ok) + else if(prim == GS_LINELIST && m_count == 512 * 2 && ok) { // normally, this step would copy the video onto screen with 512 texture mapped horizontal lines, // but we use the stored video data to create a new texture, and replace the lines with two triangles ok = false; - m_dev.CreateTexture(*t, 512, 512); + m_dev->Recycle(t->m_texture); - t->Update(CRect(0, 0, 448, 512), video, 512*4); + t->m_texture = m_dev->CreateTexture(512, 512); + + t->m_texture->Update(GSVector4i(0, 0, 448, 512), video, 512 * 4); m_vertices[0] = m_vertices[0]; m_vertices[1] = m_vertices[1]; @@ -425,13 +350,13 @@ protected: if(m_game.title == CRC::FFX) { - DWORD FBP = m_context->FRAME.Block(); - DWORD ZBP = m_context->ZBUF.Block(); - DWORD TBP = m_context->TEX0.TBP0; + uint32 FBP = m_context->FRAME.Block(); + uint32 ZBP = m_context->ZBUF.Block(); + uint32 TBP = m_context->TEX0.TBP0; if((FBP == 0x00d00 || FBP == 0x00000) && ZBP == 0x02100 && PRIM->TME && TBP == 0x01a00 && m_context->TEX0.PSM == PSM_PSMCT16S) { - m_dev.ClearDepth(ds, 0); + m_dev->ClearDepth(ds, 0); } return true; @@ -456,14 +381,14 @@ protected: #pragma endregion - #pragma region tomoyo after, clannad (palette uploaded in a point list, pure genius...) + #pragma region palette uploaded in a point list, pure genius... - if(m_game.title == CRC::TomoyoAfter || m_game.title == CRC::Clannad) + if(m_game.flags & CRC::PointListPalette) { if(prim == GS_POINTLIST && !PRIM->TME) { - DWORD bp = m_context->FRAME.Block(); - DWORD bw = m_context->FRAME.FBW; + uint32 bp = m_context->FRAME.Block(); + uint32 bw = m_context->FRAME.FBW; if(bp >= 0x03f40 && (bp & 0x1f) == 0) { @@ -509,9 +434,9 @@ protected: if(m_game.title == CRC::GodOfWar2) { - DWORD FBP = m_context->FRAME.Block(); - DWORD FBW = m_context->FRAME.FBW; - DWORD FPSM = m_context->FRAME.PSM; + uint32 FBP = m_context->FRAME.Block(); + uint32 FBW = m_context->FRAME.FBW; + uint32 FPSM = m_context->FRAME.PSM; if((FBP == 0x00f00 || FBP == 0x00100) && FPSM == PSM_PSMZ24) // ntsc 0xf00, pal 0x100 { @@ -521,9 +446,9 @@ protected: TEX0.TBW = FBW; TEX0.PSM = FPSM; - if(GSTextureCache::GSDepthStencil* ds = m_tc->GetDepthStencil(TEX0, m_width, m_height)) + if(GSTextureCache::Target* ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, true)) { - m_dev.ClearDepth(ds->m_texture, 0); + m_dev->ClearDepth(ds->m_texture, 0); } return false; @@ -534,6 +459,30 @@ protected: #pragma endregion + #pragma region Simpsons Game z buffer clear + + if(m_game.title == CRC::SimpsonsGame) + { + uint32 FBP = m_context->FRAME.Block(); + uint32 FBW = m_context->FRAME.FBW; + uint32 FPSM = m_context->FRAME.PSM; + + if(FBP == 0x01800 && FPSM == PSM_PSMZ24) + { + // instead of just simply drawing a full height 512x512 sprite to clear the z buffer, + // it uses a 512x256 sprite only, yet it is still able to fill the whole surface with zeros, + // how? by using a render target that overlaps with the lower half of the z buffer... + + m_dev->ClearDepth(ds, 0); + + return false; + } + + return true; + } + + #pragma endregion + return true; } @@ -543,8 +492,8 @@ protected: if(m_game.title == CRC::DBZBT2) { - DWORD FBP = m_context->FRAME.Block(); - DWORD TBP0 = m_context->TEX0.TBP0; + uint32 FBP = m_context->FRAME.Block(); + uint32 TBP0 = m_context->TEX0.TBP0; if(PRIM->TME && (FBP == 0x03c00 && TBP0 == 0x03c80 || FBP == 0x03ac0 && TBP0 == 0x03b40)) { @@ -554,7 +503,7 @@ protected: BITBLTBUF.SBW = 1; BITBLTBUF.SPSM = PSM_PSMCT32; - InvalidateLocalMem(BITBLTBUF, CRect(0, 0, 64, 64)); + InvalidateLocalMem(BITBLTBUF, GSVector4i(0, 0, 64, 64)); } } @@ -564,7 +513,7 @@ protected: if(m_game.title == CRC::MajokkoALaMode2) { - DWORD FBP = m_context->FRAME.Block(); + uint32 FBP = m_context->FRAME.Block(); if(!PRIM->TME && FBP == 0x03f40) { @@ -574,7 +523,7 @@ protected: BITBLTBUF.SBW = 1; BITBLTBUF.SPSM = PSM_PSMCT32; - InvalidateLocalMem(BITBLTBUF, CRect(0, 0, 16, 16)); + InvalidateLocalMem(BITBLTBUF, GSVector4i(0, 0, 16, 16)); } } @@ -587,7 +536,7 @@ protected: if(m_game.title == CRC::DBZBT2) { - DWORD FBP = m_context->FRAME.Block(); + uint32 FBP = m_context->FRAME.Block(); if(FBP == 0x03c00 || FBP == 0x03ac0) { @@ -601,7 +550,7 @@ protected: if(m_game.title == CRC::MajokkoALaMode2) { - DWORD FBP = m_context->FRAME.Block(); + uint32 FBP = m_context->FRAME.Block(); if(FBP == 0x03f40) { @@ -615,7 +564,7 @@ protected: if(m_game.title == CRC::TalesOfAbyss) { - DWORD FBP = m_context->FRAME.Block(); + uint32 FBP = m_context->FRAME.Block(); if(FBP == 0x036e0 || FBP == 0x03560 || FBP == 0x038e0) { @@ -629,8 +578,9 @@ protected: } public: - GSRendererHW(BYTE* base, bool mt, void (*irq)(), const GSRendererSettings& rs, bool psrr) - : GSRendererT(base, mt, irq, rs, psrr) + GSRendererHW(uint8* base, bool mt, void (*irq)(), GSDevice* dev, GSTextureCache* tc) + : GSRendererT(base, mt, irq, dev) + , m_tc(tc) , m_width(1024) , m_height(1024) , m_skip(0) @@ -638,11 +588,9 @@ public: { if(!m_nativeres) { - m_width = AfxGetApp()->GetProfileInt(_T("Settings"), _T("resx"), m_width); - m_height = AfxGetApp()->GetProfileInt(_T("Settings"), _T("resy"), m_height); + m_width = theApp.GetConfig("resx", m_width); + m_height = theApp.GetConfig("resy", m_height); } - - m_tc = new TextureCache(this); } virtual ~GSRendererHW() @@ -650,7 +598,7 @@ public: delete m_tc; } - void SetGameCRC(DWORD crc, int options) + void SetGameCRC(uint32 crc, int options) { __super::SetGameCRC(crc, options); diff --git a/plugins/GSdx/GSRendererHW10.cpp b/plugins/GSdx/GSRendererHW10.cpp deleted file mode 100644 index 0265f582d8..0000000000 --- a/plugins/GSdx/GSRendererHW10.cpp +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright (C) 2007-2009 Gabest - * http://www.gabest.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "stdafx.h" -#include "GSRendererHW10.h" -#include "GSCrc.h" -#include "resource.h" - -GSRendererHW10::GSRendererHW10(BYTE* base, bool mt, void (*irq)(), const GSRendererSettings& rs) - : GSRendererHW(base, mt, irq, rs, true) -{ - InitVertexKick(); -} - -bool GSRendererHW10::Create(LPCTSTR title) -{ - if(!__super::Create(title)) - return false; - - if(!m_tfx.Create(&m_dev)) - return false; - - // - - D3D10_DEPTH_STENCIL_DESC dsd; - - memset(&dsd, 0, sizeof(dsd)); - - dsd.DepthEnable = false; - dsd.StencilEnable = true; - dsd.StencilReadMask = 1; - dsd.StencilWriteMask = 1; - dsd.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS; - dsd.FrontFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE; - dsd.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; - dsd.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP; - dsd.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS; - dsd.BackFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE; - dsd.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; - dsd.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP; - - m_dev->CreateDepthStencilState(&dsd, &m_date.dss); - - D3D10_BLEND_DESC bd; - - memset(&bd, 0, sizeof(bd)); - - m_dev->CreateBlendState(&bd, &m_date.bs); - - // - - return true; -} - -template -void GSRendererHW10::VertexKick(bool skip) -{ - Vertex& dst = m_vl.AddTail(); - - dst.m128i[0] = m_v.m128i[0]; - dst.m128i[1] = m_v.m128i[1]; - - if(tme && fst) - { - GSVector4::storel(&dst.ST, m_v.GetUV()); - } - - DWORD count = 0; - - if(Vertex* v = DrawingKick(skip, count)) - { - GSVector4i scissor = m_context->scissor.dx10; - - #if _M_SSE >= 0x401 - - GSVector4i pmin, pmax, v0, v1, v2; - - switch(prim) - { - case GS_POINTLIST: - v0 = GSVector4i::load((int)v[0].p.xy).upl16(); - pmin = v0; - pmax = v0; - break; - case GS_LINELIST: - case GS_LINESTRIP: - case GS_SPRITE: - v0 = GSVector4i::load((int)v[0].p.xy); - v1 = GSVector4i::load((int)v[1].p.xy); - pmin = v0.min_u16(v1).upl16(); - pmax = v0.max_u16(v1).upl16(); - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - v0 = GSVector4i::load((int)v[0].p.xy); - v1 = GSVector4i::load((int)v[1].p.xy); - v2 = GSVector4i::load((int)v[2].p.xy); - pmin = v0.min_u16(v1).min_u16(v2).upl16(); - pmax = v0.max_u16(v1).max_u16(v2).upl16(); - break; - } - - GSVector4i test = (pmax < scissor) | (pmin > scissor.zwxy()); - - if(test.mask() & 0xff) - { - return; - } - - #else - - switch(prim) - { - case GS_POINTLIST: - if(v[0].p.x < scissor.x - || v[0].p.x > scissor.z - || v[0].p.y < scissor.y - || v[0].p.y > scissor.w) - { - return; - } - break; - case GS_LINELIST: - case GS_LINESTRIP: - case GS_SPRITE: - if(v[0].p.x < scissor.x && v[1].p.x < scissor.x - || v[0].p.x > scissor.z && v[1].p.x > scissor.z - || v[0].p.y < scissor.y && v[1].p.y < scissor.y - || v[0].p.y > scissor.w && v[1].p.y > scissor.w) - { - return; - } - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - if(v[0].p.x < scissor.x && v[1].p.x < scissor.x && v[2].p.x < scissor.x - || v[0].p.x > scissor.z && v[1].p.x > scissor.z && v[2].p.x > scissor.z - || v[0].p.y < scissor.y && v[1].p.y < scissor.y && v[2].p.y < scissor.y - || v[0].p.y > scissor.w && v[1].p.y > scissor.w && v[2].p.y > scissor.w) - { - return; - } - break; - } - - #endif - - m_count += count; - } -} - -void GSRendererHW10::Draw(int prim, Texture& rt, Texture& ds, GSTextureCache::GSTexture* tex) -{ - GSDrawingEnvironment& env = m_env; - GSDrawingContext* context = m_context; -/* - if(s_dump) - { - TRACE(_T("\n")); - - TRACE(_T("PRIM = %d, ZMSK = %d, ZTE = %d, ZTST = %d, ATE = %d, ATST = %d, AFAIL = %d, AREF = %02x\n"), - PRIM->PRIM, context->ZBUF.ZMSK, - context->TEST.ZTE, context->TEST.ZTST, - context->TEST.ATE, context->TEST.ATST, context->TEST.AFAIL, context->TEST.AREF); - - for(int i = 0; i < m_count; i++) - { - TRACE(_T("[%d] %3.0f %3.0f %3.0f %3.0f\n"), i, (float)m_vertices[i].p.x / 16, (float)m_vertices[i].p.y / 16, (float)m_vertices[i].p.z, (float)m_vertices[i].a); - } - } -*/ - D3D10_PRIMITIVE_TOPOLOGY topology; - int prims = 0; - - switch(prim) - { - case GS_POINTLIST: - topology = D3D10_PRIMITIVE_TOPOLOGY_POINTLIST; - prims = m_count; - break; - case GS_LINELIST: - case GS_LINESTRIP: - case GS_SPRITE: - topology = D3D10_PRIMITIVE_TOPOLOGY_LINELIST; - prims = m_count / 2; - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - topology = D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - prims = m_count / 3; - break; - default: - __assume(0); - } - - m_perfmon.Put(GSPerfMon::Prim, prims); - m_perfmon.Put(GSPerfMon::Draw, 1); - - // date - - SetupDATE(rt, ds); - - // - - m_dev.BeginScene(); - - // om - - GSTextureFX10::OMDepthStencilSelector om_dssel; - - om_dssel.zte = context->TEST.ZTE; - om_dssel.ztst = context->TEST.ZTST; - om_dssel.zwe = !context->ZBUF.ZMSK; - om_dssel.date = context->FRAME.PSM != PSM_PSMCT24 ? context->TEST.DATE : 0; - - GSTextureFX10::OMBlendSelector om_bsel; - - om_bsel.abe = PRIM->ABE || (prim == 1 || prim == 2) && PRIM->AA1; - om_bsel.a = context->ALPHA.A; - om_bsel.b = context->ALPHA.B; - om_bsel.c = context->ALPHA.C; - om_bsel.d = context->ALPHA.D; - om_bsel.wr = (context->FRAME.FBMSK & 0x000000ff) != 0x000000ff; - om_bsel.wg = (context->FRAME.FBMSK & 0x0000ff00) != 0x0000ff00; - om_bsel.wb = (context->FRAME.FBMSK & 0x00ff0000) != 0x00ff0000; - om_bsel.wa = (context->FRAME.FBMSK & 0xff000000) != 0xff000000; - - float bf = (float)(int)context->ALPHA.FIX / 0x80; - - // vs - - GSTextureFX10::VSSelector vs_sel; - - vs_sel.bpp = 0; - vs_sel.bppz = 0; - vs_sel.tme = PRIM->TME; - vs_sel.fst = PRIM->FST; - vs_sel.prim = prim; - - if(tex) - { - vs_sel.bpp = tex->m_bpp2; - } - - if(om_dssel.zte && om_dssel.ztst > 0 && om_dssel.zwe) - { - if(context->ZBUF.PSM == PSM_PSMZ24) - { - if(WrapZ(0xffffff)) - { - vs_sel.bppz = 1; - om_dssel.ztst = 1; - } - } - else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S) - { - if(WrapZ(0xffff)) - { - vs_sel.bppz = 2; - om_dssel.ztst = 1; - } - } - } - - GSTextureFX10::VSConstantBuffer vs_cb; - - float sx = 2.0f * rt.m_scale.x / (rt.GetWidth() * 16); - float sy = 2.0f * rt.m_scale.y / (rt.GetHeight() * 16); - float ox = (float)(int)context->XYOFFSET.OFX; - float oy = (float)(int)context->XYOFFSET.OFY; - - vs_cb.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f); - vs_cb.VertexOffset = GSVector4(ox * sx + 1, -(oy * sy + 1), 0.0f, -1.0f); - vs_cb.TextureScale = GSVector2(1.0f, 1.0f); - - if(PRIM->TME && PRIM->FST) - { - vs_cb.TextureScale.x = 1.0f / (16 << context->TEX0.TW); - vs_cb.TextureScale.y = 1.0f / (16 << context->TEX0.TH); - } - - // gs - - GSTextureFX10::GSSelector gs_sel; - - gs_sel.iip = PRIM->IIP; - gs_sel.prim = GSUtil::GetPrimClass(prim); - - // ps - - GSTextureFX10::PSSelector ps_sel; - - ps_sel.fst = PRIM->FST; - ps_sel.wms = context->CLAMP.WMS; - ps_sel.wmt = context->CLAMP.WMT; - ps_sel.bpp = 0; - ps_sel.aem = env.TEXA.AEM; - ps_sel.tfx = context->TEX0.TFX; - ps_sel.tcc = context->TEX0.TCC; - ps_sel.ate = context->TEST.ATE; - ps_sel.atst = context->TEST.ATST; - ps_sel.fog = PRIM->FGE; - ps_sel.clr1 = om_bsel.abe && om_bsel.a == 1 && om_bsel.b == 2 && om_bsel.d == 1; - ps_sel.fba = context->FBA.FBA; - ps_sel.aout = context->FRAME.PSM == PSM_PSMCT16 || context->FRAME.PSM == PSM_PSMCT16S || (context->FRAME.FBMSK & 0xff000000) == 0x7f000000 ? 1 : 0; - - GSTextureFX10::PSSamplerSelector ps_ssel; - - ps_ssel.min = m_filter == 2 ? (context->TEX1.MMIN & 1) : m_filter; - ps_ssel.mag = m_filter == 2 ? (context->TEX1.MMAG & 1) : m_filter; - ps_ssel.tau = 0; - ps_ssel.tav = 0; - - GSTextureFX10::PSConstantBuffer ps_cb; - - ps_cb.FogColor = GSVector4(env.FOGCOL.FCR, env.FOGCOL.FCG, env.FOGCOL.FCB, 0) / 255.0f; - ps_cb.TA0 = (float)(int)env.TEXA.TA0 / 255; - ps_cb.TA1 = (float)(int)env.TEXA.TA1 / 255; - ps_cb.AREF = (float)(int)context->TEST.AREF / 255; - - if(context->TEST.ATST == 2 || context->TEST.ATST == 5) - { - ps_cb.AREF -= 0.9f/256; - } - else if(context->TEST.ATST == 3 || context->TEST.ATST == 6) - { - ps_cb.AREF += 0.9f/256; - } - - if(tex) - { - ps_sel.bpp = tex->m_bpp2; - - switch(context->CLAMP.WMS) - { - case 0: - ps_ssel.tau = 1; - break; - case 1: - ps_ssel.tau = 0; - break; - case 2: - ps_cb.MINU = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW); - ps_cb.MAXU = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW); - ps_ssel.tau = 0; - break; - case 3: - ps_cb.UMSK = context->CLAMP.MINU; - ps_cb.UFIX = context->CLAMP.MAXU; - ps_ssel.tau = 1; - break; - default: - __assume(0); - } - - switch(context->CLAMP.WMT) - { - case 0: - ps_ssel.tav = 1; - break; - case 1: - ps_ssel.tav = 0; - break; - case 2: - ps_cb.MINV = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH); - ps_cb.MAXV = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH); - ps_ssel.tav = 0; - break; - case 3: - ps_cb.VMSK = context->CLAMP.MINV; - ps_cb.VFIX = context->CLAMP.MAXV; - ps_ssel.tav = 1; - break; - default: - __assume(0); - } - - float w = (float)tex->m_texture.GetWidth(); - float h = (float)tex->m_texture.GetHeight(); - - ps_cb.WH = GSVector2(w, h); - ps_cb.rWrH = GSVector2(1.0f / w, 1.0f / h); - } - else - { - ps_sel.tfx = 4; - } - - // rs - - int w = rt.GetWidth(); - int h = rt.GetHeight(); - - CRect scissor = (CRect)GSVector4i(GSVector4(rt.m_scale).xyxy() * context->scissor.in) & CRect(0, 0, w, h); - - // - - m_tfx.SetupOM(om_dssel, om_bsel, bf, rt, ds); - m_tfx.SetupIA(m_vertices, m_count, topology); - m_tfx.SetupVS(vs_sel, &vs_cb); - m_tfx.SetupGS(gs_sel); - m_tfx.SetupPS(ps_sel, &ps_cb, ps_ssel, - tex ? (ID3D10ShaderResourceView*)tex->m_texture : NULL, - tex ? (ID3D10ShaderResourceView*)tex->m_palette : NULL); - m_tfx.SetupRS(w, h, scissor); - - // draw - - if(context->TEST.DoFirstPass()) - { - m_tfx.Draw(); - } - - if(context->TEST.DoSecondPass()) - { - ASSERT(!env.PABE.PABE); - - static const DWORD iatst[] = {1, 0, 5, 6, 7, 2, 3, 4}; - - ps_sel.atst = iatst[ps_sel.atst]; - - m_tfx.UpdatePS(ps_sel, &ps_cb, ps_ssel); - - bool z = om_dssel.zwe; - bool r = om_bsel.wr; - bool g = om_bsel.wg; - bool b = om_bsel.wb; - bool a = om_bsel.wa; - - switch(context->TEST.AFAIL) - { - case 0: z = r = g = b = a = false; break; // none - case 1: z = false; break; // rgba - case 2: r = g = b = a = false; break; // z - case 3: z = a = false; break; // rgb - default: __assume(0); - } - - if(z || r || g || b || a) - { - om_dssel.zwe = z; - om_bsel.wr = r; - om_bsel.wg = g; - om_bsel.wb = b; - om_bsel.wa = a; - - m_tfx.UpdateOM(om_dssel, om_bsel, bf); - - m_tfx.Draw(); - } - } - - m_dev.EndScene(); -} - -bool GSRendererHW10::WrapZ(DWORD maxz) -{ - // should only run once if z values are in the z buffer range - - for(int i = 0, j = m_count; i < j; i++) - { - if(m_vertices[i].p.z <= maxz) - { - return false; - } - } - - return true; -} - -void GSRendererHW10::SetupDATE(Texture& rt, Texture& ds) -{ - if(!m_context->TEST.DATE) return; // || (::GetAsyncKeyState(VK_CONTROL) & 0x8000) - - // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows - - GSVector4 mm; - - // TODO - - mm = GSVector4(-1, -1, 1, 1); - - // if(m_count < 100) - { - GSVector4 pmin(65535, 65535, 0, 0); - GSVector4 pmax = GSVector4::zero(); - - for(int i = 0, j = m_count; i < j; i++) - { - GSVector4 p(GSVector4i(m_vertices[i].m128i[0]).uph16()); - - pmin = p.minv(pmin); - pmax = p.maxv(pmax); - } - - mm += pmin.xyxy(pmax); - - int w = rt.GetWidth(); - int h = rt.GetHeight(); - - float sx = 2.0f * rt.m_scale.x / (w * 16); - float sy = 2.0f * rt.m_scale.y / (h * 16); - float ox = (float)(int)m_context->XYOFFSET.OFX; - float oy = (float)(int)m_context->XYOFFSET.OFY; - - mm.x = (mm.x - ox) * sx - 1; - mm.y = (mm.y - oy) * sy - 1; - mm.z = (mm.z - ox) * sx - 1; - mm.w = (mm.w - oy) * sy - 1; - - if(mm.x < -1) mm.x = -1; - if(mm.y < -1) mm.y = -1; - if(mm.z > +1) mm.z = +1; - if(mm.w > +1) mm.w = +1; - } - - GSVector4 uv = (mm + 1.0f) / 2.0f; - - // - - m_dev.BeginScene(); - - // om - - GSTexture10 tmp; - - m_dev.CreateRenderTarget(tmp, rt.GetWidth(), rt.GetHeight()); - - m_dev.OMSetRenderTargets(tmp, ds); - m_dev.OMSetDepthStencilState(m_date.dss, 1); - m_dev.OMSetBlendState(m_date.bs, 0); - - m_dev->ClearDepthStencilView(ds, D3D10_CLEAR_STENCIL, 0, 0); - - // ia - - GSVertexPT1 vertices[] = - { - {GSVector4(mm.x, -mm.y, 0.5f, 1.0f), GSVector2(uv.x, uv.y)}, - {GSVector4(mm.z, -mm.y, 0.5f, 1.0f), GSVector2(uv.z, uv.y)}, - {GSVector4(mm.x, -mm.w, 0.5f, 1.0f), GSVector2(uv.x, uv.w)}, - {GSVector4(mm.z, -mm.w, 0.5f, 1.0f), GSVector2(uv.z, uv.w)}, - }; - - D3D10_BOX box = {0, 0, 0, sizeof(vertices), 1, 1}; - m_dev->UpdateSubresource(m_dev.m_convert.vb, 0, &box, vertices, 0, 0); - - m_dev.IASetVertexBuffer(m_dev.m_convert.vb, sizeof(vertices[0])); - m_dev.IASetInputLayout(m_dev.m_convert.il); - m_dev.IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - // vs - - m_dev.VSSetShader(m_dev.m_convert.vs, NULL); - - // gs - - m_dev.GSSetShader(NULL); - - // ps - - m_dev.PSSetShaderResources(rt, NULL); - m_dev.PSSetShader(m_dev.m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL); - m_dev.PSSetSamplerState(m_dev.m_convert.pt, NULL); - - // rs - - m_dev.RSSet(tmp.GetWidth(), tmp.GetHeight()); - - // set - - m_dev.DrawPrimitive(countof(vertices)); - - // - - m_dev.EndScene(); - - m_dev.Recycle(tmp); -} diff --git a/plugins/GSdx/GSRendererHW9.cpp b/plugins/GSdx/GSRendererHW9.cpp deleted file mode 100644 index 47acb327a3..0000000000 --- a/plugins/GSdx/GSRendererHW9.cpp +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Copyright (C) 2007-2009 Gabest - * http://www.gabest.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "stdafx.h" -#include "GSRendererHW9.h" -#include "GSCrc.h" -#include "resource.h" - -GSRendererHW9::GSRendererHW9(BYTE* base, bool mt, void (*irq)(), const GSRendererSettings& rs) - : GSRendererHW(base, mt, irq, rs, false) -{ - m_fba.enabled = !!AfxGetApp()->GetProfileInt(_T("Settings"), _T("fba"), TRUE); - m_logz = !!AfxGetApp()->GetProfileInt(_T("Settings"), _T("logz"), FALSE); - - InitVertexKick(); -} - -bool GSRendererHW9::Create(LPCTSTR title) -{ - if(!__super::Create(title)) - return false; - - if(!m_tfx.Create(&m_dev)) - return false; - - // - - memset(&m_date.dss, 0, sizeof(m_date.dss)); - - m_date.dss.StencilEnable = true; - m_date.dss.StencilReadMask = 1; - m_date.dss.StencilWriteMask = 1; - m_date.dss.StencilFunc = D3DCMP_ALWAYS; - m_date.dss.StencilPassOp = D3DSTENCILOP_REPLACE; - - memset(&m_date.bs, 0, sizeof(m_date.bs)); - - // - - memset(&m_fba.dss, 0, sizeof(m_fba.dss)); - - m_fba.dss.StencilEnable = true; - m_fba.dss.StencilReadMask = 2; - m_fba.dss.StencilWriteMask = 2; - m_fba.dss.StencilFunc = D3DCMP_EQUAL; - m_fba.dss.StencilPassOp = D3DSTENCILOP_ZERO; - m_fba.dss.StencilFailOp = D3DSTENCILOP_ZERO; - m_fba.dss.StencilDepthFailOp = D3DSTENCILOP_ZERO; - - memset(&m_fba.bs, 0, sizeof(m_fba.bs)); - - m_fba.bs.RenderTargetWriteMask = D3DCOLORWRITEENABLE_ALPHA; - - // - - return true; -} - -template -void GSRendererHW9::VertexKick(bool skip) -{ - Vertex& dst = m_vl.AddTail(); - - dst.p.x = (float)(int)m_v.XYZ.X; - dst.p.y = (float)(int)m_v.XYZ.Y; - dst.p.z = (float)m_v.XYZ.Z; - - dst.c0 = m_v.RGBAQ.ai32[0]; - dst.c1 = m_v.FOG.ai32[1]; - - if(tme) - { - if(fst) - { - GSVector4::storel(&dst.t, m_v.GetUV()); - } - else - { - dst.t.x = m_v.ST.S; - dst.t.y = m_v.ST.T; - dst.p.w = m_v.RGBAQ.Q; - } - } - - DWORD count = 0; - - if(Vertex* v = DrawingKick(skip, count)) - { - GSVector4 scissor = m_context->scissor.dx9; - - GSVector4 pmin, pmax; - - switch(prim) - { - case GS_POINTLIST: - pmin = v[0].p; - pmax = v[0].p; - break; - case GS_LINELIST: - case GS_LINESTRIP: - case GS_SPRITE: - pmin = v[0].p.minv(v[1].p); - pmax = v[0].p.maxv(v[1].p); - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - pmin = v[0].p.minv(v[1].p).minv(v[2].p); - pmax = v[0].p.maxv(v[1].p).maxv(v[2].p); - break; - } - - GSVector4 test = (pmax < scissor) | (pmin > scissor.zwxy()); - - if(test.mask() & 3) - { - return; - } - - switch(prim) - { - case GS_POINTLIST: - break; - case GS_LINELIST: - case GS_LINESTRIP: - if(PRIM->IIP == 0) {v[0].c0 = v[1].c0;} - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - if(PRIM->IIP == 0) {v[0].c0 = v[1].c0 = v[2].c0;} - break; - case GS_SPRITE: - if(PRIM->IIP == 0) {v[0].c0 = v[1].c0;} - v[0].p.z = v[1].p.z; - v[0].p.w = v[1].p.w; - v[0].c1 = v[1].c1; - v[2] = v[1]; - v[3] = v[1]; - v[1].p.y = v[0].p.y; - v[1].t.y = v[0].t.y; - v[2].p.x = v[0].p.x; - v[2].t.x = v[0].t.x; - v[4] = v[1]; - v[5] = v[2]; - count += 4; - break; - } - - m_count += count; - } -} - -void GSRendererHW9::Draw(int prim, Texture& rt, Texture& ds, GSTextureCache::GSTexture* tex) -{ - GSDrawingEnvironment& env = m_env; - GSDrawingContext* context = m_context; - - D3DPRIMITIVETYPE topology; - int prims = 0; - - switch(prim) - { - case GS_POINTLIST: - topology = D3DPT_POINTLIST; - prims = m_count; - break; - case GS_LINELIST: - case GS_LINESTRIP: - topology = D3DPT_LINELIST; - prims = m_count / 2; - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - case GS_SPRITE: - topology = D3DPT_TRIANGLELIST; - prims = m_count / 3; - break; - default: - __assume(0); - } - - m_perfmon.Put(GSPerfMon::Prim, prims); - m_perfmon.Put(GSPerfMon::Draw, 1); - - // date - - SetupDATE(rt, ds); - - // - - m_dev.BeginScene(); - - m_dev->SetRenderState(D3DRS_SHADEMODE, PRIM->IIP ? D3DSHADE_GOURAUD : D3DSHADE_FLAT); // TODO - - // om - - GSTextureFX9::OMDepthStencilSelector om_dssel; - - om_dssel.zte = context->TEST.ZTE; - om_dssel.ztst = context->TEST.ZTST; - om_dssel.zwe = !context->ZBUF.ZMSK; - om_dssel.date = context->FRAME.PSM != PSM_PSMCT24 ? context->TEST.DATE : 0; - om_dssel.fba = m_fba.enabled ? context->FBA.FBA : 0; - - GSTextureFX9::OMBlendSelector om_bsel; - - om_bsel.abe = PRIM->ABE || (prim == 1 || prim == 2) && PRIM->AA1; - om_bsel.a = context->ALPHA.A; - om_bsel.b = context->ALPHA.B; - om_bsel.c = context->ALPHA.C; - om_bsel.d = context->ALPHA.D; - om_bsel.wr = (context->FRAME.FBMSK & 0x000000ff) != 0x000000ff; - om_bsel.wg = (context->FRAME.FBMSK & 0x0000ff00) != 0x0000ff00; - om_bsel.wb = (context->FRAME.FBMSK & 0x00ff0000) != 0x00ff0000; - om_bsel.wa = (context->FRAME.FBMSK & 0xff000000) != 0xff000000; - - BYTE bf = context->ALPHA.FIX >= 0x80 ? 0xff : (BYTE)(context->ALPHA.FIX * 2); - - // vs - - GSTextureFX9::VSSelector vs_sel; - - vs_sel.bppz = 0; - vs_sel.tme = PRIM->TME; - vs_sel.fst = PRIM->FST; - vs_sel.logz = m_logz ? 1 : 0; - - if(om_dssel.zte && om_dssel.ztst > 0 && om_dssel.zwe) - { - if(context->ZBUF.PSM == PSM_PSMZ24) - { - if(WrapZ(0xffffff)) - { - vs_sel.bppz = 1; - om_dssel.ztst = 1; - } - } - else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S) - { - if(WrapZ(0xffff)) - { - vs_sel.bppz = 2; - om_dssel.ztst = 1; - } - } - } - - GSTextureFX9::VSConstantBuffer vs_cb; - - float sx = 2.0f * rt.m_scale.x / (rt.GetWidth() * 16); - float sy = 2.0f * rt.m_scale.y / (rt.GetHeight() * 16); - float ox = (float)(int)context->XYOFFSET.OFX; - float oy = (float)(int)context->XYOFFSET.OFY; - - vs_cb.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f); - vs_cb.VertexOffset = GSVector4(ox * sx + 1, -(oy * sy + 1), 0.0f, -1.0f); - vs_cb.TextureScale = GSVector2(1.0f, 1.0f); - - if(PRIM->TME && PRIM->FST) - { - vs_cb.TextureScale.x = 1.0f / (16 << context->TEX0.TW); - vs_cb.TextureScale.y = 1.0f / (16 << context->TEX0.TH); - } - - // ps - - GSTextureFX9::PSSelector ps_sel; - - ps_sel.fst = PRIM->FST; - ps_sel.wms = context->CLAMP.WMS; - ps_sel.wmt = context->CLAMP.WMT; - ps_sel.bpp = 0; - ps_sel.aem = env.TEXA.AEM; - ps_sel.tfx = context->TEX0.TFX; - ps_sel.tcc = context->TEX0.TCC; - ps_sel.ate = context->TEST.ATE; - ps_sel.atst = context->TEST.ATST; - ps_sel.fog = PRIM->FGE; - ps_sel.clr1 = om_bsel.abe && om_bsel.a == 1 && om_bsel.b == 2 && om_bsel.d == 1; - ps_sel.rt = tex && tex->m_rendered; - - GSTextureFX9::PSSamplerSelector ps_ssel; - - ps_ssel.min = m_filter == 2 ? (context->TEX1.MMIN & 1) : m_filter; - ps_ssel.mag = m_filter == 2 ? (context->TEX1.MMAG & 1) : m_filter; - ps_ssel.tau = 0; - ps_ssel.tav = 0; - - GSTextureFX9::PSConstantBuffer ps_cb; - - ps_cb.FogColor = GSVector4(env.FOGCOL.FCR, env.FOGCOL.FCG, env.FOGCOL.FCB, 0) / 255.0f; - ps_cb.TA0 = (float)(int)env.TEXA.TA0 / 255; - ps_cb.TA1 = (float)(int)env.TEXA.TA1 / 255; - ps_cb.AREF = (float)(int)context->TEST.AREF / 255; - - if(context->TEST.ATST == 2 || context->TEST.ATST == 5) - { - ps_cb.AREF -= 0.9f/256; - } - else if(context->TEST.ATST == 3 || context->TEST.ATST == 6) - { - ps_cb.AREF += 0.9f/256; - } - - if(tex) - { - ps_sel.bpp = tex->m_bpp2; - - switch(context->CLAMP.WMS) - { - case 0: - ps_ssel.tau = 1; - break; - case 1: - ps_ssel.tau = 0; - break; - case 2: - ps_cb.MINU = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW); - ps_cb.MAXU = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW); - ps_ssel.tau = 0; - break; - case 3: - ps_cb.UMSK = context->CLAMP.MINU; - ps_cb.UFIX = context->CLAMP.MAXU; - ps_ssel.tau = 1; - break; - default: - __assume(0); - } - - switch(context->CLAMP.WMT) - { - case 0: - ps_ssel.tav = 1; - break; - case 1: - ps_ssel.tav = 0; - break; - case 2: - ps_cb.MINV = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH); - ps_cb.MAXV = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH); - ps_ssel.tav = 0; - break; - case 3: - ps_cb.VMSK = context->CLAMP.MINV; - ps_cb.VFIX = context->CLAMP.MAXV; - ps_ssel.tav = 1; - break; - default: - __assume(0); - } - - float w = (float)tex->m_texture.GetWidth(); - float h = (float)tex->m_texture.GetHeight(); - - ps_cb.WH = GSVector2(w, h); - ps_cb.rWrH = GSVector2(1.0f / w, 1.0f / h); - } - else - { - ps_sel.tfx = 4; - } - - // rs - - int w = rt.GetWidth(); - int h = rt.GetHeight(); - - CRect scissor = (CRect)GSVector4i(GSVector4(rt.m_scale).xyxy() * context->scissor.in) & CRect(0, 0, w, h); - - // - - m_tfx.SetupOM(om_dssel, om_bsel, bf, rt, ds); - m_tfx.SetupIA(m_vertices, m_count, topology); - m_tfx.SetupVS(vs_sel, &vs_cb); - m_tfx.SetupPS(ps_sel, &ps_cb, ps_ssel, - tex ? (IDirect3DTexture9*)tex->m_texture : NULL, - tex ? (IDirect3DTexture9*)tex->m_palette : NULL, - m_psrr); - m_tfx.SetupRS(w, h, scissor); - - // draw - - if(context->TEST.DoFirstPass()) - { - m_dev.DrawPrimitive(); - } - - if(context->TEST.DoSecondPass()) - { - ASSERT(!env.PABE.PABE); - - static const DWORD iatst[] = {1, 0, 5, 6, 7, 2, 3, 4}; - - ps_sel.atst = iatst[ps_sel.atst]; - - m_tfx.UpdatePS(ps_sel, &ps_cb, ps_ssel, m_psrr); - - bool z = om_dssel.zwe; - bool r = om_bsel.wr; - bool g = om_bsel.wg; - bool b = om_bsel.wb; - bool a = om_bsel.wa; - - switch(context->TEST.AFAIL) - { - case 0: z = r = g = b = a = false; break; // none - case 1: z = false; break; // rgba - case 2: r = g = b = a = false; break; // z - case 3: z = a = false; break; // rgb - default: __assume(0); - } - - if(z || r || g || b || a) - { - om_dssel.zwe = z; - om_bsel.wr = r; - om_bsel.wg = g; - om_bsel.wb = b; - om_bsel.wa = a; - - m_tfx.UpdateOM(om_dssel, om_bsel, bf); - - m_dev.DrawPrimitive(); - } - } - - m_dev.EndScene(); - - if(om_dssel.fba) UpdateFBA(rt); -} - -bool GSRendererHW9::WrapZ(float maxz) -{ - // should only run once if z values are in the z buffer range - - for(int i = 0, j = m_count; i < j; i++) - { - if(m_vertices[i].p.z <= maxz) - { - return false; - } - } - - return true; -} - -void GSRendererHW9::SetupDATE(Texture& rt, Texture& ds) -{ - if(!m_context->TEST.DATE) return; // || (::GetAsyncKeyState(VK_CONTROL) & 0x8000) - - // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows - - GSVector4 mm; - - // TODO - - mm = GSVector4(-1, -1, 1, 1); - - // if(m_count < 100) - { - GSVector4 pmin(65535, 65535, 0, 0); - GSVector4 pmax = GSVector4::zero(); - - for(int i = 0, j = m_count; i < j; i++) - { - GSVector4 p(m_vertices[i].p); - - pmin = p.minv(pmin); - pmax = p.maxv(pmax); - } - - mm += pmin.xyxy(pmax); - - int w = rt.GetWidth(); - int h = rt.GetHeight(); - - float sx = 2.0f * rt.m_scale.x / (w * 16); - float sy = 2.0f * rt.m_scale.y / (h * 16); - float ox = (float)(int)m_context->XYOFFSET.OFX; - float oy = (float)(int)m_context->XYOFFSET.OFY; - - mm.x = (mm.x - ox) * sx - 1; - mm.y = (mm.y - oy) * sy - 1; - mm.z = (mm.z - ox) * sx - 1; - mm.w = (mm.w - oy) * sy - 1; - - if(mm.x < -1) mm.x = -1; - if(mm.y < -1) mm.y = -1; - if(mm.z > +1) mm.z = +1; - if(mm.w > +1) mm.w = +1; - } - - GSVector4 uv = (mm + 1.0f) / 2.0f; - - // - - m_dev.BeginScene(); - - // om - - GSTexture9 tmp; - - m_dev.CreateRenderTarget(tmp, rt.GetWidth(), rt.GetHeight()); - - m_dev.OMSetRenderTargets(tmp, ds); - m_dev.OMSetDepthStencilState(&m_date.dss, 1); - m_dev.OMSetBlendState(&m_date.bs, 0); - - m_dev->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 0, 0); - - // ia - - GSVertexPT1 vertices[] = - { - {GSVector4(mm.x, -mm.y, 0.5f, 1.0f), GSVector2(uv.x, uv.y)}, - {GSVector4(mm.z, -mm.y, 0.5f, 1.0f), GSVector2(uv.z, uv.y)}, - {GSVector4(mm.x, -mm.w, 0.5f, 1.0f), GSVector2(uv.x, uv.w)}, - {GSVector4(mm.z, -mm.w, 0.5f, 1.0f), GSVector2(uv.z, uv.w)}, - }; - - m_dev.IASetVertexBuffer(4, vertices); - m_dev.IASetInputLayout(m_dev.m_convert.il); - m_dev.IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP); - - // vs - - m_dev.VSSetShader(m_dev.m_convert.vs, NULL, 0); - - // ps - - m_dev.PSSetShaderResources(rt, NULL); - m_dev.PSSetShader(m_dev.m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL, 0); - m_dev.PSSetSamplerState(&m_dev.m_convert.pt); - - // rs - - m_dev.RSSet(tmp.GetWidth(), tmp.GetHeight()); - - // - - m_dev.DrawPrimitive(); - - // - - m_dev.EndScene(); - - m_dev.Recycle(tmp); -} - -void GSRendererHW9::UpdateFBA(Texture& rt) -{ - m_dev.BeginScene(); - - // om - - m_dev.OMSetDepthStencilState(&m_fba.dss, 2); - m_dev.OMSetBlendState(&m_fba.bs, 0); - - // vs - - m_dev.VSSetShader(NULL, NULL, 0); - - // ps - - m_dev.PSSetShader(m_dev.m_convert.ps[4], NULL, 0); - - // - - int w = rt.GetWidth(); - int h = rt.GetHeight(); - - GSVertexP vertices[] = - { - {GSVector4(0, 0, 0, 0)}, - {GSVector4(w, 0, 0, 0)}, - {GSVector4(0, h, 0, 0)}, - {GSVector4(w, h, 0, 0)}, - }; - - m_dev->SetFVF(D3DFVF_XYZRHW); - - m_dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(vertices[0])); - - // - - m_dev.EndScene(); -} diff --git a/plugins/GSdx/GSRendererNull.h b/plugins/GSdx/GSRendererNull.h index bb9152443e..285cdc4d2f 100644 --- a/plugins/GSdx/GSRendererNull.h +++ b/plugins/GSdx/GSRendererNull.h @@ -24,26 +24,26 @@ #include "GSRenderer.h" #include "GSDeviceNull.h" -template class GSRendererNull : public GSRendererT +class GSRendererNull : public GSRendererT { protected: void Draw() { } - bool GetOutput(int i, Texture& t) + GSTexture* GetOutput(int i) { - return false; + return NULL; } public: - GSRendererNull(BYTE* base, bool mt, void (*irq)(), const GSRendererSettings& rs) - : GSRendererT(base, mt, irq, rs) + GSRendererNull(uint8* base, bool mt, void (*irq)(), GSDevice* dev) + : GSRendererT(base, mt, irq, dev) { - InitVertexKick >(); + InitVertexKick(); } - template void VertexKick(bool skip) + template void VertexKick(bool skip) { } }; \ No newline at end of file diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp new file mode 100644 index 0000000000..107eea2bab --- /dev/null +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSRendererOGL.h" +#include "GSCrc.h" +#include "resource.h" + +GSRendererOGL::GSRendererOGL(uint8* base, bool mt, void (*irq)()) + : GSRendererHW(base, mt, irq, new GSDeviceOGL(), new GSTextureCacheOGL(this)) +{ + InitVertexKick(); +} + +bool GSRendererOGL::Create(const string& title) +{ + if(!__super::Create(title)) + return false; + + // TODO + + /* + + if(!m_tfx.Create((GSDeviceOGL*)m_dev)) + return false; + + */ + + return true; +} + +template +void GSRendererOGL::VertexKick(bool skip) +{ + GSVertexOGL& dst = m_vl.AddTail(); + + // TODO + + int count = 0; + + if(GSVertexOGL* v = DrawingKick(skip, count)) + { + // TODO + + m_count += count; + } +} + +void GSRendererOGL::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) +{ + GSDrawingEnvironment& env = m_env; + GSDrawingContext* context = m_context; + + // m_perfmon.Put(GSPerfMon::Prim, prims); + + m_dev->BeginScene(); + + // TODO + + m_dev->EndScene(); +} diff --git a/plugins/GSdx/GSRendererOGL.h b/plugins/GSdx/GSRendererOGL.h new file mode 100644 index 0000000000..9dc3587b93 --- /dev/null +++ b/plugins/GSdx/GSRendererOGL.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSRendererHW.h" +#include "GSVertexHW.h" +#include "GSTextureCacheOGL.h" +// TODO: #include "GSTextureFXOGL.h" + +class GSRendererOGL : public GSRendererHW +{ +protected: + void Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); + +public: + GSRendererOGL(uint8* base, bool mt, void (*irq)()); + + bool Create(const string& title); + + template void VertexKick(bool skip); +}; \ No newline at end of file diff --git a/plugins/GSdx/GSRendererSW.cpp b/plugins/GSdx/GSRendererSW.cpp index b422422e62..63bee1db97 100644 --- a/plugins/GSdx/GSRendererSW.cpp +++ b/plugins/GSdx/GSRendererSW.cpp @@ -23,3 +23,606 @@ #include "GSRendererSW.h" const GSVector4 g_pos_scale(1.0f / 16, 1.0f / 16, 1.0f, 128.0f); + +GSRendererSW::GSRendererSW(uint8* base, bool mt, void (*irq)(), GSDevice* dev) + : GSRendererT(base, mt, irq, dev) +{ + m_tc = new GSTextureCacheSW(this); + + memset(m_texture, 0, sizeof(m_texture)); + + m_rl.Create(this, theApp.GetConfig("swthreads", 1)); + + InitVertexKick(); +} + +GSRendererSW::~GSRendererSW() +{ + delete m_tc; +} + +void GSRendererSW::Reset() +{ + // TODO: GSreset can come from the main thread too => crash + // m_tc->RemoveAll(); + + m_reset = true; + + __super::Reset(); +} + +void GSRendererSW::VSync(int field) +{ + __super::VSync(field); + + m_tc->IncAge(); + + if(m_reset) + { + m_tc->RemoveAll(); + + m_reset = false; + } + + // if((m_perfmon.GetFrame() & 255) == 0) m_rl.PrintStats(); +} + +void GSRendererSW::ResetDevice() +{ + for(int i = 0; i < countof(m_texture); i++) + { + delete m_texture[i]; + + m_texture[i] = NULL; + } +} + +GSTexture* GSRendererSW::GetOutput(int i) +{ + const GSRegDISPFB& DISPFB = m_regs->DISP[i].DISPFB; + + GIFRegTEX0 TEX0; + + TEX0.TBP0 = DISPFB.Block(); + TEX0.TBW = DISPFB.FBW; + TEX0.PSM = DISPFB.PSM; + + GSVector4i r(0, 0, TEX0.TBW * 64, GetFrameRect(i).bottom); + + // TODO: round up bottom + + int w = r.width(); + int h = r.height(); + + if(m_texture[i]) + { + if(m_texture[i]->GetWidth() != w || m_texture[i]->GetHeight() != h) + { + delete m_texture[i]; + + m_texture[i] = NULL; + } + } + + if(!m_texture[i]) + { + m_texture[i] = m_dev->CreateTexture(w, h); + + if(!m_texture[i]) + { + return NULL; + } + } + + // TODO + static uint8* buff = (uint8*)_aligned_malloc(1024 * 1024 * 4, 16); + static int pitch = 1024 * 4; + + m_mem.ReadTexture(r, buff, pitch, TEX0, m_env.TEXA); + + m_texture[i]->Update(r, buff, pitch); + + if(s_dump) + { + if(s_save) + { + m_texture[i]->Save(format("c:\\temp1\\_%05d_f%I64d_fr%d_%05x_%d.bmp", s_n, m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM)); + } + + s_n++; + } + + return m_texture[i]; +} + +void GSRendererSW::Draw() +{ + GS_PRIM_CLASS primclass = GSUtil::GetPrimClass(PRIM->PRIM); + + m_vt.Update(m_vertices, m_count, primclass, PRIM, m_context); + + if(m_dump) + { + m_dump.Object(m_vertices, m_count, primclass); + } + + GSScanlineParam p; + + GetScanlineParam(p, primclass); + + if((p.fm & p.zm) == 0xffffffff) + { + return; + } + + if(s_dump) + { + uint64 frame = m_perfmon.GetFrame(); + + string s; + + if(s_save && PRIM->TME) + { + s = format("c:\\temp1\\_%05d_f%I64d_tex_%05x_%d.bmp", s_n, frame, (int)m_context->TEX0.TBP0, (int)m_context->TEX0.PSM); + + m_mem.SaveBMP(s, m_context->TEX0.TBP0, m_context->TEX0.TBW, m_context->TEX0.PSM, 1 << m_context->TEX0.TW, 1 << m_context->TEX0.TH); + } + + s_n++; + + if(s_save) + { + s = format("c:\\temp1\\_%05d_f%I64d_rt0_%05x_%d.bmp", s_n, frame, m_context->FRAME.Block(), m_context->FRAME.PSM); + + m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);//GetFrameSize(1).cy); + } + + if(s_savez) + { + s = format("c:\\temp1\\_%05d_f%I64d_rz0_%05x_%d.bmp", s_n, frame, m_context->ZBUF.Block(), m_context->ZBUF.PSM); + + m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameRect().width(), 512); + } + + s_n++; + } + + GSRasterizerData data; + + data.scissor = GSVector4i(m_context->scissor.in); + data.scissor.z = min(data.scissor.z, (int)m_context->FRAME.FBW * 64); // TODO: find a game that overflows and check which one is the right behaviour + data.primclass = primclass; + data.vertices = m_vertices; + data.count = m_count; + data.param = &p; + + m_rl.Draw(&data); + + GSRasterizerStats stats; + + m_rl.GetStats(stats); + + m_perfmon.Put(GSPerfMon::Draw, 1); + m_perfmon.Put(GSPerfMon::Prim, stats.prims); + m_perfmon.Put(GSPerfMon::Fillrate, stats.pixels); + + GSVector4i r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(data.scissor); + + GIFRegBITBLTBUF BITBLTBUF; + + BITBLTBUF.DBW = m_context->FRAME.FBW; + + if(p.fm != 0xffffffff) + { + BITBLTBUF.DBP = m_context->FRAME.Block(); + BITBLTBUF.DPSM = m_context->FRAME.PSM; + + m_tc->InvalidateVideoMem(BITBLTBUF, r); + } + + if(p.zm != 0xffffffff) + { + BITBLTBUF.DBP = m_context->ZBUF.Block(); + BITBLTBUF.DPSM = m_context->ZBUF.PSM; + + m_tc->InvalidateVideoMem(BITBLTBUF, r); + } + + if(s_dump) + { + uint64 frame = m_perfmon.GetFrame(); + + string s; + + if(s_save) + { + s = format("c:\\temp1\\_%05d_f%I64d_rt1_%05x_%d.bmp", s_n, frame, m_context->FRAME.Block(), m_context->FRAME.PSM); + + m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);//GetFrameSize(1).cy); + } + + if(s_savez) + { + s = format("c:\\temp1\\_%05d_f%I64d_rz1_%05x_%d.bmp", s_n, frame, m_context->ZBUF.Block(), m_context->ZBUF.PSM); + + m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameRect().width(), 512); + } + + s_n++; + } + + if(0)//stats.ticks > 5000000) + { + printf("* [%I64d | %012I64x] ticks %I64d prims %d (%d) pixels %d (%d)\n", + m_perfmon.GetFrame(), p.sel.key, + stats.ticks, + stats.prims, stats.prims > 0 ? (int)(stats.ticks / stats.prims) : -1, + stats.pixels, stats.pixels > 0 ? (int)(stats.ticks / stats.pixels) : -1); + } +} + +void GSRendererSW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) +{ + m_tc->InvalidateVideoMem(BITBLTBUF, r); +} + +void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) +{ + const GSDrawingEnvironment& env = m_env; + const GSDrawingContext* context = m_context; + + p.vm = m_mem.m_vm8; + + p.fbo = m_mem.GetOffset(context->FRAME.Block(), context->FRAME.FBW, context->FRAME.PSM); + p.zbo = m_mem.GetOffset(context->ZBUF.Block(), context->FRAME.FBW, context->ZBUF.PSM); + p.fzbo = m_mem.GetOffset4(context->FRAME, context->ZBUF); + + p.sel.key = 0; + + p.sel.fpsm = 3; + p.sel.zpsm = 3; + p.sel.atst = ATST_ALWAYS; + p.sel.tfx = TFX_NONE; + p.sel.ababcd = 255; + p.sel.sprite = primclass == GS_SPRITE_CLASS ? 1 : 0; + + p.fm = context->FRAME.FBMSK; + p.zm = context->ZBUF.ZMSK || context->TEST.ZTE == 0 ? 0xffffffff : 0; + + if(context->TEST.ZTE && context->TEST.ZTST == ZTST_NEVER) + { + p.fm = 0xffffffff; + p.zm = 0xffffffff; + } + + if(PRIM->TME) + { + m_mem.m_clut.Read32(context->TEX0, env.TEXA); + } + + if(context->TEST.ATE) + { + if(!TryAlphaTest(p.fm, p.zm)) + { + p.sel.atst = context->TEST.ATST; + p.sel.afail = context->TEST.AFAIL; + } + } + + bool fwrite = p.fm != 0xffffffff; + bool ftest = p.sel.atst != ATST_ALWAYS || context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24; + + p.sel.fwrite = fwrite; + p.sel.ftest = ftest; + + if(fwrite || ftest) + { + p.sel.fpsm = GSUtil::EncodePSM(context->FRAME.PSM); + + if((primclass == GS_LINE_CLASS || primclass == GS_TRIANGLE_CLASS) && m_vt.m_eq.rgba != 0xffff) + { + p.sel.iip = PRIM->IIP; + } + + if(PRIM->TME) + { + p.sel.tfx = context->TEX0.TFX; + p.sel.tcc = context->TEX0.TCC; + p.sel.fst = PRIM->FST; + p.sel.ltf = IsLinear(); + p.sel.tlu = GSLocalMemory::m_psm[context->TEX0.PSM].pal > 0; + p.sel.wms = context->CLAMP.WMS; + p.sel.wmt = context->CLAMP.WMT; + + if(/*p.sel.iip == 0 &&*/ p.sel.tfx == TFX_MODULATE && p.sel.tcc && m_vt.m_eq.rgba == 0xffff && m_vt.m_min.c.eq(GSVector4i(128))) + { + // modulate does not do anything when vertex color is 0x80 + + p.sel.tfx = TFX_DECAL; + } + + if(p.sel.fst == 0) + { + // skip per pixel division if q is constant + + GSVertexSW* v = m_vertices; + + if(m_vt.m_eq.q) + { + p.sel.fst = 1; + + if(v[0].t.z != 1.0f) + { + GSVector4 w = v[0].t.zzzz().rcpnr(); + + for(int i = 0, j = m_count; i < j; i++) + { + v[i].t *= w; + } + } + } + else if(primclass == GS_SPRITE_CLASS) + { + p.sel.fst = 1; + + for(int i = 0, j = m_count; i < j; i += 2) + { + GSVector4 w = v[i + 1].t.zzzz().rcpnr(); + + v[i + 0].t *= w; + v[i + 1].t *= w; + } + } + } + + if(p.sel.ltf) + { + GSVector4 half(0x8000, 0x8000); + + if(p.sel.fst) + { + // if q is constant we can do the half pel shift for bilinear sampling on the vertices + + GSVertexSW* v = m_vertices; + + for(int i = 0, j = m_count; i < j; i++) + { + v[i].t -= half; + } + } + } + + GSVector4i r; + + GetTextureMinMax(r, p.sel.ltf); + + const GSTextureCacheSW::GSTexture* t = m_tc->Lookup(context->TEX0, env.TEXA, r); + + if(!t) {ASSERT(0); return;} + + p.tex = t->m_buff; + p.clut = m_mem.m_clut; + p.tw = t->m_tw; + } + + p.sel.fge = PRIM->FGE; + + if(context->FRAME.PSM != PSM_PSMCT24) + { + p.sel.date = context->TEST.DATE; + p.sel.datm = context->TEST.DATM; + } + + if(!IsOpaque()) + { + p.sel.abe = PRIM->ABE; + p.sel.ababcd = context->ALPHA.u32[0]; + + if(env.PABE.PABE) + { + p.sel.pabe = 1; + } + + if(PRIM->AA1 && (primclass == GS_LINE_CLASS || primclass == GS_TRIANGLE_CLASS)) + { + p.sel.aa1 = m_aa1 ? 1 : 0; + } + } + + if(p.sel.date + || p.sel.aba == 1 || p.sel.abb == 1 || p.sel.abc == 1 || p.sel.abd == 1 + || p.sel.atst != ATST_ALWAYS && p.sel.afail == AFAIL_RGB_ONLY + || p.sel.fpsm == 0 && p.fm != 0 && p.fm != 0xffffffff + || p.sel.fpsm == 1 && (p.fm & 0x00ffffff) != 0 && (p.fm & 0x00ffffff) != 0x00ffffff + || p.sel.fpsm == 2 && (p.fm & 0x80f8f8f8) != 0 && (p.fm & 0x80f8f8f8) != 0x80f8f8f8) + { + p.sel.rfb = 1; + } + + p.sel.colclamp = env.COLCLAMP.CLAMP; + p.sel.fba = context->FBA.FBA; + p.sel.dthe = env.DTHE.DTHE; + } + + bool zwrite = p.zm != 0xffffffff; + bool ztest = context->TEST.ZTE && context->TEST.ZTST > 1; + + p.sel.zwrite = zwrite; + p.sel.ztest = ztest; + + if(zwrite || ztest) + { + p.sel.zpsm = GSUtil::EncodePSM(context->ZBUF.PSM); + p.sel.ztst = ztest ? context->TEST.ZTST : 1; + p.sel.zoverflow = GSVector4i(m_vt.m_max.p).z == 0x80000000; + } +} + +template +void GSRendererSW::VertexKick(bool skip) +{ + const GSDrawingContext* context = m_context; + + GSVector4i xy = GSVector4i::load((int)m_v.XYZ.u32[0]); + + xy = xy.insert16<3>(m_v.FOG.F); + xy = xy.upl16(); + xy -= context->XYOFFSET; + + GSVertexSW v; + + v.p = GSVector4(xy) * g_pos_scale; + + v.c = GSVector4(GSVector4i::load((int)m_v.RGBAQ.u32[0]).u8to32() << 7); + + if(tme) + { + float q; + + if(fst) + { + v.t = GSVector4(((GSVector4i)m_v.UV).upl16() << (16 - 4)); + q = 1.0f; + } + else + { + v.t = GSVector4(m_v.ST.S, m_v.ST.T); + v.t *= GSVector4(0x10000 << context->TEX0.TW, 0x10000 << context->TEX0.TH); + q = m_v.RGBAQ.Q; + } + + v.t = v.t.xyxy(GSVector4::load(q)); + } + + GSVertexSW& dst = m_vl.AddTail(); + + dst = v; + + dst.p.z = (float)min(m_v.XYZ.Z, 0xffffff00); // max value which can survive the uint32 => float => uint32 conversion + + int count = 0; + + if(GSVertexSW* v = DrawingKick(skip, count)) + { +if(!m_dump) +{ + GSVector4 pmin, pmax; + + switch(prim) + { + case GS_POINTLIST: + pmin = v[0].p; + pmax = v[0].p; + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + pmin = v[0].p.minv(v[1].p); + pmax = v[0].p.maxv(v[1].p); + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + pmin = v[0].p.minv(v[1].p).minv(v[2].p); + pmax = v[0].p.maxv(v[1].p).maxv(v[2].p); + break; + } + + GSVector4 scissor = context->scissor.ex; + + GSVector4 test = (pmax < scissor) | (pmin > scissor.zwxy()); + + switch(prim) + { + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + case GS_SPRITE: + test |= pmin.ceil() == pmax.ceil(); + break; + } + + switch(prim) + { + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + // are in line or just two of them are the same (cross product == 0) + GSVector4 tmp = (v[1].p - v[0].p) * (v[2].p - v[0].p).yxwz(); + test |= tmp == tmp.yxwz(); + break; + } + + if(test.mask() & 3) + { + return; + } +} + switch(prim) + { + case GS_POINTLIST: + break; + case GS_LINELIST: + case GS_LINESTRIP: + if(PRIM->IIP == 0) {v[0].c = v[1].c;} + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + if(PRIM->IIP == 0) {v[0].c = v[2].c; v[1].c = v[2].c;} + break; + case GS_SPRITE: + break; + } + + if(m_count < 30 && m_count >= 3) + { + GSVertexSW* v = &m_vertices[m_count - 3]; + + int tl = 0; + int br = 0; + + bool isquad = false; + + switch(prim) + { + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + case GS_TRIANGLELIST: + isquad = GSVertexSW::IsQuad(v, tl, br); + break; + } + + if(isquad) + { + m_count -= 3; + + if(m_count > 0) + { + tl += m_count; + br += m_count; + + Flush(); + } + + if(tl != 0) m_vertices[0] = m_vertices[tl]; + if(br != 1) m_vertices[1] = m_vertices[br]; + + m_count = 2; + + uint32 tmp = PRIM->PRIM; + PRIM->PRIM = GS_SPRITE; + + Flush(); + + PRIM->PRIM = tmp; + + m_perfmon.Put(GSPerfMon::Quad, 1); + + return; + } + } + + m_count += count; + } +} diff --git a/plugins/GSdx/GSRendererSW.h b/plugins/GSdx/GSRendererSW.h index 178800736d..542e53e6b3 100644 --- a/plugins/GSdx/GSRendererSW.h +++ b/plugins/GSdx/GSRendererSW.h @@ -25,879 +25,28 @@ #include "GSTextureCacheSW.h" #include "GSDrawScanline.h" -extern const GSVector4 g_pos_scale; - -template -class GSRendererSW : public GSRendererT +class GSRendererSW : public GSRendererT { protected: GSRasterizerList m_rl; GSTextureCacheSW* m_tc; - GSVertexTrace m_vtrace; - Texture m_texture[2]; + GSTexture* m_texture[2]; bool m_reset; - void Reset() - { - // TODO: GSreset can come from the main thread too => crash - // m_tc->RemoveAll(); + void Reset(); + void VSync(int field); + void ResetDevice(); + GSTexture* GetOutput(int i); - m_reset = true; + void Draw(); + void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r); - __super::Reset(); - } - - void VSync(int field) - { - __super::VSync(field); - - m_tc->IncAge(); - - if(m_reset) - { - m_tc->RemoveAll(); - - m_reset = false; - } - - // if((m_perfmon.GetFrame() & 255) == 0) m_rl.PrintStats(); - } - - void ResetDevice() - { - m_texture[0] = Texture(); - m_texture[1] = Texture(); - } - - bool GetOutput(int i, Texture& t) - { - const GSRegDISPFB& DISPFB = m_regs->DISP[i].DISPFB; - - GIFRegTEX0 TEX0; - - TEX0.TBP0 = DISPFB.Block(); - TEX0.TBW = DISPFB.FBW; - TEX0.PSM = DISPFB.PSM; - - CRect r(0, 0, TEX0.TBW * 64, GetFrameRect(i).bottom); - - // TODO: round up bottom - - if(m_texture[i].GetWidth() != r.Width() || m_texture[i].GetHeight() != r.Height()) - { - m_texture[i] = Texture(); - } - - if(!m_texture[i] && !m_dev.CreateTexture(m_texture[i], r.Width(), r.Height())) - { - return false; - } - - GIFRegCLAMP CLAMP; - - CLAMP.WMS = CLAMP.WMT = 1; - - // TODO - static BYTE* buff = (BYTE*)_aligned_malloc(1024 * 1024 * 4, 16); - static int pitch = 1024 * 4; - - m_mem.ReadTexture(r, buff, pitch, TEX0, m_env.TEXA, CLAMP); - - m_texture[i].Update(r, buff, pitch); - - t = m_texture[i]; - - if(s_dump) - { - CString str; - str.Format(_T("c:\\temp1\\_%05d_f%I64d_fr%d_%05x_%d.bmp"), s_n++, m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM); - if(s_save) t.Save(str); - } - - return true; - } - - bool TryAlphaTest(DWORD& fm, DWORD& zm) - { - const GSDrawingEnvironment& env = m_env; - const GSDrawingContext* context = m_context; - - bool pass = true; - - if(context->TEST.ATST == ATST_NEVER) - { - pass = false; - } - else if(context->TEST.ATST != ATST_ALWAYS) - { - GSVector4i af = GSVector4i(m_vtrace.m_min.c.wwww(m_vtrace.m_max.c)) >> 7; - - int amin, amax; - - if(PRIM->TME && (context->TEX0.TCC || context->TEX0.TFX == TFX_DECAL)) - { - DWORD bpp = GSLocalMemory::m_psm[context->TEX0.PSM].trbpp; - DWORD cbpp = GSLocalMemory::m_psm[context->TEX0.CPSM].trbpp; - DWORD pal = GSLocalMemory::m_psm[context->TEX0.PSM].pal; - - if(bpp == 32) - { - return false; - } - else if(bpp == 24) - { - amin = env.TEXA.AEM ? 0 : env.TEXA.TA0; - amax = env.TEXA.TA0; - } - else if(bpp == 16) - { - amin = env.TEXA.AEM ? 0 : min(env.TEXA.TA0, env.TEXA.TA1); - amax = max(env.TEXA.TA0, env.TEXA.TA1); - } - else - { - m_mem.m_clut.GetAlphaMinMax32(amin, amax); - } - - switch(context->TEX0.TFX) - { - case TFX_MODULATE: - amin = (amin * af.x) >> 7; - amax = (amax * af.z) >> 7; - if(amin > 255) amin = 255; - if(amax > 255) amax = 255; - break; - case TFX_DECAL: - break; - case TFX_HIGHLIGHT: - amin = amin + af.x; - amax = amax + af.z; - if(amin > 255) amin = 255; - if(amax > 255) amax = 255; - break; - case TFX_HIGHLIGHT2: - break; - default: - __assume(0); - } - } - else - { - amin = af.x; - amax = af.z; - } - - int aref = context->TEST.AREF; - - switch(context->TEST.ATST) - { - case ATST_NEVER: - pass = false; - break; - case ATST_ALWAYS: - pass = true; - break; - case ATST_LESS: - if(amax < aref) pass = true; - else if(amin >= aref) pass = false; - else return false; - break; - case ATST_LEQUAL: - if(amax <= aref) pass = true; - else if(amin > aref) pass = false; - else return false; - break; - case ATST_EQUAL: - if(amin == aref && amax == aref) pass = true; - else if(amin > aref || amax < aref) pass = false; - else return false; - break; - case ATST_GEQUAL: - if(amin >= aref) pass = true; - else if(amax < aref) pass = false; - else return false; - break; - case ATST_GREATER: - if(amin > aref) pass = true; - else if(amax <= aref) pass = false; - else return false; - break; - case ATST_NOTEQUAL: - if(amin == aref && amax == aref) pass = false; - else if(amin > aref || amax < aref) pass = true; - else return false; - break; - default: - __assume(0); - } - } - - if(!pass) - { - switch(context->TEST.AFAIL) - { - case AFAIL_KEEP: fm = zm = 0xffffffff; break; - case AFAIL_FB_ONLY: zm = 0xffffffff; break; - case AFAIL_ZB_ONLY: fm = 0xffffffff; break; - case AFAIL_RGB_ONLY: fm |= 0xff000000; zm = 0xffffffff; break; - default: __assume(0); - } - } - - return true; - } - - void GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) - { - const GSDrawingEnvironment& env = m_env; - const GSDrawingContext* context = m_context; - - p.vm = m_mem.m_vm32; - - p.fbo = m_mem.GetOffset(context->FRAME.Block(), context->FRAME.FBW, context->FRAME.PSM); - p.zbo = m_mem.GetOffset(context->ZBUF.Block(), context->FRAME.FBW, context->ZBUF.PSM); - p.fzbo = m_mem.GetOffset4(context->FRAME, context->ZBUF); - - p.sel.key = 0; - - p.sel.fpsm = 3; - p.sel.zpsm = 3; - p.sel.atst = ATST_ALWAYS; - p.sel.tfx = TFX_NONE; - p.sel.ababcd = 255; - p.sel.sprite = primclass == GS_SPRITE_CLASS ? 1 : 0; - - p.fm = context->FRAME.FBMSK; - p.zm = context->ZBUF.ZMSK || context->TEST.ZTE == 0 ? 0xffffffff : 0; - - if(context->TEST.ZTE && context->TEST.ZTST == ZTST_NEVER) - { - p.fm = 0xffffffff; - p.zm = 0xffffffff; - } - - if(PRIM->TME) - { - m_mem.m_clut.Read32(context->TEX0, env.TEXA); - } - - if(context->TEST.ATE) - { - if(!TryAlphaTest(p.fm, p.zm)) - { - p.sel.atst = context->TEST.ATST; - p.sel.afail = context->TEST.AFAIL; - } - } - - bool fwrite = p.fm != 0xffffffff; - bool ftest = p.sel.atst != ATST_ALWAYS || context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24; - - p.sel.fwrite = fwrite; - p.sel.ftest = ftest; - - if(fwrite || ftest) - { - p.sel.fpsm = GSUtil::EncodePSM(context->FRAME.PSM); - - if((primclass == GS_LINE_CLASS || primclass == GS_TRIANGLE_CLASS) && m_vtrace.m_eq.rgba != 15) - { - p.sel.iip = PRIM->IIP; - } - - if(PRIM->TME) - { - p.sel.tfx = context->TEX0.TFX; - p.sel.tcc = context->TEX0.TCC; - p.sel.fst = PRIM->FST; - p.sel.ltf = context->TEX1.IsLinear(); - p.sel.tlu = GSLocalMemory::m_psm[context->TEX0.PSM].pal > 0; - p.sel.wms = context->CLAMP.WMS; - p.sel.wmt = context->CLAMP.WMT; - - if(p.sel.iip == 0 && p.sel.tfx == TFX_MODULATE && p.sel.tcc) - { - if(m_vtrace.m_eq.rgba == 15 && (m_vtrace.m_min.c == GSVector4(128.0f * 128.0f)).alltrue()) - { - // modulate does not do anything when vertex color is 0x80 - - p.sel.tfx = TFX_DECAL; - } - } - - if(p.sel.tfx == TFX_DECAL) - { - p.sel.tcc = 1; - } - - if(p.sel.fst == 0) - { - // skip per pixel division if q is constant - - GSVertexSW* v = m_vertices; - - if(m_vtrace.m_eq.q) - { - p.sel.fst = 1; - - if(v[0].t.z != 1.0f) - { - GSVector4 w = v[0].t.zzzz().rcpnr(); - - for(int i = 0, j = m_count; i < j; i++) - { - v[i].t *= w; - } - - m_vtrace.m_min.t *= w; - m_vtrace.m_max.t *= w; - } - } - else if(primclass == GS_SPRITE_CLASS) - { - p.sel.fst = 1; - - GSVector4 tmin = GSVector4(FLT_MAX); - GSVector4 tmax = GSVector4(-FLT_MAX); - - for(int i = 0, j = m_count; i < j; i += 2) - { - GSVector4 w = v[i + 1].t.zzzz().rcpnr(); - - GSVector4 v0 = v[i + 0].t * w; - GSVector4 v1 = v[i + 1].t * w; - - v[i + 0].t = v0; - v[i + 1].t = v1; - - tmin = tmin.minv(v0).minv(v1); - tmax = tmax.maxv(v0).maxv(v1); - } - - m_vtrace.m_max.t = tmax; - m_vtrace.m_min.t = tmin; - } - } - - if(p.sel.fst) - { - // if q is constant we can do the half pel shift for bilinear sampling on the vertices - - if(p.sel.ltf) - { - GSVector4 half(0x8000, 0x8000); - - GSVertexSW* v = m_vertices; - - for(int i = 0, j = m_count; i < j; i++) - { - v[i].t -= half; - } - - m_vtrace.m_min.t -= half; - m_vtrace.m_max.t += half; - } - } - /* - else - { - GSVector4 tmin = GSVector4(FLT_MAX); - GSVector4 tmax = GSVector4(-FLT_MAX); - - GSVertexSW* v = m_vertices; - - for(int i = 0, j = m_count; i < j; i++) - { - GSVector4 v0 = v[i].t * v[i].t.zzzz().rcpnr(); - - tmin = tmin.minv(v0); - tmax = tmax.maxv(v0); - } - - if(p.sel.ltf) - { - GSVector4 half(0x8000, 0x8000); - - tmin -= half; - tmax += half; - } - - m_vtrace.min.t = tmin; - m_vtrace.max.t = tmax; - } - */ - - CRect r; - - int w = 1 << context->TEX0.TW; - int h = 1 << context->TEX0.TH; - - MinMaxUV(w, h, r, p.sel.fst); - - const GSTextureCacheSW::GSTexture* t = m_tc->Lookup(context->TEX0, env.TEXA, &r); - - if(!t) {ASSERT(0); return;} - - p.tex = t->m_buff; - p.clut = m_mem.m_clut; - p.tw = t->m_tw; - } - - p.sel.fge = PRIM->FGE; - - if(context->FRAME.PSM != PSM_PSMCT24) - { - p.sel.date = context->TEST.DATE; - p.sel.datm = context->TEST.DATM; - } - - if(PRIM->ABE && !context->ALPHA.IsOpaque() || PRIM->AA1) - { - p.sel.abe = PRIM->ABE; - p.sel.ababcd = context->ALPHA.ai32[0]; - - if(env.PABE.PABE) - { - p.sel.pabe = 1; - } - - if(PRIM->AA1 && (primclass == GS_LINE_CLASS || primclass == GS_TRIANGLE_CLASS)) - { - p.sel.aa1 = m_aa1 ? 1 : 0; - } - } - - if(p.sel.date - || p.sel.aba == 1 || p.sel.abb == 1 || p.sel.abc == 1 || p.sel.abd == 1 - || p.sel.atst != ATST_ALWAYS && p.sel.afail == AFAIL_RGB_ONLY - || p.sel.fpsm == 0 && p.fm != 0 && p.fm != 0xffffffff - || p.sel.fpsm == 1 && (p.fm & 0x00ffffff) != 0 && (p.fm & 0x00ffffff) != 0x00ffffff - || p.sel.fpsm == 2 && (p.fm & 0x80f8f8f8) != 0 && (p.fm & 0x80f8f8f8) != 0x80f8f8f8) - { - p.sel.rfb = 1; - } - - p.sel.colclamp = env.COLCLAMP.CLAMP; - p.sel.fba = context->FBA.FBA; - p.sel.dthe = env.DTHE.DTHE; - } - - bool zwrite = p.zm != 0xffffffff; - bool ztest = context->TEST.ZTE && context->TEST.ZTST > 1; - - p.sel.zwrite = zwrite; - p.sel.ztest = ztest; - - if(zwrite || ztest) - { - p.sel.zpsm = GSUtil::EncodePSM(context->ZBUF.PSM); - p.sel.ztst = ztest ? context->TEST.ZTST : 1; - p.sel.zoverflow = GSVector4i(m_vtrace.m_max.p).z == 0x80000000; - } - } - - void Draw() - { - GS_PRIM_CLASS primclass = GSUtil::GetPrimClass(PRIM->PRIM); - - m_vtrace.Update(m_vertices, m_count, primclass, PRIM->IIP, PRIM->TME, m_context->TEX0.TFX); - - if(m_dump) - { - m_dump.Object(m_vertices, m_count, primclass); - } - - GSScanlineParam p; - - GetScanlineParam(p, primclass); - - if((p.fm & p.zm) == 0xffffffff) - { - return; - } - - if(s_dump) - { - CString str; - str.Format(_T("c:\\temp1\\_%05d_f%I64d_tex_%05x_%d.bmp"), s_n++, m_perfmon.GetFrame(), (int)m_context->TEX0.TBP0, (int)m_context->TEX0.PSM); - if(PRIM->TME) if(s_save) {m_mem.SaveBMP(str, m_context->TEX0.TBP0, m_context->TEX0.TBW, m_context->TEX0.PSM, 1 << m_context->TEX0.TW, 1 << m_context->TEX0.TH);} - str.Format(_T("c:\\temp1\\_%05d_f%I64d_rt0_%05x_%d.bmp"), s_n++, m_perfmon.GetFrame(), m_context->FRAME.Block(), m_context->FRAME.PSM); - if(s_save) {m_mem.SaveBMP(str, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameSize(1).cx, 512);}//GetFrameSize(1).cy); - str.Format(_T("c:\\temp1\\_%05d_f%I64d_rz0_%05x_%d.bmp"), s_n-1, m_perfmon.GetFrame(), m_context->ZBUF.Block(), m_context->ZBUF.PSM); - if(s_savez) {m_mem.SaveBMP(str, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameSize(1).cx, 512);} - } - - GSRasterizerData data; - - data.scissor = GSVector4i(m_context->scissor.in); - data.scissor.z = min(data.scissor.z, (int)m_context->FRAME.FBW * 64); // TODO: find a game that overflows and check which one is the right behaviour - data.primclass = primclass; - data.vertices = m_vertices; - data.count = m_count; - data.param = &p; - - m_rl.Draw(&data); - - GSRasterizerStats stats; - - m_rl.GetStats(stats); - - m_perfmon.Put(GSPerfMon::Draw, 1); - m_perfmon.Put(GSPerfMon::Prim, stats.prims); - m_perfmon.Put(GSPerfMon::Fillrate, stats.pixels); - - GSVector4i pos(m_vtrace.m_min.p.xyxy(m_vtrace.m_max.p)); - - GSVector4i scissor = data.scissor; - - CRect r; - - r.left = max(scissor.x, min(scissor.z, pos.x)); - r.top = max(scissor.y, min(scissor.w, pos.y)); - r.right = max(scissor.x, min(scissor.z, pos.z)); - r.bottom = max(scissor.y, min(scissor.w, pos.w)); - - GIFRegBITBLTBUF BITBLTBUF; - - BITBLTBUF.DBW = m_context->FRAME.FBW; - - if(p.fm != 0xffffffff) - { - BITBLTBUF.DBP = m_context->FRAME.Block(); - BITBLTBUF.DPSM = m_context->FRAME.PSM; - - m_tc->InvalidateVideoMem(BITBLTBUF, r); - } - - if(p.zm != 0xffffffff) - { - BITBLTBUF.DBP = m_context->ZBUF.Block(); - BITBLTBUF.DPSM = m_context->ZBUF.PSM; - - m_tc->InvalidateVideoMem(BITBLTBUF, r); - } - - if(s_dump) - { - CString str; - str.Format(_T("c:\\temp1\\_%05d_f%I64d_rt1_%05x_%d.bmp"), s_n++, m_perfmon.GetFrame(), m_context->FRAME.Block(), m_context->FRAME.PSM); - if(s_save) {m_mem.SaveBMP(str, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameSize(1).cx, 512);}//GetFrameSize(1).cy); - str.Format(_T("c:\\temp1\\_%05d_f%I64d_rz1_%05x_%d.bmp"), s_n-1, m_perfmon.GetFrame(), m_context->ZBUF.Block(), m_context->ZBUF.PSM); - if(s_savez) {m_mem.SaveBMP(str, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameSize(1).cx, 512);} - } - - if(0)//stats.ticks > 1000000) - { - printf("* [%I64d | %012I64x] ticks %I64d prims %d (%d) pixels %d (%d)\n", - m_perfmon.GetFrame(), p.sel.key, - stats.ticks, - stats.prims, stats.prims > 0 ? (int)(stats.ticks / stats.prims) : -1, - stats.pixels, stats.pixels > 0 ? (int)(stats.ticks / stats.pixels) : -1); - } - } - - void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, CRect r) - { - m_tc->InvalidateVideoMem(BITBLTBUF, r); - } - - void MinMaxUV(int w, int h, CRect& r, DWORD fst) - { - const GSDrawingContext* context = m_context; - - int wms = context->CLAMP.WMS; - int wmt = context->CLAMP.WMT; - - int minu = (int)context->CLAMP.MINU; - int minv = (int)context->CLAMP.MINV; - int maxu = (int)context->CLAMP.MAXU; - int maxv = (int)context->CLAMP.MAXV; - - GSVector4i vr(0, 0, w, h); - - switch(wms) - { - case CLAMP_REPEAT: - break; - case CLAMP_CLAMP: - break; - case CLAMP_REGION_CLAMP: - if(vr.x < minu) vr.x = minu; - if(vr.z > maxu + 1) vr.z = maxu + 1; - break; - case CLAMP_REGION_REPEAT: - vr.x = maxu; - vr.z = vr.x + (minu + 1); - break; - default: - __assume(0); - } - - switch(wmt) - { - case CLAMP_REPEAT: - break; - case CLAMP_CLAMP: - break; - case CLAMP_REGION_CLAMP: - if(vr.y < minv) vr.y = minv; - if(vr.w > maxv + 1) vr.w = maxv + 1; - break; - case CLAMP_REGION_REPEAT: - vr.y = maxv; - vr.w = vr.y + (minv + 1); - break; - default: - __assume(0); - } - - if(fst) - { - GSVector4i uv = GSVector4i(m_vtrace.m_min.t.xyxy(m_vtrace.m_max.t)).sra32(16); -/* - int tw = context->TEX0.TW; - int th = context->TEX0.TH; - - GSVector4i u = uv & GSVector4i::xffffffff().srl32(32 - tw); - GSVector4i v = uv & GSVector4i::xffffffff().srl32(32 - th); - - GSVector4i uu = uv.sra32(tw); - GSVector4i vv = uv.sra32(th); - - int mask = (uu.upl32(vv) == uu.uph32(vv)).mask(); -*/ - switch(wms) - { - case CLAMP_REPEAT: -/* - if(mask & 0x000f) - { - if(vr.x < u.x) vr.x = u.x; - if(vr.z > u.z + 1) vr.z = u.z + 1; - } -*/ - break; - case CLAMP_CLAMP: - case CLAMP_REGION_CLAMP: - if(vr.x < uv.x) vr.x = uv.x; - if(vr.z > uv.z + 1) vr.z = uv.z + 1; - break; - case CLAMP_REGION_REPEAT: // TODO - break; - default: - __assume(0); - } - - switch(wmt) - { - case CLAMP_REPEAT: -/* - if(mask & 0xf000) - { - if(vr.y < v.y) vr.y = v.y; - if(vr.w > v.w + 1) vr.w = v.w + 1; - } -*/ - break; - case CLAMP_CLAMP: - case CLAMP_REGION_CLAMP: - if(vr.y < uv.y) vr.y = uv.y; - if(vr.w > uv.w + 1) vr.w = uv.w + 1; - break; - case CLAMP_REGION_REPEAT: // TODO - break; - default: - __assume(0); - } - } - - r = vr; - - r &= CRect(0, 0, w, h); - } + void GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass); public: - GSRendererSW(BYTE* base, bool mt, void (*irq)(), const GSRendererSettings& rs, int threads) - : GSRendererT(base, mt, irq, rs) - { - m_rl.Create(this, threads); + GSRendererSW(uint8* base, bool mt, void (*irq)(), GSDevice* dev); + virtual ~GSRendererSW(); - m_tc = new GSTextureCacheSW(this); - - InitVertexKick >(); - } - - virtual ~GSRendererSW() - { - delete m_tc; - } - - template - void VertexKick(bool skip) - { - const GSDrawingContext* context = m_context; - - GSVector4i xy = GSVector4i::load((int)m_v.XYZ.ai32[0]); - - xy = xy.insert16<3>(m_v.FOG.F); - xy = xy.upl16(); - xy -= context->XYOFFSET; - - GSVertexSW v; - - v.p = GSVector4(xy) * g_pos_scale; - - v.c = GSVector4(GSVector4i::load((int)m_v.RGBAQ.ai32[0]).u8to32() << 7); - - if(tme) - { - float q; - - if(fst) - { - v.t = GSVector4(((GSVector4i)m_v.UV).upl16() << (16 - 4)); - q = 1.0f; - } - else - { - v.t = GSVector4(m_v.ST.S, m_v.ST.T); - v.t *= GSVector4(0x10000 << context->TEX0.TW, 0x10000 << context->TEX0.TH); - q = m_v.RGBAQ.Q; - } - - v.t = v.t.xyxy(GSVector4::load(q)); - } - - GSVertexSW& dst = m_vl.AddTail(); - - dst = v; - - dst.p.z = (float)min(m_v.XYZ.Z, 0xffffff00); // max value which can survive the DWORD => float => DWORD conversion - - DWORD count = 0; - - if(GSVertexSW* v = DrawingKick(skip, count)) - { -if(!m_dump) -{ - GSVector4 pmin, pmax; - - switch(prim) - { - case GS_POINTLIST: - pmin = v[0].p; - pmax = v[0].p; - break; - case GS_LINELIST: - case GS_LINESTRIP: - case GS_SPRITE: - pmin = v[0].p.minv(v[1].p); - pmax = v[0].p.maxv(v[1].p); - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - pmin = v[0].p.minv(v[1].p).minv(v[2].p); - pmax = v[0].p.maxv(v[1].p).maxv(v[2].p); - break; - } - - GSVector4 scissor = context->scissor.ex; - - GSVector4 test = (pmax < scissor) | (pmin > scissor.zwxy()); - - switch(prim) - { - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - case GS_SPRITE: - test |= pmin.ceil() == pmax.ceil(); - break; - } - - switch(prim) - { - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - // are in line or just two of them are the same (cross product == 0) - GSVector4 tmp = (v[1].p - v[0].p) * (v[2].p - v[0].p).yxwz(); - test |= tmp == tmp.yxwz(); - break; - } - - if(test.mask() & 3) - { - return; - } -} - switch(prim) - { - case GS_POINTLIST: - break; - case GS_LINELIST: - case GS_LINESTRIP: - if(PRIM->IIP == 0) {v[0].c = v[1].c;} - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - if(PRIM->IIP == 0) {v[0].c = v[2].c; v[1].c = v[2].c;} - break; - case GS_SPRITE: - break; - } - - if(m_count < 30 && m_count >= 3) - { - GSVertexSW* v = &m_vertices[m_count - 3]; - - int tl = 0; - int br = 0; - - bool isquad = false; - - switch(prim) - { - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - case GS_TRIANGLELIST: - isquad = GSVertexSW::IsQuad(v, tl, br); - break; - } - - if(isquad) - { - m_count -= 3; - - if(m_count > 0) - { - tl += m_count; - br += m_count; - - Flush(); - } - - if(tl != 0) m_vertices[0] = m_vertices[tl]; - if(br != 1) m_vertices[1] = m_vertices[br]; - - m_count = 2; - - UINT32 tmp = PRIM->PRIM; - PRIM->PRIM = GS_SPRITE; - - Flush(); - - PRIM->PRIM = tmp; - - m_perfmon.Put(GSPerfMon::Quad, 1); - - return; - } - } - - m_count += count; - } - } + template + void VertexKick(bool skip); }; diff --git a/plugins/GSdx/GSScanlineEnvironment.h b/plugins/GSdx/GSScanlineEnvironment.h index d959930197..b7ee1cdb9a 100644 --- a/plugins/GSdx/GSScanlineEnvironment.h +++ b/plugins/GSdx/GSScanlineEnvironment.h @@ -28,63 +28,63 @@ union GSScanlineSelector { struct { - DWORD fpsm:2; // 0 - DWORD zpsm:2; // 2 - DWORD ztst:2; // 4 (0: off, 1: write, 2: test (ge), 3: test (g)) - DWORD atst:3; // 6 - DWORD afail:2; // 9 - DWORD iip:1; // 11 - DWORD tfx:3; // 12 - DWORD tcc:1; // 15 - DWORD fst:1; // 16 - DWORD ltf:1; // 17 - DWORD tlu:1; // 18 - DWORD fge:1; // 19 - DWORD date:1; // 20 - DWORD abe:1; // 21 - DWORD aba:2; // 22 - DWORD abb:2; // 24 - DWORD abc:2; // 26 - DWORD abd:2; // 28 - DWORD pabe:1; // 30 - DWORD aa1:1; // 31 + uint32 fpsm:2; // 0 + uint32 zpsm:2; // 2 + uint32 ztst:2; // 4 (0: off, 1: write, 2: test (ge), 3: test (g)) + uint32 atst:3; // 6 + uint32 afail:2; // 9 + uint32 iip:1; // 11 + uint32 tfx:3; // 12 + uint32 tcc:1; // 15 + uint32 fst:1; // 16 + uint32 ltf:1; // 17 + uint32 tlu:1; // 18 + uint32 fge:1; // 19 + uint32 date:1; // 20 + uint32 abe:1; // 21 + uint32 aba:2; // 22 + uint32 abb:2; // 24 + uint32 abc:2; // 26 + uint32 abd:2; // 28 + uint32 pabe:1; // 30 + uint32 aa1:1; // 31 - DWORD fwrite:1; // 32 - DWORD ftest:1; // 33 - DWORD rfb:1; // 34 - DWORD zwrite:1; // 35 - DWORD ztest:1; // 36 - DWORD zoverflow:1; // 37 (z max >= 0x80000000) - DWORD wms:2; // 38 - DWORD wmt:2; // 40 - DWORD datm:1; // 42 - DWORD colclamp:1; // 43 - DWORD fba:1; // 44 - DWORD dthe:1; // 45 - DWORD sprite:1; // 46 - DWORD edge:1; // 47 + uint32 fwrite:1; // 32 + uint32 ftest:1; // 33 + uint32 rfb:1; // 34 + uint32 zwrite:1; // 35 + uint32 ztest:1; // 36 + uint32 zoverflow:1; // 37 (z max >= 0x80000000) + uint32 wms:2; // 38 + uint32 wmt:2; // 40 + uint32 datm:1; // 42 + uint32 colclamp:1; // 43 + uint32 fba:1; // 44 + uint32 dthe:1; // 45 + uint32 sprite:1; // 46 + uint32 edge:1; // 47 }; struct { - DWORD _pad1:22; - DWORD ababcd:8; - DWORD _pad2:2; - DWORD fb:2; - DWORD _pad3:1; - DWORD zb:2; + uint32 _pad1:22; + uint32 ababcd:8; + uint32 _pad2:2; + uint32 fb:2; + uint32 _pad3:1; + uint32 zb:2; }; struct { - DWORD lo; - DWORD hi; + uint32 lo; + uint32 hi; }; - UINT64 key; + uint64 key; - operator DWORD() {return lo;} - operator UINT64() {return key;} + operator uint32() {return lo;} + operator uint64() {return key;} bool IsSolidRect() { @@ -105,22 +105,22 @@ __declspec(align(16)) struct GSScanlineParam void* vm; const void* tex; - const DWORD* clut; - DWORD tw; + const uint32* clut; + uint32 tw; GSLocalMemory::Offset* fbo; GSLocalMemory::Offset* zbo; GSLocalMemory::Offset4* fzbo; - DWORD fm, zm; + uint32 fm, zm; }; __declspec(align(16)) struct GSScanlineEnvironment { void* vm; const void* tex; - const DWORD* clut; - DWORD tw; + const uint32* clut; + uint32 tw; GSVector4i* fbr; GSVector4i* zbr; diff --git a/plugins/GSdx/GSSetting.h b/plugins/GSdx/GSSetting.h index 0124dc014a..ced75eb7b9 100644 --- a/plugins/GSdx/GSSetting.h +++ b/plugins/GSdx/GSSetting.h @@ -23,23 +23,7 @@ struct GSSetting { - DWORD id; - const TCHAR* name; - const TCHAR* note; - - static void InitComboBox(const GSSetting* settings, int count, CComboBox& combobox, DWORD sel, DWORD maxid = ~0) - { - for(int i = 0; i < count; i++) - { - if(settings[i].id <= maxid) - { - CString str = settings[i].name; - if(settings[i].note != NULL) str = str + _T(" (") + settings[i].note + _T(")"); - int item = combobox.AddString(str); - combobox.SetItemData(item, settings[i].id); - if(settings[i].id == sel) combobox.SetCurSel(item); - } - } - } - + uint32 id; + const char* name; + const char* note; }; diff --git a/plugins/GSdx/GSSettingsDlg.cpp b/plugins/GSdx/GSSettingsDlg.cpp index 333744a560..002c5ae1e7 100644 --- a/plugins/GSdx/GSSettingsDlg.cpp +++ b/plugins/GSdx/GSSettingsDlg.cpp @@ -23,302 +23,207 @@ #include "GSdx.h" #include "GSSettingsDlg.h" #include "GSUtil.h" -#include -#include +#include "resource.h" GSSetting GSSettingsDlg::g_renderers[] = { - {0, _T("Direct3D9 (Hardware)"), NULL}, - {1, _T("Direct3D9 (Software)"), NULL}, - {2, _T("Direct3D9 (Null)"), NULL}, - {3, _T("Direct3D10 (Hardware)"), NULL}, - {4, _T("Direct3D10 (Software)"), NULL}, - {5, _T("Direct3D10 (Null)"), NULL}, - {6, _T("Null (Software)"), NULL}, - {7, _T("Null (Null)"), NULL}, -}; - -GSSetting GSSettingsDlg::g_psversion[] = -{ - {D3DPS_VERSION(3, 0), _T("Pixel Shader 3.0"), NULL}, - {D3DPS_VERSION(2, 0), _T("Pixel Shader 2.0"), NULL}, - //{D3DPS_VERSION(1, 4), _T("Pixel Shader 1.4"), NULL}, - //{D3DPS_VERSION(1, 1), _T("Pixel Shader 1.1"), NULL}, - //{D3DPS_VERSION(0, 0), _T("Fixed Pipeline (bogus)"), NULL}, + {0, "Direct3D9 (Hardware)", NULL}, + {1, "Direct3D9 (Software)", NULL}, + {2, "Direct3D9 (Null)", NULL}, + {3, "Direct3D10 (Hardware)", NULL}, + {4, "Direct3D10 (Software)", NULL}, + {5, "Direct3D10 (Null)", NULL}, + {6, "Direct3D11 (Hardware)", NULL}, + {7, "Direct3D11 (Software)", NULL}, + {8, "Direct3D11 (Null)", NULL}, + #if 0 + {9, "OpenGL (Hardware)", NULL}, + {10, "OpenGL (Software)", NULL}, + {11, "OpenGL (Null)", NULL}, + #endif + {12, "Null (Software)", NULL}, + {13, "Null (Null)", NULL}, }; GSSetting GSSettingsDlg::g_interlace[] = { - {0, _T("None"), NULL}, - {1, _T("Weave tff"), _T("saw-tooth")}, - {2, _T("Weave bff"), _T("saw-tooth")}, - {3, _T("Bob tff"), _T("use blend if shaking")}, - {4, _T("Bob bff"), _T("use blend if shaking")}, - {5, _T("Blend tff"), _T("slight blur, 1/2 fps")}, - {6, _T("Blend bff"), _T("slight blur, 1/2 fps")}, + {0, "None", NULL}, + {1, "Weave tff", "saw-tooth"}, + {2, "Weave bff", "saw-tooth"}, + {3, "Bob tff", "use blend if shaking"}, + {4, "Bob bff", "use blend if shaking"}, + {5, "Blend tff", "slight blur, 1/2 fps"}, + {6, "Blend bff", "slight blur, 1/2 fps"}, }; GSSetting GSSettingsDlg::g_aspectratio[] = { - {0, _T("Stretch"), NULL}, - {1, _T("4:3"), NULL}, - {2, _T("16:9"), NULL}, + {0, "Stretch", NULL}, + {1, "4:3", NULL}, + {2, "16:9", NULL}, }; -IMPLEMENT_DYNAMIC(GSSettingsDlg, CDialog) -GSSettingsDlg::GSSettingsDlg(CWnd* pParent /*=NULL*/) - : CDialog(GSSettingsDlg::IDD, pParent) - , m_filter(1) - , m_nativeres(FALSE) - , m_vsync(FALSE) - , m_logz(FALSE) - , m_fba(TRUE) - , m_aa1(FALSE) - , m_blur(FALSE) +GSSettingsDlg::GSSettingsDlg() + : GSDialog(IDD_CONFIG) { } -GSSettingsDlg::~GSSettingsDlg() +void GSSettingsDlg::OnInit() { -} + __super::OnInit(); -LRESULT GSSettingsDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) -{ - LRESULT ret = __super::DefWindowProc(message, wParam, lParam); - - if(message == WM_INITDIALOG) - { - SendMessage(WM_KICKIDLE); - } - - return ret; -} - -void GSSettingsDlg::DoDataExchange(CDataExchange* pDX) -{ - __super::DoDataExchange(pDX); - DDX_Control(pDX, IDC_COMBO3, m_resolution); - DDX_Control(pDX, IDC_COMBO1, m_renderer); - DDX_Control(pDX, IDC_COMBO4, m_psversion); - DDX_Control(pDX, IDC_COMBO2, m_interlace); - DDX_Control(pDX, IDC_COMBO5, m_aspectratio); - DDX_Check(pDX, IDC_CHECK4, m_filter); - DDX_Control(pDX, IDC_SPIN1, m_resx); - DDX_Control(pDX, IDC_SPIN2, m_resy); - DDX_Control(pDX, IDC_SPIN3, m_swthreads); - DDX_Check(pDX, IDC_CHECK1, m_nativeres); - DDX_Control(pDX, IDC_EDIT1, m_resxedit); - DDX_Control(pDX, IDC_EDIT2, m_resyedit); - DDX_Control(pDX, IDC_EDIT3, m_swthreadsedit); - DDX_Check(pDX, IDC_CHECK2, m_vsync); - DDX_Check(pDX, IDC_CHECK5, m_logz); - DDX_Check(pDX, IDC_CHECK7, m_fba); - DDX_Check(pDX, IDC_CHECK8, m_aa1); - DDX_Check(pDX, IDC_CHECK9, m_blur); -} - -BEGIN_MESSAGE_MAP(GSSettingsDlg, CDialog) - ON_MESSAGE_VOID(WM_KICKIDLE, OnKickIdle) - ON_UPDATE_COMMAND_UI(IDC_SPIN1, OnUpdateResolution) - ON_UPDATE_COMMAND_UI(IDC_SPIN2, OnUpdateResolution) - ON_UPDATE_COMMAND_UI(IDC_EDIT1, OnUpdateResolution) - ON_UPDATE_COMMAND_UI(IDC_EDIT2, OnUpdateResolution) - ON_UPDATE_COMMAND_UI(IDC_COMBO4, OnUpdateD3D9Options) - ON_UPDATE_COMMAND_UI(IDC_CHECK3, OnUpdateD3D9Options) - ON_UPDATE_COMMAND_UI(IDC_CHECK5, OnUpdateD3D9Options) - ON_UPDATE_COMMAND_UI(IDC_CHECK7, OnUpdateD3D9Options) - ON_UPDATE_COMMAND_UI(IDC_SPIN3, OnUpdateSWOptions) - ON_UPDATE_COMMAND_UI(IDC_EDIT3, OnUpdateSWOptions) - ON_CBN_SELCHANGE(IDC_COMBO1, &GSSettingsDlg::OnCbnSelchangeCombo1) -END_MESSAGE_MAP() - -void GSSettingsDlg::OnKickIdle() -{ - UpdateDialogControls(this, false); -} - -BOOL GSSettingsDlg::OnInitDialog() -{ - __super::OnInitDialog(); - - CWinApp* pApp = AfxGetApp(); - - D3DCAPS9 caps; - memset(&caps, 0, sizeof(caps)); - caps.PixelShaderVersion = D3DPS_VERSION(0, 0); - - m_modes.RemoveAll(); - - // windowed + m_modes.clear(); { D3DDISPLAYMODE mode; memset(&mode, 0, sizeof(mode)); - m_modes.AddTail(mode); + m_modes.push_back(mode); - int iItem = m_resolution.AddString(_T("Windowed")); - m_resolution.SetItemDataPtr(iItem, m_modes.GetTailPosition()); - m_resolution.SetCurSel(iItem); - } + ComboBoxAppend(IDC_RESOLUTION, "Windowed", (LPARAM)&m_modes.back(), true); - // fullscreen - - if(CComPtr d3d = Direct3DCreate9(D3D_SDK_VERSION)) - { - UINT ModeWidth = pApp->GetProfileInt(_T("Settings"), _T("ModeWidth"), 0); - UINT ModeHeight = pApp->GetProfileInt(_T("Settings"), _T("ModeHeight"), 0); - UINT ModeRefreshRate = pApp->GetProfileInt(_T("Settings"), _T("ModeRefreshRate"), 0); - - UINT nModes = d3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8); - - for(UINT i = 0; i < nModes; i++) + if(CComPtr d3d = Direct3DCreate9(D3D_SDK_VERSION)) { - D3DDISPLAYMODE mode; + uint32 w = theApp.GetConfig("ModeWidth", 0); + uint32 h = theApp.GetConfig("ModeHeight", 0); + uint32 hz = theApp.GetConfig("ModeRefreshRate", 0); - if(S_OK == d3d->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &mode)) + uint32 n = d3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8); + + for(uint32 i = 0; i < n; i++) { - CString str; - str.Format(_T("%dx%d %dHz"), mode.Width, mode.Height, mode.RefreshRate); - int iItem = m_resolution.AddString(str); - - m_modes.AddTail(mode); - m_resolution.SetItemDataPtr(iItem, m_modes.GetTailPosition()); - - if(ModeWidth == mode.Width && ModeHeight == mode.Height && ModeRefreshRate == mode.RefreshRate) + if(S_OK == d3d->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &mode)) { - m_resolution.SetCurSel(iItem); + m_modes.push_back(mode); + + string str = format("%dx%d %dHz", mode.Width, mode.Height, mode.RefreshRate); + + ComboBoxAppend(IDC_RESOLUTION, str.c_str(), (LPARAM)&m_modes.back(), w == mode.Width && h == mode.Height && hz == mode.RefreshRate); } } } - - d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps); } bool isdx10avail = GSUtil::IsDirect3D10Available(); + bool isdx11avail = GSUtil::IsDirect3D11Available(); - CAtlArray renderers; + vector renderers; for(size_t i = 0; i < countof(g_renderers); i++) { if(i >= 3 && i <= 5 && !isdx10avail) continue; + if(i >= 6 && i <= 8 && !isdx11avail) continue; - renderers.Add(g_renderers[i]); + renderers.push_back(g_renderers[i]); } - GSSetting::InitComboBox(renderers.GetData(), renderers.GetCount(), m_renderer, pApp->GetProfileInt(_T("Settings"), _T("Renderer"), 0)); - GSSetting::InitComboBox(g_psversion, countof(g_psversion), m_psversion, pApp->GetProfileInt(_T("Settings"), _T("PixelShaderVersion2"), D3DPS_VERSION(2, 0)), caps.PixelShaderVersion); - GSSetting::InitComboBox(g_interlace, countof(g_interlace), m_interlace, pApp->GetProfileInt(_T("Settings"), _T("Interlace"), 0)); - GSSetting::InitComboBox(g_aspectratio, countof(g_aspectratio), m_aspectratio, pApp->GetProfileInt(_T("Settings"), _T("AspectRatio"), 1)); + ComboBoxInit(IDC_RENDERER, &renderers[0], renderers.size(), theApp.GetConfig("Renderer", 0)); + ComboBoxInit(IDC_INTERLACE, g_interlace, countof(g_interlace), theApp.GetConfig("Interlace", 0)); + ComboBoxInit(IDC_ASPECTRATIO, g_aspectratio, countof(g_aspectratio), theApp.GetConfig("AspectRatio", 1)); - OnCbnSelchangeCombo1(); + CheckDlgButton(m_hWnd, IDC_FILTER, theApp.GetConfig("filter", 1)); + CheckDlgButton(m_hWnd, IDC_VSYNC, theApp.GetConfig("vsync", 0)); + CheckDlgButton(m_hWnd, IDC_LOGZ, theApp.GetConfig("logz", 0)); + CheckDlgButton(m_hWnd, IDC_FBA, theApp.GetConfig("fba", 1)); + CheckDlgButton(m_hWnd, IDC_AA1, theApp.GetConfig("aa1", 0)); + CheckDlgButton(m_hWnd, IDC_BLUR, theApp.GetConfig("blur", 0)); + CheckDlgButton(m_hWnd, IDC_NATIVERES, theApp.GetConfig("nativeres", 0)); - // + SendMessage(GetDlgItem(m_hWnd, IDC_RESX), UDM_SETRANGE, 0, MAKELPARAM(4096, 512)); + SendMessage(GetDlgItem(m_hWnd, IDC_RESX), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfig("resx", 1024), 0)); - m_filter = pApp->GetProfileInt(_T("Settings"), _T("filter"), 1); - m_vsync = !!pApp->GetProfileInt(_T("Settings"), _T("vsync"), FALSE); - m_logz = !!pApp->GetProfileInt(_T("Settings"), _T("logz"), FALSE); - m_fba = !!pApp->GetProfileInt(_T("Settings"), _T("fba"), TRUE); - m_aa1 = !!pApp->GetProfileInt(_T("Settings"), _T("aa1"), FALSE); - m_blur = !!pApp->GetProfileInt(_T("Settings"), _T("blur"), FALSE); + SendMessage(GetDlgItem(m_hWnd, IDC_RESY), UDM_SETRANGE, 0, MAKELPARAM(4096, 512)); + SendMessage(GetDlgItem(m_hWnd, IDC_RESY), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfig("resy", 1024), 0)); - m_resx.SetRange(512, 4096); - m_resy.SetRange(512, 4096); - m_resx.SetPos(pApp->GetProfileInt(_T("Settings"), _T("resx"), 1024)); - m_resy.SetPos(pApp->GetProfileInt(_T("Settings"), _T("resy"), 1024)); - m_nativeres = !!pApp->GetProfileInt(_T("Settings"), _T("nativeres"), FALSE); + SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETRANGE, 0, MAKELPARAM(16, 1)); + SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfig("swthreads", 1), 0)); - m_resx.EnableWindow(!m_nativeres); - m_resy.EnableWindow(!m_nativeres); - m_resxedit.EnableWindow(!m_nativeres); - m_resyedit.EnableWindow(!m_nativeres); - - m_swthreads.SetRange(1, 16); - m_swthreads.SetPos(pApp->GetProfileInt(_T("Settings"), _T("swthreads"), 1)); - - // - - UpdateData(FALSE); - - return TRUE; // return TRUE unless you set the focus to a control - // EXCEPTION: OCX Property Pages should return FALSE + UpdateControls(); } -void GSSettingsDlg::OnOK() +bool GSSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code) { - CWinApp* pApp = AfxGetApp(); - - UpdateData(); - - if(m_resolution.GetCurSel() >= 0) + if(id == IDC_RENDERER && code == CBN_SELCHANGE) { - D3DDISPLAYMODE& mode = m_modes.GetAt((POSITION)m_resolution.GetItemData(m_resolution.GetCurSel())); - pApp->WriteProfileInt(_T("Settings"), _T("ModeWidth"), mode.Width); - pApp->WriteProfileInt(_T("Settings"), _T("ModeHeight"), mode.Height); - pApp->WriteProfileInt(_T("Settings"), _T("ModeRefreshRate"), mode.RefreshRate); + UpdateControls(); + } + else if(id == IDC_NATIVERES && code == BN_CLICKED) + { + UpdateControls(); + } + else if(id == IDOK) + { + INT_PTR data; + + if(ComboBoxGetSelData(IDC_RESOLUTION, data)) + { + const D3DDISPLAYMODE* mode = (D3DDISPLAYMODE*)data; + + theApp.SetConfig("ModeWidth", (int)mode->Width); + theApp.SetConfig("ModeHeight", (int)mode->Height); + theApp.SetConfig("ModeRefreshRate", (int)mode->RefreshRate); + } + + if(ComboBoxGetSelData(IDC_RENDERER, data)) + { + theApp.SetConfig("Renderer", (int)data); + } + + if(ComboBoxGetSelData(IDC_INTERLACE, data)) + { + theApp.SetConfig("Interlace", (int)data); + } + + if(ComboBoxGetSelData(IDC_ASPECTRATIO, data)) + { + theApp.SetConfig("AspectRatio", (int)data); + } + + theApp.SetConfig("filter", (int)IsDlgButtonChecked(m_hWnd, IDC_FILTER)); + theApp.SetConfig("vsync", (int)IsDlgButtonChecked(m_hWnd, IDC_VSYNC)); + theApp.SetConfig("logz", (int)IsDlgButtonChecked(m_hWnd, IDC_LOGZ)); + theApp.SetConfig("fba", (int)IsDlgButtonChecked(m_hWnd, IDC_FBA)); + theApp.SetConfig("aa1", (int)IsDlgButtonChecked(m_hWnd, IDC_AA1)); + theApp.SetConfig("blur", (int)IsDlgButtonChecked(m_hWnd, IDC_BLUR)); + theApp.SetConfig("nativeres", (int)IsDlgButtonChecked(m_hWnd, IDC_NATIVERES)); + + theApp.SetConfig("resx", (int)SendMessage(GetDlgItem(m_hWnd, IDC_RESX), UDM_GETPOS, 0, 0)); + theApp.SetConfig("resy", (int)SendMessage(GetDlgItem(m_hWnd, IDC_RESY), UDM_GETPOS, 0, 0)); + theApp.SetConfig("swthreads", (int)SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_GETPOS, 0, 0)); } - if(m_renderer.GetCurSel() >= 0) - { - pApp->WriteProfileInt(_T("Settings"), _T("Renderer"), (DWORD)m_renderer.GetItemData(m_renderer.GetCurSel())); - } - - if(m_psversion.GetCurSel() >= 0) - { - pApp->WriteProfileInt(_T("Settings"), _T("PixelShaderVersion2"), (DWORD)m_psversion.GetItemData(m_psversion.GetCurSel())); - } - - if(m_interlace.GetCurSel() >= 0) - { - pApp->WriteProfileInt(_T("Settings"), _T("Interlace"), (DWORD)m_interlace.GetItemData(m_interlace.GetCurSel())); - } - - if(m_aspectratio.GetCurSel() >= 0) - { - pApp->WriteProfileInt(_T("Settings"), _T("AspectRatio"), (DWORD)m_aspectratio.GetItemData(m_aspectratio.GetCurSel())); - } - - pApp->WriteProfileInt(_T("Settings"), _T("filter"), m_filter); - pApp->WriteProfileInt(_T("Settings"), _T("vsync"), m_vsync); - pApp->WriteProfileInt(_T("Settings"), _T("logz"), m_logz); - pApp->WriteProfileInt(_T("Settings"), _T("fba"), m_fba); - pApp->WriteProfileInt(_T("Settings"), _T("aa1"), m_aa1); - pApp->WriteProfileInt(_T("Settings"), _T("blur"), m_blur); - - pApp->WriteProfileInt(_T("Settings"), _T("resx"), m_resx.GetPos()); - pApp->WriteProfileInt(_T("Settings"), _T("resy"), m_resy.GetPos()); - pApp->WriteProfileInt(_T("Settings"), _T("swthreads"), m_swthreads.GetPos()); - pApp->WriteProfileInt(_T("Settings"), _T("nativeres"), m_nativeres); - - __super::OnOK(); + return __super::OnCommand(hWnd, id, code); } -void GSSettingsDlg::OnUpdateResolution(CCmdUI* pCmdUI) +void GSSettingsDlg::UpdateControls() { - UpdateData(); + INT_PTR i; - int i = (int)m_renderer.GetItemData(m_renderer.GetCurSel()); + if(ComboBoxGetSelData(IDC_RENDERER, i)) + { + bool dx9 = i >= 0 && i <= 2; + bool dx10 = i >= 3 && i <= 5; + bool dx11 = i >= 6 && i <= 8; + bool ogl = i >= 9 && i <= 12; + bool hw = i == 0 || i == 3 || i == 6 || i == 9; + bool sw = i == 1 || i == 4 || i == 7 || i == 10; + bool native = !!IsDlgButtonChecked(m_hWnd, IDC_NATIVERES); - pCmdUI->Enable(!m_nativeres && (i == 0 || i == 3)); -} - -void GSSettingsDlg::OnUpdateD3D9Options(CCmdUI* pCmdUI) -{ - int i = (int)m_renderer.GetItemData(m_renderer.GetCurSel()); - - pCmdUI->Enable(i >= 0 && i <= 2); -} - -void GSSettingsDlg::OnUpdateSWOptions(CCmdUI* pCmdUI) -{ - int i = (int)m_renderer.GetItemData(m_renderer.GetCurSel()); - - pCmdUI->Enable(i == 1 || i == 4 || i == 6); -} - -void GSSettingsDlg::OnCbnSelchangeCombo1() -{ - int i = (int)m_renderer.GetItemData(m_renderer.GetCurSel()); - - GetDlgItem(IDC_LOGO9)->ShowWindow(i >= 0 && i <= 2 ? SW_SHOW : SW_HIDE); - GetDlgItem(IDC_LOGO10)->ShowWindow(i >= 3 && i <= 5 ? SW_SHOW : SW_HIDE); + ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO9), dx9 ? SW_SHOW : SW_HIDE); + ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO10), dx10 ? SW_SHOW : SW_HIDE); + // TODO: ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO11), dx11 ? SW_SHOW : SW_HIDE); + // TODO: ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO_OGL), ogl ? SW_SHOW : SW_HIDE); + + EnableWindow(GetDlgItem(m_hWnd, IDC_RESOLUTION), dx9); + EnableWindow(GetDlgItem(m_hWnd, IDC_RESX), hw && !native); + EnableWindow(GetDlgItem(m_hWnd, IDC_RESX_EDIT), hw && !native); + EnableWindow(GetDlgItem(m_hWnd, IDC_RESY), hw && !native); + EnableWindow(GetDlgItem(m_hWnd, IDC_RESY_EDIT), hw && !native); + EnableWindow(GetDlgItem(m_hWnd, IDC_NATIVERES), hw); + EnableWindow(GetDlgItem(m_hWnd, IDC_FILTER), hw && !native); + EnableWindow(GetDlgItem(m_hWnd, IDC_LOGZ), dx9 && hw); + EnableWindow(GetDlgItem(m_hWnd, IDC_FBA), dx9 && hw); + EnableWindow(GetDlgItem(m_hWnd, IDC_AA1), sw); + EnableWindow(GetDlgItem(m_hWnd, IDC_SWTHREADS_EDIT), sw); + EnableWindow(GetDlgItem(m_hWnd, IDC_SWTHREADS), sw); + } } diff --git a/plugins/GSdx/GSSettingsDlg.h b/plugins/GSdx/GSSettingsDlg.h index e2b68c41bf..82e947eabc 100644 --- a/plugins/GSdx/GSSettingsDlg.h +++ b/plugins/GSdx/GSSettingsDlg.h @@ -21,59 +21,23 @@ #pragma once +#include "GSDialog.h" #include "GSSetting.h" -#include "resource.h" -class GSSettingsDlg : public CDialog +class GSSettingsDlg : public GSDialog { - DECLARE_DYNAMIC(GSSettingsDlg) + list m_modes; -private: - CAtlList m_modes; - -public: - GSSettingsDlg(CWnd* pParent = NULL); // standard constructor - virtual ~GSSettingsDlg(); - - static GSSetting g_renderers[]; - static GSSetting g_psversion[]; - static GSSetting g_interlace[]; - static GSSetting g_aspectratio[]; - -// Dialog Data - enum { IDD = IDD_CONFIG }; - CComboBox m_resolution; - CComboBox m_renderer; - CComboBox m_psversion; - CComboBox m_interlace; - CComboBox m_aspectratio; - int m_filter; - CSpinButtonCtrl m_resx; - CSpinButtonCtrl m_resy; - CSpinButtonCtrl m_swthreads; - BOOL m_nativeres; - CEdit m_resxedit; - CEdit m_resyedit; - CEdit m_swthreadsedit; - BOOL m_vsync; - BOOL m_logz; - BOOL m_fba; - BOOL m_aa1; - BOOL m_blur; + void UpdateControls(); protected: - virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam); - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - virtual BOOL OnInitDialog(); - virtual void OnOK(); - - DECLARE_MESSAGE_MAP() + void OnInit(); + bool OnCommand(HWND hWnd, UINT id, UINT code); public: - afx_msg void OnKickIdle(); - afx_msg void OnUpdateResolution(CCmdUI* pCmdUI); - afx_msg void OnUpdateD3D9Options(CCmdUI* pCmdUI); - afx_msg void OnUpdateSWOptions(CCmdUI* pCmdUI); - afx_msg void OnCbnSelchangeCombo1(); -}; + GSSettingsDlg(); + static GSSetting g_renderers[]; + static GSSetting g_interlace[]; + static GSSetting g_aspectratio[]; +}; \ No newline at end of file diff --git a/plugins/GSdx/GSSetupPrimCodeGenerator.cpp b/plugins/GSdx/GSSetupPrimCodeGenerator.cpp index d44768d68f..3efc752076 100644 --- a/plugins/GSdx/GSSetupPrimCodeGenerator.cpp +++ b/plugins/GSdx/GSSetupPrimCodeGenerator.cpp @@ -24,7 +24,7 @@ #include "StdAfx.h" #include "GSSetupPrimCodeGenerator.h" -GSSetupPrimCodeGenerator::GSSetupPrimCodeGenerator(GSScanlineEnvironment& env, UINT64 key, void* ptr, size_t maxsize) +GSSetupPrimCodeGenerator::GSSetupPrimCodeGenerator(GSScanlineEnvironment& env, uint64 key, void* ptr, size_t maxsize) : CodeGenerator(maxsize, ptr) , m_env(env) { @@ -33,7 +33,7 @@ GSSetupPrimCodeGenerator::GSSetupPrimCodeGenerator(GSScanlineEnvironment& env, U m_en.z = m_sel.zb ? 1 : 0; m_en.f = m_sel.fb && m_sel.fge ? 1 : 0; m_en.t = m_sel.fb && m_sel.tfx != TFX_NONE ? 1 : 0; - m_en.c = m_sel.fb && m_sel.tfx != TFX_DECAL ? 1 : 0; + m_en.c = m_sel.fb && !(m_sel.tfx == TFX_DECAL && m_sel.tcc) ? 1 : 0; #if _M_AMD64 #error TODO @@ -44,8 +44,6 @@ GSSetupPrimCodeGenerator::GSSetupPrimCodeGenerator(GSScanlineEnvironment& env, U void GSSetupPrimCodeGenerator::Generate() { - const int params = 0; - if((m_en.z || m_en.f) && !m_sel.sprite || m_en.t || m_en.c && m_sel.iip) { for(int i = 0; i < 5; i++) diff --git a/plugins/GSdx/GSSetupPrimCodeGenerator.h b/plugins/GSdx/GSSetupPrimCodeGenerator.h index f12913da7b..af7dd116b8 100644 --- a/plugins/GSdx/GSSetupPrimCodeGenerator.h +++ b/plugins/GSdx/GSSetupPrimCodeGenerator.h @@ -38,7 +38,7 @@ class GSSetupPrimCodeGenerator : public CodeGenerator GSScanlineEnvironment& m_env; GSScanlineSelector m_sel; - struct {DWORD z:1, f:1, t:1, c:1;} m_en; + struct {uint32 z:1, f:1, t:1, c:1;} m_en; void Generate(); @@ -47,5 +47,5 @@ class GSSetupPrimCodeGenerator : public CodeGenerator void Color(); public: - GSSetupPrimCodeGenerator(GSScanlineEnvironment& env, UINT64 key, void* ptr, size_t maxsize); + GSSetupPrimCodeGenerator(GSScanlineEnvironment& env, uint64 key, void* ptr, size_t maxsize); }; \ No newline at end of file diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 11d681a337..197f12d81e 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -22,7 +22,7 @@ #include "stdafx.h" #include "GSState.h" -GSState::GSState(BYTE* base, bool mt, void (*irq)()) +GSState::GSState(uint8* base, bool mt, void (*irq)()) : m_mt(mt) , m_irq(irq) , m_crc(0) @@ -80,7 +80,7 @@ GSState::GSState(BYTE* base, bool mt, void (*irq)()) m_sssize += sizeof(m_tr.x); m_sssize += sizeof(m_tr.y); m_sssize += m_mem.m_vmsize; - m_sssize += (sizeof(m_path[0].tag) + sizeof(m_path[0].nreg)) * 3; + m_sssize += (sizeof(m_path[0].tag) + sizeof(m_path[0].reg)) * 3; m_sssize += sizeof(m_q); ASSERT(base); @@ -202,112 +202,65 @@ void GSState::ResetHandlers() m_fpGIFRegHandlers[GIF_A_D_REG_LABEL] = &GSState::GIFRegHandlerLABEL; } -CPoint GSState::GetDisplayPos(int i) +GSVector4i GSState::GetDisplayRect(int i) { - ASSERT(i >= 0 && i < 2); + if(i < 0) i = IsEnabled(1) ? 1 : 0; - CPoint p; + GSVector4i r; - p.x = m_regs->DISP[i].DISPLAY.DX / (m_regs->DISP[i].DISPLAY.MAGH + 1); - p.y = m_regs->DISP[i].DISPLAY.DY / (m_regs->DISP[i].DISPLAY.MAGV + 1); + r.left = m_regs->DISP[i].DISPLAY.DX / (m_regs->DISP[i].DISPLAY.MAGH + 1); + r.top = m_regs->DISP[i].DISPLAY.DY / (m_regs->DISP[i].DISPLAY.MAGV + 1); + r.right = r.left + (m_regs->DISP[i].DISPLAY.DW + 1) / (m_regs->DISP[i].DISPLAY.MAGH + 1); + r.bottom = r.top + (m_regs->DISP[i].DISPLAY.DH + 1) / (m_regs->DISP[i].DISPLAY.MAGV + 1); - return p; + return r; } -CSize GSState::GetDisplaySize(int i) +GSVector4i GSState::GetFrameRect(int i) { - ASSERT(i >= 0 && i < 2); + if(i < 0) i = IsEnabled(1) ? 1 : 0; - CSize s; + GSVector4i r = GetDisplayRect(i); - s.cx = (m_regs->DISP[i].DISPLAY.DW + 1) / (m_regs->DISP[i].DISPLAY.MAGH + 1); - s.cy = (m_regs->DISP[i].DISPLAY.DH + 1) / (m_regs->DISP[i].DISPLAY.MAGV + 1); + int w = r.width(); + int h = r.height(); - return s; + if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD && h > 1) h >>= 1; + + r.left = m_regs->DISP[i].DISPFB.DBX; + r.top = m_regs->DISP[i].DISPFB.DBY; + r.right = r.left + w; + r.bottom = r.top + h; + + return r; } -CRect GSState::GetDisplayRect(int i) -{ - return CRect(GetDisplayPos(i), GetDisplaySize(i)); -} - -CSize GSState::GetDisplayPos() -{ - return GetDisplayPos(IsEnabled(1) ? 1 : 0); -} - -CSize GSState::GetDisplaySize() -{ - return GetDisplaySize(IsEnabled(1) ? 1 : 0); -} - -CRect GSState::GetDisplayRect() -{ - return GetDisplayRect(IsEnabled(1) ? 1 : 0); -} - -CPoint GSState::GetFramePos(int i) -{ - ASSERT(i >= 0 && i < 2); - - return CPoint(m_regs->DISP[i].DISPFB.DBX, m_regs->DISP[i].DISPFB.DBY); -} - -CSize GSState::GetFrameSize(int i) -{ - CSize s = GetDisplaySize(i); - - if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD && s.cy > 1) s.cy >>= 1; - - return s; -} - -CRect GSState::GetFrameRect(int i) -{ - return CRect(GetFramePos(i), GetFrameSize(i)); -} - -CSize GSState::GetFramePos() -{ - return GetFramePos(IsEnabled(1) ? 1 : 0); -} - -CSize GSState::GetFrameSize() -{ - return GetFrameSize(IsEnabled(1) ? 1 : 0); -} - -CRect GSState::GetFrameRect() -{ - return GetFrameRect(IsEnabled(1) ? 1 : 0); -} - -CSize GSState::GetDeviceSize(int i) +GSVector2i GSState::GetDeviceSize(int i) { // TODO: other params of SMODE1 should affect the true device display size // TODO2: pal games at 60Hz - CSize s = GetDisplaySize(i); + if(i < 0) i = IsEnabled(1) ? 1 : 0; - if(s.cy == 2 * 416 || s.cy == 2 * 448 || s.cy == 2 * 512) + GSVector4i r = GetDisplayRect(i); + + int w = r.width(); + int h = r.height(); + + if(h == 2 * 416 || h == 2 * 448 || h == 2 * 512) { - s.cy /= 2; + h /= 2; } else { - s.cy = (m_regs->SMODE1.CMOD & 1) ? 512 : 448; + h = (m_regs->SMODE1.CMOD & 1) ? 512 : 448; } - return s; + return GSVector2i(w, h); } -CSize GSState::GetDeviceSize() -{ - return GetDeviceSize(IsEnabled(1) ? 1 : 0); -} - bool GSState::IsEnabled(int i) { ASSERT(i >= 0 && i < 2); @@ -326,7 +279,7 @@ bool GSState::IsEnabled(int i) int GSState::GetFPS() { - return ((m_regs->SMODE1.CMOD & 1) ? 50 : 60) / (m_regs->SMODE2.INT ? 1 : 2); + return ((m_regs->SMODE1.CMOD & 1) ? 50 : 60) >> (1 - m_regs->SMODE2.INT); } // GIFPackedRegHandler* @@ -349,12 +302,12 @@ void GSState::GIFPackedRegHandlerRGBA(GIFPackedReg* r) GSVector4i mask = GSVector4i::load(0x0c080400); GSVector4i v = GSVector4i::load(r).shuffle8(mask); - m_v.RGBAQ.ai32[0] = (UINT32)GSVector4i::store(v); + m_v.RGBAQ.u32[0] = (uint32)GSVector4i::store(v); #elif _M_SSE >= 0x200 GSVector4i v = GSVector4i::load(r) & GSVector4i::x000000ff(); - m_v.RGBAQ.ai32[0] = v.rgba32(); + m_v.RGBAQ.u32[0] = v.rgba32(); #else @@ -372,12 +325,12 @@ void GSState::GIFPackedRegHandlerSTQ(GIFPackedReg* r) { #if defined(_M_AMD64) - m_v.ST.i64 = r->ai64[0]; + m_v.ST.u64 = r->u64[0]; #elif _M_SSE >= 0x200 GSVector4i v = GSVector4i::loadl(r); - GSVector4i::storel(&m_v.ST.i64, v); + GSVector4i::storel(&m_v.ST.u64, v); #else @@ -394,7 +347,7 @@ void GSState::GIFPackedRegHandlerUV(GIFPackedReg* r) #if _M_SSE >= 0x200 GSVector4i v = GSVector4i::loadl(r) & GSVector4i::x00003fff(); - m_v.UV.ai32[0] = (UINT32)GSVector4i::store(v.ps32(v)); + m_v.UV.u32[0] = (uint32)GSVector4i::store(v.ps32(v)); #else @@ -425,12 +378,12 @@ void GSState::GIFPackedRegHandlerXYZ2(GIFPackedReg* r) template void GSState::GIFPackedRegHandlerTEX0(GIFPackedReg* r) { - GIFRegHandlerTEX0((GIFReg*)&r->ai64[0]); + GIFRegHandlerTEX0((GIFReg*)&r->u64[0]); } template void GSState::GIFPackedRegHandlerCLAMP(GIFPackedReg* r) { - GIFRegHandlerCLAMP((GIFReg*)&r->ai64[0]); + GIFRegHandlerCLAMP((GIFReg*)&r->u64[0]); } void GSState::GIFPackedRegHandlerFOG(GIFPackedReg* r) @@ -440,25 +393,17 @@ void GSState::GIFPackedRegHandlerFOG(GIFPackedReg* r) void GSState::GIFPackedRegHandlerXYZF3(GIFPackedReg* r) { - GIFRegHandlerXYZF3((GIFReg*)&r->ai64[0]); + GIFRegHandlerXYZF3((GIFReg*)&r->u64[0]); } void GSState::GIFPackedRegHandlerXYZ3(GIFPackedReg* r) { - GIFRegHandlerXYZ3((GIFReg*)&r->ai64[0]); + GIFRegHandlerXYZ3((GIFReg*)&r->u64[0]); } void GSState::GIFPackedRegHandlerA_D(GIFPackedReg* r) { - (this->*m_fpGIFRegHandlers[(BYTE)r->A_D.ADDR])(&r->r); -} - -void GSState::GIFPackedRegHandlerA_D(GIFPackedReg* r, int size) -{ - for(int i = 0; i < size; i++) - { - (this->*m_fpGIFRegHandlers[(BYTE)r[i].A_D.ADDR])(&r[i].r); - } + (this->*m_fpGIFRegHandlers[r->A_D.ADDR])(&r->r); } void GSState::GIFPackedRegHandlerNOP(GIFPackedReg* r) @@ -478,7 +423,7 @@ void GSState::GIFRegHandlerPRIM(GIFReg* r) if(GSUtil::GetPrimClass(m_env.PRIM.PRIM) == GSUtil::GetPrimClass(r->PRIM.PRIM)) { - if(((m_env.PRIM.i64 ^ r->PRIM.i64) & ~7) != 0) + if(((m_env.PRIM.u64 ^ r->PRIM.u64) & ~7) != 0) { Flush(); } @@ -510,7 +455,7 @@ void GSState::GIFRegHandlerST(GIFReg* r) void GSState::GIFRegHandlerUV(GIFReg* r) { - m_v.UV.ai32[0] = r->UV.ai32[0] & 0x3fff3fff; + m_v.UV.u32[0] = r->UV.u32[0] & 0x3fff3fff; } void GSState::GIFRegHandlerXYZF2(GIFReg* r) @@ -521,9 +466,9 @@ void GSState::GIFRegHandlerXYZF2(GIFReg* r) m_v.XYZ.Z = r->XYZF.Z; m_v.FOG.F = r->XYZF.F; */ - m_v.XYZ.ai32[0] = r->XYZF.ai32[0]; - m_v.XYZ.ai32[1] = r->XYZF.ai32[1] & 0x00ffffff; - m_v.FOG.ai32[1] = r->XYZF.ai32[1] & 0xff000000; + m_v.XYZ.u32[0] = r->XYZF.u32[0]; + m_v.XYZ.u32[1] = r->XYZF.u32[1] & 0x00ffffff; + m_v.FOG.u32[1] = r->XYZF.u32[1] & 0xff000000; VertexKick(false); } @@ -541,7 +486,7 @@ template void GSState::GIFRegHandlerTEX0(GIFReg* r) bool wt = m_mem.m_clut.WriteTest(r->TEX0, m_env.TEXCLUT); - if(wt || PRIM->CTXT == i && !(m_env.CTXT[i].TEX0 == (GSVector4i)r->TEX0).alltrue()) + if(wt || PRIM->CTXT == i && r->TEX0 != m_env.CTXT[i].TEX0) { Flush(); } @@ -566,7 +511,7 @@ template void GSState::GIFRegHandlerTEX0(GIFReg* r) template void GSState::GIFRegHandlerCLAMP(GIFReg* r) { - if(PRIM->CTXT == i && !(m_env.CTXT[i].CLAMP == (GSVector4i)r->CLAMP).alltrue()) + if(PRIM->CTXT == i && r->CLAMP != m_env.CTXT[i].CLAMP) { Flush(); } @@ -587,9 +532,9 @@ void GSState::GIFRegHandlerXYZF3(GIFReg* r) m_v.XYZ.Z = r->XYZF.Z; m_v.FOG.F = r->XYZF.F; */ - m_v.XYZ.ai32[0] = r->XYZF.ai32[0]; - m_v.XYZ.ai32[1] = r->XYZF.ai32[1] & 0x00ffffff; - m_v.FOG.ai32[1] = r->XYZF.ai32[1] & 0xff000000; + m_v.XYZ.u32[0] = r->XYZF.u32[0]; + m_v.XYZ.u32[1] = r->XYZF.u32[1] & 0x00ffffff; + m_v.FOG.u32[1] = r->XYZF.u32[1] & 0xff000000; VertexKick(true); } @@ -607,7 +552,7 @@ void GSState::GIFRegHandlerNOP(GIFReg* r) template void GSState::GIFRegHandlerTEX1(GIFReg* r) { - if(PRIM->CTXT == i && !(m_env.CTXT[i].TEX1 == (GSVector4i)r->TEX1).alltrue()) + if(PRIM->CTXT == i && r->TEX1 != m_env.CTXT[i].TEX1) { Flush(); } @@ -619,9 +564,9 @@ template void GSState::GIFRegHandlerTEX2(GIFReg* r) { // m_env.CTXT[i].TEX2 = r->TEX2; // not used - UINT64 mask = 0xFFFFFFE003F00000ui64; // TEX2 bits + uint64 mask = 0xFFFFFFE003F00000ui64; // TEX2 bits - r->i64 = (r->i64 & mask) | (m_env.CTXT[i].TEX0.i64 & ~mask); + r->u64 = (r->u64 & mask) | (m_env.CTXT[i].TEX0.u64 & ~mask); GIFRegHandlerTEX0(r); } @@ -630,7 +575,7 @@ template void GSState::GIFRegHandlerXYOFFSET(GIFReg* r) { GSVector4i o = (GSVector4i)r->XYOFFSET & GSVector4i::x0000ffff(); - if(!(m_env.CTXT[i].XYOFFSET == o).alltrue()) + if(!o.eq(m_env.CTXT[i].XYOFFSET)) { Flush(); } @@ -642,7 +587,7 @@ template void GSState::GIFRegHandlerXYOFFSET(GIFReg* r) void GSState::GIFRegHandlerPRMODECONT(GIFReg* r) { - if(!(m_env.PRMODECONT == (GSVector4i)r->PRMODECONT).alltrue()) + if(r->PRMODECONT != m_env.PRMODECONT) { Flush(); } @@ -651,7 +596,7 @@ void GSState::GIFRegHandlerPRMODECONT(GIFReg* r) PRIM = m_env.PRMODECONT.AC ? &m_env.PRIM : (GIFRegPRIM*)&m_env.PRMODE; - if(PRIM->PRIM == 7) TRACE(_T("Invalid PRMODECONT/PRIM\n")); + // if(PRIM->PRIM == 7) printf("Invalid PRMODECONT/PRIM\n"); m_context = &m_env.CTXT[PRIM->CTXT]; @@ -665,7 +610,7 @@ void GSState::GIFRegHandlerPRMODE(GIFReg* r) Flush(); } - UINT32 _PRIM = m_env.PRMODE._PRIM; + uint32 _PRIM = m_env.PRMODE._PRIM; m_env.PRMODE = (GSVector4i)r->PRMODE; m_env.PRMODE._PRIM = _PRIM; @@ -676,7 +621,7 @@ void GSState::GIFRegHandlerPRMODE(GIFReg* r) void GSState::GIFRegHandlerTEXCLUT(GIFReg* r) { - if(!(m_env.TEXCLUT == (GSVector4i)r->TEXCLUT).alltrue()) + if(r->TEXCLUT != m_env.TEXCLUT) { Flush(); } @@ -686,7 +631,7 @@ void GSState::GIFRegHandlerTEXCLUT(GIFReg* r) void GSState::GIFRegHandlerSCANMSK(GIFReg* r) { - if(!(m_env.SCANMSK == (GSVector4i)r->SCANMSK).alltrue()) + if(r->SCANMSK != m_env.SCANMSK) { Flush(); } @@ -696,7 +641,7 @@ void GSState::GIFRegHandlerSCANMSK(GIFReg* r) template void GSState::GIFRegHandlerMIPTBP1(GIFReg* r) { - if(PRIM->CTXT == i && !(m_env.CTXT[i].MIPTBP1 == (GSVector4i)r->MIPTBP1).alltrue()) + if(PRIM->CTXT == i && r->MIPTBP1 != m_env.CTXT[i].MIPTBP1) { Flush(); } @@ -706,7 +651,7 @@ template void GSState::GIFRegHandlerMIPTBP1(GIFReg* r) template void GSState::GIFRegHandlerMIPTBP2(GIFReg* r) { - if(PRIM->CTXT == i && !(m_env.CTXT[i].MIPTBP2 == (GSVector4i)r->MIPTBP2).alltrue()) + if(PRIM->CTXT == i && r->MIPTBP2 != m_env.CTXT[i].MIPTBP2) { Flush(); } @@ -716,7 +661,7 @@ template void GSState::GIFRegHandlerMIPTBP2(GIFReg* r) void GSState::GIFRegHandlerTEXA(GIFReg* r) { - if(!(m_env.TEXA == (GSVector4i)r->TEXA).alltrue()) + if(r->TEXA != m_env.TEXA) { Flush(); } @@ -726,7 +671,7 @@ void GSState::GIFRegHandlerTEXA(GIFReg* r) void GSState::GIFRegHandlerFOGCOL(GIFReg* r) { - if(!(m_env.FOGCOL == (GSVector4i)r->FOGCOL).alltrue()) + if(r->FOGCOL != m_env.FOGCOL) { Flush(); } @@ -743,7 +688,7 @@ void GSState::GIFRegHandlerTEXFLUSH(GIFReg* r) template void GSState::GIFRegHandlerSCISSOR(GIFReg* r) { - if(PRIM->CTXT == i && !(m_env.CTXT[i].SCISSOR == (GSVector4i)r->SCISSOR).alltrue()) + if(PRIM->CTXT == i && r->SCISSOR != m_env.CTXT[i].SCISSOR) { Flush(); } @@ -760,7 +705,7 @@ template void GSState::GIFRegHandlerALPHA(GIFReg* r) ASSERT(r->ALPHA.C != 3); ASSERT(r->ALPHA.D != 3); - if(PRIM->CTXT == i && !(m_env.CTXT[i].ALPHA == (GSVector4i)r->ALPHA).alltrue()) + if(PRIM->CTXT == i && r->ALPHA != m_env.CTXT[i].ALPHA) { Flush(); } @@ -769,14 +714,14 @@ template void GSState::GIFRegHandlerALPHA(GIFReg* r) // A/B/C/D == 3? => 2 - m_env.CTXT[i].ALPHA.ai32[0] = ((~m_env.CTXT[i].ALPHA.ai32[0] >> 1) | 0xAA) & m_env.CTXT[i].ALPHA.ai32[0]; + m_env.CTXT[i].ALPHA.u32[0] = ((~m_env.CTXT[i].ALPHA.u32[0] >> 1) | 0xAA) & m_env.CTXT[i].ALPHA.u32[0]; } void GSState::GIFRegHandlerDIMX(GIFReg* r) { bool update = false; - if(!(m_env.DIMX == (GSVector4i)r->DIMX).alltrue()) + if(r->DIMX != m_env.DIMX) { Flush(); @@ -793,7 +738,7 @@ void GSState::GIFRegHandlerDIMX(GIFReg* r) void GSState::GIFRegHandlerDTHE(GIFReg* r) { - if(!(m_env.DTHE == (GSVector4i)r->DTHE).alltrue()) + if(r->DTHE != m_env.DTHE) { Flush(); } @@ -803,7 +748,7 @@ void GSState::GIFRegHandlerDTHE(GIFReg* r) void GSState::GIFRegHandlerCOLCLAMP(GIFReg* r) { - if(!(m_env.COLCLAMP == (GSVector4i)r->COLCLAMP).alltrue()) + if(r->COLCLAMP != m_env.COLCLAMP) { Flush(); } @@ -813,7 +758,7 @@ void GSState::GIFRegHandlerCOLCLAMP(GIFReg* r) template void GSState::GIFRegHandlerTEST(GIFReg* r) { - if(PRIM->CTXT == i && !(m_env.CTXT[i].TEST == (GSVector4i)r->TEST).alltrue()) + if(PRIM->CTXT == i && r->TEST != m_env.CTXT[i].TEST) { Flush(); } @@ -823,7 +768,7 @@ template void GSState::GIFRegHandlerTEST(GIFReg* r) void GSState::GIFRegHandlerPABE(GIFReg* r) { - if(!(m_env.PABE == (GSVector4i)r->PABE).alltrue()) + if(r->PABE != m_env.PABE) { Flush(); } @@ -833,7 +778,7 @@ void GSState::GIFRegHandlerPABE(GIFReg* r) template void GSState::GIFRegHandlerFBA(GIFReg* r) { - if(PRIM->CTXT == i && !(m_env.CTXT[i].FBA == (GSVector4i)r->FBA).alltrue()) + if(PRIM->CTXT == i && r->FBA != m_env.CTXT[i].FBA) { Flush(); } @@ -843,7 +788,7 @@ template void GSState::GIFRegHandlerFBA(GIFReg* r) template void GSState::GIFRegHandlerFRAME(GIFReg* r) { - if(PRIM->CTXT == i && !(m_env.CTXT[i].FRAME == (GSVector4i)r->FRAME).alltrue()) + if(PRIM->CTXT == i && r->FRAME != m_env.CTXT[i].FRAME) { Flush(); } @@ -853,7 +798,7 @@ template void GSState::GIFRegHandlerFRAME(GIFReg* r) template void GSState::GIFRegHandlerZBUF(GIFReg* r) { - if(r->ZBUF.ai32[0] == 0) + if(r->ZBUF.u32[0] == 0) { // during startup all regs are cleared to 0 (by the bios or something), so we mask z until this register becomes valid @@ -862,7 +807,7 @@ template void GSState::GIFRegHandlerZBUF(GIFReg* r) r->ZBUF.PSM |= 0x30; - if(PRIM->CTXT == i && !(m_env.CTXT[i].ZBUF == (GSVector4i)r->ZBUF).alltrue()) + if(PRIM->CTXT == i && r->ZBUF != m_env.CTXT[i].ZBUF) { Flush(); } @@ -880,7 +825,7 @@ template void GSState::GIFRegHandlerZBUF(GIFReg* r) void GSState::GIFRegHandlerBITBLTBUF(GIFReg* r) { - if(!(m_env.BITBLTBUF == (GSVector4i)r->BITBLTBUF).alltrue()) + if(r->BITBLTBUF != m_env.BITBLTBUF) { FlushWrite(); } @@ -900,7 +845,7 @@ void GSState::GIFRegHandlerBITBLTBUF(GIFReg* r) void GSState::GIFRegHandlerTRXPOS(GIFReg* r) { - if(!(m_env.TRXPOS == (GSVector4i)r->TRXPOS).alltrue()) + if(r->TRXPOS != m_env.TRXPOS) { FlushWrite(); } @@ -910,7 +855,7 @@ void GSState::GIFRegHandlerTRXPOS(GIFReg* r) void GSState::GIFRegHandlerTRXREG(GIFReg* r) { - if(!(m_env.TRXREG == (GSVector4i)r->TRXREG).alltrue()) + if(r->TRXREG != m_env.TRXREG) { FlushWrite(); } @@ -945,7 +890,7 @@ void GSState::GIFRegHandlerHWREG(GIFReg* r) { ASSERT(m_env.TRXDIR.XDIR == 0); // host => local - Write((BYTE*)r, 8); // hunting ground + Write((uint8*)r, 8); // hunting ground } void GSState::GIFRegHandlerSIGNAL(GIFReg* r) @@ -998,7 +943,7 @@ void GSState::FlushWrite() m_perfmon.Put(GSPerfMon::Swizzle, len); - CRect r; + GSVector4i r; r.left = m_env.TRXPOS.DSAX; r.top = y; @@ -1008,48 +953,74 @@ void GSState::FlushWrite() InvalidateVideoMem(m_env.BITBLTBUF, r); /* static int n = 0; - CString str; - str.Format(_T("c:\\temp1\\[%04d]_%05x_%d_%d_%d_%d_%d_%d.bmp"), + string s; + s = format("c:\\temp1\\[%04d]_%05x_%d_%d_%d_%d_%d_%d.bmp", n++, (int)m_env.BITBLTBUF.DBP, (int)m_env.BITBLTBUF.DBW, (int)m_env.BITBLTBUF.DPSM, r.left, r.top, r.right, r.bottom); - m_mem.SaveBMP(str, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW, m_env.BITBLTBUF.DPSM, r.right, r.bottom); + m_mem.SaveBMP(s, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW, m_env.BITBLTBUF.DPSM, r.right, r.bottom); */ } // -void GSState::Write(BYTE* mem, int len) +void GSState::Write(uint8* mem, int len) { - int dx = m_env.TRXPOS.DSAX; - int dy = m_env.TRXPOS.DSAY; int w = m_env.TRXREG.RRW; int h = m_env.TRXREG.RRH; - // TRACE(_T("Write len=%d DBP=%05x DBW=%d DPSM=%d DSAX=%d DSAY=%d RRW=%d RRH=%d\n"), len, (int)m_env.BITBLTBUF.DBP, (int)m_env.BITBLTBUF.DBW, (int)m_env.BITBLTBUF.DPSM, dx, dy, w, h); + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM]; - if(!m_tr.Update(w, h, GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].trbpp, len)) + // printf("Write len=%d DBP=%05x DBW=%d DPSM=%d DSAX=%d DSAY=%d RRW=%d RRH=%d\n", len, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW, m_env.BITBLTBUF.DPSM, m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, m_env.TRXREG.RRW, m_env.TRXREG.RRH); + + if(!m_tr.Update(w, h, psm.trbpp, len)) { return; } - memcpy(&m_tr.buff[m_tr.end], mem, len); - - m_tr.end += len; - if(PRIM->TME && (m_env.BITBLTBUF.DBP == m_context->TEX0.TBP0 || m_env.BITBLTBUF.DBP == m_context->TEX0.CBP)) // TODO: hmmmm { FlushPrim(); } - if(m_tr.end >= m_tr.total) + if(m_tr.end == 0 && len >= m_tr.total) { - FlushWrite(); + // received all data in one piece, no need to buffer it + + // printf("%d >= %d\n", len, m_tr.total); + + (m_mem.*psm.wi)(m_tr.x, m_tr.y, mem, m_tr.total, m_env.BITBLTBUF, m_env.TRXPOS, m_env.TRXREG); + + m_tr.start = m_tr.end = m_tr.total; + + m_perfmon.Put(GSPerfMon::Swizzle, len); + + GSVector4i r; + + r.left = m_env.TRXPOS.DSAX; + r.top = m_env.TRXPOS.DSAY; + r.right = r.left + m_env.TRXREG.RRW; + r.bottom = r.top + m_env.TRXREG.RRH; + + InvalidateVideoMem(m_env.BITBLTBUF, r); + } + else + { + // printf("%d += %d (%d)\n", m_tr.end, len, m_tr.total); + + memcpy(&m_tr.buff[m_tr.end], mem, len); + + m_tr.end += len; + + if(m_tr.end >= m_tr.total) + { + FlushWrite(); + } } m_mem.m_clut.Invalidate(); } -void GSState::Read(BYTE* mem, int len) +void GSState::Read(uint8* mem, int len) { if(len <= 0) return; @@ -1058,7 +1029,7 @@ void GSState::Read(BYTE* mem, int len) int w = m_env.TRXREG.RRW; int h = m_env.TRXREG.RRH; - // TRACE(_T("Read len=%d SBP=%05x SBW=%d SPSM=%d SSAX=%d SSAY=%d RRW=%d RRH=%d\n"), len, (int)m_env.BITBLTBUF.SBP, (int)m_env.BITBLTBUF.SBW, (int)m_env.BITBLTBUF.SPSM, sx, sy, w, h); + // printf("Read len=%d SBP=%05x SBW=%d SPSM=%d SSAX=%d SSAY=%d RRW=%d RRH=%d\n", len, (int)m_env.BITBLTBUF.SBP, (int)m_env.BITBLTBUF.SBW, (int)m_env.BITBLTBUF.SPSM, sx, sy, w, h); if(!m_tr.Update(w, h, GSLocalMemory::m_psm[m_env.BITBLTBUF.SPSM].trbpp, len)) { @@ -1067,7 +1038,7 @@ void GSState::Read(BYTE* mem, int len) if(m_tr.x == sx && m_tr.y == sy) { - InvalidateLocalMem(m_env.BITBLTBUF, CRect(CPoint(sx, sy), CSize(w, h))); + InvalidateLocalMem(m_env.BITBLTBUF, GSVector4i(sx, sy, sx + w, sy + h)); } m_mem.ReadImageX(m_tr.x, m_tr.y, mem, len, m_env.BITBLTBUF, m_env.TRXPOS, m_env.TRXREG); @@ -1085,15 +1056,21 @@ void GSState::Move() int w = m_env.TRXREG.RRW; int h = m_env.TRXREG.RRH; - InvalidateLocalMem(m_env.BITBLTBUF, CRect(CPoint(sx, sy), CSize(w, h))); - InvalidateVideoMem(m_env.BITBLTBUF, CRect(CPoint(dx, dy), CSize(w, h))); + InvalidateLocalMem(m_env.BITBLTBUF, GSVector4i(sx, sy, sx + w, sy + h)); + InvalidateVideoMem(m_env.BITBLTBUF, GSVector4i(dx, dy, dx + w, dy + h)); int xinc = 1; int yinc = 1; - if(sx < dx) {sx += w - 1; dx += w - 1; xinc = -1;} - if(sy < dy) {sy += h - 1; dy += h - 1; yinc = -1;} - + if(m_env.TRXPOS.DIRX) {sx += w - 1; dx += w - 1; xinc = -1;} + if(m_env.TRXPOS.DIRY) {sy += h - 1; dy += h - 1; yinc = -1;} +/* + printf("%05x %d %d => %05x %d %d (%d%d), %d %d %d %d %d %d\n", + m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW, m_env.BITBLTBUF.SPSM, + m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW, m_env.BITBLTBUF.DPSM, + m_env.TRXPOS.DIRX, m_env.TRXPOS.DIRY, + sx, sy, dx, dy, w, h); +*/ /* GSLocalMemory::readPixel rp = GSLocalMemory::m_psm[m_env.BITBLTBUF.SPSM].rp; GSLocalMemory::writePixel wp = GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].wp; @@ -1106,19 +1083,82 @@ void GSState::Move() const GSLocalMemory::psm_t& spsm = GSLocalMemory::m_psm[m_env.BITBLTBUF.SPSM]; const GSLocalMemory::psm_t& dpsm = GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM]; - if(m_env.BITBLTBUF.SPSM == PSM_PSMCT32 && m_env.BITBLTBUF.DPSM == PSM_PSMCT32) + // TODO: unroll inner loops (width has special size requirement, must be multiples of 1 << n, depending on the format) + + if(spsm.trbpp == dpsm.trbpp && spsm.trbpp >= 16) + { + int* soffset = spsm.rowOffset[0]; + int* doffset = dpsm.rowOffset[0]; + + if(spsm.trbpp == 32) + { + for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w) + { + uint32 sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW); + uint32 dbase = dpsm.pa(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW); + + for(int x = 0; x < w; x++, sx += xinc, dx += xinc) + { + m_mem.WritePixel32(dbase + doffset[dx], m_mem.ReadPixel32(sbase + soffset[sx])); + } + } + } + else if(spsm.trbpp == 24) + { + for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w) + { + uint32 sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW); + uint32 dbase = dpsm.pa(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW); + + for(int x = 0; x < w; x++, sx += xinc, dx += xinc) + { + m_mem.WritePixel24(dbase + doffset[dx], m_mem.ReadPixel24(sbase + soffset[sx])); + } + } + } + else // if(spsm.trbpp == 16) + { + for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w) + { + uint32 sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW); + uint32 dbase = dpsm.pa(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW); + + for(int x = 0; x < w; x++, sx += xinc, dx += xinc) + { + m_mem.WritePixel16(dbase + doffset[dx], m_mem.ReadPixel16(sbase + soffset[sx])); + } + } + } + } + else if(m_env.BITBLTBUF.SPSM == PSM_PSMT8 && m_env.BITBLTBUF.DPSM == PSM_PSMT8) { for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w) { - DWORD sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW); + uint32 sbase = GSLocalMemory::PixelAddress8(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW); int* soffset = spsm.rowOffset[sy & 7]; - DWORD dbase = dpsm.pa(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW); + uint32 dbase = GSLocalMemory::PixelAddress8(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW); int* doffset = dpsm.rowOffset[dy & 7]; for(int x = 0; x < w; x++, sx += xinc, dx += xinc) { - m_mem.WritePixel32(dbase + doffset[dx], m_mem.ReadPixel32(sbase + soffset[sx])); + m_mem.WritePixel8(dbase + doffset[dx], m_mem.ReadPixel8(sbase + soffset[sx])); + } + } + } + else if(m_env.BITBLTBUF.SPSM == PSM_PSMT4 && m_env.BITBLTBUF.DPSM == PSM_PSMT4) + { + for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w) + { + uint32 sbase = GSLocalMemory::PixelAddress4(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW); + int* soffset = spsm.rowOffset[sy & 7]; + + uint32 dbase = GSLocalMemory::PixelAddress4(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW); + int* doffset = dpsm.rowOffset[dy & 7]; + + for(int x = 0; x < w; x++, sx += xinc, dx += xinc) + { + m_mem.WritePixel4(dbase + doffset[dx], m_mem.ReadPixel4(sbase + soffset[sx])); } } } @@ -1126,10 +1166,10 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w) { - DWORD sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW); + uint32 sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW); int* soffset = spsm.rowOffset[sy & 7]; - DWORD dbase = dpsm.pa(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW); + uint32 dbase = dpsm.pa(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW); int* doffset = dpsm.rowOffset[dy & 7]; for(int x = 0; x < w; x++, sx += xinc, dx += xinc) @@ -1140,7 +1180,7 @@ void GSState::Move() } } -void GSState::SoftReset(BYTE mask) +void GSState::SoftReset(uint32 mask) { if(mask & 1) memset(&m_path[0], 0, sizeof(GIFPath)); if(mask & 2) memset(&m_path[1], 0, sizeof(GIFPath)); @@ -1151,7 +1191,7 @@ void GSState::SoftReset(BYTE mask) m_q = 1; } -void GSState::ReadFIFO(BYTE* mem, int size) +void GSState::ReadFIFO(uint8* mem, int size) { GSPerfMonAutoTimer pmat(m_perfmon); @@ -1167,21 +1207,21 @@ void GSState::ReadFIFO(BYTE* mem, int size) } } -template void GSState::Transfer<0>(BYTE* mem, UINT32 size); -template void GSState::Transfer<1>(BYTE* mem, UINT32 size); -template void GSState::Transfer<2>(BYTE* mem, UINT32 size); +template void GSState::Transfer<0>(uint8* mem, uint32 size); +template void GSState::Transfer<1>(uint8* mem, uint32 size); +template void GSState::Transfer<2>(uint8* mem, uint32 size); -template void GSState::Transfer(BYTE* mem, UINT32 size) +template void GSState::Transfer(uint8* mem, uint32 size) { GSPerfMonAutoTimer pmat(m_perfmon); - BYTE* start = mem; + uint8* start = mem; GIFPath& path = m_path[index]; while(size > 0) { - if(path.tag.NLOOP == 0) + if(path.nloop == 0) { path.SetTag(mem); @@ -1193,20 +1233,17 @@ template void GSState::Transfer(BYTE* mem, UINT32 size) m_path3hack = 1; } - if(path.tag.NLOOP > 0) // eeuser 7.2.2. GIFtag: "... when NLOOP is 0, the GIF does not output anything, and values other than the EOP field are disregarded." + if(path.nloop > 0) // eeuser 7.2.2. GIFtag: "... when NLOOP is 0, the GIF does not output anything, and values other than the EOP field are disregarded." { m_q = 1.0f; - if(path.tag.PRE) - { - ASSERT(path.tag.FLG != GIF_FLG_IMAGE); // kingdom hearts, ffxii, tales of abyss, berserk + // ASSERT(!(path.tag.PRE && path.tag.FLG == GIF_FLG_REGLIST)); // kingdom hearts - if((path.tag.FLG & 2) == 0) - { - GIFReg r; - r.i64 = path.tag.PRIM; - (this->*m_fpGIFRegHandlers[GIF_A_D_REG_PRIM])(&r); - } + if(path.tag.PRE && path.tag.FLG == GIF_FLG_PACKED) + { + GIFReg r; + r.u64 = path.tag.PRIM; + GIFRegHandlerPRIM(&r); } } } @@ -1218,37 +1255,44 @@ template void GSState::Transfer(BYTE* mem, UINT32 size) // first try a shortcut for a very common case - if(path.nreg == 0 && path.tag.NREG == 1 && size >= path.tag.NLOOP && path.GetReg() == GIF_REG_A_D) + if(path.adonly && size >= path.nloop) { - int n = path.tag.NLOOP; + size -= path.nloop; - GIFPackedRegHandlerA_D((GIFPackedReg*)mem, n); + do + { + (this->*m_fpGIFRegHandlers[((GIFPackedReg*)mem)->A_D.ADDR])(&((GIFPackedReg*)mem)->r); - mem += n * sizeof(GIFPackedReg); - size -= n; - - path.tag.NLOOP = 0; + mem += sizeof(GIFPackedReg); + } + while(--path.nloop > 0); } else { - while(size > 0) + do { - (this->*m_fpGIFPackedRegHandlers[path.GetReg()])((GIFPackedReg*)mem); + uint32 reg = path.GetReg(); - size--; - mem += sizeof(GIFPackedReg); - - if((++path.nreg & 0xf) == path.tag.NREG) + switch(reg) { - path.nreg = 0; - path.tag.NLOOP--; - - if(path.tag.NLOOP == 0) - { - break; - } + case GIF_REG_RGBA: + GIFPackedRegHandlerRGBA((GIFPackedReg*)mem); + break; + case GIF_REG_STQ: + GIFPackedRegHandlerSTQ((GIFPackedReg*)mem); + break; + case GIF_REG_UV: + GIFPackedRegHandlerUV((GIFPackedReg*)mem); + break; + default: + (this->*m_fpGIFPackedRegHandlers[reg])((GIFPackedReg*)mem); + break; } + + mem += sizeof(GIFPackedReg); + size--; } + while(path.StepReg() && size > 0); } break; @@ -1257,24 +1301,14 @@ template void GSState::Transfer(BYTE* mem, UINT32 size) size *= 2; - while(size > 0) + do { (this->*m_fpGIFRegHandlers[path.GetReg()])((GIFReg*)mem); - size--; mem += sizeof(GIFReg); - - if((++path.nreg & 0xf) == path.tag.NREG) - { - path.nreg = 0; - path.tag.NLOOP--; - - if(path.tag.NLOOP == 0) - { - break; - } - } + size--; } + while(path.StepReg() && size > 0); if(size & 1) mem += sizeof(GIFReg); @@ -1286,13 +1320,14 @@ template void GSState::Transfer(BYTE* mem, UINT32 size) ASSERT(0); - path.tag.NLOOP = 0; + path.nloop = 0; break; case GIF_FLG_IMAGE: + { - int len = (int)min(size, path.tag.NLOOP); + int len = (int)min(size, path.nloop); //ASSERT(!(len&3)); @@ -1315,7 +1350,7 @@ template void GSState::Transfer(BYTE* mem, UINT32 size) } mem += len * 16; - path.tag.NLOOP -= len; + path.nloop -= len; size -= len; } @@ -1328,7 +1363,7 @@ template void GSState::Transfer(BYTE* mem, UINT32 size) if(index == 0) { - if(path.tag.EOP && path.tag.NLOOP == 0) + if(path.tag.EOP && path.nloop == 0) { break; } @@ -1342,13 +1377,13 @@ template void GSState::Transfer(BYTE* mem, UINT32 size) if(index == 0) { - if(size == 0 && path.tag.NLOOP > 0) + if(size == 0 && path.nloop > 0) { if(m_mt) { // TODO - path.tag.NLOOP = 0; + path.nloop = 0; } else { @@ -1358,13 +1393,13 @@ template void GSState::Transfer(BYTE* mem, UINT32 size) } } -template static void WriteState(BYTE*& dst, T* src, size_t len = sizeof(T)) +template static void WriteState(uint8*& dst, T* src, size_t len = sizeof(T)) { memcpy(dst, src, len); dst += len; } -template static void ReadState(T* dst, BYTE*& src, size_t len = sizeof(T)) +template static void ReadState(T* dst, uint8*& src, size_t len = sizeof(T)) { memcpy(dst, src, len); src += len; @@ -1385,7 +1420,7 @@ int GSState::Freeze(GSFreezeData* fd, bool sizeonly) Flush(); - BYTE* data = fd->data; + uint8* data = fd->data; WriteState(data, &m_version); WriteState(data, &m_env.PRIM); @@ -1433,8 +1468,11 @@ int GSState::Freeze(GSFreezeData* fd, bool sizeonly) for(int i = 0; i < 3; i++) { + m_path[i].tag.NREG = m_path[i].nreg; + m_path[i].tag.NLOOP = m_path[i].nloop; + WriteState(data, &m_path[i].tag); - WriteState(data, &m_path[i].nreg); + WriteState(data, &m_path[i].reg); } WriteState(data, &m_q); @@ -1454,7 +1492,7 @@ int GSState::Defrost(const GSFreezeData* fd) return -1; } - BYTE* data = fd->data; + uint8* data = fd->data; int version; @@ -1507,7 +1545,7 @@ int GSState::Defrost(const GSFreezeData* fd) if(version <= 4) { - data += sizeof(DWORD) * 7; // skip + data += sizeof(uint32) * 7; // skip } } @@ -1525,7 +1563,7 @@ int GSState::Defrost(const GSFreezeData* fd) for(int i = 0; i < 3; i++) { ReadState(&m_path[i].tag, data); - ReadState(&m_path[i].nreg, data); + ReadState(&m_path[i].reg, data); m_path[i].SetTag(&m_path[i].tag); // expand regs } @@ -1548,7 +1586,7 @@ m_perfmon.SetFrame(5000); return 0; } -void GSState::SetGameCRC(DWORD crc, int options) +void GSState::SetGameCRC(uint32 crc, int options) { m_crc = crc; m_options = options; @@ -1620,7 +1658,7 @@ GSState::GSTransferBuffer::GSTransferBuffer() { x = y = 0; start = end = total = 0; - buff = (BYTE*)_aligned_malloc(1024 * 1024 * 4, 16); + buff = (uint8*)_aligned_malloc(1024 * 1024 * 4, 16); } GSState::GSTransferBuffer::~GSTransferBuffer() @@ -1665,12 +1703,12 @@ bool GSState::GSTransferBuffer::Update(int tw, int th, int bpp, int& len) struct GSFrameInfo { - DWORD FBP; - DWORD FPSM; - DWORD FBMSK; + uint32 FBP; + uint32 FPSM; + uint32 FBMSK; + uint32 TBP0; + uint32 TPSM; bool TME; - DWORD TBP0; - DWORD TPSM; }; typedef bool (*GetSkipCount)(const GSFrameInfo& fi, int& skip); @@ -1757,9 +1795,9 @@ bool GSC_SFEX3(const GSFrameInfo& fi, int& skip) { if(skip == 0) { - if(fi.TME && fi.FBP == 0x00f00 && fi.FPSM == PSM_PSMCT16 && (fi.TBP0 == 0x00500 || fi.TBP0 == 0x00000) && fi.TPSM == PSM_PSMCT32) + if(fi.TME && fi.FBP == 0x00500 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x00f00 && fi.TPSM == PSM_PSMCT16) { - skip = 4; + skip = 2; // blur } } @@ -2063,14 +2101,21 @@ bool GSC_GodOfWar2(const GSFrameInfo& fi, int& skip) { if(skip == 0) { - if(fi.TME && fi.FBP == 0x00100 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x00100 && fi.TPSM == PSM_PSMCT16 // ntsc - || fi.TME && fi.FBP == 0x02100 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x02100 && fi.TPSM == PSM_PSMCT16) // pal + if(fi.TME) { - skip = 29; // shadows - } - else if(fi.TME && fi.FBP == 0x00500 && fi.FPSM == PSM_PSMCT24 && fi.TBP0 == 0x02100 && fi.TPSM == PSM_PSMCT32) // pal - { - // skip = 17; // only looks correct at native resolution + if(fi.FBP == 0x00100 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x00100 && fi.TPSM == PSM_PSMCT16 // ntsc + || fi.FBP == 0x02100 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x02100 && fi.TPSM == PSM_PSMCT16) // pal + { + skip = 29; // shadows + } + else if(fi.FBP == 0x00500 && fi.FPSM == PSM_PSMCT24 && fi.TBP0 == 0x02100 && fi.TPSM == PSM_PSMCT32) // pal + { + // skip = 17; // only looks correct at native resolution + } + else if(fi.FBP == 0x01300 && fi.FPSM == PSM_PSMCT24 && fi.TBP0 == 0x00100 && fi.TPSM == PSM_PSMCT32) // ntsc + { + // skip = 15; // only looks correct at native resolution + } } } else @@ -2130,6 +2175,42 @@ bool GSC_TalesOfAbyss(const GSFrameInfo& fi, int& skip) return true; } +bool GSC_SonicUnleashed(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x02200 && fi.FPSM == PSM_PSMCT16S && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT16) + { + skip = 1000; // shadow + } + } + else + { + if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x02200 && fi.TPSM == PSM_PSMCT16S) + { + skip = 2; + } + } + + return true; +} + +bool GSC_Genji(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x01500 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x00e00 && fi.TPSM == PSM_PSMZ16) + { + skip = 6; // + } + } + else + { + } + + return true; +} + bool GSState::IsBadFrame(int& skip) { GSFrameInfo fi; @@ -2175,6 +2256,8 @@ bool GSState::IsBadFrame(int& skip) map[CRC::GiTS] = GSC_GiTS; map[CRC::Onimusha3] = GSC_Onimusha3; map[CRC::TalesOfAbyss] = GSC_TalesOfAbyss; + map[CRC::SonicUnleashed] = GSC_SonicUnleashed; + map[CRC::Genji] = GSC_Genji; } // TODO: just set gsc in SetGameCRC once diff --git a/plugins/GSdx/GSState.h b/plugins/GSdx/GSState.h index 5aeb4fe202..0f7163aa0b 100644 --- a/plugins/GSdx/GSState.h +++ b/plugins/GSdx/GSState.h @@ -55,7 +55,6 @@ class GSState : public GSAlignedClass<16> void GIFPackedRegHandlerXYZF3(GIFPackedReg* r); void GIFPackedRegHandlerXYZ3(GIFPackedReg* r); void GIFPackedRegHandlerA_D(GIFPackedReg* r); - void GIFPackedRegHandlerA_D(GIFPackedReg* r, int size); void GIFPackedRegHandlerNOP(GIFPackedReg* r); typedef void (GSState::*GIFRegHandler)(GIFReg* r); @@ -118,7 +117,7 @@ class GSState : public GSAlignedClass<16> int x, y; int start, end, total; bool overflow; - BYTE* buff; + uint8* buff; GSTransferBuffer(); virtual ~GSTransferBuffer(); @@ -205,58 +204,49 @@ public: GSDrawingContext* m_context; GSVertex m_v; float m_q; - DWORD m_vprim; + uint32 m_vprim; GSPerfMon m_perfmon; - DWORD m_crc; + uint32 m_crc; int m_options; int m_frameskip; CRC::Game m_game; GSDump m_dump; public: - GSState(BYTE* base, bool mt, void (*irq)()); + GSState(uint8* base, bool mt, void (*irq)()); virtual ~GSState(); void ResetHandlers(); - CPoint GetDisplayPos(int i); - CSize GetDisplaySize(int i); - CRect GetDisplayRect(int i); - CSize GetDisplayPos(); - CSize GetDisplaySize(); - CRect GetDisplayRect(); - CPoint GetFramePos(int i); - CSize GetFrameSize(int i); - CRect GetFrameRect(int i); - CSize GetFramePos(); - CSize GetFrameSize(); - CRect GetFrameRect(); - CSize GetDeviceSize(int i); - CSize GetDeviceSize(); + GSVector4i GetDisplayRect(int i = -1); + GSVector4i GetFrameRect(int i = -1); + GSVector2i GetDeviceSize(int i = -1); + bool IsEnabled(int i); + int GetFPS(); virtual void Reset(); virtual void Flush(); virtual void FlushPrim() = 0; virtual void ResetPrim() = 0; - virtual void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, CRect r) {} - virtual void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, CRect r) {} + virtual void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) {} + virtual void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) {} virtual void InvalidateTextureCache() {} void Move(); - void Write(BYTE* mem, int len); - void Read(BYTE* mem, int len); + void Write(uint8* mem, int len); + void Read(uint8* mem, int len); - void SoftReset(BYTE mask); - void WriteCSR(UINT32 csr) {m_regs->CSR.ai32[1] = csr;} - void ReadFIFO(BYTE* mem, int size); - template void Transfer(BYTE* mem, UINT32 size); + void SoftReset(uint32 mask); + void WriteCSR(uint32 csr) {m_regs->CSR.u32[1] = csr;} + void ReadFIFO(uint8* mem, int size); + template void Transfer(uint8* mem, uint32 size); int Freeze(GSFreezeData* fd, bool sizeonly); int Defrost(const GSFreezeData* fd); - void GetLastTag(UINT32* tag) {*tag = m_path3hack; m_path3hack = 0;} - virtual void SetGameCRC(DWORD crc, int options); + void GetLastTag(uint32* tag) {*tag = m_path3hack; m_path3hack = 0;} + virtual void SetGameCRC(uint32 crc, int options); void SetFrameSkip(int frameskip); }; diff --git a/plugins/GSdx/GSTables.cpp b/plugins/GSdx/GSTables.cpp index ec0aa149e7..f24b9ec179 100644 --- a/plugins/GSdx/GSTables.cpp +++ b/plugins/GSdx/GSTables.cpp @@ -22,21 +22,21 @@ #include "StdAfx.h" #include "GSTables.h" -const BYTE blockTable32[4][8] = { +const uint8 blockTable32[4][8] = { { 0, 1, 4, 5, 16, 17, 20, 21}, { 2, 3, 6, 7, 18, 19, 22, 23}, { 8, 9, 12, 13, 24, 25, 28, 29}, { 10, 11, 14, 15, 26, 27, 30, 31} }; -const BYTE blockTable32Z[4][8] = { +const uint8 blockTable32Z[4][8] = { { 24, 25, 28, 29, 8, 9, 12, 13}, { 26, 27, 30, 31, 10, 11, 14, 15}, { 16, 17, 20, 21, 0, 1, 4, 5}, { 18, 19, 22, 23, 2, 3, 6, 7} }; -const BYTE blockTable16[8][4] = { +const uint8 blockTable16[8][4] = { { 0, 2, 8, 10 }, { 1, 3, 9, 11 }, { 4, 6, 12, 14 }, @@ -47,7 +47,7 @@ const BYTE blockTable16[8][4] = { { 21, 23, 29, 31 } }; -const BYTE blockTable16S[8][4] = { +const uint8 blockTable16S[8][4] = { { 0, 2, 16, 18 }, { 1, 3, 17, 19 }, { 8, 10, 24, 26 }, @@ -58,7 +58,7 @@ const BYTE blockTable16S[8][4] = { { 13, 15, 29, 31 } }; -const BYTE blockTable16Z[8][4] = { +const uint8 blockTable16Z[8][4] = { { 24, 26, 16, 18 }, { 25, 27, 17, 19 }, { 28, 30, 20, 22 }, @@ -69,7 +69,7 @@ const BYTE blockTable16Z[8][4] = { { 13, 15, 5, 7 } }; -const BYTE blockTable16SZ[8][4] = { +const uint8 blockTable16SZ[8][4] = { { 24, 26, 8, 10 }, { 25, 27, 9, 11 }, { 16, 18, 0, 2 }, @@ -80,14 +80,14 @@ const BYTE blockTable16SZ[8][4] = { { 21, 23, 5, 7 } }; -const BYTE blockTable8[4][8] = { +const uint8 blockTable8[4][8] = { { 0, 1, 4, 5, 16, 17, 20, 21}, { 2, 3, 6, 7, 18, 19, 22, 23}, { 8, 9, 12, 13, 24, 25, 28, 29}, { 10, 11, 14, 15, 26, 27, 30, 31} }; -const BYTE blockTable4[8][4] = { +const uint8 blockTable4[8][4] = { { 0, 2, 8, 10 }, { 1, 3, 9, 11 }, { 4, 6, 12, 14 }, @@ -98,7 +98,7 @@ const BYTE blockTable4[8][4] = { { 21, 23, 29, 31 } }; -const BYTE columnTable32[8][8] = { +const uint8 columnTable32[8][8] = { { 0, 1, 4, 5, 8, 9, 12, 13 }, { 2, 3, 6, 7, 10, 11, 14, 15 }, { 16, 17, 20, 21, 24, 25, 28, 29 }, @@ -109,7 +109,7 @@ const BYTE columnTable32[8][8] = { { 50, 51, 54, 55, 58, 59, 62, 63 }, }; -const BYTE columnTable16[8][16] = { +const uint8 columnTable16[8][16] = { { 0, 2, 8, 10, 16, 18, 24, 26, 1, 3, 9, 11, 17, 19, 25, 27 }, { 4, 6, 12, 14, 20, 22, 28, 30, @@ -128,7 +128,7 @@ const BYTE columnTable16[8][16] = { 101, 103, 109, 111, 117, 119, 125, 127 }, }; -const BYTE columnTable8[16][16] = { +const uint8 columnTable8[16][16] = { { 0, 4, 16, 20, 32, 36, 48, 52, // column 0 2, 6, 18, 22, 34, 38, 50, 54 }, { 8, 12, 24, 28, 40, 44, 56, 60, @@ -163,7 +163,7 @@ const BYTE columnTable8[16][16] = { 203, 207, 219, 223, 235, 239, 251, 255 }, }; -const WORD columnTable4[16][32] = { +const uint16 columnTable4[16][32] = { { 0, 8, 32, 40, 64, 72, 96, 104, // column 0 2, 10, 34, 42, 66, 74, 98, 106, 4, 12, 36, 44, 68, 76, 100, 108, @@ -230,7 +230,7 @@ const WORD columnTable4[16][32] = { 407, 415, 439, 447, 471, 479, 503, 511 }, }; -const BYTE clutTableT32I8[128] = +const uint8 clutTableT32I8[128] = { 0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15, 64, 65, 68, 69, 72, 73, 76, 77, 66, 67, 70, 71, 74, 75, 78, 79, @@ -242,13 +242,13 @@ const BYTE clutTableT32I8[128] = 112, 113, 116, 117, 120, 121, 124, 125, 114, 115, 118, 119, 122, 123, 126, 127 }; -const BYTE clutTableT32I4[16] = +const uint8 clutTableT32I4[16] = { 0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15 }; -const BYTE clutTableT16I8[32] = +const uint8 clutTableT16I8[32] = { 0, 2, 8, 10, 16, 18, 24, 26, 4, 6, 12, 14, 20, 22, 28, 30, @@ -256,7 +256,7 @@ const BYTE clutTableT16I8[32] = 5, 7, 13, 15, 21, 23, 29, 31 }; -const BYTE clutTableT16I4[16] = +const uint8 clutTableT16I4[16] = { 0, 2, 8, 10, 16, 18, 24, 26, 4, 6, 12, 14, 20, 22, 28, 30 diff --git a/plugins/GSdx/GSTables.h b/plugins/GSdx/GSTables.h index 1ed40beea8..258a22d0e8 100644 --- a/plugins/GSdx/GSTables.h +++ b/plugins/GSdx/GSTables.h @@ -21,19 +21,19 @@ #pragma once -extern const BYTE blockTable32[4][8]; -extern const BYTE blockTable32Z[4][8]; -extern const BYTE blockTable16[8][4]; -extern const BYTE blockTable16S[8][4]; -extern const BYTE blockTable16Z[8][4]; -extern const BYTE blockTable16SZ[8][4]; -extern const BYTE blockTable8[4][8]; -extern const BYTE blockTable4[8][4]; -extern const BYTE columnTable32[8][8]; -extern const BYTE columnTable16[8][16]; -extern const BYTE columnTable8[16][16]; -extern const WORD columnTable4[16][32]; -extern const BYTE clutTableT32I8[128]; -extern const BYTE clutTableT32I4[16]; -extern const BYTE clutTableT16I8[32]; -extern const BYTE clutTableT16I4[16]; +extern const uint8 blockTable32[4][8]; +extern const uint8 blockTable32Z[4][8]; +extern const uint8 blockTable16[8][4]; +extern const uint8 blockTable16S[8][4]; +extern const uint8 blockTable16Z[8][4]; +extern const uint8 blockTable16SZ[8][4]; +extern const uint8 blockTable8[4][8]; +extern const uint8 blockTable4[8][4]; +extern const uint8 columnTable32[8][8]; +extern const uint8 columnTable16[8][16]; +extern const uint8 columnTable8[16][16]; +extern const uint16 columnTable4[16][32]; +extern const uint8 clutTableT32I8[128]; +extern const uint8 clutTableT32I4[16]; +extern const uint8 clutTableT16I8[32]; +extern const uint8 clutTableT16I4[16]; diff --git a/plugins/GSdx/GSTexture.h b/plugins/GSdx/GSTexture.h index fbf204ada8..41fa86f904 100644 --- a/plugins/GSdx/GSTexture.h +++ b/plugins/GSdx/GSTexture.h @@ -28,21 +28,25 @@ class GSTexture public: GSVector2 m_scale; + struct GSMap {uint8* bits; int pitch;}; + + enum {None, RenderTarget, DepthStencil, Texture, Offscreen}; + public: GSTexture() : m_scale(1, 1) {} virtual ~GSTexture() {} - enum {None, RenderTarget, DepthStencil, Texture, Offscreen}; + virtual operator bool() {ASSERT(0); return false;} - virtual operator bool() = 0; virtual int GetType() const = 0; virtual int GetWidth() const = 0; virtual int GetHeight() const = 0; virtual int GetFormat() const = 0; - virtual bool Update(const CRect& r, const void* data, int pitch) = 0; - virtual bool Map(BYTE** bits, int& pitch, const RECT* r = NULL) = 0; - virtual void Unmap() = 0; - virtual bool Save(CString fn, bool dds = false) = 0; - CSize GetSize() {return CSize(GetWidth(), GetHeight());} + virtual bool Update(const GSVector4i& r, const void* data, int pitch) = 0; + virtual bool Map(GSMap& m, const GSVector4i* r = NULL) = 0; + virtual void Unmap() = 0; + virtual bool Save(const string& fn, bool dds = false) = 0; + + GSVector2i GetSize() const {return GSVector2i(GetWidth(), GetHeight());} }; diff --git a/plugins/GSdx/GSTexture10.cpp b/plugins/GSdx/GSTexture10.cpp index 615e8c25bc..57f88bea4d 100644 --- a/plugins/GSdx/GSTexture10.cpp +++ b/plugins/GSdx/GSTexture10.cpp @@ -22,11 +22,6 @@ #include "stdafx.h" #include "GSTexture10.h" -GSTexture10::GSTexture10() -{ - memset(&m_desc, 0, sizeof(m_desc)); -} - GSTexture10::GSTexture10(ID3D10Texture2D* texture) : m_texture(texture) { @@ -36,15 +31,6 @@ GSTexture10::GSTexture10(ID3D10Texture2D* texture) m_texture->GetDesc(&m_desc); } -GSTexture10::~GSTexture10() -{ -} - -GSTexture10::operator bool() -{ - return !!m_texture; -} - int GSTexture10::GetType() const { if(m_desc.BindFlags & D3D10_BIND_RENDER_TARGET) return GSTexture::RenderTarget; @@ -69,7 +55,7 @@ int GSTexture10::GetFormat() const return m_desc.Format; } -bool GSTexture10::Update(const CRect& r, const void* data, int pitch) +bool GSTexture10::Update(const GSVector4i& r, const void* data, int pitch) { if(m_dev && m_texture) { @@ -83,16 +69,23 @@ bool GSTexture10::Update(const CRect& r, const void* data, int pitch) return false; } -bool GSTexture10::Map(BYTE** bits, int& pitch, const RECT* r) +bool GSTexture10::Map(GSMap& m, const GSVector4i* r) { - if(m_texture) + if(r != NULL) + { + // ASSERT(0); // not implemented + + return false; + } + + if(m_texture && m_desc.Usage == D3D10_USAGE_STAGING) { D3D10_MAPPED_TEXTURE2D map; if(SUCCEEDED(m_texture->Map(0, D3D10_MAP_READ_WRITE, 0, &map))) { - *bits = (BYTE*)map.pData; - pitch = (int)map.RowPitch; + m.bits = (uint8*)map.pData; + m.pitch = (int)map.RowPitch; return true; } @@ -109,7 +102,7 @@ void GSTexture10::Unmap() } } -bool GSTexture10::Save(CString fn, bool dds) +bool GSTexture10::Save(const string& fn, bool dds) { CComPtr res; @@ -143,14 +136,14 @@ bool GSTexture10::Save(CString fn, bool dds) hr = src->Map(0, D3D10_MAP_READ, 0, &sm); hr = dst->Map(0, D3D10_MAP_WRITE, 0, &dm); - BYTE* s = (BYTE*)sm.pData; - BYTE* d = (BYTE*)dm.pData; + uint8* s = (uint8*)sm.pData; + uint8* d = (uint8*)dm.pData; - for(UINT y = 0; y < desc.Height; y++, s += sm.RowPitch, d += dm.RowPitch) + for(uint32 y = 0; y < desc.Height; y++, s += sm.RowPitch, d += dm.RowPitch) { - for(UINT x = 0; x < desc.Width; x++) + for(uint32 x = 0; x < desc.Width; x++) { - ((UINT*)d)[x] = (UINT)(((float*)s)[x*2] * UINT_MAX); + ((uint32*)d)[x] = (uint32)(((float*)s)[x*2] * UINT_MAX); } } @@ -164,12 +157,7 @@ bool GSTexture10::Save(CString fn, bool dds) res = m_texture; } - return SUCCEEDED(D3DX10SaveTextureToFile(res, dds ? D3DX10_IFF_DDS : D3DX10_IFF_BMP, fn)); -} - -ID3D10Texture2D* GSTexture10::operator->() -{ - return m_texture; + return SUCCEEDED(D3DX10SaveTextureToFile(res, dds ? D3DX10_IFF_DDS : D3DX10_IFF_BMP, fn.c_str())); } GSTexture10::operator ID3D10Texture2D*() @@ -181,7 +169,21 @@ GSTexture10::operator ID3D10ShaderResourceView*() { if(!m_srv && m_dev && m_texture) { - m_dev->CreateShaderResourceView(m_texture, NULL, &m_srv); + D3D10_SHADER_RESOURCE_VIEW_DESC* desc = NULL; + + if(m_desc.Format == DXGI_FORMAT_R32G8X24_TYPELESS) + { + desc = new D3D10_SHADER_RESOURCE_VIEW_DESC(); + memset(desc, 0, sizeof(*desc)); + desc->Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + desc->ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; + desc->Texture2D.MostDetailedMip = 0; + desc->Texture2D.MipLevels = 1; + } + + m_dev->CreateShaderResourceView(m_texture, desc, &m_srv); + + delete desc; } return m_srv; @@ -203,7 +205,19 @@ GSTexture10::operator ID3D10DepthStencilView*() { if(!m_dsv && m_dev && m_texture) { - m_dev->CreateDepthStencilView(m_texture, NULL, &m_dsv); + D3D10_DEPTH_STENCIL_VIEW_DESC* desc = NULL; + + if(m_desc.Format == DXGI_FORMAT_R32G8X24_TYPELESS) + { + desc = new D3D10_DEPTH_STENCIL_VIEW_DESC(); + memset(desc, 0, sizeof(*desc)); + desc->Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + desc->ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D; + } + + m_dev->CreateDepthStencilView(m_texture, desc, &m_dsv); + + delete desc; } return m_dsv; diff --git a/plugins/GSdx/GSTexture10.h b/plugins/GSdx/GSTexture10.h index 9c1eb30964..530ec3be3c 100644 --- a/plugins/GSdx/GSTexture10.h +++ b/plugins/GSdx/GSTexture10.h @@ -33,22 +33,17 @@ class GSTexture10 : public GSTexture CComPtr m_dsv; public: - GSTexture10(); explicit GSTexture10(ID3D10Texture2D* texture); - virtual ~GSTexture10(); - - operator bool(); int GetType() const; int GetWidth() const; int GetHeight() const; int GetFormat() const; - bool Update(const CRect& r, const void* data, int pitch); - bool Map(BYTE** bits, int& pitch, const RECT* r = NULL); - void Unmap(); - bool Save(CString fn, bool dds = false); - ID3D10Texture2D* operator->(); // TODO: remove direct access + bool Update(const GSVector4i& r, const void* data, int pitch); + bool Map(GSMap& m, const GSVector4i* r); + void Unmap(); + bool Save(const string& fn, bool dds = false); operator ID3D10Texture2D*(); operator ID3D10ShaderResourceView*(); diff --git a/plugins/GSdx/GSTexture11.cpp b/plugins/GSdx/GSTexture11.cpp new file mode 100644 index 0000000000..991128f156 --- /dev/null +++ b/plugins/GSdx/GSTexture11.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSTexture11.h" + +GSTexture11::GSTexture11(ID3D11Texture2D* texture) + : m_texture(texture) +{ + ASSERT(m_texture); + + m_texture->GetDevice(&m_dev); + m_texture->GetDesc(&m_desc); + + m_dev->GetImmediateContext(&m_ctx); +} + +int GSTexture11::GetType() const +{ + if(m_desc.BindFlags & D3D11_BIND_RENDER_TARGET) return GSTexture::RenderTarget; + if(m_desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) return GSTexture::DepthStencil; + if(m_desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) return GSTexture::Texture; + if(m_desc.Usage == D3D11_USAGE_STAGING) return GSTexture::Offscreen; + return GSTexture::None; +} + +int GSTexture11::GetWidth() const +{ + return m_desc.Width; +} + +int GSTexture11::GetHeight() const +{ + return m_desc.Height; +} + +int GSTexture11::GetFormat() const +{ + return m_desc.Format; +} + +bool GSTexture11::Update(const GSVector4i& r, const void* data, int pitch) +{ + if(m_dev && m_texture) + { + D3D11_BOX box = {r.left, r.top, 0, r.right, r.bottom, 1}; + + m_ctx->UpdateSubresource(m_texture, 0, &box, data, pitch, 0); + + return true; + } + + return false; +} + +bool GSTexture11::Map(GSMap& m, const GSVector4i* r) +{ + if(r != NULL) + { + // ASSERT(0); // not implemented + + return false; + } + + if(m_texture && m_desc.Usage == D3D11_USAGE_STAGING) + { + D3D11_MAPPED_SUBRESOURCE map; + + if(SUCCEEDED(m_ctx->Map(m_texture, 0, D3D11_MAP_READ_WRITE, 0, &map))) + { + m.bits = (uint8*)map.pData; + m.pitch = (int)map.RowPitch; + + return true; + } + } + + return false; +} + +void GSTexture11::Unmap() +{ + if(m_texture) + { + m_ctx->Unmap(m_texture, 0); + } +} + +bool GSTexture11::Save(const string& fn, bool dds) +{ + CComPtr res; + + if(m_desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) + { + HRESULT hr; + + D3D11_TEXTURE2D_DESC desc; + + memset(&desc, 0, sizeof(desc)); + + m_texture->GetDesc(&desc); + + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + + CComPtr src, dst; + + hr = m_dev->CreateTexture2D(&desc, NULL, &src); + + m_ctx->CopyResource(src, m_texture); + + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + hr = m_dev->CreateTexture2D(&desc, NULL, &dst); + + D3D11_MAPPED_SUBRESOURCE sm, dm; + + hr = m_ctx->Map(src, 0, D3D11_MAP_READ, 0, &sm); + hr = m_ctx->Map(dst, 0, D3D11_MAP_WRITE, 0, &dm); + + uint8* s = (uint8*)sm.pData; + uint8* d = (uint8*)dm.pData; + + for(uint32 y = 0; y < desc.Height; y++, s += sm.RowPitch, d += dm.RowPitch) + { + for(uint32 x = 0; x < desc.Width; x++) + { + ((uint32*)d)[x] = (uint32)(((float*)s)[x*2] * UINT_MAX); + } + } + + m_ctx->Unmap(src, 0); + m_ctx->Unmap(dst, 0); + + res = dst; + } + else + { + res = m_texture; + } + + return SUCCEEDED(D3DX11SaveTextureToFile(m_ctx, res, dds ? D3DX11_IFF_DDS : D3DX11_IFF_BMP, fn.c_str())); +} + +GSTexture11::operator ID3D11Texture2D*() +{ + return m_texture; +} + +GSTexture11::operator ID3D11ShaderResourceView*() +{ + if(!m_srv && m_dev && m_texture) + { + m_dev->CreateShaderResourceView(m_texture, NULL, &m_srv); + } + + return m_srv; +} + +GSTexture11::operator ID3D11RenderTargetView*() +{ + ASSERT(m_dev); + + if(!m_rtv && m_dev && m_texture) + { + m_dev->CreateRenderTargetView(m_texture, NULL, &m_rtv); + } + + return m_rtv; +} + +GSTexture11::operator ID3D11DepthStencilView*() +{ + if(!m_dsv && m_dev && m_texture) + { + m_dev->CreateDepthStencilView(m_texture, NULL, &m_dsv); + } + + return m_dsv; +} diff --git a/plugins/GSdx/GSTexture11.h b/plugins/GSdx/GSTexture11.h new file mode 100644 index 0000000000..6b3b16fb6c --- /dev/null +++ b/plugins/GSdx/GSTexture11.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSTexture.h" + +class GSTexture11 : public GSTexture +{ + CComPtr m_dev; + CComPtr m_ctx; + CComPtr m_texture; + D3D11_TEXTURE2D_DESC m_desc; + CComPtr m_srv; + CComPtr m_rtv; + CComPtr m_dsv; + +public: + explicit GSTexture11(ID3D11Texture2D* texture); + + int GetType() const; + int GetWidth() const; + int GetHeight() const; + int GetFormat() const; + + bool Update(const GSVector4i& r, const void* data, int pitch); + bool Map(GSMap& m, const GSVector4i* r); + void Unmap(); + bool Save(const string& fn, bool dds = false); + + operator ID3D11Texture2D*(); + operator ID3D11ShaderResourceView*(); + operator ID3D11RenderTargetView*(); + operator ID3D11DepthStencilView*(); +}; diff --git a/plugins/GSdx/GSTexture7.cpp b/plugins/GSdx/GSTexture7.cpp index e69406e928..44dd81f7e9 100644 --- a/plugins/GSdx/GSTexture7.cpp +++ b/plugins/GSdx/GSTexture7.cpp @@ -22,12 +22,6 @@ #include "stdafx.h" #include "GSTexture7.h" -GSTexture7::GSTexture7() - : m_type(GSTexture::None) -{ - memset(&m_desc, 0, sizeof(m_desc)); -} - GSTexture7::GSTexture7(int type, IDirectDrawSurface7* system) : m_type(type) , m_system(system) @@ -51,15 +45,6 @@ GSTexture7::GSTexture7(int type, IDirectDrawSurface7* system, IDirectDrawSurface video->GetSurfaceDesc(&m_desc); } -GSTexture7::~GSTexture7() -{ -} - -GSTexture7::operator bool() -{ - return !!m_system; -} - int GSTexture7::GetType() const { return m_type; @@ -80,11 +65,11 @@ int GSTexture7::GetFormat() const return (int)m_desc.ddpfPixelFormat.dwFourCC; } -bool GSTexture7::Update(const CRect& r, const void* data, int pitch) +bool GSTexture7::Update(const GSVector4i& r, const void* data, int pitch) { HRESULT hr; - CRect r2 = r; + GSVector4i r2 = r; DDSURFACEDESC2 desc; @@ -92,14 +77,14 @@ bool GSTexture7::Update(const CRect& r, const void* data, int pitch) desc.dwSize = sizeof(desc); - if(SUCCEEDED(hr = m_system->Lock(&r2, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL))) + if(SUCCEEDED(hr = m_system->Lock(r2, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL))) { - BYTE* src = (BYTE*)data; - BYTE* dst = (BYTE*)desc.lpSurface; + uint8* src = (uint8*)data; + uint8* dst = (uint8*)desc.lpSurface; int bytes = min(pitch, desc.lPitch); - for(int i = 0, j = r.Height(); i < j; i++, src += pitch, dst += desc.lPitch) + for(int i = 0, j = r.height(); i < j; i++, src += pitch, dst += desc.lPitch) { // memcpy(dst, src, bytes); @@ -120,11 +105,11 @@ bool GSTexture7::Update(const CRect& r, const void* data, int pitch) } } - hr = m_system->Unlock(&r2); + hr = m_system->Unlock(r2); if(m_video) { - hr = m_video->Blt(&r2, m_system, &r2, DDBLT_WAIT, NULL); + hr = m_video->Blt(r2, m_system, r2, DDBLT_WAIT, NULL); } return true; @@ -133,20 +118,23 @@ bool GSTexture7::Update(const CRect& r, const void* data, int pitch) return false; } -bool GSTexture7::Map(BYTE** bits, int& pitch, const RECT* r) +bool GSTexture7::Map(GSMap& m, const GSVector4i* r) { HRESULT hr; - CRect r2 = r; + if(r != NULL) + { + // ASSERT(0); // not implemented + + return false; + } DDSURFACEDESC2 desc; - if(SUCCEEDED(hr = m_system->Lock(&r2, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL))) + if(SUCCEEDED(hr = m_system->Lock(NULL, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL))) { - *bits = (BYTE*)desc.lpSurface; - pitch = (int)desc.lPitch; - - m_lr = r; + m.bits = (uint8*)desc.lpSurface; + m.pitch = (int)desc.lPitch; return true; } @@ -162,11 +150,11 @@ void GSTexture7::Unmap() if(m_video) { - hr = m_video->Blt(&m_lr, m_system, &m_lr, DDBLT_WAIT, NULL); + hr = m_video->Blt(NULL, m_system, NULL, DDBLT_WAIT, NULL); } } -bool GSTexture7::Save(CString fn, bool dds) +bool GSTexture7::Save(const string& fn, bool dds) { // TODO diff --git a/plugins/GSdx/GSTexture7.h b/plugins/GSdx/GSTexture7.h index 62eef7ea28..c69b1a96b1 100644 --- a/plugins/GSdx/GSTexture7.h +++ b/plugins/GSdx/GSTexture7.h @@ -30,24 +30,20 @@ class GSTexture7 : public GSTexture CComPtr m_system; CComPtr m_video; DDSURFACEDESC2 m_desc; - CRect m_lr; public: - GSTexture7(); - explicit GSTexture7(int type, IDirectDrawSurface7* system); + GSTexture7(int type, IDirectDrawSurface7* system); GSTexture7(int type, IDirectDrawSurface7* system, IDirectDrawSurface7* video); - virtual ~GSTexture7(); - - operator bool(); int GetType() const; int GetWidth() const; int GetHeight() const; int GetFormat() const; - bool Update(const CRect& r, const void* data, int pitch); - bool Map(BYTE** bits, int& pitch, const RECT* r = NULL); + + bool Update(const GSVector4i& r, const void* data, int pitch); + bool Map(GSMap& m, const GSVector4i* r); void Unmap(); - bool Save(CString fn, bool dds = false); + bool Save(const string& fn, bool dds = false); IDirectDrawSurface7* operator->(); // TODO: remove direct access diff --git a/plugins/GSdx/GSTexture9.cpp b/plugins/GSdx/GSTexture9.cpp index bff9df141c..daacf8e5dd 100644 --- a/plugins/GSdx/GSTexture9.cpp +++ b/plugins/GSdx/GSTexture9.cpp @@ -22,11 +22,6 @@ #include "stdafx.h" #include "GSTexture9.h" -GSTexture9::GSTexture9() -{ - memset(&m_desc, 0, sizeof(m_desc)); -} - GSTexture9::GSTexture9(IDirect3DSurface9* surface) { m_surface = surface; @@ -36,8 +31,9 @@ GSTexture9::GSTexture9(IDirect3DSurface9* surface) if(m_desc.Type != D3DRTYPE_SURFACE) { - HRESULT hr = surface->GetContainer(__uuidof(IDirect3DTexture9), (void**)&m_texture); - ASSERT(SUCCEEDED(hr)); + surface->GetContainer(__uuidof(IDirect3DTexture9), (void**)&m_texture); + + ASSERT(m_texture != NULL); } } @@ -48,17 +44,14 @@ GSTexture9::GSTexture9(IDirect3DTexture9* texture) texture->GetDevice(&m_dev); texture->GetLevelDesc(0, &m_desc); texture->GetSurfaceLevel(0, &m_surface); + + ASSERT(m_surface != NULL); } GSTexture9::~GSTexture9() { } -GSTexture9::operator bool() -{ - return !!m_surface; -} - int GSTexture9::GetType() const { if(m_desc.Usage & D3DUSAGE_RENDERTARGET) return GSTexture::RenderTarget; @@ -83,25 +76,28 @@ int GSTexture9::GetFormat() const return m_desc.Format; } -bool GSTexture9::Update(const CRect& r, const void* data, int pitch) +bool GSTexture9::Update(const GSVector4i& r, const void* data, int pitch) { - if(CComPtr surface = *this) + if(m_surface) { D3DLOCKED_RECT lr; - if(SUCCEEDED(surface->LockRect(&lr, r, 0))) + if(SUCCEEDED(m_surface->LockRect(&lr, r, 0))) { - BYTE* src = (BYTE*)data; - BYTE* dst = (BYTE*)lr.pBits; + uint8* src = (uint8*)data; + uint8* dst = (uint8*)lr.pBits; - int bytes = min(pitch, lr.Pitch); + int bytes = r.width() << (m_desc.Format == D3DFMT_A1R5G5B5 ? 1 : 2); - for(int i = 0, j = r.Height(); i < j; i++, src += pitch, dst += lr.Pitch) + bytes = min(bytes, pitch); + bytes = min(bytes, lr.Pitch); + + for(int i = 0, j = r.height(); i < j; i++, src += pitch, dst += lr.Pitch) { memcpy(dst, src, bytes); } - surface->UnlockRect(); + m_surface->UnlockRect(); return true; } @@ -110,18 +106,18 @@ bool GSTexture9::Update(const CRect& r, const void* data, int pitch) return false; } -bool GSTexture9::Map(BYTE** bits, int& pitch, const RECT* r) +bool GSTexture9::Map(GSMap& m, const GSVector4i* r) { HRESULT hr; - if(CComPtr surface = *this) + if(m_surface) { D3DLOCKED_RECT lr; - if(SUCCEEDED(hr = surface->LockRect(&lr, r, 0))) + if(SUCCEEDED(hr = m_surface->LockRect(&lr, (LPRECT)r, 0))) { - *bits = (BYTE*)lr.pBits; - pitch = (int)lr.Pitch; + m.bits = (uint8*)lr.pBits; + m.pitch = (int)lr.Pitch; return true; } @@ -132,13 +128,13 @@ bool GSTexture9::Map(BYTE** bits, int& pitch, const RECT* r) void GSTexture9::Unmap() { - if(CComPtr surface = *this) + if(m_surface) { - surface->UnlockRect(); + m_surface->UnlockRect(); } } -bool GSTexture9::Save(CString fn, bool dds) +bool GSTexture9::Save(const string& fn, bool dds) { CComPtr surface; @@ -160,12 +156,12 @@ bool GSTexture9::Save(CString fn, bool dds) hr = m_surface->LockRect(&slr, NULL, 0); hr = surface->LockRect(&dlr, NULL, 0); - BYTE* s = (BYTE*)slr.pBits; - BYTE* d = (BYTE*)dlr.pBits; + uint8* s = (uint8*)slr.pBits; + uint8* d = (uint8*)dlr.pBits; - for(UINT y = 0; y < desc.Height; y++, s += slr.Pitch, d += dlr.Pitch) + for(uint32 y = 0; y < desc.Height; y++, s += slr.Pitch, d += dlr.Pitch) { - for(UINT x = 0; x < desc.Width; x++) + for(uint32 x = 0; x < desc.Width; x++) { ((float*)d)[x] = ((float*)s)[x]; } @@ -181,40 +177,23 @@ bool GSTexture9::Save(CString fn, bool dds) if(surface != NULL) { - return SUCCEEDED(D3DXSaveSurfaceToFile(fn, dds ? D3DXIFF_DDS : D3DXIFF_BMP, surface, NULL, NULL)); + return SUCCEEDED(D3DXSaveSurfaceToFile(fn.c_str(), dds ? D3DXIFF_DDS : D3DXIFF_BMP, surface, NULL, NULL)); } /* if(CComQIPtr texture = surface) { - return SUCCEEDED(D3DXSaveTextureToFile(fn, dds ? D3DXIFF_DDS : D3DXIFF_BMP, texture, NULL)); + return SUCCEEDED(D3DXSaveTextureToFile(fn.c_str(), dds ? D3DXIFF_DDS : D3DXIFF_BMP, texture, NULL)); } */ return false; } -IDirect3DTexture9* GSTexture9::operator->() -{ - return m_texture; -} - GSTexture9::operator IDirect3DSurface9*() { - if(m_texture && !m_surface) - { - m_texture->GetSurfaceLevel(0, &m_surface); - } - return m_surface; } GSTexture9::operator IDirect3DTexture9*() { - if(m_surface && !m_texture) - { - m_surface->GetContainer(__uuidof(IDirect3DTexture9), (void**)&m_texture); - - ASSERT(m_texture); - } - return m_texture; } diff --git a/plugins/GSdx/GSTexture9.h b/plugins/GSdx/GSTexture9.h index c952cda68e..be8bac79fe 100644 --- a/plugins/GSdx/GSTexture9.h +++ b/plugins/GSdx/GSTexture9.h @@ -31,23 +31,19 @@ class GSTexture9 : public GSTexture D3DSURFACE_DESC m_desc; public: - GSTexture9(); explicit GSTexture9(IDirect3DSurface9* surface); explicit GSTexture9(IDirect3DTexture9* texture); virtual ~GSTexture9(); - operator bool(); - int GetType() const; int GetWidth() const; int GetHeight() const; int GetFormat() const; - bool Update(const CRect& r, const void* data, int pitch); - bool Map(BYTE** bits, int& pitch, const RECT* r = NULL); - void Unmap(); - bool Save(CString fn, bool dds = false); - IDirect3DTexture9* operator->(); // TODO: remove direct access + bool Update(const GSVector4i& r, const void* data, int pitch); + bool Map(GSMap& m, const GSVector4i* r); + void Unmap(); + bool Save(const string& fn, bool dds = false); operator IDirect3DSurface9*(); operator IDirect3DTexture9*(); diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index 9174325f7a..897f6be043 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -21,3 +21,818 @@ #include "StdAfx.h" #include "GSTextureCache.h" + +GSTextureCache::GSTextureCache(GSRenderer* r) + : m_renderer(r) +{ +} + +GSTextureCache::~GSTextureCache() +{ + RemoveAll(); +} + +void GSTextureCache::RemoveAll() +{ + m_src.RemoveAll(); + + for(int type = 0; type < 2; type++) + { + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); i++) + { + delete *i; + } + + m_dst[type].clear(); + } +} + +GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r) +{ + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; + const uint32* clut = m_renderer->m_mem.m_clut; + + Source* src = NULL; + + const hash_map& map = m_src.m_map[TEX0.TBP0 >> 5]; + + for(hash_map::const_iterator i = map.begin(); i != map.end(); i++) + { + Source* s = i->first; + + if(((s->m_TEX0.u32[0] ^ TEX0.u32[0]) | ((s->m_TEX0.u32[1] ^ TEX0.u32[1]) & 3)) != 0) // TBP0 TBW PSM TW TH + { + continue; + } + + if((psm.trbpp == 16 || psm.trbpp == 24) && TEX0.TCC && TEXA != s->m_TEXA) + { + continue; + } + + if(psm.pal > 0 && !GSVector4i::compare(s->m_clut, clut, psm.pal * sizeof(clut[0]))) + { + continue; + } + + src = s; + + break; + } + + Target* dst = NULL; + + if(src == NULL) + { + for(int type = 0; type < 2 && dst == NULL; type++) + { + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); i++) + { + Target* t = *i; + + if(t->m_used && t->m_dirty.empty() && GSUtil::HasSharedBits(t->m_TEX0.TBP0, t->m_TEX0.PSM, TEX0.TBP0, TEX0.PSM)) + { + dst = t; + + break; + } + } + } + } + + if(src == NULL) + { + src = CreateSource(); + + if(!(dst ? src->Create(dst) : src->Create())) + { + delete src; + + return NULL; + } + + if(psm.pal > 0) + { + memcpy(src->m_clut, clut, psm.pal * sizeof(clut[0])); + } + + m_src.Add(src, TEX0); + } + + if(psm.pal > 0) + { + int size = psm.pal * sizeof(clut[0]); + + if(src->m_palette) + { + if(src->m_initpalette || GSVector4i::update(src->m_clut, clut, size)) + { + src->m_palette->Update(GSVector4i(0, 0, psm.pal, 1), src->m_clut, size); + src->m_initpalette = false; + } + } + } + + src->Update(TEX0, TEXA, r); + + m_src.m_used = true; + + return src; +} + +GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used, bool fb) +{ + Target* dst = NULL; + + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); i++) + { + Target* t = *i; + + if(t->m_TEX0.TBP0 == TEX0.TBP0) + { + m_dst[type].splice(m_dst[type].begin(), m_dst[type], i); + + dst = t; + + if(!fb) dst->m_TEX0 = TEX0; + + break; + } + } + + if(dst == NULL && fb) + { + // HACK: try to find something close to the base pointer + + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); i++) + { + Target* t = *i; + + if(t->m_TEX0.TBP0 <= TEX0.TBP0 && TEX0.TBP0 < t->m_TEX0.TBP0 + 0x700 && (!dst || t->m_TEX0.TBP0 >= dst->m_TEX0.TBP0)) + { + dst = t; + } + } + } + + if(dst == NULL) + { + dst = CreateTarget(); + + dst->m_TEX0 = TEX0; + + if(!dst->Create(w, h, type)) + { + delete dst; + + return NULL; + } + + m_dst[type].push_front(dst); + } + else + { + dst->Update(); + } + + if(m_renderer->CanUpscale()) + { + GSVector4i fr = m_renderer->GetFrameRect(); + + int ww = (int)(fr.left + dst->m_TEX0.TBW * 64); + int hh = (int)(fr.top + m_renderer->GetDisplayRect().height()); + + if(hh <= m_renderer->GetDeviceSize().y / 2) + { + hh *= 2; + } +/* + if(hh < 512) + { + hh = 512; + } +*/ + if(ww > 0 && hh > 0) + { + dst->m_texture->m_scale.x = (float)w / ww; + dst->m_texture->m_scale.y = (float)h / hh; + } + } + + if(used) + { + dst->m_used = true; + } + + return dst; +} + +void GSTextureCache::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& rect, bool target) +{ + bool found = false; + + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[BITBLTBUF.DPSM]; + + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; + + GSVector2i bs = (bp & 31) == 0 ? psm.pgs : psm.bs; + + GSVector4i r = rect.ralign(bs); + + if(!target) + { + const hash_map& map = m_src.m_map[bp >> 5]; + + for(hash_map::const_iterator i = map.begin(); i != map.end(); ) + { + hash_map::const_iterator j = i++; + + Source* s = j->first; + + if(GSUtil::HasSharedBits(bp, BITBLTBUF.DPSM, s->m_TEX0.TBP0, s->m_TEX0.PSM)) + { + m_src.RemoveAt(s); + } + } + } + + for(int y = r.top; y < r.bottom; y += bs.y) + { + uint32 base = psm.bn(0, y, bp, bw); + + for(int x = r.left; x < r.right; x += bs.x) + { + uint32 page = (base + psm.blockOffset[x >> 3]) >> 5; + + if(page < MAX_PAGES) + { + const hash_map& map = m_src.m_map[page]; + + for(hash_map::const_iterator i = map.begin(); i != map.end(); ) + { + hash_map::const_iterator j = i++; + + Source* s = j->first; + + if(GSUtil::HasSharedBits(BITBLTBUF.DPSM, s->m_TEX0.PSM)) + { + if(!s->m_target) + { + s->m_blocks -= s->m_valid[page].count; + + s->m_valid[page].block = 0; + s->m_valid[page].count = 0; + + found = true; + } + else + { + if(s->m_TEX0.TBP0 == bp) + { + m_src.RemoveAt(s); + } + } + } + } + } + } + } + + if(!target) return; + + for(int type = 0; type < 2; type++) + { + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); ) + { + list::iterator j = i++; + + Target* t = *j; + + if(GSUtil::HasSharedBits(BITBLTBUF.DBP, BITBLTBUF.DPSM, t->m_TEX0.TBP0, t->m_TEX0.PSM)) + { + if(!found && GSUtil::HasCompatibleBits(BITBLTBUF.DPSM, t->m_TEX0.PSM)) + { + t->m_dirty.push_back(GSDirtyRect(r, BITBLTBUF.DPSM)); + t->m_TEX0.TBW = BITBLTBUF.DBW; + } + else + { + m_dst[type].erase(j); + delete t; + continue; + } + } + + if(GSUtil::HasSharedBits(BITBLTBUF.DPSM, t->m_TEX0.PSM) && BITBLTBUF.DBP < t->m_TEX0.TBP0) + { + uint32 rowsize = BITBLTBUF.DBW * 8192; + uint32 offset = (uint32)((t->m_TEX0.TBP0 - BITBLTBUF.DBP) * 256); + + if(rowsize > 0 && offset % rowsize == 0) + { + int y = GSLocalMemory::m_psm[BITBLTBUF.DPSM].pgs.y * offset / rowsize; + + if(r.bottom > y) + { + // TODO: do not add this rect above too + t->m_dirty.push_back(GSDirtyRect(GSVector4i(r.left, r.top - y, r.right, r.bottom - y), BITBLTBUF.DPSM)); + t->m_TEX0.TBW = BITBLTBUF.DBW; + continue; + } + } + } + } + } +} + +void GSTextureCache::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) +{ + for(list::iterator i = m_dst[RenderTarget].begin(); i != m_dst[RenderTarget].end(); ) + { + list::iterator j = i++; + + Target* t = *j; + + if(GSUtil::HasSharedBits(BITBLTBUF.SBP, BITBLTBUF.SPSM, t->m_TEX0.TBP0, t->m_TEX0.PSM)) + { + if(GSUtil::HasCompatibleBits(BITBLTBUF.SPSM, t->m_TEX0.PSM)) + { + t->Read(r); + + return; + } + else if(BITBLTBUF.SPSM == PSM_PSMCT32 && (t->m_TEX0.PSM == PSM_PSMCT16 || t->m_TEX0.PSM == PSM_PSMCT16S)) + { + // ffx-2 riku changing to her default (shoots some reflecting glass at the end), 16-bit rt read as 32-bit + + t->Read(GSVector4i(r.left, r.top, r.right, r.top + (r.bottom - r.top) * 2)); + + return; + } + else + { + m_dst[RenderTarget].erase(j); + + delete t; + } + } + } +/* + // no good, ffx does a lot of readback after exiting menu, at 0x02f00 this wrongly finds rt 0x02100 (0,448 - 512,480) + + GSRenderTarget* rt2 = NULL; + int ymin = INT_MAX; + + pos = m_rt.GetHeadPosition(); + + while(pos) + { + GSRenderTarget* rt = m_rt.GetNext(pos); + + if(HasSharedBits(BITBLTBUF.SPSM, rt->m_TEX0.PSM) && BITBLTBUF.SBP > rt->m_TEX0.TBP0) + { + // ffx2 pause screen background + + uint32 rowsize = BITBLTBUF.SBW * 8192; + uint32 offset = (uint32)((BITBLTBUF.SBP - rt->m_TEX0.TBP0) * 256); + + if(rowsize > 0 && offset % rowsize == 0) + { + int y = GSLocalMemory::m_psm[BITBLTBUF.SPSM].pgs.y * offset / rowsize; + + if(y < ymin && y < 512) + { + rt2 = rt; + ymin = y; + } + } + } + } + + if(rt2) + { + rt2->Read(GSVector4i(r.left, r.top + ymin, r.right, r.bottom + ymin)); + } + + // TODO: ds +*/ +} + +void GSTextureCache::IncAge() +{ + int maxage = m_src.m_used ? 3 : 30; + + for(hash_map::iterator i = m_src.m_surfaces.begin(); i != m_src.m_surfaces.end(); ) + { + hash_map::iterator j = i++; + + Source* s = j->first; + + if(++s->m_age > maxage) + { + m_src.RemoveAt(s); + } + } + + m_src.m_used = false; + + maxage = 3; + + for(int type = 0; type < 2; type++) + { + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); ) + { + list::iterator j = i++; + + Target* t = *j; + + if(++t->m_age > maxage) + { + m_dst[type].erase(j); + + delete t; + } + } + } +} + +// GSTextureCache::Surface + +GSTextureCache::Surface::Surface(GSRenderer* r) + : m_renderer(r) + , m_texture(NULL) + , m_age(0) +{ + m_TEX0.TBP0 = (uint32)~0; +} + +GSTextureCache::Surface::~Surface() +{ + m_renderer->m_dev->Recycle(m_texture); +} + +void GSTextureCache::Surface::Update() +{ + m_age = 0; +} + +// GSTextureCache::Source + +GSTextureCache::Source::Source(GSRenderer* r) + : Surface(r) + , m_palette(NULL) + , m_initpalette(false) + , m_bpp(0) + , m_target(false) +{ + memset(m_valid, 0, sizeof(m_valid)); + + m_clut = (uint32*)_aligned_malloc(256 * sizeof(uint32), 16); + + memset(m_clut, 0, sizeof(m_clut)); + + m_write.rect = (GSVector4i*)_aligned_malloc(3 * sizeof(GSVector4i), 16); + m_write.count = 0; +} + +GSTextureCache::Source::~Source() +{ + m_renderer->m_dev->Recycle(m_palette); + + _aligned_free(m_clut); + + _aligned_free(m_write.rect); +} + +void GSTextureCache::Source::Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& rect) +{ + __super::Update(); + + if(m_target) + { + return; + } + + m_TEX0 = TEX0; + m_TEXA = TEXA; + + if(m_blocks == m_total_blocks) + { + return; + } + + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[m_TEX0.PSM]; + + GSVector2i bs = psm.bs; + + GSVector4i r = rect.ralign(bs); + + uint32 bp = m_TEX0.TBP0; + uint32 bw = m_TEX0.TBW; + + bool repeating = (1 << m_TEX0.TW) > (bw << 6); // TODO: bw == 0 + + uint32 blocks = 0; + + for(int y = r.top; y < r.bottom; y += bs.y) + { + uint32 base = psm.bn(0, y, bp, bw); + + for(int x = r.left; x < r.right; x += bs.x) + { + uint32 block = base + psm.blockOffset[x >> 3]; + + if(block < MAX_BLOCKS) + { + uint32 row = block >> 5; + uint32 col = 1 << (block & 31); + + if((m_valid[row].block & col) == 0) + { + if(!repeating) m_valid[row].block |= col; + + m_valid[row].count++; + + Write(GSVector4i(x, y, x + bs.x, y + bs.y)); + + blocks++; + } + } + } + } + + if(blocks > 0) + { + if(repeating) + { + for(int y = r.top; y < r.bottom; y += bs.y) + { + uint32 base = psm.bn(0, y, bp, bw); + + for(int x = r.left; x < r.right; x += bs.x) + { + uint32 block = base + psm.blockOffset[x >> 3]; + + if(block < MAX_BLOCKS) + { + uint32 row = block >> 5; + uint32 col = 1 << (block & 31); + + m_valid[row].block |= col; + } + } + } + } + + m_blocks += blocks; + + m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, bs.x * bs.y * sizeof(uint32) * blocks); + + Flush(m_write.count); + } +} + +void GSTextureCache::Source::Write(const GSVector4i& r) +{ + m_write.rect[m_write.count++] = r; + + while(m_write.count >= 2) + { + GSVector4i& a = m_write.rect[m_write.count - 2]; + GSVector4i& b = m_write.rect[m_write.count - 1]; + + if((a == b.zyxw()).mask() == 0xfff0) + { + a.right = b.right; // extend right + + m_write.count--; + } + else if((a == b.xwzy()).mask() == 0xff0f) + { + a.bottom = b.bottom; // extend down + + m_write.count--; + } + else + { + break; + } + } + + if(m_write.count > 2) + { + Flush(1); + } +} + +void GSTextureCache::Source::Flush(uint32 count) +{ + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[m_TEX0.PSM]; + + int tw = 1 << m_TEX0.TW; + int th = 1 << m_TEX0.TH; + + GSVector4i tr(0, 0, tw, th); + + // TODO + static uint8* buff = (uint8*)_aligned_malloc(1024 * 1024 * sizeof(uint32), 16); + + int pitch = max(tw, psm.bs.x) * sizeof(uint32); + + const GSLocalMemory& mem = m_renderer->m_mem; + + GSLocalMemory::readTexture rtx = psm.rtx; + + for(uint32 i = 0; i < count; i++) + { + GSVector4i r = m_write.rect[i]; + + if((r > tr).mask() & 0xff00) + { + (mem.*rtx)(r, buff, pitch, m_TEX0, m_TEXA); + + m_texture->Update(r.rintersect(tr), buff, pitch); + } + else + { + GSTexture::GSMap m; + + if(m_texture->Map(m, &r)) + { + (mem.*rtx)(r, m.bits, m.pitch, m_TEX0, m_TEXA); + + m_texture->Unmap(); + } + else + { + (mem.*rtx)(r, buff, pitch, m_TEX0, m_TEXA); + + m_texture->Update(r, buff, pitch); + } + } + } + + if(count < m_write.count) + { + memcpy(m_write.rect[0], &m_write.rect[count], (m_write.count - count) * sizeof(m_write.rect[0])); + } + + m_write.count -= count; + + //_aligned_free(buff); +} + +// GSTextureCache::Target + +GSTextureCache::Target::Target(GSRenderer* r) + : Surface(r) + , m_type(-1) + , m_used(false) +{ +} + +bool GSTextureCache::Target::Create(int w, int h, int type) +{ + ASSERT(m_texture == NULL); + + // FIXME: initial data should be unswizzled from local mem in Update() if dirty + + m_type = type; + + if(type == RenderTarget) + { + m_texture = m_renderer->m_dev->CreateRenderTarget(w, h); + + m_used = true; + } + else if(type == DepthStencil) + { + m_texture = m_renderer->m_dev->CreateDepthStencil(w, h); + } + + return m_texture != NULL; +} + +void GSTextureCache::Target::Update() +{ + __super::Update(); + + // FIXME: the union of the rects may also update wrong parts of the render target (but a lot faster :) + + GSVector4i r = m_dirty.GetDirtyRectAndClear(m_TEX0, m_texture->GetSize()); + + if(r.rempty()) return; + + if(m_type == RenderTarget) + { + int w = r.width(); + int h = r.height(); + + if(GSTexture* t = m_renderer->m_dev->CreateTexture(w, h)) + { + GIFRegTEXA TEXA; + + TEXA.AEM = 1; + TEXA.TA0 = 0; + TEXA.TA1 = 0x80; + + GSTexture::GSMap m; + + if(t->Map(m)) + { + m_renderer->m_mem.ReadTexture(r, m.bits, m.pitch, m_TEX0, TEXA); + + t->Unmap(); + } + else + { + static uint8* buff = (uint8*)::_aligned_malloc(1024 * 1024 * 4, 16); + + int pitch = ((w + 3) & ~3) * 4; + + m_renderer->m_mem.ReadTexture(r, buff, pitch, m_TEX0, TEXA); + + t->Update(r.rsize(), buff, pitch); + } + + // m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, w * h * 4); + + m_renderer->m_dev->StretchRect(t, m_texture, GSVector4(r) * GSVector4(m_texture->m_scale).xyxy()); + + m_renderer->m_dev->Recycle(t); + } + } + else if(m_type == DepthStencil) + { + // do the most likely thing a direct write would do, clear it + + m_renderer->m_dev->ClearDepth(m_texture, 0); + } +} + +// GSTextureCache::SourceMap + +void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0) +{ + m_surfaces[s] = true; + + int tw = 1 << TEX0.TW; + int th = 1 << TEX0.TH; + + uint32 bp = TEX0.TBP0; + uint32 bw = TEX0.TBW; + + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; + + GSVector2i bs = psm.bs; + + int blocks = 0; + + for(int y = 0; y < th; y += bs.y) + { + uint32 base = psm.bn(0, y, bp, bw); + + for(int x = 0; x < tw; x += bs.x) + { + uint32 block = base + psm.blockOffset[x >> 3]; + + if(block < MAX_BLOCKS) + { + m_map[block >> 5][s] = true; + + blocks++; + } + } + } + + s->m_blocks = 0; + s->m_total_blocks = blocks; +} + +void GSTextureCache::SourceMap::RemoveAll() +{ + for(hash_map::iterator i = m_surfaces.begin(); i != m_surfaces.end(); i++) + { + delete i->first; + } + + m_surfaces.clear(); + + for(int i = 0; i < MAX_PAGES; i++) + { + m_map[i].clear(); + } +} + +void GSTextureCache::SourceMap::RemoveAt(Source* s) +{ + m_surfaces.erase(s); + + for(int i = 0; i < countof(m_map); i++) + { + m_map[i].erase(s); + } + + delete s; +} diff --git a/plugins/GSdx/GSTextureCache.h b/plugins/GSdx/GSTextureCache.h index bc84dad34c..277b5d046f 100644 --- a/plugins/GSdx/GSTextureCache.h +++ b/plugins/GSdx/GSTextureCache.h @@ -23,794 +23,104 @@ #include "GSRenderer.h" -template class GSTextureCache +class GSTextureCache { - typedef typename Device::Texture Texture; - public: - class GSSurface + enum {RenderTarget, DepthStencil}; + + class Surface : public GSAlignedClass<16> { protected: - GSRenderer* m_renderer; - - typedef typename Device::Texture Texture; + GSRenderer* m_renderer; public: - Texture m_texture; - Texture m_palette; - bool m_initpalette; - int m_age; - GSDirtyRectList m_dirty; + GSTexture* m_texture; GIFRegTEX0 m_TEX0; - - explicit GSSurface(GSRenderer* renderer) - : m_renderer(renderer) - , m_age(0) - , m_initpalette(false) - { - m_TEX0.TBP0 = (UINT32)~0; - } - - virtual ~GSSurface() - { - m_renderer->m_dev.Recycle(m_texture); - m_renderer->m_dev.Recycle(m_palette); - } - - virtual void Update() - { - m_age = 0; - } - }; - - class GSRenderTarget : public GSSurface - { - public: - bool m_used; - - explicit GSRenderTarget(GSRenderer* renderer) - : GSSurface(renderer) - , m_used(true) - { - } - - virtual bool Create(int w, int h) - { - // FIXME: initial data should be unswizzled from local mem in Update() if dirty - - return m_renderer->m_dev.CreateRenderTarget(m_texture, w, h); - } - - virtual void Read(CRect r) = 0; - }; - - class GSDepthStencil : public GSSurface - { - public: - bool m_used; - - explicit GSDepthStencil(GSRenderer* renderer) - : GSSurface(renderer) - , m_used(false) - { - } - - virtual bool Create(int w, int h) - { - // FIXME: initial data should be unswizzled from local mem in Update() if dirty - - return m_renderer->m_dev.CreateDepthStencil(m_texture, w, h); - } - - }; - - class GSTexture : public GSSurface - { - protected: - bool GetDirtyRect(CRect& rr) - { - int w = 1 << m_TEX0.TW; - int h = 1 << m_TEX0.TH; - - CRect r(0, 0, w, h); - - POSITION pos = m_dirty.GetHeadPosition(); - - while(pos) - { - const CRect& dirty = m_dirty.GetNext(pos).GetDirtyRect(m_TEX0) & r; - - if(!(m_valid & dirty).IsRectEmpty()) - { - // find the rect having the largest area, outside dirty, inside m_valid - - CRect left(m_valid.left, m_valid.top, min(m_valid.right, dirty.left), m_valid.bottom); - CRect top(m_valid.left, m_valid.top, m_valid.right, min(m_valid.bottom, dirty.top)); - CRect right(max(m_valid.left, dirty.right), m_valid.top, m_valid.right, m_valid.bottom); - CRect bottom(m_valid.left, max(m_valid.top, dirty.bottom), m_valid.right, m_valid.bottom); - - int leftsize = !left.IsRectEmpty() ? left.Width() * left.Height() : 0; - int topsize = !top.IsRectEmpty() ? top.Width() * top.Height() : 0; - int rightsize = !right.IsRectEmpty() ? right.Width() * right.Height() : 0; - int bottomsize = !bottom.IsRectEmpty() ? bottom.Width() * bottom.Height() : 0; - - // TODO: sort - - m_valid = - leftsize > 0 ? left : - topsize > 0 ? top : - rightsize > 0 ? right : - bottomsize > 0 ? bottom : - CRect(0, 0, 0, 0); - } - } - - m_dirty.RemoveAll(); - - m_renderer->MinMaxUV(w, h, r); - - if(GSUtil::IsRectInRect(r, m_valid)) - { - return false; - } - else if(GSUtil::IsRectInRectH(r, m_valid) && (r.left >= m_valid.left || r.right <= m_valid.right)) - { - r.top = m_valid.top; - r.bottom = m_valid.bottom; - if(r.left < m_valid.left) r.right = m_valid.left; - else r.left = m_valid.right; // if(r.right > m_valid.right) - } - else if(GSUtil::IsRectInRectV(r, m_valid) && (r.top >= m_valid.top || r.bottom <= m_valid.bottom)) - { - r.left = m_valid.left; - r.right = m_valid.right; - if(r.top < m_valid.top) r.bottom = m_valid.top; - else r.top = m_valid.bottom; // if(r.bottom > m_valid.bottom) - } - else - { - r |= m_valid; - } - - if(r.IsRectEmpty()) - { - return false; - } - - rr = r; - - return true; - } + GIFRegTEXA m_TEXA; + int m_age; public: - GIFRegCLAMP m_CLAMP; - DWORD* m_clut; // * - CRect m_valid; + explicit Surface(GSRenderer* r); + virtual ~Surface(); + + virtual void Update(); + }; + + class Target; + + class Source : public Surface + { + struct {GSVector4i* rect; uint32 count;} m_write; + + void Write(const GSVector4i& r); + void Flush(uint32 count); + + public: + GSTexture* m_palette; + bool m_initpalette; + uint32 m_blocks, m_total_blocks; + struct {uint32 block, count;} m_valid[MAX_PAGES]; // each uint32 bits map to the 32 blocks of that page + uint32* m_clut; int m_bpp; - int m_bpp2; - bool m_rendered; + bool m_target; - explicit GSTexture(GSRenderer* renderer) - : GSSurface(renderer) - , m_valid(0, 0, 0, 0) - , m_bpp(0) - , m_bpp2(0) - , m_rendered(false) - { - m_clut = (DWORD*)_aligned_malloc(256 * sizeof(DWORD), 16); - - memset(m_clut, 0, sizeof(m_clut)); - } - - ~GSTexture() - { - _aligned_free(m_clut); - } + public: + explicit Source(GSRenderer* renderer); + virtual ~Source(); virtual bool Create() = 0; - virtual bool Create(GSRenderTarget* rt) = 0; - virtual bool Create(GSDepthStencil* ds) = 0; + virtual bool Create(Target* dst) = 0; + virtual void Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& rect); + }; + + class Target : public Surface + { + public: + int m_type; + bool m_used; + GSDirtyRectList m_dirty; + + public: + explicit Target(GSRenderer* r); + + virtual bool Create(int w, int h, int type); + virtual void Update(); + virtual void Read(const GSVector4i& r) = 0; }; protected: - GSRenderer* m_renderer; - CAtlList m_rt; - CAtlList m_ds; - CAtlList m_tex; + GSRenderer* m_renderer; - template void RecycleByAge(CAtlList& l, int maxage = 60) + struct SourceMap { - POSITION pos = l.GetHeadPosition(); + hash_map m_surfaces; + hash_map m_map[MAX_PAGES]; + bool m_used; - while(pos) - { - POSITION cur = pos; + SourceMap() : m_used(false) {} - T* t = l.GetNext(pos); + void Add(Source* s, const GIFRegTEX0& TEX0); + void RemoveAll(); + void RemoveAt(Source* s); - if(++t->m_age > maxage) - { - l.RemoveAt(cur); + } m_src; - delete t; - } - } - } + list m_dst[2]; - virtual GSRenderTarget* CreateRenderTarget() = 0; - virtual GSDepthStencil* CreateDepthStencil() = 0; - virtual GSTexture* CreateTexture() = 0; + virtual Source* CreateSource() = 0; + virtual Target* CreateTarget() = 0; public: - GSTextureCache(GSRenderer* renderer) - : m_renderer(renderer) - { - } + GSTextureCache(GSRenderer* r); + virtual ~GSTextureCache(); - virtual ~GSTextureCache() - { - RemoveAll(); - } + void RemoveAll(); - void RemoveAll() - { - while(m_rt.GetCount()) delete m_rt.RemoveHead(); - while(m_ds.GetCount()) delete m_ds.RemoveHead(); - while(m_tex.GetCount()) delete m_tex.RemoveHead(); - } + Source* LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r); + Target* LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used, bool fb = false); - GSRenderTarget* GetRenderTarget(const GIFRegTEX0& TEX0, int w, int h, bool fb = false) - { - GSRenderTarget* rt = NULL; + void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool target = true); + void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r); - if(rt == NULL) - { - for(POSITION pos = m_rt.GetHeadPosition(); pos; m_rt.GetNext(pos)) - { - GSRenderTarget* rt2 = m_rt.GetAt(pos); - - if(rt2->m_TEX0.TBP0 == TEX0.TBP0) - { - m_rt.MoveToHead(pos); - - rt = rt2; - - if(!fb) rt->m_TEX0 = TEX0; - - rt->Update(); - - break; - } - } - } - - if(rt == NULL && fb) - { - // HACK: try to find something close to the base pointer - - for(POSITION pos = m_rt.GetHeadPosition(); pos; m_rt.GetNext(pos)) - { - GSRenderTarget* rt2 = m_rt.GetAt(pos); - - if(rt2->m_TEX0.TBP0 <= TEX0.TBP0 && TEX0.TBP0 < rt2->m_TEX0.TBP0 + 0x700 && (!rt || rt2->m_TEX0.TBP0 >= rt->m_TEX0.TBP0)) - { - rt = rt2; - } - } - - if(rt) - { - rt->Update(); - } - } - - if(rt == NULL) - { - rt = CreateRenderTarget(); - - rt->m_TEX0 = TEX0; - - if(!rt->Create(w, h)) - { - delete rt; - - return NULL; - } - - m_rt.AddHead(rt); - } - - if(m_renderer->CanUpscale()) - { - int ww = (int)(m_renderer->GetFramePos().cx + rt->m_TEX0.TBW * 64); - int hh = (int)(m_renderer->GetFramePos().cy + m_renderer->GetDisplaySize().cy); - - if(hh <= m_renderer->GetDeviceSize().cy / 2) - { - hh *= 2; - } - - if(ww > 0 && hh > 0) - { - rt->m_texture.m_scale.x = (float)w / ww; - rt->m_texture.m_scale.y = (float)h / hh; - } - } - - if(!fb) - { - rt->m_used = true; - } - - return rt; - } - - GSDepthStencil* GetDepthStencil(const GIFRegTEX0& TEX0, int w, int h) - { - GSDepthStencil* ds = NULL; - - if(ds == NULL) - { - for(POSITION pos = m_ds.GetHeadPosition(); pos; m_ds.GetNext(pos)) - { - GSDepthStencil* ds2 = m_ds.GetAt(pos); - - if(ds2->m_TEX0.TBP0 == TEX0.TBP0) - { - m_ds.MoveToHead(pos); - - ds = ds2; - - ds->m_TEX0 = TEX0; - - ds->Update(); - - break; - } - } - } - - if(ds == NULL) - { - ds = CreateDepthStencil(); - - ds->m_TEX0 = TEX0; - - if(!ds->Create(w, h)) - { - delete ds; - - return NULL; - } - - m_ds.AddHead(ds); - } - - if(m_renderer->m_context->DepthWrite()) - { - ds->m_used = true; - } - - return ds; - } - - GSTexture* GetTexture() - { - const GIFRegTEX0& TEX0 = m_renderer->m_context->TEX0; - const GIFRegCLAMP& CLAMP = m_renderer->m_context->CLAMP; - - const DWORD* clut = m_renderer->m_mem.m_clut; - const int pal = GSLocalMemory::m_psm[TEX0.PSM].pal; - - if(pal > 0) - { - m_renderer->m_mem.m_clut.Read(TEX0); - - /* - POSITION pos = m_tex.GetHeadPosition(); - - while(pos) - { - POSITION cur = pos; - - GSSurface* s = m_tex.GetNext(pos); - - if(s->m_TEX0.TBP0 == TEX0.CBP) - { - m_tex.RemoveAt(cur); - - delete s; - } - } - - pos = m_rt.GetHeadPosition(); - - while(pos) - { - POSITION cur = pos; - - GSSurface* s = m_rt.GetNext(pos); - - if(s->m_TEX0.TBP0 == TEX0.CBP) - { - m_rt.RemoveAt(cur); - - delete s; - } - } - - pos = m_ds.GetHeadPosition(); - - while(pos) - { - POSITION cur = pos; - - GSSurface* s = m_ds.GetNext(pos); - - if(s->m_TEX0.TBP0 == TEX0.CBP) - { - m_ds.RemoveAt(cur); - - delete s; - } - } - */ - } - - GSTexture* t = NULL; - - for(POSITION pos = m_tex.GetHeadPosition(); pos; m_tex.GetNext(pos)) - { - t = m_tex.GetAt(pos); - - if(GSUtil::HasSharedBits(t->m_TEX0.TBP0, t->m_TEX0.PSM, TEX0.TBP0, TEX0.PSM)) - { - if(TEX0.PSM == t->m_TEX0.PSM && TEX0.TBW == t->m_TEX0.TBW - && TEX0.TW == t->m_TEX0.TW && TEX0.TH == t->m_TEX0.TH - && (m_renderer->m_psrr || (CLAMP.WMS != 3 && t->m_CLAMP.WMS != 3 && CLAMP.WMT != 3 && t->m_CLAMP.WMT != 3 || CLAMP.i64 == t->m_CLAMP.i64)) - && (pal == 0 || TEX0.CPSM == t->m_TEX0.CPSM && GSVector4i::compare(t->m_clut, clut, pal * sizeof(clut[0])))) - { - m_tex.MoveToHead(pos); - - break; - } - } - - t = NULL; - } - - if(t == NULL) - { - for(POSITION pos = m_rt.GetHeadPosition(); pos; m_rt.GetNext(pos)) - { - GSRenderTarget* rt = m_rt.GetAt(pos); - - if(rt->m_dirty.IsEmpty() && GSUtil::HasSharedBits(rt->m_TEX0.TBP0, rt->m_TEX0.PSM, TEX0.TBP0, TEX0.PSM)) - { - t = CreateTexture(); - - if(!t->Create(rt)) - { - delete t; - - return NULL; - } - - m_tex.AddHead(t); - - break; - } - } - } - - if(t == NULL) - { - for(POSITION pos = m_ds.GetHeadPosition(); pos; m_ds.GetNext(pos)) - { - GSDepthStencil* ds = m_ds.GetAt(pos); - - if(ds->m_dirty.IsEmpty() && ds->m_used && GSUtil::HasSharedBits(ds->m_TEX0.TBP0, ds->m_TEX0.PSM, TEX0.TBP0, TEX0.PSM)) - { - t = CreateTexture(); - - if(!t->Create(ds)) - { - delete t; - - return NULL; - } - - m_tex.AddHead(t); - - break; - } - } - } - - if(t == NULL) - { - t = CreateTexture(); - - if(!t->Create()) - { - delete t; - - return NULL; - } - - m_tex.AddHead(t); - } - - if(pal > 0) - { - int size = pal * sizeof(clut[0]); - - if(t->m_palette) - { - if(t->m_initpalette) - { - memcpy(t->m_clut, clut, size); - t->m_palette.Update(CRect(0, 0, pal, 1), t->m_clut, size); - t->m_initpalette = false; - } - else - { - if(GSVector4i::update(t->m_clut, clut, size)) - { - t->m_palette.Update(CRect(0, 0, pal, 1), t->m_clut, size); - } - } - } - else - { - memcpy(t->m_clut, clut, size); - } - } - - t->Update(); - - return t; - } - - void InvalidateTextures(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF) - { - POSITION pos = m_tex.GetHeadPosition(); - - while(pos) - { - POSITION cur = pos; - - GSTexture* t = m_tex.GetNext(pos); - - if(GSUtil::HasSharedBits(FRAME.Block(), FRAME.PSM, t->m_TEX0.TBP0, t->m_TEX0.PSM) - || GSUtil::HasSharedBits(ZBUF.Block(), ZBUF.PSM, t->m_TEX0.TBP0, t->m_TEX0.PSM)) - { - m_tex.RemoveAt(cur); - - delete t; - } - } - } - - void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const CRect& r) - { - bool found = false; - - POSITION pos = m_tex.GetHeadPosition(); - - while(pos) - { - POSITION cur = pos; - - GSTexture* t = m_tex.GetNext(pos); - - if(GSUtil::HasSharedBits(BITBLTBUF.DBP, BITBLTBUF.DPSM, t->m_TEX0.TBP0, t->m_TEX0.PSM)) - { - if(BITBLTBUF.DBW == t->m_TEX0.TBW && !t->m_rendered) - { - t->m_dirty.AddTail(GSDirtyRect(BITBLTBUF.DPSM, r)); - - found = true; - } - else - { - m_tex.RemoveAt(cur); - - delete t; - } - } - else if(GSUtil::HasCompatibleBits(BITBLTBUF.DPSM, t->m_TEX0.PSM)) - { - if(BITBLTBUF.DBW == t->m_TEX0.TBW && !t->m_rendered) - { - int rowsize = (int)BITBLTBUF.DBW * 8192; - int offset = ((int)BITBLTBUF.DBP - (int)t->m_TEX0.TBP0) * 256; - - if(rowsize > 0 && offset % rowsize == 0) - { - int y = m_renderer->m_mem.m_psm[BITBLTBUF.DPSM].pgs.cy * offset / rowsize; - - CRect r2(r.left, r.top + y, r.right, r.bottom + y); - - int w = 1 << t->m_TEX0.TW; - int h = 1 << t->m_TEX0.TH; - - if(r2.bottom > 0 && r2.top < h && r2.right > 0 && r2.left < w) - { - t->m_dirty.AddTail(GSDirtyRect(BITBLTBUF.DPSM, r2)); - } - } - } - } - } - - pos = m_rt.GetHeadPosition(); - - while(pos) - { - POSITION cur = pos; - - GSRenderTarget* rt = m_rt.GetNext(pos); - - if(GSUtil::HasSharedBits(BITBLTBUF.DBP, BITBLTBUF.DPSM, rt->m_TEX0.TBP0, rt->m_TEX0.PSM)) - { - if(!found && GSUtil::HasCompatibleBits(BITBLTBUF.DPSM, rt->m_TEX0.PSM)) - { - rt->m_dirty.AddTail(GSDirtyRect(BITBLTBUF.DPSM, r)); - rt->m_TEX0.TBW = BITBLTBUF.DBW; - } - else - { - m_rt.RemoveAt(cur); - delete rt; - continue; - } - } - - if(GSUtil::HasSharedBits(BITBLTBUF.DPSM, rt->m_TEX0.PSM) && BITBLTBUF.DBP < rt->m_TEX0.TBP0) - { - DWORD rowsize = BITBLTBUF.DBW * 8192; - DWORD offset = (DWORD)((rt->m_TEX0.TBP0 - BITBLTBUF.DBP) * 256); - - if(rowsize > 0 && offset % rowsize == 0) - { - int y = m_renderer->m_mem.m_psm[BITBLTBUF.DPSM].pgs.cy * offset / rowsize; - - if(r.bottom > y) - { - // TODO: do not add this rect above too - rt->m_dirty.AddTail(GSDirtyRect(BITBLTBUF.DPSM, CRect(r.left, r.top - y, r.right, r.bottom - y))); - rt->m_TEX0.TBW = BITBLTBUF.DBW; - continue; - } - } - } - } - - // copypaste for ds - - pos = m_ds.GetHeadPosition(); - - while(pos) - { - POSITION cur = pos; - - GSDepthStencil* ds = m_ds.GetNext(pos); - - if(GSUtil::HasSharedBits(BITBLTBUF.DBP, BITBLTBUF.DPSM, ds->m_TEX0.TBP0, ds->m_TEX0.PSM)) - { - if(!found && GSUtil::HasCompatibleBits(BITBLTBUF.DPSM, ds->m_TEX0.PSM)) - { - ds->m_dirty.AddTail(GSDirtyRect(BITBLTBUF.DPSM, r)); - ds->m_TEX0.TBW = BITBLTBUF.DBW; - } - else - { - m_ds.RemoveAt(cur); - delete ds; - continue; - } - } - - if(GSUtil::HasSharedBits(BITBLTBUF.DPSM, ds->m_TEX0.PSM) && BITBLTBUF.DBP < ds->m_TEX0.TBP0) - { - DWORD rowsize = BITBLTBUF.DBW * 8192; - DWORD offset = (DWORD)((ds->m_TEX0.TBP0 - BITBLTBUF.DBP) * 256); - - if(rowsize > 0 && offset % rowsize == 0) - { - int y = m_renderer->m_mem.m_psm[BITBLTBUF.DPSM].pgs.cy * offset / rowsize; - - if(r.bottom > y) - { - // TODO: do not add this rect above too - ds->m_dirty.AddTail(GSDirtyRect(BITBLTBUF.DPSM, CRect(r.left, r.top - y, r.right, r.bottom - y))); - ds->m_TEX0.TBW = BITBLTBUF.DBW; - continue; - } - } - } - - } - } - - void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const CRect& r) - { - POSITION pos = m_rt.GetHeadPosition(); - - while(pos) - { - POSITION cur = pos; - - GSRenderTarget* rt = m_rt.GetNext(pos); - - if(GSUtil::HasSharedBits(BITBLTBUF.SBP, BITBLTBUF.SPSM, rt->m_TEX0.TBP0, rt->m_TEX0.PSM)) - { - if(GSUtil::HasCompatibleBits(BITBLTBUF.SPSM, rt->m_TEX0.PSM)) - { - rt->Read(r); - return; - } - else if(BITBLTBUF.SPSM == PSM_PSMCT32 && (rt->m_TEX0.PSM == PSM_PSMCT16 || rt->m_TEX0.PSM == PSM_PSMCT16S)) - { - // ffx-2 riku changing to her default (shoots some reflecting glass at the end), 16-bit rt read as 32-bit - - rt->Read(CRect(r.left, r.top, r.right, r.top + (r.bottom - r.top) * 2)); - return; - } - else - { - m_rt.RemoveAt(cur); - delete rt; - continue; - } - } - } -/* - // no good, ffx does a lot of readback after exiting menu, at 0x02f00 this wrongly finds rt 0x02100 (0,448 - 512,480) - - GSRenderTarget* rt2 = NULL; - int ymin = INT_MAX; - - pos = m_rt.GetHeadPosition(); - - while(pos) - { - GSRenderTarget* rt = m_rt.GetNext(pos); - - if(HasSharedBits(BITBLTBUF.SPSM, rt->m_TEX0.PSM) && BITBLTBUF.SBP > rt->m_TEX0.TBP0) - { - // ffx2 pause screen background - - DWORD rowsize = BITBLTBUF.SBW * 8192; - DWORD offset = (DWORD)((BITBLTBUF.SBP - rt->m_TEX0.TBP0) * 256); - - if(rowsize > 0 && offset % rowsize == 0) - { - int y = m_renderer->m_mem.m_psm[BITBLTBUF.SPSM].pgs.cy * offset / rowsize; - - if(y < ymin && y < 512) - { - rt2 = rt; - ymin = y; - } - } - } - } - - if(rt2) - { - rt2->Read(CRect(r.left, r.top + ymin, r.right, r.bottom + ymin)); - } - - // TODO: ds -*/ - } - - void IncAge() - { - RecycleByAge(m_tex, 2); - RecycleByAge(m_rt); - RecycleByAge(m_ds); - } + void IncAge(); }; diff --git a/plugins/GSdx/GSTextureCache10.cpp b/plugins/GSdx/GSTextureCache10.cpp index 68c989325f..e4914cb09f 100644 --- a/plugins/GSdx/GSTextureCache10.cpp +++ b/plugins/GSdx/GSTextureCache10.cpp @@ -24,233 +24,48 @@ // GSTextureCache10 -GSTextureCache10::GSTextureCache10(GSRenderer* renderer) - : GSTextureCache(renderer) +GSTextureCache10::GSTextureCache10(GSRenderer* r) + : GSTextureCache(r) { } -// GSRenderTargetHW10 +// Source10 -void GSTextureCache10::GSRenderTargetHW10::Update() -{ - __super::Update(); - - // FIXME: the union of the rects may also update wrong parts of the render target (but a lot faster :) - - CRect r = m_dirty.GetDirtyRect(m_TEX0, m_texture.GetSize()); - - m_dirty.RemoveAll(); - - if(r.IsRectEmpty()) return; - - int w = r.Width(); - int h = r.Height(); - - static BYTE* buff = (BYTE*)_aligned_malloc(1024 * 1024 * 4, 16); - static int pitch = 1024 * 4; - - GIFRegTEXA TEXA; - - TEXA.AEM = 1; - TEXA.TA0 = 0; - TEXA.TA1 = 0x80; - - GIFRegCLAMP CLAMP; - - CLAMP.WMS = 0; - CLAMP.WMT = 0; - - m_renderer->m_mem.ReadTexture(r, buff, pitch, m_TEX0, TEXA, CLAMP); - - // s->m_perfmon.Put(GSPerfMon::Unswizzle, w * h * 4); - - Texture texture; - - if(!m_renderer->m_dev.CreateTexture(texture, w, h)) - return; - - texture.Update(CRect(0, 0, w, h), buff, pitch); - - GSVector4 dr( - m_texture.m_scale.x * r.left, - m_texture.m_scale.y * r.top, - m_texture.m_scale.x * r.right, - m_texture.m_scale.y * r.bottom); - - m_renderer->m_dev.StretchRect(texture, m_texture, dr); - - m_renderer->m_dev.Recycle(texture); -} - -void GSTextureCache10::GSRenderTargetHW10::Read(CRect r) -{ - if(m_TEX0.PSM != PSM_PSMCT32 - && m_TEX0.PSM != PSM_PSMCT24 - && m_TEX0.PSM != PSM_PSMCT16 - && m_TEX0.PSM != PSM_PSMCT16S) - { - //ASSERT(0); - return; - } - - if(!m_dirty.IsEmpty()) - { - return; - } - - TRACE(_T("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n"), r.left, r.top, r.right, r.bottom, m_TEX0.TBP0); - - // m_renderer->m_perfmon.Put(GSPerfMon::ReadRT, 1); - - int w = r.Width(); - int h = r.Height(); - - GSVector4 src; - - src.x = m_texture.m_scale.x * r.left / m_texture.GetWidth(); - src.y = m_texture.m_scale.y * r.top / m_texture.GetHeight(); - src.z = m_texture.m_scale.x * r.right / m_texture.GetWidth(); - src.w = m_texture.m_scale.y * r.bottom / m_texture.GetHeight(); - - DXGI_FORMAT format = m_TEX0.PSM == PSM_PSMCT16 || m_TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM; - - Texture offscreen; - - if(!m_renderer->m_dev.CopyOffscreen(m_texture, src, offscreen, w, h, format)) - return; - - BYTE* bits; - int pitch; - - if(offscreen.Map(&bits, pitch)) - { - // TODO: block level write - - DWORD bp = m_TEX0.TBP0; - DWORD bw = m_TEX0.TBW; - - GSLocalMemory::pixelAddress pa = GSLocalMemory::m_psm[m_TEX0.PSM].pa; - - if(m_TEX0.PSM == PSM_PSMCT32) - { - for(int y = r.top; y < r.bottom; y++, bits += pitch) - { - DWORD addr = pa(0, y, bp, bw); - int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; - - for(int x = r.left, i = 0; x < r.right; x++, i++) - { - m_renderer->m_mem.WritePixel32(addr + offset[x], ((DWORD*)bits)[i]); - } - } - } - else if(m_TEX0.PSM == PSM_PSMCT24) - { - for(int y = r.top; y < r.bottom; y++, bits += pitch) - { - DWORD addr = pa(0, y, bp, bw); - int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; - - for(int x = r.left, i = 0; x < r.right; x++, i++) - { - m_renderer->m_mem.WritePixel24(addr + offset[x], ((DWORD*)bits)[i]); - } - } - } - else if(m_TEX0.PSM == PSM_PSMCT16 || m_TEX0.PSM == PSM_PSMCT16S) - { - for(int y = r.top; y < r.bottom; y++, bits += pitch) - { - DWORD addr = pa(0, y, bp, bw); - int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; - - for(int x = r.left, i = 0; x < r.right; x++, i++) - { - m_renderer->m_mem.WritePixel16(addr + offset[x], ((WORD*)bits)[i]); - } - } - } - else - { - ASSERT(0); - } - - offscreen.Unmap(); - } - - m_renderer->m_dev.Recycle(offscreen); -} - -// GSDepthStencilHW10 - -void GSTextureCache10::GSDepthStencilHW10::Update() -{ - __super::Update(); - - // TODO -} - -// GSTextureHW10 - -bool GSTextureCache10::GSTextureHW10::Create() +bool GSTextureCache10::Source10::Create() { // m_renderer->m_perfmon.Put(GSPerfMon::WriteTexture, 1); m_TEX0 = m_renderer->m_context->TEX0; - m_CLAMP = m_renderer->m_context->CLAMP; + m_TEXA = m_renderer->m_env.TEXA; - DWORD psm = m_TEX0.PSM; + m_bpp = 0; - switch(psm) - { - case PSM_PSMT8: - case PSM_PSMT8H: - case PSM_PSMT4: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - psm = m_TEX0.CPSM; - break; - } + ASSERT(m_texture == NULL); - DXGI_FORMAT format; + m_texture = m_renderer->m_dev->CreateTexture(1 << m_TEX0.TW, 1 << m_TEX0.TH); - switch(psm) - { - default: - TRACE(_T("Invalid TEX0.PSM/CPSM (%I64d, %I64d)\n"), m_TEX0.PSM, m_TEX0.CPSM); - case PSM_PSMCT32: - m_bpp = 32; - m_bpp2 = 0; - format = DXGI_FORMAT_R8G8B8A8_UNORM; - break; - case PSM_PSMCT24: - m_bpp = 32; - m_bpp2 = 1; - format = DXGI_FORMAT_R8G8B8A8_UNORM; - break; - case PSM_PSMCT16: - case PSM_PSMCT16S: - m_bpp = 16; - m_bpp2 = 5; - format = DXGI_FORMAT_R16_UNORM; - break; - } - - int w = 1 << m_TEX0.TW; - int h = 1 << m_TEX0.TH; - - return m_renderer->m_dev.CreateTexture(m_texture, w, h, format); + return m_texture != NULL; } -bool GSTextureCache10::GSTextureHW10::Create(GSRenderTarget* rt) +bool GSTextureCache10::Source10::Create(Target* dst) { - rt->Update(); + m_target = true; + + if(dst->m_type != RenderTarget) + { + // TODO + + return false; + } + + // TODO: clean up this mess + + dst->Update(); // m_renderer->m_perfmon.Put(GSPerfMon::ConvertRT2T, 1); m_TEX0 = m_renderer->m_context->TEX0; - m_CLAMP = m_renderer->m_context->CLAMP; - m_rendered = true; + m_TEXA = m_renderer->m_env.TEXA; int tw = 1 << m_TEX0.TW; int th = 1 << m_TEX0.TH; @@ -258,23 +73,32 @@ bool GSTextureCache10::GSTextureHW10::Create(GSRenderTarget* rt) // do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows) - int w = (int)(rt->m_texture.m_scale.x * tw); - int h = (int)(rt->m_texture.m_scale.y * th); + int w = (int)(dst->m_texture->m_scale.x * tw); + int h = (int)(dst->m_texture->m_scale.y * th); + + GSVector2i dstsize = dst->m_texture->GetSize(); // pitch conversion - if(rt->m_TEX0.TBW != m_TEX0.TBW) // && rt->m_TEX0.PSM == m_TEX0.PSM + if(dst->m_TEX0.TBW != m_TEX0.TBW) // && dst->m_TEX0.PSM == m_TEX0.PSM { // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) - // ASSERT(rt->m_TEX0.TBW > m_TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) + // ASSERT(dst->m_TEX0.TBW > m_TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) - m_renderer->m_dev.CreateRenderTarget(m_texture, rt->m_texture.GetWidth(), rt->m_texture.GetHeight()); + ASSERT(m_texture == NULL); + + m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y); + + GSVector4 size = GSVector4(dstsize).xyxy(); + GSVector4 scale = GSVector4(dst->m_texture->m_scale).xyxy(); int bw = 64; int bh = m_TEX0.PSM == PSM_PSMCT32 || m_TEX0.PSM == PSM_PSMCT24 ? 32 : 64; - int sw = (int)rt->m_TEX0.TBW << 6; + GSVector4i br(0, 0, bw, bh); + + int sw = (int)dst->m_TEX0.TBW << 6; int dw = (int)m_TEX0.TBW << 6; int dh = 1 << m_TEX0.TH; @@ -289,19 +113,10 @@ bool GSTextureCache10::GSTextureHW10::Create(GSRenderTarget* rt) int sx = o % sw; int sy = o / sw; - GSVector4 src, dst; - - src.x = rt->m_texture.m_scale.x * sx / rt->m_texture.GetWidth(); - src.y = rt->m_texture.m_scale.y * sy / rt->m_texture.GetHeight(); - src.z = rt->m_texture.m_scale.x * (sx + bw) / rt->m_texture.GetWidth(); - src.w = rt->m_texture.m_scale.y * (sy + bh) / rt->m_texture.GetHeight(); - - dst.x = rt->m_texture.m_scale.x * dx; - dst.y = rt->m_texture.m_scale.y * dy; - dst.z = rt->m_texture.m_scale.x * (dx + bw); - dst.w = rt->m_texture.m_scale.y * (dy + bh); - - m_renderer->m_dev.StretchRect(rt->m_texture, src, m_texture, dst); + GSVector4 sr = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size; + GSVector4 dr = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale; + + m_renderer->m_dev->StretchRect(dst->m_texture, sr, m_texture, dr); // TODO: this is quite a lot of StretchRect, do it with one Draw } @@ -319,81 +134,72 @@ bool GSTextureCache10::GSTextureHW10::Create(GSRenderTarget* rt) // width/height conversion - GSVector2 scale = rt->m_texture.m_scale; + GSVector2 scale = dst->m_texture->m_scale; - GSVector4 dst(0, 0, w, h); + GSVector4 dr(0, 0, w, h); - if(w > rt->m_texture.GetWidth()) + if(w > dstsize.x) { - scale.x = (float)rt->m_texture.GetWidth() / tw; - dst.z = (float)rt->m_texture.GetWidth() * scale.x / rt->m_texture.m_scale.x; - w = rt->m_texture.GetWidth(); + scale.x = (float)dstsize.x / tw; + dr.z = (float)dstsize.x * scale.x / dst->m_texture->m_scale.x; + w = dstsize.x; } - if(h > rt->m_texture.GetHeight()) + if(h > dstsize.y) { - scale.y = (float)rt->m_texture.GetHeight() / th; - dst.w = (float)rt->m_texture.GetHeight() * scale.y / rt->m_texture.m_scale.y; - h = rt->m_texture.GetHeight(); + scale.y = (float)dstsize.y / th; + dr.w = (float)dstsize.y * scale.y / dst->m_texture->m_scale.y; + h = dstsize.y; } - GSVector4 src(0, 0, w, h); + GSVector4 sr(0, 0, w, h); - Texture* st; - Texture* dt; - Texture tmp; + GSTexture* st = m_texture ? m_texture : dst->m_texture; + GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h); if(!m_texture) { - st = &rt->m_texture; - dt = &m_texture; - } - else - { - st = &m_texture; - dt = &tmp; + m_texture = dt; } - m_renderer->m_dev.CreateRenderTarget(*dt, w, h); - - if(src.x == dst.x && src.y == dst.y && src.z == dst.z && src.w == dst.w) + if((sr == dr).alltrue()) { D3D10_BOX box = {0, 0, 0, w, h, 1}; - m_renderer->m_dev->CopySubresourceRegion(*dt, 0, 0, 0, 0, *st, 0, &box); + (*(GSDevice10*)m_renderer->m_dev)->CopySubresourceRegion(*(GSTexture10*)dt, 0, 0, 0, 0, *(GSTexture10*)st, 0, &box); } else { - src.z /= st->GetWidth(); - src.w /= st->GetHeight(); + sr.z /= st->GetWidth(); + sr.w /= st->GetHeight(); - m_renderer->m_dev.StretchRect(*st, src, *dt, dst); + m_renderer->m_dev->StretchRect(st, sr, dt, dr); } - if(tmp) + if(dt != m_texture) { - m_renderer->m_dev.Recycle(m_texture); + m_renderer->m_dev->Recycle(m_texture); - m_texture = tmp; + m_texture = dt; } - m_texture.m_scale = scale; + m_texture->m_scale = scale; switch(m_TEX0.PSM) { case PSM_PSMCT32: - m_bpp2 = 0; + m_bpp = 0; break; case PSM_PSMCT24: - m_bpp2 = 1; + m_bpp = 1; break; case PSM_PSMCT16: case PSM_PSMCT16S: - m_bpp2 = 2; + m_bpp = 2; break; case PSM_PSMT8H: - m_bpp2 = 3; - m_renderer->m_dev.CreateTexture(m_palette, 256, 1, m_TEX0.CPSM == PSM_PSMCT32 ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGI_FORMAT_R16_UNORM); // + m_bpp = 3; + m_palette = m_renderer->m_dev->CreateTexture(256, 1); m_initpalette = true; break; case PSM_PSMT4HL: @@ -405,48 +211,104 @@ bool GSTextureCache10::GSTextureHW10::Create(GSRenderTarget* rt) return true; } -bool GSTextureCache10::GSTextureHW10::Create(GSDepthStencil* ds) + +// Target10 + +void GSTextureCache10::Target10::Read(const GSVector4i& r) { - m_rendered = true; + if(m_type != RenderTarget) + { + // TODO - // TODO + return; + } - return false; -} + if(m_TEX0.PSM != PSM_PSMCT32 + && m_TEX0.PSM != PSM_PSMCT24 + && m_TEX0.PSM != PSM_PSMCT16 + && m_TEX0.PSM != PSM_PSMCT16S) + { + //ASSERT(0); -void GSTextureCache10::GSTextureHW10::Update() -{ - __super::Update(); + return; + } - if(m_rendered) + if(!m_dirty.empty()) { return; } - CRect r; + // printf("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n", r.left, r.top, r.right, r.bottom, m_TEX0.TBP0); - if(!GetDirtyRect(r)) + // m_renderer->m_perfmon.Put(GSPerfMon::ReadRT, 1); + + int w = r.width(); + int h = r.height(); + + GSVector4 src = GSVector4(r) * GSVector4(m_texture->m_scale).xyxy() / GSVector4(m_texture->GetSize()).xyxy(); + + DXGI_FORMAT format = m_TEX0.PSM == PSM_PSMCT16 || m_TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM; + + if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(m_texture, src, w, h, format)) { - return; + GSTexture::GSMap m; + + if(offscreen->Map(m)) + { + // TODO: block level write + + uint32 bp = m_TEX0.TBP0; + uint32 bw = m_TEX0.TBW; + + GSLocalMemory::pixelAddress pa = GSLocalMemory::m_psm[m_TEX0.PSM].pa; + + if(m_TEX0.PSM == PSM_PSMCT32) + { + for(int y = r.top; y < r.bottom; y++, m.bits += m.pitch) + { + uint32 addr = pa(0, y, bp, bw); + int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; + + for(int x = r.left, i = 0; x < r.right; x++, i++) + { + m_renderer->m_mem.WritePixel32(addr + offset[x], ((uint32*)m.bits)[i]); + } + } + } + else if(m_TEX0.PSM == PSM_PSMCT24) + { + for(int y = r.top; y < r.bottom; y++, m.bits += m.pitch) + { + uint32 addr = pa(0, y, bp, bw); + int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; + + for(int x = r.left, i = 0; x < r.right; x++, i++) + { + m_renderer->m_mem.WritePixel24(addr + offset[x], ((uint32*)m.bits)[i]); + } + } + } + else if(m_TEX0.PSM == PSM_PSMCT16 || m_TEX0.PSM == PSM_PSMCT16S) + { + for(int y = r.top; y < r.bottom; y++, m.bits += m.pitch) + { + uint32 addr = pa(0, y, bp, bw); + int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; + + for(int x = r.left, i = 0; x < r.right; x++, i++) + { + m_renderer->m_mem.WritePixel16(addr + offset[x], ((uint16*)m.bits)[i]); + } + } + } + else + { + ASSERT(0); + } + + offscreen->Unmap(); + } + + m_renderer->m_dev->Recycle(offscreen); } - - m_valid |= r; - - //TRACE(_T("GSTexture::Update %d,%d - %d,%d (%08x)\n"), r.left, r.top, r.right, r.bottom, m_TEX0.TBP0); - - static BYTE* bits = (BYTE*)::_aligned_malloc(1024 * 1024 * 4, 16); - int pitch = 1024 * 4; - - if(m_renderer->m_psrr) - { - m_renderer->m_mem.ReadTextureNPNC(r, bits, pitch, m_renderer->m_context->TEX0, m_renderer->m_env.TEXA, m_renderer->m_context->CLAMP); - } - else - { - m_renderer->m_mem.ReadTextureNP(r, bits, pitch, m_renderer->m_context->TEX0, m_renderer->m_env.TEXA, m_renderer->m_context->CLAMP); - } - - m_texture.Update(r, bits, pitch); - - m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, r.Width() * r.Height() * m_bpp >> 3); } diff --git a/plugins/GSdx/GSTextureCache10.h b/plugins/GSdx/GSTextureCache10.h index 48b304325a..857d37c4e7 100644 --- a/plugins/GSdx/GSTextureCache10.h +++ b/plugins/GSdx/GSTextureCache10.h @@ -24,43 +24,29 @@ #include "GSTextureCache.h" #include "GSDevice10.h" -class GSTextureCache10 : public GSTextureCache +class GSTextureCache10 : public GSTextureCache { - typedef GSDevice10::Texture Texture; - - class GSRenderTargetHW10 : public GSRenderTarget + class Source10 : public Source { public: - explicit GSRenderTargetHW10(GSRenderer* renderer) : GSRenderTarget(renderer) {} - - void Update(); - void Read(CRect r); - }; - - class GSDepthStencilHW10 : public GSDepthStencil - { - public: - explicit GSDepthStencilHW10(GSRenderer* renderer) : GSDepthStencil(renderer) {} - - void Update(); - }; - - class GSTextureHW10 : public GSTexture - { - public: - explicit GSTextureHW10(GSRenderer* renderer) : GSTexture(renderer) {} + explicit Source10(GSRenderer* r) : Source(r) {} bool Create(); - bool Create(GSRenderTarget* rt); - bool Create(GSDepthStencil* ds); - void Update(); + bool Create(Target* dst); + }; + + class Target10 : public Target + { + public: + explicit Target10(GSRenderer* r) : Target(r) {} + + void Read(const GSVector4i& r); }; protected: - GSRenderTarget* CreateRenderTarget() {return new GSRenderTargetHW10(m_renderer);} - GSDepthStencil* CreateDepthStencil() {return new GSDepthStencilHW10(m_renderer);} - GSTexture* CreateTexture() {return new GSTextureHW10(m_renderer);} + Source* CreateSource() {return new Source10(m_renderer);} + Target* CreateTarget() {return new Target10(m_renderer);} public: - GSTextureCache10(GSRenderer* renderer); + GSTextureCache10(GSRenderer* r); }; diff --git a/plugins/GSdx/GSTextureCache11.cpp b/plugins/GSdx/GSTextureCache11.cpp new file mode 100644 index 0000000000..fc0e4ee0b4 --- /dev/null +++ b/plugins/GSdx/GSTextureCache11.cpp @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "StdAfx.h" +#include "GSTextureCache11.h" + +// GSTextureCache11 + +GSTextureCache11::GSTextureCache11(GSRenderer* r) + : GSTextureCache(r) +{ +} + +// Source11 + +bool GSTextureCache11::Source11::Create() +{ + // m_renderer->m_perfmon.Put(GSPerfMon::WriteTexture, 1); + + m_TEX0 = m_renderer->m_context->TEX0; + m_TEXA = m_renderer->m_env.TEXA; + + m_bpp = 0; + + ASSERT(m_texture == NULL); + + m_texture = m_renderer->m_dev->CreateTexture(1 << m_TEX0.TW, 1 << m_TEX0.TH); + + return m_texture != NULL; +} + +bool GSTextureCache11::Source11::Create(Target* dst) +{ + m_target = true; + + if(dst->m_type != RenderTarget) + { + // TODO + + return false; + } + + // TODO: clean up this mess + + dst->Update(); + + // m_renderer->m_perfmon.Put(GSPerfMon::ConvertRT2T, 1); + + m_TEX0 = m_renderer->m_context->TEX0; + m_TEXA = m_renderer->m_env.TEXA; + + int tw = 1 << m_TEX0.TW; + int th = 1 << m_TEX0.TH; + int tp = (int)m_TEX0.TW << 6; + + // do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows) + + int w = (int)(dst->m_texture->m_scale.x * tw); + int h = (int)(dst->m_texture->m_scale.y * th); + + GSVector2i dstsize = dst->m_texture->GetSize(); + + // pitch conversion + + if(dst->m_TEX0.TBW != m_TEX0.TBW) // && dst->m_TEX0.PSM == m_TEX0.PSM + { + // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) + + // ASSERT(dst->m_TEX0.TBW > m_TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) + + ASSERT(m_texture == NULL); + + m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y); + + GSVector4 size = GSVector4(dstsize).xyxy(); + GSVector4 scale = GSVector4(dst->m_texture->m_scale).xyxy(); + + int bw = 64; + int bh = m_TEX0.PSM == PSM_PSMCT32 || m_TEX0.PSM == PSM_PSMCT24 ? 32 : 64; + + GSVector4i br(0, 0, bw, bh); + + int sw = (int)dst->m_TEX0.TBW << 6; + + int dw = (int)m_TEX0.TBW << 6; + int dh = 1 << m_TEX0.TH; + + if(sw != 0) + for(int dy = 0; dy < dh; dy += bh) + { + for(int dx = 0; dx < dw; dx += bw) + { + int o = dy * dw / bh + dx; + + int sx = o % sw; + int sy = o / sw; + + GSVector4 sr = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size; + GSVector4 dr = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale; + + m_renderer->m_dev->StretchRect(dst->m_texture, sr, m_texture, dr); + + // TODO: this is quite a lot of StretchRect, do it with one Draw + } + } + } + else if(tw < tp) + { + // FIXME: timesplitters blurs the render target by blending itself over a couple of times + + if(tw == 256 && th == 128 && tp == 512 && (m_TEX0.TBP0 == 0 || m_TEX0.TBP0 == 0x00e00)) + { + return false; + } + } + + // width/height conversion + + GSVector2 scale = dst->m_texture->m_scale; + + GSVector4 dr(0, 0, w, h); + + if(w > dstsize.x) + { + scale.x = (float)dstsize.x / tw; + dr.z = (float)dstsize.x * scale.x / dst->m_texture->m_scale.x; + w = dstsize.x; + } + + if(h > dstsize.y) + { + scale.y = (float)dstsize.y / th; + dr.w = (float)dstsize.y * scale.y / dst->m_texture->m_scale.y; + h = dstsize.y; + } + + GSVector4 sr(0, 0, w, h); + + GSTexture* st = m_texture ? m_texture : dst->m_texture; + GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h); + + if(!m_texture) + { + m_texture = dt; + } + + if((sr == dr).alltrue()) + { + D3D11_BOX box = {0, 0, 0, w, h, 1}; + + ID3D11DeviceContext* ctx = *(GSDevice11*)m_renderer->m_dev; + + ctx->CopySubresourceRegion(*(GSTexture11*)dt, 0, 0, 0, 0, *(GSTexture11*)st, 0, &box); + } + else + { + sr.z /= st->GetWidth(); + sr.w /= st->GetHeight(); + + m_renderer->m_dev->StretchRect(st, sr, dt, dr); + } + + if(dt != m_texture) + { + m_renderer->m_dev->Recycle(m_texture); + + m_texture = dt; + } + + m_texture->m_scale = scale; + + switch(m_TEX0.PSM) + { + case PSM_PSMCT32: + m_bpp = 0; + break; + case PSM_PSMCT24: + m_bpp = 1; + break; + case PSM_PSMCT16: + case PSM_PSMCT16S: + m_bpp = 2; + break; + case PSM_PSMT8H: + m_bpp = 3; + m_palette = m_renderer->m_dev->CreateTexture(256, 1); + m_initpalette = true; + break; + case PSM_PSMT4HL: + case PSM_PSMT4HH: + ASSERT(0); // TODO + break; + } + + return true; +} + +// Target11 + +void GSTextureCache11::Target11::Read(const GSVector4i& r) +{ + if(m_type != RenderTarget) + { + // TODO + + return; + } + + if(m_TEX0.PSM != PSM_PSMCT32 + && m_TEX0.PSM != PSM_PSMCT24 + && m_TEX0.PSM != PSM_PSMCT16 + && m_TEX0.PSM != PSM_PSMCT16S) + { + //ASSERT(0); + + return; + } + + if(!m_dirty.empty()) + { + return; + } + + // printf("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n", r.left, r.top, r.right, r.bottom, m_TEX0.TBP0); + + // m_renderer->m_perfmon.Put(GSPerfMon::ReadRT, 1); + + int w = r.width(); + int h = r.height(); + + GSVector4 src = GSVector4(r) * GSVector4(m_texture->m_scale).xyxy() / GSVector4(m_texture->GetSize()).xyxy(); + + DXGI_FORMAT format = m_TEX0.PSM == PSM_PSMCT16 || m_TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM; + + if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(m_texture, src, w, h, format)) + { + GSTexture::GSMap m; + + if(offscreen->Map(m)) + { + // TODO: block level write + + uint32 bp = m_TEX0.TBP0; + uint32 bw = m_TEX0.TBW; + + GSLocalMemory::pixelAddress pa = GSLocalMemory::m_psm[m_TEX0.PSM].pa; + + if(m_TEX0.PSM == PSM_PSMCT32) + { + for(int y = r.top; y < r.bottom; y++, m.bits += m.pitch) + { + uint32 addr = pa(0, y, bp, bw); + int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; + + for(int x = r.left, i = 0; x < r.right; x++, i++) + { + m_renderer->m_mem.WritePixel32(addr + offset[x], ((uint32*)m.bits)[i]); + } + } + } + else if(m_TEX0.PSM == PSM_PSMCT24) + { + for(int y = r.top; y < r.bottom; y++, m.bits += m.pitch) + { + uint32 addr = pa(0, y, bp, bw); + int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; + + for(int x = r.left, i = 0; x < r.right; x++, i++) + { + m_renderer->m_mem.WritePixel24(addr + offset[x], ((uint32*)m.bits)[i]); + } + } + } + else if(m_TEX0.PSM == PSM_PSMCT16 || m_TEX0.PSM == PSM_PSMCT16S) + { + for(int y = r.top; y < r.bottom; y++, m.bits += m.pitch) + { + uint32 addr = pa(0, y, bp, bw); + int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; + + for(int x = r.left, i = 0; x < r.right; x++, i++) + { + m_renderer->m_mem.WritePixel16(addr + offset[x], ((uint16*)m.bits)[i]); + } + } + } + else + { + ASSERT(0); + } + + offscreen->Unmap(); + } + + m_renderer->m_dev->Recycle(offscreen); + } +} + diff --git a/plugins/GSdx/GSTextureCache11.h b/plugins/GSdx/GSTextureCache11.h new file mode 100644 index 0000000000..d02c9c5f71 --- /dev/null +++ b/plugins/GSdx/GSTextureCache11.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSTextureCache.h" +#include "GSDevice11.h" + +class GSTextureCache11 : public GSTextureCache +{ + class Source11 : public Source + { + public: + explicit Source11(GSRenderer* r) : Source(r) {} + + bool Create(); + bool Create(Target* dst); + }; + + class Target11 : public Target + { + public: + explicit Target11(GSRenderer* r) : Target(r) {} + + void Read(const GSVector4i& r); + }; + +protected: + Source* CreateSource() {return new Source11(m_renderer);} + Target* CreateTarget() {return new Target11(m_renderer);} + +public: + GSTextureCache11(GSRenderer* r); +}; diff --git a/plugins/GSdx/GSTextureCache9.cpp b/plugins/GSdx/GSTextureCache9.cpp index 31fe12f84a..6b33249851 100644 --- a/plugins/GSdx/GSTextureCache9.cpp +++ b/plugins/GSdx/GSTextureCache9.cpp @@ -24,234 +24,48 @@ // GSTextureCache9 -GSTextureCache9::GSTextureCache9(GSRenderer* renderer) - : GSTextureCache(renderer) +GSTextureCache9::GSTextureCache9(GSRenderer* r) + : GSTextureCache(r) { } -// GSRenderTarget9 +// Source9 -void GSTextureCache9::GSRenderTarget9::Update() -{ - __super::Update(); - - // FIXME: the union of the rects may also update wrong parts of the render target (but a lot faster :) - - CRect r = m_dirty.GetDirtyRect(m_TEX0, m_texture.GetSize()); - - m_dirty.RemoveAll(); - - if(r.IsRectEmpty()) return; - - int w = r.Width(); - int h = r.Height(); - - Texture texture; - - if(!m_renderer->m_dev.CreateTexture(texture, w, h)) - return; - - BYTE* bits; - int pitch; - - if(texture.Map(&bits, pitch)) - { - GIFRegTEXA TEXA; - - TEXA.AEM = 1; - TEXA.TA0 = 0; - TEXA.TA1 = 0x80; - - GIFRegCLAMP CLAMP; - - CLAMP.WMS = 0; - CLAMP.WMT = 0; - - m_renderer->m_mem.ReadTexture(r, bits, pitch, m_TEX0, TEXA, CLAMP); - - texture.Unmap(); - - // m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, r.Width() * r.Height() * 4); - - GSVector4 dr( - m_texture.m_scale.x * r.left, - m_texture.m_scale.y * r.top, - m_texture.m_scale.x * r.right, - m_texture.m_scale.y * r.bottom); - - m_renderer->m_dev.StretchRect(texture, m_texture, dr); - } - - m_renderer->m_dev.Recycle(texture); -} - -void GSTextureCache9::GSRenderTarget9::Read(CRect r) -{ - if(m_TEX0.PSM != PSM_PSMCT32 - && m_TEX0.PSM != PSM_PSMCT24 - && m_TEX0.PSM != PSM_PSMCT16 - && m_TEX0.PSM != PSM_PSMCT16S) - { - //ASSERT(0); - return; - } - - if(!m_dirty.IsEmpty()) - { - return; - } - - TRACE(_T("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n"), r.left, r.top, r.right, r.bottom, m_TEX0.TBP0); - - // m_renderer->m_perfmon.Put(GSPerfMon::ReadRT, 1); - - int w = r.Width(); - int h = r.Height(); - - GSVector4 src; - - src.x = m_texture.m_scale.x * r.left / m_texture.GetWidth(); - src.y = m_texture.m_scale.y * r.top / m_texture.GetHeight(); - src.z = m_texture.m_scale.x * r.right / m_texture.GetWidth(); - src.w = m_texture.m_scale.y * r.bottom / m_texture.GetHeight(); - - Texture offscreen; - - if(!m_renderer->m_dev.CopyOffscreen(m_texture, src, offscreen, w, h)) - return; - - BYTE* bits; - int pitch; - - if(offscreen.Map(&bits, pitch)) - { - // TODO: block level write - - DWORD bp = m_TEX0.TBP0; - DWORD bw = m_TEX0.TBW; - - GSLocalMemory::pixelAddress pa = GSLocalMemory::m_psm[m_TEX0.PSM].pa; - - if(m_TEX0.PSM == PSM_PSMCT32) - { - for(int y = r.top; y < r.bottom; y++, bits += pitch) - { - DWORD addr = pa(0, y, bp, bw); - int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; - - for(int x = r.left, i = 0; x < r.right; x++, i++) - { - m_renderer->m_mem.WritePixel32(addr + offset[x], ((DWORD*)bits)[i]); - } - } - } - else if(m_TEX0.PSM == PSM_PSMCT24) - { - for(int y = r.top; y < r.bottom; y++, bits += pitch) - { - DWORD addr = pa(0, y, bp, bw); - int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; - - for(int x = r.left, i = 0; x < r.right; x++, i++) - { - m_renderer->m_mem.WritePixel24(addr + offset[x], ((DWORD*)bits)[i]); - } - } - } - else if(m_TEX0.PSM == PSM_PSMCT16 || m_TEX0.PSM == PSM_PSMCT16S) - { - for(int y = r.top; y < r.bottom; y++, bits += pitch) - { - DWORD addr = pa(0, y, bp, bw); - int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; - - for(int x = r.left, i = 0; x < r.right; x++, i++) - { - m_renderer->m_mem.WriteFrame16(addr + offset[x], ((DWORD*)bits)[i]); - } - } - } - else - { - ASSERT(0); - } - - offscreen.Unmap(); - } - - m_renderer->m_dev.Recycle(offscreen); -} - -// GSDepthStencil9 - -void GSTextureCache9::GSDepthStencil9::Update() -{ - __super::Update(); - - // TODO -} - -// GSTexture9 - -bool GSTextureCache9::GSTexture9::Create() +bool GSTextureCache9::Source9::Create() { // m_renderer->m_perfmon.Put(GSPerfMon::WriteTexture, 1); m_TEX0 = m_renderer->m_context->TEX0; - m_CLAMP = m_renderer->m_context->CLAMP; + m_TEXA = m_renderer->m_env.TEXA; - DWORD psm = m_TEX0.PSM; + m_bpp = 0; - switch(psm) - { - case PSM_PSMT8: - case PSM_PSMT8H: - case PSM_PSMT4: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - psm = m_TEX0.CPSM; - break; - } + ASSERT(m_texture == NULL); - D3DFORMAT format; + m_texture = m_renderer->m_dev->CreateTexture(1 << m_TEX0.TW, 1 << m_TEX0.TH); - switch(psm) - { - default: - TRACE(_T("Invalid TEX0.PSM/CPSM (%I64d, %I64d)\n"), m_TEX0.PSM, m_TEX0.CPSM); - case PSM_PSMCT32: - m_bpp = 32; - m_bpp2 = 0; - format = D3DFMT_A8R8G8B8; - break; - case PSM_PSMCT24: - m_bpp = 32; - m_bpp2 = 1; - format = D3DFMT_A8R8G8B8; - break; - case PSM_PSMCT16: - case PSM_PSMCT16S: - m_bpp = 16; - m_bpp2 = 2; - format = D3DFMT_A1R5G5B5; - break; - } - - int w = 1 << m_TEX0.TW; - int h = 1 << m_TEX0.TH; - - return m_renderer->m_dev.CreateTexture(m_texture, w, h, format); + return m_texture != NULL; } -bool GSTextureCache9::GSTexture9::Create(GSRenderTarget* rt) +bool GSTextureCache9::Source9::Create(Target* dst) { - rt->Update(); + m_target = true; + + if(dst->m_type != RenderTarget) + { + // TODO + + return false; + } + + // TODO: clean up this mess + + dst->Update(); // m_renderer->m_perfmon.Put(GSPerfMon::ConvertRT2T, 1); m_TEX0 = m_renderer->m_context->TEX0; - m_CLAMP = m_renderer->m_context->CLAMP; - m_rendered = true; + m_TEXA = m_renderer->m_env.TEXA; int tw = 1 << m_TEX0.TW; int th = 1 << m_TEX0.TH; @@ -259,27 +73,37 @@ bool GSTextureCache9::GSTexture9::Create(GSRenderTarget* rt) // do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows) - int w = (int)(rt->m_texture.m_scale.x * tw); - int h = (int)(rt->m_texture.m_scale.y * th); + int w = (int)(dst->m_texture->m_scale.x * tw); + int h = (int)(dst->m_texture->m_scale.y * th); + + GSVector2i dstsize = dst->m_texture->GetSize(); // pitch conversion - if(rt->m_TEX0.TBW != m_TEX0.TBW) // && rt->m_TEX0.PSM == m_TEX0.PSM + if(dst->m_TEX0.TBW != m_TEX0.TBW) // && dst->m_TEX0.PSM == m_TEX0.PSM { // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) - // ASSERT(rt->m_TEX0.TBW > m_TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) + // ASSERT(dst->m_TEX0.TBW > m_TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) - m_renderer->m_dev.CreateRenderTarget(m_texture, rt->m_texture.GetWidth(), rt->m_texture.GetHeight()); + ASSERT(m_texture == NULL); + + m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y); + + GSVector4 size = GSVector4(dstsize).xyxy(); + GSVector4 scale = GSVector4(dst->m_texture->m_scale).xyxy(); int bw = 64; int bh = m_TEX0.PSM == PSM_PSMCT32 || m_TEX0.PSM == PSM_PSMCT24 ? 32 : 64; - int sw = (int)rt->m_TEX0.TBW << 6; + GSVector4i br(0, 0, bw, bh); + + int sw = (int)dst->m_TEX0.TBW << 6; int dw = (int)m_TEX0.TBW << 6; int dh = 1 << m_TEX0.TH; + if(sw != 0) for(int dy = 0; dy < dh; dy += bh) { for(int dx = 0; dx < dw; dx += bw) @@ -289,19 +113,10 @@ bool GSTextureCache9::GSTexture9::Create(GSRenderTarget* rt) int sx = o % sw; int sy = o / sw; - GSVector4 src, dst; + GSVector4 sr = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size; + GSVector4 dr = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale; - src.x = rt->m_texture.m_scale.x * sx / rt->m_texture.GetWidth(); - src.y = rt->m_texture.m_scale.y * sy / rt->m_texture.GetHeight(); - src.z = rt->m_texture.m_scale.x * (sx + bw) / rt->m_texture.GetWidth(); - src.w = rt->m_texture.m_scale.y * (sy + bh) / rt->m_texture.GetHeight(); - - dst.x = rt->m_texture.m_scale.x * dx; - dst.y = rt->m_texture.m_scale.y * dy; - dst.z = rt->m_texture.m_scale.x * (dx + bw); - dst.w = rt->m_texture.m_scale.y * (dy + bh); - - m_renderer->m_dev.StretchRect(rt->m_texture, src, m_texture, dst); + m_renderer->m_dev->StretchRect(dst->m_texture, sr, m_texture, dr); // TODO: this is quite a lot of StretchRect, do it with one Draw } @@ -319,81 +134,72 @@ bool GSTextureCache9::GSTexture9::Create(GSRenderTarget* rt) // width/height conversion - GSVector2 scale = rt->m_texture.m_scale; + GSVector2 scale = dst->m_texture->m_scale; - GSVector4 dst(0, 0, w, h); + GSVector4 dr(0, 0, w, h); - if(w > rt->m_texture.GetWidth()) + if(w > dstsize.x) { - scale.x = (float)rt->m_texture.GetWidth() / tw; - dst.z = (float)rt->m_texture.GetWidth() * scale.x / rt->m_texture.m_scale.x; - w = rt->m_texture.GetWidth(); + scale.x = (float)dstsize.x / tw; + dr.z = (float)dstsize.x * scale.x / dst->m_texture->m_scale.x; + w = dstsize.x; } - if(h > rt->m_texture.GetHeight()) + if(h > dstsize.y) { - scale.y = (float)rt->m_texture.GetHeight() / th; - dst.w = (float)rt->m_texture.GetHeight() * scale.y / rt->m_texture.m_scale.y; - h = rt->m_texture.GetHeight(); + scale.y = (float)dstsize.y / th; + dr.w = (float)dstsize.y * scale.y / dst->m_texture->m_scale.y; + h = dstsize.y; } - GSVector4 src(0, 0, w, h); + GSVector4 sr(0, 0, w, h); - Texture* st; - Texture* dt; - Texture tmp; + GSTexture* st = m_texture ? m_texture : dst->m_texture; + GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h); if(!m_texture) { - st = &rt->m_texture; - dt = &m_texture; + m_texture = dt; + } + + if((sr == dr).alltrue()) + { + GSVector4i r(0, 0, w, h); + + (*(GSDevice9*)m_renderer->m_dev)->StretchRect(*(GSTexture9*)st, r, *(GSTexture9*)dt, r, D3DTEXF_POINT); } else { - st = &m_texture; - dt = &tmp; + sr.z /= st->GetWidth(); + sr.w /= st->GetHeight(); + + m_renderer->m_dev->StretchRect(st, sr, dt, dr); } - m_renderer->m_dev.CreateRenderTarget(*dt, w, h); - - if(src.x == dst.x && src.y == dst.y && src.z == dst.z && src.w == dst.w) + if(dt != m_texture) { - CRect r(0, 0, w, h); + m_renderer->m_dev->Recycle(m_texture); - m_renderer->m_dev->StretchRect(*st, r, *dt, r, D3DTEXF_POINT); - } - else - { - src.z /= st->GetWidth(); - src.w /= st->GetHeight(); - - m_renderer->m_dev.StretchRect(*st, src, *dt, dst); + m_texture = dt; } - if(tmp) - { - m_renderer->m_dev.Recycle(m_texture); - - m_texture = tmp; - } - - m_texture.m_scale = scale; + m_texture->m_scale = scale; switch(m_TEX0.PSM) { case PSM_PSMCT32: - m_bpp2 = 0; + m_bpp = 0; break; case PSM_PSMCT24: - m_bpp2 = 1; + m_bpp = 1; break; case PSM_PSMCT16: case PSM_PSMCT16S: - m_bpp2 = 2; + m_bpp = 2; break; case PSM_PSMT8H: - m_bpp2 = 3; - m_renderer->m_dev.CreateTexture(m_palette, 256, 1, m_TEX0.CPSM == PSM_PSMCT32 ? D3DFMT_A8R8G8B8 : D3DFMT_A1R5G5B5); + m_bpp = 3; + m_palette = m_renderer->m_dev->CreateTexture(256, 1); m_initpalette = true; break; case PSM_PSMT4HL: @@ -405,49 +211,103 @@ bool GSTextureCache9::GSTexture9::Create(GSRenderTarget* rt) return true; } -bool GSTextureCache9::GSTexture9::Create(GSDepthStencil* ds) + +// Target9 + +void GSTextureCache9::Target9::Read(const GSVector4i& r) { - m_rendered = true; + if(m_type != RenderTarget) + { + // TODO - // TODO + return; + } - return false; -} + if(m_TEX0.PSM != PSM_PSMCT32 + && m_TEX0.PSM != PSM_PSMCT24 + && m_TEX0.PSM != PSM_PSMCT16 + && m_TEX0.PSM != PSM_PSMCT16S) + { + //ASSERT(0); -void GSTextureCache9::GSTexture9::Update() -{ - __super::Update(); + return; + } - if(m_rendered) + if(!m_dirty.empty()) { return; } - CRect r; + // printf("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n", r.left, r.top, r.right, r.bottom, m_TEX0.TBP0); - if(!GetDirtyRect(r)) + // m_renderer->m_perfmon.Put(GSPerfMon::ReadRT, 1); + + int w = r.width(); + int h = r.height(); + + GSVector4 src = GSVector4(r) * GSVector4(m_texture->m_scale).xyxy() / GSVector4(m_texture->GetSize()).xyxy(); + + if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(m_texture, src, w, h)) { - return; - } + GSTexture::GSMap m; - m_valid |= r; - - BYTE* bits; - int pitch; - - if(m_texture.Map(&bits, pitch, &r)) - { - if(m_renderer->m_psrr) + if(offscreen->Map(m)) { - m_renderer->m_mem.ReadTextureNPNC(r, bits, pitch, m_renderer->m_context->TEX0, m_renderer->m_env.TEXA, m_renderer->m_context->CLAMP); - } - else - { - m_renderer->m_mem.ReadTextureNP(r, bits, pitch, m_renderer->m_context->TEX0, m_renderer->m_env.TEXA, m_renderer->m_context->CLAMP); + // TODO: block level write + + uint32 bp = m_TEX0.TBP0; + uint32 bw = m_TEX0.TBW; + + GSLocalMemory::pixelAddress pa = GSLocalMemory::m_psm[m_TEX0.PSM].pa; + + if(m_TEX0.PSM == PSM_PSMCT32) + { + for(int y = r.top; y < r.bottom; y++, m.bits += m.pitch) + { + uint32 addr = pa(0, y, bp, bw); + int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; + + for(int x = r.left, i = 0; x < r.right; x++, i++) + { + m_renderer->m_mem.WritePixel32(addr + offset[x], ((uint32*)m.bits)[i]); + } + } + } + else if(m_TEX0.PSM == PSM_PSMCT24) + { + for(int y = r.top; y < r.bottom; y++, m.bits += m.pitch) + { + uint32 addr = pa(0, y, bp, bw); + int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; + + for(int x = r.left, i = 0; x < r.right; x++, i++) + { + m_renderer->m_mem.WritePixel24(addr + offset[x], ((uint32*)m.bits)[i]); + } + } + } + else if(m_TEX0.PSM == PSM_PSMCT16 || m_TEX0.PSM == PSM_PSMCT16S) + { + for(int y = r.top; y < r.bottom; y++, m.bits += m.pitch) + { + uint32 addr = pa(0, y, bp, bw); + int* offset = GSLocalMemory::m_psm[m_TEX0.PSM].rowOffset[y & 7]; + + for(int x = r.left, i = 0; x < r.right; x++, i++) + { + m_renderer->m_mem.WriteFrame16(addr + offset[x], ((uint32*)m.bits)[i]); + } + } + } + else + { + ASSERT(0); + } + + offscreen->Unmap(); } - m_texture.Unmap(); + m_renderer->m_dev->Recycle(offscreen); } - - m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, r.Width() * r.Height() * m_bpp >> 3); } + diff --git a/plugins/GSdx/GSTextureCache9.h b/plugins/GSdx/GSTextureCache9.h index e0f73ec01a..0d0aedb2e9 100644 --- a/plugins/GSdx/GSTextureCache9.h +++ b/plugins/GSdx/GSTextureCache9.h @@ -24,43 +24,29 @@ #include "GSTextureCache.h" #include "GSDevice9.h" -class GSTextureCache9 : public GSTextureCache +class GSTextureCache9 : public GSTextureCache { - typedef GSDevice9::Texture Texture; - - class GSRenderTarget9 : public GSRenderTarget + class Source9 : public Source { public: - explicit GSRenderTarget9(GSRenderer* renderer) : GSRenderTarget(renderer) {} - - void Update(); - void Read(CRect r); - }; - - class GSDepthStencil9 : public GSDepthStencil - { - public: - explicit GSDepthStencil9(GSRenderer* renderer) : GSDepthStencil(renderer) {} - - void Update(); - }; - - class GSTexture9 : public GSTexture - { - public: - explicit GSTexture9(GSRenderer* renderer) : GSTexture(renderer) {} + explicit Source9(GSRenderer* r) : Source(r) {} bool Create(); - bool Create(GSRenderTarget* rt); - bool Create(GSDepthStencil* ds); - void Update(); + bool Create(Target* dst); + }; + + class Target9 : public Target + { + public: + explicit Target9(GSRenderer* r) : Target(r) {} + + void Read(const GSVector4i& r); }; protected: - GSRenderTarget* CreateRenderTarget() {return new GSRenderTarget9(m_renderer);} - GSDepthStencil* CreateDepthStencil() {return new GSDepthStencil9(m_renderer);} - GSTexture* CreateTexture() {return new GSTexture9(m_renderer);} + Source* CreateSource() {return new Source9(m_renderer);} + Target* CreateTarget() {return new Target9(m_renderer);} public: - GSTextureCache9(GSRenderer* renderer); + GSTextureCache9(GSRenderer* r); }; \ No newline at end of file diff --git a/plugins/GSdx/GSTextureCacheOGL.cpp b/plugins/GSdx/GSTextureCacheOGL.cpp new file mode 100644 index 0000000000..99131040df --- /dev/null +++ b/plugins/GSdx/GSTextureCacheOGL.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "StdAfx.h" +#include "GSTextureCacheOGL.h" + +// GSTextureCacheOGL + +GSTextureCacheOGL::GSTextureCacheOGL(GSRenderer* r) + : GSTextureCache(r) +{ +} + +// SourceOGL + +bool GSTextureCacheOGL::SourceOGL::Create() +{ + // TODO + + return true; +} + +bool GSTextureCacheOGL::SourceOGL::Create(Target* dst) +{ + m_target = true; + + // TODO + + return true; +} + +// TargetOGL + +void GSTextureCacheOGL::TargetOGL::Read(const GSVector4i& r) +{ + // TODO +} diff --git a/plugins/GSdx/GSTextureCacheOGL.h b/plugins/GSdx/GSTextureCacheOGL.h new file mode 100644 index 0000000000..41bb7d4c8b --- /dev/null +++ b/plugins/GSdx/GSTextureCacheOGL.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSTextureCache.h" +#include "GSDeviceOGL.h" + +class GSTextureCacheOGL : public GSTextureCache +{ + class SourceOGL : public Source + { + public: + explicit SourceOGL(GSRenderer* r) : Source(r) {} + + bool Create(); + bool Create(Target* dst); + }; + + class TargetOGL : public Target + { + public: + explicit TargetOGL(GSRenderer* r) : Target(r) {} + + void Read(const GSVector4i& r); + }; + +protected: + Source* CreateSource() {return new SourceOGL(m_renderer);} + Target* CreateTarget() {return new TargetOGL(m_renderer);} + +public: + GSTextureCacheOGL(GSRenderer* r); +}; diff --git a/plugins/GSdx/GSTextureCacheSW.cpp b/plugins/GSdx/GSTextureCacheSW.cpp index e1b6e66aa2..17bd198170 100644 --- a/plugins/GSdx/GSTextureCacheSW.cpp +++ b/plugins/GSdx/GSTextureCacheSW.cpp @@ -22,54 +22,38 @@ #include "StdAfx.h" #include "GSTextureCacheSW.h" -// static FILE* m_log = NULL; - GSTextureCacheSW::GSTextureCacheSW(GSState* state) : m_state(state) { - // m_log = _tfopen(_T("c:\\log.txt"), _T("w")); } GSTextureCacheSW::~GSTextureCacheSW() { - // fclose(m_log); - RemoveAll(); } -const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const CRect* r) +const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r) { - GSLocalMemory& mem = m_state->m_mem; - const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; - const CAtlList& t2p = m_p2t[TEX0.TBP0 >> 5]; - - // fprintf(m_log, "lu %05x %d %d (%d) ", TEX0.TBP0, TEX0.TBW, TEX0.PSM, t2p.GetCount()); - - // if(r) fprintf(m_log, "(%d %d %d %d) ", r->left, r->top, r->right, r->bottom); - GSTexture* t = NULL; - POSITION pos = t2p.GetHeadPosition(); + const hash_map& map = m_map[TEX0.TBP0 >> 5]; - while(pos) + for(hash_map::const_iterator i = map.begin(); i != map.end(); i++) { - GSTexture* t2 = t2p.GetNext(pos)->t; + GSTexture* t2 = i->first; - // if(t2->m_TEX0.TBP0 != TEX0.TBP0 || t2->m_TEX0.TBW != TEX0.TBW || t2->m_TEX0.PSM != TEX0.PSM || t2->m_TEX0.TW != TEX0.TW || t2->m_TEX0.TH != TEX0.TH) - if(((t2->m_TEX0.ai32[0] ^ TEX0.ai32[0]) | ((t2->m_TEX0.ai32[1] ^ TEX0.ai32[1]) & 3)) != 0) + if(((t2->m_TEX0.u32[0] ^ TEX0.u32[0]) | ((t2->m_TEX0.u32[1] ^ TEX0.u32[1]) & 3)) != 0) // TBP0 TBW PSM TW TH { continue; } - if((psm.trbpp == 16 || psm.trbpp == 24) && (t2->m_TEX0.TCC != TEX0.TCC || TEX0.TCC == 1 && !(t2->m_TEXA == (GSVector4i)TEXA).alltrue())) + if((psm.trbpp == 16 || psm.trbpp == 24) && TEX0.TCC && TEXA != t2->m_TEXA) { continue; } - // fprintf(m_log, "cache hit\n"); - t = t2; t->m_age = 0; @@ -79,50 +63,47 @@ const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TE if(t == NULL) { - // fprintf(m_log, "cache miss\n"); - t = new GSTexture(m_state); - t->m_pos = m_textures.AddTail(t); + m_textures[t] = true; int tw = 1 << TEX0.TW; int th = 1 << TEX0.TH; - DWORD bp = TEX0.TBP0; - DWORD bw = TEX0.TBW; + uint32 bp = TEX0.TBP0; + uint32 bw = TEX0.TBW; - for(int j = 0, y = 0; y < th; j++, y += psm.pgs.cy) + GSVector2i s = (bp & 31) == 0 ? psm.pgs : psm.bs; + + for(int y = 0; y < th; y += s.y) { - DWORD page = psm.pgn(0, y, bp, bw); + uint32 base = psm.bn(0, y, bp, bw); - for(int i = 0, x = 0; x < tw && page < MAX_PAGES; i++, x += psm.pgs.cx, page++) + for(int x = 0; x < tw; x += s.x) { - GSTexturePage* p = new GSTexturePage(); - - p->t = t; - p->row = j; - p->col = i; + uint32 page = (base + psm.blockOffset[x >> 3]) >> 5; - GSTexturePageEntry* p2te = new GSTexturePageEntry(); - - p2te->p2t = &m_p2t[page]; - p2te->pos = m_p2t[page].AddHead(p); - - t->m_p2te.AddTail(p2te); - - t->m_maxpages++; + if(page < MAX_PAGES) + { + m_map[page][t] = true; + } } } } if(!t->Update(TEX0, TEXA, r)) { - m_textures.RemoveAt(t->m_pos); + printf("!@#$%\n"); // memory allocation may fail if the game is too hungry + + m_textures.erase(t); + + for(int i = 0; i < MAX_PAGES; i++) + { + m_map[i].erase(t); + } delete t; - printf("!@#$%\n"); // memory allocation may fail if the game is too hungry - return NULL; } @@ -131,96 +112,74 @@ const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TE void GSTextureCacheSW::RemoveAll() { - POSITION pos = m_textures.GetHeadPosition(); - - while(pos) + for(hash_map::iterator i = m_textures.begin(); i != m_textures.end(); i++) { - delete m_textures.GetNext(pos); + delete i->first; } - m_textures.RemoveAll(); + m_textures.clear(); for(int i = 0; i < MAX_PAGES; i++) { - CAtlList& t2p = m_p2t[i]; - - ASSERT(t2p.IsEmpty()); - - POSITION pos = t2p.GetHeadPosition(); - - while(pos) - { - delete t2p.GetNext(pos); - } - - t2p.RemoveAll(); + m_map[i].clear(); } } void GSTextureCacheSW::IncAge() { - POSITION pos = m_textures.GetHeadPosition(); - - while(pos) + for(hash_map::iterator i = m_textures.begin(); i != m_textures.end(); ) { - POSITION cur = pos; + hash_map::iterator j = i++; - GSTexture* t = m_textures.GetNext(pos); + GSTexture* t = j->first; - if(++t->m_age > 3) + if(++t->m_age > 30) { - m_textures.RemoveAt(cur); + m_textures.erase(j); + + for(int i = 0; i < MAX_PAGES; i++) + { + m_map[i].erase(t); + } delete t; } } } -void GSTextureCacheSW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const CRect& r) +void GSTextureCacheSW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& rect) { const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[BITBLTBUF.DPSM]; - CRect r2; + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; - r2.left = r.left & ~(psm.pgs.cx - 1); - r2.top = r.top & ~(psm.pgs.cy - 1); - r2.right = (r.right + (psm.pgs.cx - 1)) & ~(psm.pgs.cx - 1); - r2.bottom = (r.bottom + (psm.pgs.cy - 1)) & ~(psm.pgs.cy - 1); + GSVector2i s = (bp & 31) == 0 ? psm.pgs : psm.bs; - DWORD bp = BITBLTBUF.DBP; - DWORD bw = BITBLTBUF.DBW; + GSVector4i r = rect.ralign(s); - // fprintf(m_log, "ivm %05x %d %d (%d %d %d %d)\n", bp, bw, BITBLTBUF.DPSM, r2.left, r2.top, r2.right, r2.bottom); - - for(int y = r2.top; y < r2.bottom; y += psm.pgs.cy) + for(int y = r.top; y < r.bottom; y += s.y) { - DWORD page = psm.pgn(r2.left, y, bp, bw); + uint32 base = psm.bn(0, y, bp, bw); - for(int x = r2.left; x < r2.right && page < MAX_PAGES; x += psm.pgs.cx, page++) + for(int x = r.left; x < r.right; x += s.x) { - const CAtlList& t2p = m_p2t[page]; + uint32 page = (base + psm.blockOffset[x >> 3]) >> 5; - POSITION pos = t2p.GetHeadPosition(); - - while(pos) + if(page < MAX_PAGES) { - GSTexturePage* p = t2p.GetNext(pos); + const hash_map& map = m_map[page]; - DWORD flag = 1 << p->col; - - if((p->t->m_valid[p->row] & flag) == 0) + for(hash_map::const_iterator i = map.begin(); i != map.end(); i++) { - continue; - } + GSTexture* t = i->first; - if(GSUtil::HasSharedBits(BITBLTBUF.DPSM, p->t->m_TEX0.PSM)) - { - p->t->m_valid[p->row] &= ~flag; - p->t->m_pages--; + if(GSUtil::HasSharedBits(BITBLTBUF.DPSM, t->m_TEX0.PSM)) + { + t->m_valid[page] = 0; - // fprintf(m_log, "ivm hit %05x %d %d (%d %d) (%d)", p->t->m_TEX0.TBP0, p->t->m_TEX0.TBW, p->t->m_TEX0.PSM, p->row, p->col, p->t->m_pages); - // if(p->t->m_pages == 0) fprintf(m_log, " *"); - // fprintf(m_log, "\n"); + t->m_complete = false; + } } } } @@ -233,10 +192,8 @@ GSTextureCacheSW::GSTexture::GSTexture(GSState* state) : m_state(state) , m_buff(NULL) , m_tw(0) - , m_maxpages(0) - , m_pages(0) - , m_pos(NULL) , m_age(0) + , m_complete(false) { memset(m_valid, 0, sizeof(m_valid)); } @@ -247,30 +204,11 @@ GSTextureCacheSW::GSTexture::~GSTexture() { _aligned_free(m_buff); } - - POSITION pos = m_p2te.GetHeadPosition(); - - while(pos) - { - GSTexturePageEntry* p2te = m_p2te.GetNext(pos); - - GSTexturePage* p = p2te->p2t->GetAt(p2te->pos); - - ASSERT(p->t == this); - - delete p; - - p2te->p2t->RemoveAt(p2te->pos); - - delete p2te; - } - - m_p2te.RemoveAll(); } -bool GSTextureCacheSW::GSTexture::Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const CRect* r) +bool GSTextureCacheSW::GSTexture::Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& rect) { - if(m_pages == m_maxpages) + if(m_complete) { return true; } @@ -278,21 +216,16 @@ bool GSTextureCacheSW::GSTexture::Update(const GIFRegTEX0& TEX0, const GIFRegTEX m_TEX0 = TEX0; m_TEXA = TEXA; - GSLocalMemory& mem = m_state->m_mem; - const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; - int tw = 1 << TEX0.TW; - int th = 1 << TEX0.TH; + GSVector2i s = psm.bs; - if(tw < psm.bs.cx) tw = psm.bs.cx; - if(th < psm.bs.cy) th = psm.bs.cy; + int tw = max(1 << TEX0.TW, s.x); + int th = max(1 << TEX0.TH, s.y); if(m_buff == NULL) { - // fprintf(m_log, "up new (%d %d)\n", tw, th); - - m_buff = _aligned_malloc(tw * th * sizeof(DWORD), 16); + m_buff = _aligned_malloc(tw * th * sizeof(uint32), 16); if(m_buff == NULL) { @@ -302,75 +235,105 @@ bool GSTextureCacheSW::GSTexture::Update(const GIFRegTEX0& TEX0, const GIFRegTEX m_tw = max(psm.pal > 0 ? 5 : 3, TEX0.TW); // makes one row 32 bytes at least, matches the smallest block size that is allocated above for m_buff } - CRect r2; + GSVector4i r = rect.ralign(s); - if(r) + if(r.left == 0 && r.top == 0 && r.right == tw && r.bottom == th) { - r2.left = r->left & ~(psm.pgs.cx - 1); - r2.top = r->top & ~(psm.pgs.cy - 1); - r2.right = (r->right + (psm.pgs.cx - 1)) & ~(psm.pgs.cx - 1); - r2.bottom = (r->bottom + (psm.pgs.cy - 1)) & ~(psm.pgs.cy - 1); + m_complete = true; // lame, but better than nothing } - // TODO + GSLocalMemory& mem = m_state->m_mem; + + uint32 bp = TEX0.TBP0; + uint32 bw = TEX0.TBW; + + GSLocalMemory::readTextureBlock rtxb = psm.rtxbP; - GSLocalMemory::readTexture rt = psm.pal > 0 ? psm.rtxP : psm.rtx; int bytes = psm.pal > 0 ? 1 : 4; - BYTE* dst = (BYTE*)m_buff; + uint32 pitch = (1 << m_tw) * bytes; - DWORD pitch = (1 << m_tw) * bytes; - DWORD mask = pitch - 1; + uint8* dst = (uint8*)m_buff + pitch * r.top; - for(int j = 0, y = 0; y < th; j++, y += psm.pgs.cy, dst += pitch * psm.pgs.cy) + uint32 blocks = 0; + + if(tw <= (bw << 6)) { - if(m_valid[j] == mask) + for(int y = r.top, o = pitch * s.y; y < r.bottom; y += s.y, dst += o) { - continue; + uint32 base = psm.bn(0, y, bp, bw); + + for(int x = r.left; x < r.right; x += s.x) + { + uint32 block = base + psm.blockOffset[x >> 3]; + + if(block < MAX_BLOCKS) + { + uint32 row = block >> 5; + uint32 col = 1 << (block & 31); + + if((m_valid[row] & col) == 0) + { + m_valid[row] |= col; + + (mem.*rtxb)(block, &dst[x * bytes], pitch, TEXA); + + blocks++; + } + } + } + } + } + else + { + // unfortunatelly a block may be part of the same texture multiple times at different places (tw 1024 > tbw 640, between 640 -> 1024 it is repeated from the next row), + // so just can't set the block's bit to valid in one pass, even if 99.9% of the games don't address the repeated part at the right side + + // TODO: still bogus if those repeated parts aren't fetched together + + for(int y = r.top, o = pitch * s.y; y < r.bottom; y += s.y, dst += o) + { + uint32 base = psm.bn(0, y, bp, bw); + + for(int x = r.left; x < r.right; x += s.x) + { + uint32 block = base + psm.blockOffset[x >> 3]; + + if(block < MAX_BLOCKS) + { + uint32 row = block >> 5; + uint32 col = 1 << (block & 31); + + if((m_valid[row] & col) == 0) + { + (mem.*rtxb)(block, &dst[x * bytes], pitch, TEXA); + + blocks++; + } + } + } } - if(r) + for(int y = r.top; y < r.bottom; y += s.y) { - if(y < r2.top) continue; - if(y >= r2.bottom) break; - } + uint32 base = psm.bn(0, y, bp, bw); - DWORD page = psm.pgn(0, y, TEX0.TBP0, TEX0.TBW); - - for(int i = 0, x = 0; x < tw && page < MAX_PAGES; i++, x += psm.pgs.cx, page++) - { - if(r) + for(int x = r.left; x < r.right; x += s.x) { - if(x < r2.left) continue; - if(x >= r2.right) break; + uint32 block = base + psm.blockOffset[x >> 3]; + + if(block < MAX_BLOCKS) + { + uint32 row = block >> 5; + uint32 col = 1 << (block & 31); + + m_valid[row] |= col; + } } - - DWORD flag = 1 << i; - - if(m_valid[j] & flag) - { - continue; - } - - m_valid[j] |= flag; - m_pages++; - - ASSERT(m_pages <= m_maxpages); - - CRect r; - - r.left = x; - r.top = y; - r.right = min(x + psm.pgs.cx, tw); - r.bottom = min(y + psm.pgs.cy, th); - - // fprintf(m_log, "up fetch (%d %d) (%d %d %d %d)\n", j, i, r.left, r.top, r.right, r.bottom); - - (mem.*rt)(r, &dst[x * bytes], pitch, TEX0, TEXA); - - m_state->m_perfmon.Put(GSPerfMon::Unswizzle, r.Width() * r.Height() * bytes); } } + m_state->m_perfmon.Put(GSPerfMon::Unswizzle, s.x * s.y * bytes * blocks); + return true; -} \ No newline at end of file +} diff --git a/plugins/GSdx/GSTextureCacheSW.h b/plugins/GSdx/GSTextureCacheSW.h index 8f123300a6..ccb57495e4 100644 --- a/plugins/GSdx/GSTextureCacheSW.h +++ b/plugins/GSdx/GSTextureCacheSW.h @@ -23,28 +23,9 @@ #include "GSRenderer.h" -#define MAX_PAGES 512 - class GSTextureCacheSW { public: - class GSTexture; - class GSTexturePage; - - class GSTexturePage - { - public: - GSTexture* t; - DWORD row, col; - }; - - class GSTexturePageEntry - { - public: - CAtlList* p2t; - POSITION pos; - }; - class GSTexture { public: @@ -52,32 +33,29 @@ public: GIFRegTEX0 m_TEX0; GIFRegTEXA m_TEXA; void* m_buff; - DWORD m_tw; - DWORD m_valid[32]; - DWORD m_maxpages; - DWORD m_pages; - CAtlList m_p2te; - POSITION m_pos; - DWORD m_age; + uint32 m_tw; + uint32 m_valid[MAX_PAGES]; // each uint32 bits map to the 32 blocks of that page + uint32 m_age; + bool m_complete; explicit GSTexture(GSState* state); virtual ~GSTexture(); - bool Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const CRect* r = NULL); + bool Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r); }; protected: GSState* m_state; - CAtlList m_textures; - CAtlList m_p2t[MAX_PAGES]; + hash_map m_textures; + hash_map m_map[MAX_PAGES]; public: GSTextureCacheSW(GSState* state); virtual ~GSTextureCacheSW(); - const GSTexture* Lookup(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const CRect* r = NULL); + const GSTexture* Lookup(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r); void RemoveAll(); void IncAge(); - void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const CRect& r); + void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r); }; diff --git a/plugins/GSdx/GSTextureFX.cpp b/plugins/GSdx/GSTextureFX.cpp new file mode 100644 index 0000000000..f243c41679 --- /dev/null +++ b/plugins/GSdx/GSTextureFX.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSTextureFX.h" + +GSTextureFX::GSTextureFX() + : m_dev(NULL) +{ +} + +bool GSTextureFX::Create(GSDevice* dev) +{ + m_dev = dev; + + return true; +} + diff --git a/plugins/GSdx/GSTextureFX.h b/plugins/GSdx/GSTextureFX.h new file mode 100644 index 0000000000..b3b3dcf692 --- /dev/null +++ b/plugins/GSdx/GSTextureFX.h @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSVector.h" +#include "GSDevice.h" +#include "GSAlignedClass.h" + +class GSTextureFX : public GSAlignedClass<16> +{ +public: + #pragma pack(push, 1) + + __declspec(align(16)) struct VSConstantBuffer + { + GSVector4 VertexScale; + GSVector4 VertexOffset; + GSVector2 TextureScale; + float _pad[2]; + + struct VSConstantBuffer() + { + memset(this, 0, sizeof(*this)); + } + + __forceinline bool Update(const VSConstantBuffer* cb) + { + GSVector4i* a = (GSVector4i*)this; + GSVector4i* b = (GSVector4i*)cb; + + GSVector4i b0 = b[0]; + GSVector4i b1 = b[1]; + GSVector4i b2 = b[2]; + + if(!((a[0] == b0) & (a[1] == b1) & (a[2] == b2)).alltrue()) + { + a[0] = b0; + a[1] = b1; + a[2] = b2; + + return true; + } + + return false; + } + }; + + struct VSSelector + { + union + { + struct + { + uint32 bppz:2; + uint32 tme:1; + uint32 fst:1; + uint32 logz:1; + uint32 prim:2; + }; + + uint32 key; + }; + + operator uint32() {return key & 0x7f;} + + VSSelector() : key(0) {} + }; + + __declspec(align(16)) struct PSConstantBuffer + { + GSVector4 FogColor_AREF; + GSVector4 HalfTexel; + GSVector4 WH; + GSVector4 MinMax; + GSVector4 MinF_TA; + GSVector4i MskFix; + + struct PSConstantBuffer() + { + memset(this, 0, sizeof(*this)); + } + + __forceinline bool Update(const PSConstantBuffer* cb) + { + GSVector4i* a = (GSVector4i*)this; + GSVector4i* b = (GSVector4i*)cb; + + GSVector4i b0 = b[0]; + GSVector4i b1 = b[1]; + GSVector4i b2 = b[2]; + GSVector4i b3 = b[3]; + GSVector4i b4 = b[4]; + GSVector4i b5 = b[5]; + + if(!((a[0] == b0) & (a[1] == b1) & (a[2] == b2) & (a[3] == b3) & (a[4] == b4) & (a[5] == b5)).alltrue()) + { + a[0] = b0; + a[1] = b1; + a[2] = b2; + a[3] = b3; + a[4] = b4; + a[5] = b5; + + return true; + } + + return false; + } + }; + + struct GSSelector + { + union + { + struct + { + uint32 iip:1; + uint32 prim:2; + }; + + uint32 key; + }; + + operator uint32() {return key & 0x7;} + + GSSelector() : key(0) {} + }; + + struct PSSelector + { + union + { + struct + { + uint32 fst:1; + uint32 wms:2; + uint32 wmt:2; + uint32 bpp:3; + uint32 aem:1; + uint32 tfx:3; + uint32 tcc:1; + uint32 ate:1; + uint32 atst:3; + uint32 fog:1; + uint32 clr1:1; + uint32 fba:1; + uint32 aout:1; + uint32 rt:1; + uint32 ltf:1; + }; + + uint32 key; + }; + + operator uint32() {return key & 0x7fffff;} + + PSSelector() : key(0) {} + }; + + struct PSSamplerSelector + { + union + { + struct + { + uint32 tau:1; + uint32 tav:1; + uint32 ltf:1; + }; + + uint32 key; + }; + + operator uint32() {return key & 0x7;} + + PSSamplerSelector() : key(0) {} + }; + + struct OMDepthStencilSelector + { + union + { + struct + { + uint32 zte:1; + uint32 ztst:2; + uint32 zwe:1; + uint32 date:1; + uint32 fba:1; + }; + + uint32 key; + }; + + operator uint32() {return key & 0x3f;} + + OMDepthStencilSelector() : key(0) {} + }; + + struct OMBlendSelector + { + union + { + struct + { + uint32 abe:1; + uint32 a:2; + uint32 b:2; + uint32 c:2; + uint32 d:2; + uint32 wr:1; + uint32 wg:1; + uint32 wb:1; + uint32 wa:1; + }; + + uint32 key; + }; + + operator uint32() {return key & 0x1fff;} + + OMBlendSelector() : key(0) {} + }; + + #pragma pack(pop) + +protected: + GSDevice* m_dev; + +public: + GSTextureFX(); + + virtual bool Create(GSDevice* dev); + + virtual void SetupIA(const void* vertices, int count, int prim) = 0; + virtual void SetupVS(VSSelector sel, const VSConstantBuffer* cb) = 0; + virtual void SetupGS(GSSelector sel) = 0; + virtual void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) = 0; + virtual void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) = 0; + virtual void SetupRS(int w, int h, const GSVector4i& scissor) = 0; + virtual void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds) = 0; + virtual void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) = 0; +}; diff --git a/plugins/GSdx/GSTextureFX10.cpp b/plugins/GSdx/GSTextureFX10.cpp index 0f3073d9cf..3750a5b9c8 100644 --- a/plugins/GSdx/GSTextureFX10.cpp +++ b/plugins/GSdx/GSTextureFX10.cpp @@ -24,30 +24,17 @@ #include "resource.h" GSTextureFX10::GSTextureFX10() - : m_dev(NULL) - , m_vb_max(0) - , m_vb_start(0) - , m_vb_count(0) { memset(&m_vs_cb_cache, 0, sizeof(m_vs_cb_cache)); memset(&m_ps_cb_cache, 0, sizeof(m_ps_cb_cache)); } -bool GSTextureFX10::Create(GSDevice10* dev) +bool GSTextureFX10::Create(GSDevice* dev) { - m_dev = dev; - - // - - VSSelector sel; - - sel.bppz = 0; - sel.tme = 0; - sel.fst = 0; - - VSConstantBuffer cb; - - SetupVS(sel, &cb); // creates layout + if(!__super::Create(dev)) + { + return false; + } HRESULT hr; @@ -59,7 +46,7 @@ bool GSTextureFX10::Create(GSDevice10* dev) bd.Usage = D3D10_USAGE_DEFAULT; bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER; - hr = (*m_dev)->CreateBuffer(&bd, NULL, &m_vs_cb); + hr = (*(GSDevice10*)dev)->CreateBuffer(&bd, NULL, &m_vs_cb); if(FAILED(hr)) return false; @@ -69,7 +56,7 @@ bool GSTextureFX10::Create(GSDevice10* dev) bd.Usage = D3D10_USAGE_DEFAULT; bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER; - hr = (*m_dev)->CreateBuffer(&bd, NULL, &m_ps_cb); + hr = (*(GSDevice10*)dev)->CreateBuffer(&bd, NULL, &m_ps_cb); if(FAILED(hr)) return false; @@ -77,7 +64,7 @@ bool GSTextureFX10::Create(GSDevice10* dev) memset(&sd, 0, sizeof(sd)); - sd.Filter = D3D10_ENCODE_BASIC_FILTER(D3D10_FILTER_TYPE_POINT, D3D10_FILTER_TYPE_POINT, D3D10_FILTER_TYPE_POINT, false); + sd.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT; sd.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP; sd.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP; sd.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP; @@ -85,7 +72,7 @@ bool GSTextureFX10::Create(GSDevice10* dev) sd.MaxAnisotropy = 16; sd.ComparisonFunc = D3D10_COMPARISON_NEVER; - hr = (*m_dev)->CreateSamplerState(&sd, &m_palette_ss); + hr = (*(GSDevice10*)dev)->CreateSamplerState(&sd, &m_palette_ss); if(FAILED(hr)) return false; @@ -94,247 +81,191 @@ bool GSTextureFX10::Create(GSDevice10* dev) return true; } -bool GSTextureFX10::SetupIA(const GSVertexHW10* vertices, int count, D3D10_PRIMITIVE_TOPOLOGY prim) +void GSTextureFX10::SetupIA(const void* vertices, int count, int prim) { - HRESULT hr; + GSDevice10* dev = (GSDevice10*)m_dev; - if(max(count * 3 / 2, 10000) > m_vb_max) - { - m_vb_old = m_vb; - m_vb = NULL; - m_vb_max = max(count * 2, 10000); - m_vb_start = 0; - m_vb_count = 0; - } - - if(!m_vb) - { - D3D10_BUFFER_DESC bd; - - memset(&bd, 0, sizeof(bd)); - - bd.Usage = D3D10_USAGE_DYNAMIC; - bd.ByteWidth = m_vb_max * sizeof(vertices[0]); - bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; - bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; - - hr = (*m_dev)->CreateBuffer(&bd, NULL, &m_vb); - - if(FAILED(hr)) return false; - } - - GSVertexHW10* v = NULL; - - int next = m_vb_start + m_vb_count; - - if(next + count > m_vb_max) - { - if(SUCCEEDED(m_vb->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&v))) - { - memcpy(v, vertices, count * sizeof(vertices[0])); - - m_vb->Unmap(); - } - - m_vb_start = 0; - m_vb_count = count; - } - else - { - if(SUCCEEDED(m_vb->Map(D3D10_MAP_WRITE_NO_OVERWRITE, 0, (void**)&v))) - { - memcpy(&v[next], vertices, count * sizeof(vertices[0])); - - m_vb->Unmap(); - } - - m_vb_start = next; - m_vb_count = count; - } - - m_dev->IASetVertexBuffer(m_vb, sizeof(vertices[0])); - m_dev->IASetInputLayout(m_il); - m_dev->IASetPrimitiveTopology(prim); - - return true; + dev->IASetVertexBuffer(vertices, sizeof(GSVertexHW10), count); + dev->IASetInputLayout(m_il); + dev->IASetPrimitiveTopology((D3D10_PRIMITIVE_TOPOLOGY)prim); } -bool GSTextureFX10::SetupVS(VSSelector sel, const VSConstantBuffer* cb) +void GSTextureFX10::SetupVS(VSSelector sel, const VSConstantBuffer* cb) { - CComPtr vs; + GSDevice10* dev = (GSDevice10*)m_dev; - if(CRBMap >::CPair* pair = m_vs.Lookup(sel)) - { - vs = pair->m_value; - } - else - { - CStringA str[5]; + hash_map >::const_iterator i = m_vs.find(sel); - str[0].Format("%d", sel.bpp); - str[1].Format("%d", sel.bppz); - str[2].Format("%d", sel.tme); - str[3].Format("%d", sel.fst); - str[4].Format("%d", sel.prim); + if(i == m_vs.end()) + { + string str[4]; + + str[0] = format("%d", sel.bppz); + str[1] = format("%d", sel.tme); + str[2] = format("%d", sel.fst); + str[3] = format("%d", sel.prim); D3D10_SHADER_MACRO macro[] = { - {"VS_BPP", str[0]}, - {"VS_BPPZ", str[1]}, - {"VS_TME", str[2]}, - {"VS_FST", str[3]}, - {"VS_PRIM", str[4]}, + {"VS_BPPZ", str[0].c_str()}, + {"VS_TME", str[1].c_str()}, + {"VS_FST", str[2].c_str()}, + {"VS_PRIM", str[3].c_str()}, {NULL, NULL}, }; D3D10_INPUT_ELEMENT_DESC layout[] = { - {"POSITION", 0, DXGI_FORMAT_R16G16_UINT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0}, - {"POSITION", 1, DXGI_FORMAT_R32_UINT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 1, DXGI_FORMAT_R32_FLOAT, 0, 20, D3D10_INPUT_PER_VERTEX_DATA, 0}, - {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 1, DXGI_FORMAT_R32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 0, DXGI_FORMAT_R16G16_UINT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 1, DXGI_FORMAT_R32_UINT, 0, 20, D3D10_INPUT_PER_VERTEX_DATA, 0}, {"COLOR", 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 28, D3D10_INPUT_PER_VERTEX_DATA, 0}, }; CComPtr il; + CComPtr vs; - m_dev->CompileShader(IDR_TFX10_FX, "vs_main", macro, &vs, layout, countof(layout), &il); + dev->CompileShader(IDR_TFX_FX, "vs_main", macro, &vs, layout, countof(layout), &il); if(m_il == NULL) { m_il = il; } - m_vs.SetAt(sel, vs); + m_vs[sel] = vs; + + i = m_vs.find(sel); } if(m_vs_cb_cache.Update(cb)) { - (*m_dev)->UpdateSubresource(m_vs_cb, 0, NULL, cb, 0, 0); + (*dev)->UpdateSubresource(m_vs_cb, 0, NULL, cb, 0, 0); } - m_dev->VSSetShader(vs, m_vs_cb); - - return true; + dev->VSSetShader(i->second, m_vs_cb); } -bool GSTextureFX10::SetupGS(GSSelector sel) +void GSTextureFX10::SetupGS(GSSelector sel) { - HRESULT hr; + GSDevice10* dev = (GSDevice10*)m_dev; - CComPtr gs; + ID3D10GeometryShader* gs = NULL; if(sel.prim > 0 && (sel.iip == 0 || sel.prim == 3)) // geometry shader works in every case, but not needed { - if(CRBMap >::CPair* pair = m_gs.Lookup(sel)) + hash_map >::const_iterator i = m_gs.find(sel); + + if(i != m_gs.end()) { - gs = pair->m_value; + gs = i->second; } else { - CStringA str[2]; + string str[2]; - str[0].Format("%d", sel.iip); - str[1].Format("%d", sel.prim); + str[0] = format("%d", sel.iip); + str[1] = format("%d", sel.prim); D3D10_SHADER_MACRO macro[] = { - {"IIP", str[0]}, - {"PRIM", str[1]}, + {"GS_IIP", str[0].c_str()}, + {"GS_PRIM", str[1].c_str()}, {NULL, NULL}, }; - hr = m_dev->CompileShader(IDR_TFX10_FX, "gs_main", macro, &gs); + dev->CompileShader(IDR_TFX_FX, "gs_main", macro, &gs); - m_gs.SetAt(sel, gs); + m_gs[sel] = gs; } } - m_dev->GSSetShader(gs); - - return true; + dev->GSSetShader(gs); } -bool GSTextureFX10::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, ID3D10ShaderResourceView* tex, ID3D10ShaderResourceView* pal) +void GSTextureFX10::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) { - m_dev->PSSetShaderResources(tex, pal); + ((GSDevice10*)m_dev)->PSSetShaderResources(tex, pal); UpdatePS(sel, cb, ssel); - - return true; } void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) { - HRESULT hr; + GSDevice10* dev = (GSDevice10*)m_dev; - CComPtr ps; + hash_map >::const_iterator i = m_ps.find(sel); - if(CRBMap >::CPair* pair = m_ps.Lookup(sel)) + if(i == m_ps.end()) { - ps = pair->m_value; - } - else - { - CStringA str[13]; + string str[14]; - str[0].Format("%d", sel.fst); - str[1].Format("%d", sel.wms); - str[2].Format("%d", sel.wmt); - str[3].Format("%d", sel.bpp); - str[4].Format("%d", sel.aem); - str[5].Format("%d", sel.tfx); - str[6].Format("%d", sel.tcc); - str[7].Format("%d", sel.ate); - str[8].Format("%d", sel.atst); - str[9].Format("%d", sel.fog); - str[10].Format("%d", sel.clr1); - str[11].Format("%d", sel.fba); - str[12].Format("%d", sel.aout); + str[0] = format("%d", sel.fst); + str[1] = format("%d", sel.wms); + str[2] = format("%d", sel.wmt); + str[3] = format("%d", sel.bpp); + str[4] = format("%d", sel.aem); + str[5] = format("%d", sel.tfx); + str[6] = format("%d", sel.tcc); + str[7] = format("%d", sel.ate); + str[8] = format("%d", sel.atst); + str[9] = format("%d", sel.fog); + str[10] = format("%d", sel.clr1); + str[11] = format("%d", sel.fba); + str[12] = format("%d", sel.aout); + str[13] = format("%d", sel.ltf); D3D10_SHADER_MACRO macro[] = { - {"FST", str[0]}, - {"WMS", str[1]}, - {"WMT", str[2]}, - {"BPP", str[3]}, - {"AEM", str[4]}, - {"TFX", str[5]}, - {"TCC", str[6]}, - {"ATE", str[7]}, - {"ATST", str[8]}, - {"FOG", str[9]}, - {"CLR1", str[10]}, - {"FBA", str[11]}, - {"AOUT", str[12]}, + {"PS_FST", str[0].c_str()}, + {"PS_WMS", str[1].c_str()}, + {"PS_WMT", str[2].c_str()}, + {"PS_BPP", str[3].c_str()}, + {"PS_AEM", str[4].c_str()}, + {"PS_TFX", str[5].c_str()}, + {"PS_TCC", str[6].c_str()}, + {"PS_ATE", str[7].c_str()}, + {"PS_ATST", str[8].c_str()}, + {"PS_FOG", str[9].c_str()}, + {"PS_CLR1", str[10].c_str()}, + {"PS_FBA", str[11].c_str()}, + {"PS_AOUT", str[12].c_str()}, + {"PS_LTF", str[13].c_str()}, {NULL, NULL}, }; - hr = m_dev->CompileShader(IDR_TFX10_FX, "ps_main", macro, &ps); + CComPtr ps; + + dev->CompileShader(IDR_TFX_FX, "ps_main", macro, &ps); - m_ps.SetAt(sel, ps); + m_ps[sel] = ps; + + i = m_ps.find(sel); } if(m_ps_cb_cache.Update(cb)) { - (*m_dev)->UpdateSubresource(m_ps_cb, 0, NULL, cb, 0, 0); + (*dev)->UpdateSubresource(m_ps_cb, 0, NULL, cb, 0, 0); } - m_dev->PSSetShader(ps, m_ps_cb); + dev->PSSetShader(i->second, m_ps_cb); - CComPtr ss0, ss1; + ID3D10SamplerState* ss0 = NULL; + ID3D10SamplerState* ss1 = NULL; if(sel.tfx != 4) { - if(sel.bpp >= 3 || sel.wms >= 3 || sel.wmt >= 3) + if(!(sel.bpp < 3 && sel.wms < 3 && sel.wmt < 3)) { - ssel.min = ssel.mag = 0; + ssel.ltf = 0; } - if(CRBMap >::CPair* pair = m_ps_ss.Lookup(ssel)) + hash_map >::const_iterator i = m_ps_ss.find(ssel); + + if(i != m_ps_ss.end()) { - ss0 = pair->m_value; + ss0 = (*i).second; } else { @@ -342,11 +273,7 @@ void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl memset(&sd, 0, sizeof(sd)); - sd.Filter = D3D10_ENCODE_BASIC_FILTER( - (ssel.min ? D3D10_FILTER_TYPE_LINEAR : D3D10_FILTER_TYPE_POINT), - (ssel.mag ? D3D10_FILTER_TYPE_LINEAR : D3D10_FILTER_TYPE_POINT), - D3D10_FILTER_TYPE_POINT, - false); + sd.Filter = ssel.ltf ? D3D10_FILTER_MIN_MAG_LINEAR_MIP_POINT : D3D10_FILTER_MIN_MAG_MIP_POINT; sd.AddressU = ssel.tau ? D3D10_TEXTURE_ADDRESS_WRAP : D3D10_TEXTURE_ADDRESS_CLAMP; sd.AddressV = ssel.tav ? D3D10_TEXTURE_ADDRESS_WRAP : D3D10_TEXTURE_ADDRESS_CLAMP; @@ -356,9 +283,9 @@ void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl sd.MaxAnisotropy = 16; sd.ComparisonFunc = D3D10_COMPARISON_NEVER; - hr = (*m_dev)->CreateSamplerState(&sd, &ss0); + (*dev)->CreateSamplerState(&sd, &ss0); - m_ps_ss.SetAt(ssel, ss0); + m_ps_ss[ssel] = ss0; } if(sel.bpp == 3) @@ -367,32 +294,28 @@ void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl } } - m_dev->PSSetSamplerState(ss0, ss1); + dev->PSSetSamplerState(ss0, ss1); } -void GSTextureFX10::SetupRS(UINT w, UINT h, const RECT& scissor) +void GSTextureFX10::SetupRS(int w, int h, const GSVector4i& scissor) { - m_dev->RSSet(w, h, &scissor); + ((GSDevice10*)m_dev)->RSSet(w, h, &scissor); } -void GSTextureFX10::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float bf, ID3D10RenderTargetView* rtv, ID3D10DepthStencilView* dsv) +void GSTextureFX10::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds) { - UpdateOM(dssel, bsel, bf); + UpdateOM(dssel, bsel, afix); - m_dev->OMSetRenderTargets(rtv, dsv); + ((GSDevice10*)m_dev)->OMSetRenderTargets(rt, ds); } -void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float bf) +void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) { - HRESULT hr; + GSDevice10* dev = (GSDevice10*)m_dev; - CComPtr dss; + hash_map >::const_iterator i = m_om_dss.find(dssel); - if(CRBMap >::CPair* pair = m_om_dss.Lookup(dssel)) - { - dss = pair->m_value; - } - else + if(i == m_om_dss.end()) { D3D10_DEPTH_STENCIL_DESC dsd; @@ -428,20 +351,20 @@ void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, dsd.DepthFunc = ztst[dssel.ztst]; } - hr = (*m_dev)->CreateDepthStencilState(&dsd, &dss); + CComPtr dss; - m_om_dss.SetAt(dssel, dss); + (*dev)->CreateDepthStencilState(&dsd, &dss); + + m_om_dss[dssel] = dss; + + i = m_om_dss.find(dssel); } - m_dev->OMSetDepthStencilState(dss, 1); + dev->OMSetDepthStencilState((*i).second, 1); - CComPtr bs; + hash_map >::const_iterator j = m_om_bs.find(bsel); - if(CRBMap >::CPair* pair = m_om_bs.Lookup(bsel)) - { - bs = pair->m_value; - } - else + if(j == m_om_bs.end()) { D3D10_BLEND_DESC bd; @@ -569,15 +492,14 @@ void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, if(bsel.wb) bd.RenderTargetWriteMask[0] |= D3D10_COLOR_WRITE_ENABLE_BLUE; if(bsel.wa) bd.RenderTargetWriteMask[0] |= D3D10_COLOR_WRITE_ENABLE_ALPHA; - hr = (*m_dev)->CreateBlendState(&bd, &bs); + CComPtr bs; - m_om_bs.SetAt(bsel, bs); + (*dev)->CreateBlendState(&bd, &bs); + + m_om_bs[bsel] = bs; + + j = m_om_bs.find(bsel); } - m_dev->OMSetBlendState(bs, bf); -} - -void GSTextureFX10::Draw() -{ - m_dev->DrawPrimitive(m_vb_count, m_vb_start); + dev->OMSetBlendState(j->second, (float)(int)afix / 0x80); } diff --git a/plugins/GSdx/GSTextureFX10.h b/plugins/GSdx/GSTextureFX10.h index 6dcaedc29e..566809a360 100644 --- a/plugins/GSdx/GSTextureFX10.h +++ b/plugins/GSdx/GSTextureFX10.h @@ -21,212 +21,21 @@ #pragma once +#include "GSTextureFX.h" #include "GSDevice10.h" -class GSTextureFX10 +class GSTextureFX10 : public GSTextureFX { -public: - #pragma pack(push, 1) - - __declspec(align(16)) struct VSConstantBuffer - { - GSVector4 VertexScale; - GSVector4 VertexOffset; - GSVector2 TextureScale; - float _pad[2]; - - struct VSConstantBuffer() {memset(this, 0, sizeof(*this));} - - __forceinline bool Update(const VSConstantBuffer* cb) - { - GSVector4i* a = (GSVector4i*)this; - GSVector4i* b = (GSVector4i*)cb; - - GSVector4i b0 = b[0]; - GSVector4i b1 = b[1]; - GSVector4i b2 = b[2]; - - if(!((a[0] == b0) & (a[1] == b1) & (a[2] == b2)).alltrue()) - { - a[0] = b0; - a[1] = b1; - a[2] = b2; - - return true; - } - - return false; - } - }; - - union VSSelector - { - struct - { - DWORD bpp:3; - DWORD bppz:2; - DWORD tme:1; - DWORD fst:1; - DWORD prim:3; - }; - - DWORD dw; - - operator DWORD() {return dw & 0x3ff;} - }; - - __declspec(align(16)) struct PSConstantBuffer - { - GSVector4 FogColor; - float MINU; - float MAXU; - float MINV; - float MAXV; - DWORD UMSK; - DWORD UFIX; - DWORD VMSK; - DWORD VFIX; - float TA0; - float TA1; - float AREF; - float _pad[1]; - GSVector2 WH; - GSVector2 rWrH; - - struct PSConstantBuffer() {memset(this, 0, sizeof(*this));} - - __forceinline bool Update(const PSConstantBuffer* cb) - { - GSVector4i* a = (GSVector4i*)this; - GSVector4i* b = (GSVector4i*)cb; - - GSVector4i b0 = b[0]; - GSVector4i b1 = b[1]; - GSVector4i b2 = b[2]; - GSVector4i b3 = b[3]; - GSVector4i b4 = b[4]; - - if(!((a[0] == b0) & (a[1] == b1) & (a[2] == b2) & (a[3] == b3) & (a[4] == b4)).alltrue()) - { - a[0] = b0; - a[1] = b1; - a[2] = b2; - a[3] = b3; - a[4] = b4; - - return true; - } - - return false; - } - }; - - union PSSelector - { - struct - { - DWORD fst:1; - DWORD wms:2; - DWORD wmt:2; - DWORD bpp:3; - DWORD aem:1; - DWORD tfx:3; - DWORD tcc:1; - DWORD ate:1; - DWORD atst:3; - DWORD fog:1; - DWORD clr1:1; - DWORD fba:1; - DWORD aout:1; - }; - - DWORD dw; - - operator DWORD() {return dw & 0x1fffff;} - }; - - union GSSelector - { - struct - { - DWORD iip:1; - DWORD prim:2; - }; - - DWORD dw; - - operator DWORD() {return dw & 0x7;} - }; - - union PSSamplerSelector - { - struct - { - DWORD tau:1; - DWORD tav:1; - DWORD min:1; - DWORD mag:1; - }; - - DWORD dw; - - operator DWORD() {return dw & 0xf;} - }; - - union OMDepthStencilSelector - { - struct - { - DWORD zte:1; - DWORD ztst:2; - DWORD zwe:1; - DWORD date:1; - }; - - DWORD dw; - - operator DWORD() {return dw & 0x1f;} - }; - - union OMBlendSelector - { - struct - { - DWORD abe:1; - DWORD a:2; - DWORD b:2; - DWORD c:2; - DWORD d:2; - DWORD wr:1; - DWORD wg:1; - DWORD wb:1; - DWORD wa:1; - }; - - DWORD dw; - - operator DWORD() {return dw & 0x1fff;} - }; - - #pragma pack(pop) - -private: - GSDevice10* m_dev; CComPtr m_il; - CRBMapC > m_vs; + hash_map > m_vs; CComPtr m_vs_cb; - CRBMapC > m_gs; - CRBMapC > m_ps; + hash_map > m_gs; + hash_map > m_ps; CComPtr m_ps_cb; - CRBMapC > m_ps_ss; + hash_map > m_ps_ss; CComPtr m_palette_ss; - CRBMapC > m_om_dss; - CRBMapC > m_om_bs; - - CComPtr m_vb, m_vb_old; - int m_vb_max; - int m_vb_start; - int m_vb_count; + hash_map > m_om_dss; + hash_map > m_om_bs; VSConstantBuffer m_vs_cb_cache; PSConstantBuffer m_ps_cb_cache; @@ -234,15 +43,14 @@ private: public: GSTextureFX10(); - bool Create(GSDevice10* dev); + bool Create(GSDevice* dev); - bool SetupIA(const GSVertexHW10* vertices, int count, D3D10_PRIMITIVE_TOPOLOGY prim); - bool SetupVS(VSSelector sel, const VSConstantBuffer* cb); - bool SetupGS(GSSelector sel); - bool SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, ID3D10ShaderResourceView* tex, ID3D10ShaderResourceView* pal); + void SetupIA(const void* vertices, int count, int prim); + void SetupVS(VSSelector sel, const VSConstantBuffer* cb); + void SetupGS(GSSelector sel); + void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal); void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); - void SetupRS(UINT w, UINT h, const RECT& scissor); - void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float bf, ID3D10RenderTargetView* rtv, ID3D10DepthStencilView* dsv); - void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float bf); - void Draw(); + void SetupRS(int w, int h, const GSVector4i& scissor); + void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds); + void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); }; diff --git a/plugins/GSdx/GSTextureFX11.cpp b/plugins/GSdx/GSTextureFX11.cpp new file mode 100644 index 0000000000..24e2b25dbb --- /dev/null +++ b/plugins/GSdx/GSTextureFX11.cpp @@ -0,0 +1,509 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSTextureFX11.h" +#include "resource.h" + +GSTextureFX11::GSTextureFX11() +{ + memset(&m_vs_cb_cache, 0, sizeof(m_vs_cb_cache)); + memset(&m_ps_cb_cache, 0, sizeof(m_ps_cb_cache)); +} + +bool GSTextureFX11::Create(GSDevice* dev) +{ + if(!__super::Create(dev)) + { + return false; + } + + HRESULT hr; + + D3D11_BUFFER_DESC bd; + + memset(&bd, 0, sizeof(bd)); + + bd.ByteWidth = sizeof(VSConstantBuffer); + bd.Usage = D3D11_USAGE_DEFAULT; + bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + + hr = (*(GSDevice11*)dev)->CreateBuffer(&bd, NULL, &m_vs_cb); + + if(FAILED(hr)) return false; + + memset(&bd, 0, sizeof(bd)); + + bd.ByteWidth = sizeof(PSConstantBuffer); + bd.Usage = D3D11_USAGE_DEFAULT; + bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + + hr = (*(GSDevice11*)dev)->CreateBuffer(&bd, NULL, &m_ps_cb); + + if(FAILED(hr)) return false; + + D3D11_SAMPLER_DESC sd; + + memset(&sd, 0, sizeof(sd)); + + sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + sd.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + sd.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + sd.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + sd.MaxLOD = FLT_MAX; + sd.MaxAnisotropy = 16; + sd.ComparisonFunc = D3D11_COMPARISON_NEVER; + + hr = (*(GSDevice11*)dev)->CreateSamplerState(&sd, &m_palette_ss); + + if(FAILED(hr)) return false; + + // + + return true; +} + +void GSTextureFX11::SetupIA(const void* vertices, int count, int prim) +{ + GSDevice11* dev = (GSDevice11*)m_dev; + + dev->IASetVertexBuffer(vertices, sizeof(GSVertexHW11), count); + dev->IASetInputLayout(m_il); + dev->IASetPrimitiveTopology((D3D11_PRIMITIVE_TOPOLOGY)prim); +} + +void GSTextureFX11::SetupVS(VSSelector sel, const VSConstantBuffer* cb) +{ + GSDevice11* dev = (GSDevice11*)m_dev; + + hash_map >::const_iterator i = m_vs.find(sel); + + if(i == m_vs.end()) + { + string str[4]; + + str[0] = format("%d", sel.bppz); + str[1] = format("%d", sel.tme); + str[2] = format("%d", sel.fst); + str[3] = format("%d", sel.prim); + + D3D11_SHADER_MACRO macro[] = + { + {"VS_BPPZ", str[0].c_str()}, + {"VS_TME", str[1].c_str()}, + {"VS_FST", str[2].c_str()}, + {"VS_PRIM", str[3].c_str()}, + {NULL, NULL}, + }; + + D3D11_INPUT_ELEMENT_DESC layout[] = + { + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 1, DXGI_FORMAT_R32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 0, DXGI_FORMAT_R16G16_UINT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 1, DXGI_FORMAT_R32_UINT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }; + + CComPtr il; + CComPtr vs; + + dev->CompileShader(IDR_TFX_FX, "vs_main", macro, &vs, layout, countof(layout), &il); + + if(m_il == NULL) + { + m_il = il; + } + + m_vs[sel] = vs; + + i = m_vs.find(sel); + } + + if(m_vs_cb_cache.Update(cb)) + { + ID3D11DeviceContext* ctx = *dev; + + ctx->UpdateSubresource(m_vs_cb, 0, NULL, cb, 0, 0); + } + + dev->VSSetShader(i->second, m_vs_cb); +} + +void GSTextureFX11::SetupGS(GSSelector sel) +{ + GSDevice11* dev = (GSDevice11*)m_dev; + + ID3D11GeometryShader* gs = NULL; + + if(sel.prim > 0 && (sel.iip == 0 || sel.prim == 3)) // geometry shader works in every case, but not needed + { + hash_map >::const_iterator i = m_gs.find(sel); + + if(i != m_gs.end()) + { + gs = i->second; + } + else + { + string str[2]; + + str[0] = format("%d", sel.iip); + str[1] = format("%d", sel.prim); + + D3D11_SHADER_MACRO macro[] = + { + {"GS_IIP", str[0].c_str()}, + {"GS_PRIM", str[1].c_str()}, + {NULL, NULL}, + }; + + dev->CompileShader(IDR_TFX_FX, "gs_main", macro, &gs); + + m_gs[sel] = gs; + } + } + + dev->GSSetShader(gs); +} + +void GSTextureFX11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) +{ + ((GSDevice11*)m_dev)->PSSetShaderResources(tex, pal); + + UpdatePS(sel, cb, ssel); +} + +void GSTextureFX11::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) +{ + GSDevice11* dev = (GSDevice11*)m_dev; + + hash_map >::const_iterator i = m_ps.find(sel); + + if(i == m_ps.end()) + { + string str[14]; + + str[0] = format("%d", sel.fst); + str[1] = format("%d", sel.wms); + str[2] = format("%d", sel.wmt); + str[3] = format("%d", sel.bpp); + str[4] = format("%d", sel.aem); + str[5] = format("%d", sel.tfx); + str[6] = format("%d", sel.tcc); + str[7] = format("%d", sel.ate); + str[8] = format("%d", sel.atst); + str[9] = format("%d", sel.fog); + str[10] = format("%d", sel.clr1); + str[11] = format("%d", sel.fba); + str[12] = format("%d", sel.aout); + str[13] = format("%d", sel.ltf); + + D3D11_SHADER_MACRO macro[] = + { + {"PS_FST", str[0].c_str()}, + {"PS_WMS", str[1].c_str()}, + {"PS_WMT", str[2].c_str()}, + {"PS_BPP", str[3].c_str()}, + {"PS_AEM", str[4].c_str()}, + {"PS_TFX", str[5].c_str()}, + {"PS_TCC", str[6].c_str()}, + {"PS_ATE", str[7].c_str()}, + {"PS_ATST", str[8].c_str()}, + {"PS_FOG", str[9].c_str()}, + {"PS_CLR1", str[10].c_str()}, + {"PS_FBA", str[11].c_str()}, + {"PS_AOUT", str[12].c_str()}, + {"PS_LTF", str[13].c_str()}, + {NULL, NULL}, + }; + + CComPtr ps; + + dev->CompileShader(IDR_TFX_FX, "ps_main", macro, &ps); + + m_ps[sel] = ps; + + i = m_ps.find(sel); + } + + if(m_ps_cb_cache.Update(cb)) + { + ID3D11DeviceContext* ctx = *dev; + + ctx->UpdateSubresource(m_ps_cb, 0, NULL, cb, 0, 0); + } + + dev->PSSetShader(i->second, m_ps_cb); + + ID3D11SamplerState* ss0 = NULL; + ID3D11SamplerState* ss1 = NULL; + + if(sel.tfx != 4) + { + if(!(sel.bpp < 3 && sel.wms < 3 && sel.wmt < 3)) + { + ssel.ltf = 0; + } + + hash_map >::const_iterator i = m_ps_ss.find(ssel); + + if(i != m_ps_ss.end()) + { + ss0 = i->second; + } + else + { + D3D11_SAMPLER_DESC sd; + + memset(&sd, 0, sizeof(sd)); + + sd.Filter = ssel.ltf ? D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_POINT; + + sd.AddressU = ssel.tau ? D3D11_TEXTURE_ADDRESS_WRAP : D3D11_TEXTURE_ADDRESS_CLAMP; + sd.AddressV = ssel.tav ? D3D11_TEXTURE_ADDRESS_WRAP : D3D11_TEXTURE_ADDRESS_CLAMP; + sd.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + + sd.MaxLOD = FLT_MAX; + sd.MaxAnisotropy = 16; + sd.ComparisonFunc = D3D11_COMPARISON_NEVER; + + (*dev)->CreateSamplerState(&sd, &ss0); + + m_ps_ss[ssel] = ss0; + } + + if(sel.bpp == 3) + { + ss1 = m_palette_ss; + } + } + + dev->PSSetSamplerState(ss0, ss1); +} + +void GSTextureFX11::SetupRS(int w, int h, const GSVector4i& scissor) +{ + ((GSDevice11*)m_dev)->RSSet(w, h, &scissor); +} + +void GSTextureFX11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds) +{ + UpdateOM(dssel, bsel, afix); + + ((GSDevice11*)m_dev)->OMSetRenderTargets(rt, ds); +} + +void GSTextureFX11::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) +{ + GSDevice11* dev = (GSDevice11*)m_dev; + + hash_map >::const_iterator i = m_om_dss.find(dssel); + + if(i == m_om_dss.end()) + { + D3D11_DEPTH_STENCIL_DESC dsd; + + memset(&dsd, 0, sizeof(dsd)); + + if(dssel.date) + { + dsd.StencilEnable = true; + dsd.StencilReadMask = 1; + dsd.StencilWriteMask = 1; + dsd.FrontFace.StencilFunc = D3D11_COMPARISON_EQUAL; + dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + dsd.BackFace.StencilFunc = D3D11_COMPARISON_EQUAL; + dsd.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + dsd.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + } + + if(!(dssel.zte && dssel.ztst == 1 && !dssel.zwe)) + { + static const D3D11_COMPARISON_FUNC ztst[] = + { + D3D11_COMPARISON_NEVER, + D3D11_COMPARISON_ALWAYS, + D3D11_COMPARISON_GREATER_EQUAL, + D3D11_COMPARISON_GREATER + }; + + dsd.DepthEnable = dssel.zte; + dsd.DepthWriteMask = dssel.zwe ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; + dsd.DepthFunc = ztst[dssel.ztst]; + } + + CComPtr dss; + + (*dev)->CreateDepthStencilState(&dsd, &dss); + + m_om_dss[dssel] = dss; + + i = m_om_dss.find(dssel); + } + + dev->OMSetDepthStencilState(i->second, 1); + + hash_map >::const_iterator j = m_om_bs.find(bsel); + + if(j == m_om_bs.end()) + { + D3D11_BLEND_DESC bd; + + memset(&bd, 0, sizeof(bd)); + + bd.RenderTarget[0].BlendEnable = bsel.abe; + + if(bsel.abe) + { + // (A:Cs/Cd/0 - B:Cs/Cd/0) * C:As/Ad/FIX + D:Cs/Cd/0 + + static const struct {int bogus; D3D11_BLEND_OP op; D3D11_BLEND src, dst;} map[3*3*3*3] = + { + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ONE, D3D11_BLEND_ZERO}, // 0000: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ONE}, // 0001: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO}, // 0002: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ONE, D3D11_BLEND_ZERO}, // 0010: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ONE}, // 0011: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO}, // 0012: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ONE, D3D11_BLEND_ZERO}, // 0020: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ONE}, // 0021: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO}, // 0022: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 + {1, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_SRC1_ALPHA}, // * 0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_INV_SRC1_ALPHA}, // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As) + {0, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_SRC1_ALPHA}, // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As + {1, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_DEST_ALPHA}, // * 0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_INV_DEST_ALPHA}, // 0111: (Cs - Cd)*Ad + Cd ==> Cs*Ad + Cd*(1 - Ad) + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_DEST_ALPHA}, // 0112: (Cs - Cd)*Ad + 0 ==> Cs*Ad - Cd*Ad + {1, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_BLEND_FACTOR}, // * 0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_INV_BLEND_FACTOR}, // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F) + {0, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_BLEND_FACTOR}, // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F + {1, D3D11_BLEND_OP_ADD, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_ZERO}, // * 0200: (Cs - 0)*As + Cs ==> Cs*(As + 1) + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_ONE}, // 0201: (Cs - 0)*As + Cd ==> Cs*As + Cd + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_ZERO}, // 0202: (Cs - 0)*As + 0 ==> Cs*As + {1, D3D11_BLEND_OP_ADD, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_ZERO}, // * 0210: (Cs - 0)*Ad + Cs ==> Cs*(Ad + 1) + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_ONE}, // 0211: (Cs - 0)*Ad + Cd ==> Cs*Ad + Cd + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_ZERO}, // 0212: (Cs - 0)*Ad + 0 ==> Cs*Ad + {1, D3D11_BLEND_OP_ADD, D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_ZERO}, // * 0220: (Cs - 0)*F + Cs ==> Cs*(F + 1) + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_ONE}, // 0221: (Cs - 0)*F + Cd ==> Cs*F + Cd + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_ZERO}, // 0222: (Cs - 0)*F + 0 ==> Cs*F + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_INV_SRC1_ALPHA, D3D11_BLEND_SRC1_ALPHA}, // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As) + {1, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_SRC1_ALPHA}, // * 1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As + {0, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_SRC1_ALPHA}, // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_INV_DEST_ALPHA, D3D11_BLEND_DEST_ALPHA}, // 1010: (Cd - Cs)*Ad + Cs ==> Cd*Ad + Cs*(1 - Ad) + {1, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_DEST_ALPHA}, // * 1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad + {0, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_DEST_ALPHA}, // 1012: (Cd - Cs)*Ad + 0 ==> Cd*Ad - Cs*Ad + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_INV_BLEND_FACTOR, D3D11_BLEND_BLEND_FACTOR}, // 1020: (Cd - Cs)*F + Cs ==> Cd*F + Cs*(1 - F) + {1, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_BLEND_FACTOR},// * 1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F + {0, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_BLEND_FACTOR},// 1022: (Cd - Cs)*F + 0 ==> Cd*F - Cs*F + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ONE, D3D11_BLEND_ZERO}, // 1100: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ONE}, // 1101: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO}, // 1102: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ONE, D3D11_BLEND_ZERO}, // 1110: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ONE}, // 1111: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO}, // 1112: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ONE, D3D11_BLEND_ZERO}, // 1120: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ONE}, // 1121: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO}, // 1122: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ONE, D3D11_BLEND_SRC1_ALPHA}, // 1200: (Cd - 0)*As + Cs ==> Cs + Cd*As + {2, D3D11_BLEND_OP_ADD, D3D11_BLEND_DEST_COLOR, D3D11_BLEND_SRC1_ALPHA}, // ** 1201: (Cd - 0)*As + Cd ==> Cd*(1 + As) // ffxii main menu background glow effect + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_SRC1_ALPHA}, // 1202: (Cd - 0)*As + 0 ==> Cd*As + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ONE, D3D11_BLEND_DEST_ALPHA}, // 1210: (Cd - 0)*Ad + Cs ==> Cs + Cd*Ad + {2, D3D11_BLEND_OP_ADD, D3D11_BLEND_DEST_COLOR, D3D11_BLEND_DEST_ALPHA}, // ** 1211: (Cd - 0)*Ad + Cd ==> Cd*(1 + Ad) + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_DEST_ALPHA}, // 1212: (Cd - 0)*Ad + 0 ==> Cd*Ad + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ONE, D3D11_BLEND_BLEND_FACTOR}, // 1220: (Cd - 0)*F + Cs ==> Cs + Cd*F + {2, D3D11_BLEND_OP_ADD, D3D11_BLEND_DEST_COLOR, D3D11_BLEND_BLEND_FACTOR}, // ** 1221: (Cd - 0)*F + Cd ==> Cd*(1 + F) + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_BLEND_FACTOR}, // 1222: (Cd - 0)*F + 0 ==> Cd*F + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_INV_SRC1_ALPHA, D3D11_BLEND_ZERO}, // 2000: (0 - Cs)*As + Cs ==> Cs*(1 - As) + {0, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_ONE}, // 2001: (0 - Cs)*As + Cd ==> Cd - Cs*As + {0, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_ZERO}, // 2002: (0 - Cs)*As + 0 ==> 0 - Cs*As + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_INV_DEST_ALPHA, D3D11_BLEND_ZERO}, // 2010: (0 - Cs)*Ad + Cs ==> Cs*(1 - Ad) + {0, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_ONE}, // 2011: (0 - Cs)*Ad + Cd ==> Cd - Cs*Ad + {0, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_ZERO}, // 2012: (0 - Cs)*Ad + 0 ==> 0 - Cs*Ad + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_INV_BLEND_FACTOR, D3D11_BLEND_ZERO}, // 2020: (0 - Cs)*F + Cs ==> Cs*(1 - F) + {0, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_ONE}, // 2021: (0 - Cs)*F + Cd ==> Cd - Cs*F + {0, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_ZERO}, // 2022: (0 - Cs)*F + 0 ==> 0 - Cs*F + {0, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_ONE, D3D11_BLEND_SRC1_ALPHA}, // 2100: (0 - Cd)*As + Cs ==> Cs - Cd*As + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_INV_SRC1_ALPHA}, // 2101: (0 - Cd)*As + Cd ==> Cd*(1 - As) + {0, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_ZERO, D3D11_BLEND_SRC1_ALPHA}, // 2102: (0 - Cd)*As + 0 ==> 0 - Cd*As + {0, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_ONE, D3D11_BLEND_DEST_ALPHA}, // 2110: (0 - Cd)*Ad + Cs ==> Cs - Cd*Ad + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_INV_DEST_ALPHA}, // 2111: (0 - Cd)*Ad + Cd ==> Cd*(1 - Ad) + {0, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_ONE, D3D11_BLEND_DEST_ALPHA}, // 2112: (0 - Cd)*Ad + 0 ==> 0 - Cd*Ad + {0, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_ONE, D3D11_BLEND_BLEND_FACTOR}, // 2120: (0 - Cd)*F + Cs ==> Cs - Cd*F + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_INV_BLEND_FACTOR}, // 2121: (0 - Cd)*F + Cd ==> Cd*(1 - F) + {0, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_ONE, D3D11_BLEND_BLEND_FACTOR}, // 2122: (0 - Cd)*F + 0 ==> 0 - Cd*F + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ONE, D3D11_BLEND_ZERO}, // 2200: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ONE}, // 2201: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO}, // 2202: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ONE, D3D11_BLEND_ZERO}, // 2210: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ONE}, // 2211: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO}, // 2212: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ONE, D3D11_BLEND_ZERO}, // 2220: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ONE}, // 2221: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd + {0, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO}, // 2222: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 + }; + + // bogus: 0100, 0110, 0120, 0200, 0210, 0220, 1001, 1011, 1021 + + // tricky: 1201, 1211, 1221 + // + // Source.rgb = float3(1, 1, 1); + // 1201 Cd*(1 + As) => Source * Dest color + Dest * Source1 alpha + // 1211 Cd*(1 + Ad) => Source * Dest color + Dest * Dest alpha + // 1221 Cd*(1 + F) => Source * Dest color + Dest * Factor + + int i = ((bsel.a * 3 + bsel.b) * 3 + bsel.c) * 3 + bsel.d; + + bd.RenderTarget[0].BlendOp = map[i].op; + bd.RenderTarget[0].SrcBlend = map[i].src; + bd.RenderTarget[0].DestBlend = map[i].dst; + bd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + + if(map[i].bogus == 1) + { + ASSERT(0); + + (bsel.a == 0 ? bd.RenderTarget[0].SrcBlend : bd.RenderTarget[0].DestBlend) = D3D11_BLEND_ONE; + } + } + + if(bsel.wr) bd.RenderTarget[0].RenderTargetWriteMask |= D3D11_COLOR_WRITE_ENABLE_RED; + if(bsel.wg) bd.RenderTarget[0].RenderTargetWriteMask |= D3D11_COLOR_WRITE_ENABLE_GREEN; + if(bsel.wb) bd.RenderTarget[0].RenderTargetWriteMask |= D3D11_COLOR_WRITE_ENABLE_BLUE; + if(bsel.wa) bd.RenderTarget[0].RenderTargetWriteMask |= D3D11_COLOR_WRITE_ENABLE_ALPHA; + + CComPtr bs; + + (*dev)->CreateBlendState(&bd, &bs); + + m_om_bs[bsel] = bs; + + j = m_om_bs.find(bsel); + } + + dev->OMSetBlendState(j->second, (float)(int)afix / 0x80); +} diff --git a/plugins/GSdx/GSTextureFX11.h b/plugins/GSdx/GSTextureFX11.h new file mode 100644 index 0000000000..5c2b67bcc1 --- /dev/null +++ b/plugins/GSdx/GSTextureFX11.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSTextureFX.h" +#include "GSDevice11.h" + +class GSTextureFX11 : public GSTextureFX +{ + CComPtr m_il; + hash_map > m_vs; + CComPtr m_vs_cb; + hash_map > m_gs; + hash_map > m_ps; + CComPtr m_ps_cb; + hash_map > m_ps_ss; + CComPtr m_palette_ss; + hash_map > m_om_dss; + hash_map > m_om_bs; + + VSConstantBuffer m_vs_cb_cache; + PSConstantBuffer m_ps_cb_cache; + +public: + GSTextureFX11(); + + bool Create(GSDevice* dev); + + void SetupIA(const void* vertices, int count, int prim); + void SetupVS(VSSelector sel, const VSConstantBuffer* cb); + void SetupGS(GSSelector sel); + void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal); + void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); + void SetupRS(int w, int h, const GSVector4i& scissor); + void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds); + void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); +}; diff --git a/plugins/GSdx/GSTextureFX9.cpp b/plugins/GSdx/GSTextureFX9.cpp index 82c213d165..891085c949 100644 --- a/plugins/GSdx/GSTextureFX9.cpp +++ b/plugins/GSdx/GSTextureFX9.cpp @@ -24,94 +24,95 @@ #include "resource.h" GSTextureFX9::GSTextureFX9() - : m_dev(NULL) { } -bool GSTextureFX9::Create(GSDevice9* dev) +bool GSTextureFX9::Create(GSDevice* dev) { - m_dev = dev; + if(!__super::Create(dev)) + { + return false; + } + + // create layout VSSelector sel; - - sel.bppz = 0; - sel.tme = 0; - sel.fst = 0; - sel.logz = 0; - VSConstantBuffer cb; - SetupVS(sel, &cb); // creates layout + SetupVS(sel, &cb); + + // return true; } -bool GSTextureFX9::CreateMskFix(GSTexture9& t, DWORD size, DWORD msk, DWORD fix) +GSTexture* GSTextureFX9::CreateMskFix(uint32 size, uint32 msk, uint32 fix) { - DWORD hash = (size << 20) | (msk << 10) | fix; + GSTexture* t = NULL; - if(CRBMap::CPair* pair = m_mskfix.Lookup(hash)) + uint32 hash = (size << 20) | (msk << 10) | fix; + + hash_map::iterator i = m_mskfix.find(hash); + + if(i != m_mskfix.end()) { - t = pair->m_value; + t = i->second; } else { - if(!m_dev->CreateTexture(t, size, 1, D3DFMT_R32F)) - { - return false; - } + t = m_dev->CreateTexture(size, 1, D3DFMT_R32F); - BYTE* bits; - int pitch; - - if(t.Map(&bits, pitch)) + if(t) { - for(DWORD i = 0; i < size; i++) + GSTexture::GSMap m; + + if(t->Map(m)) { - ((float*)bits)[i] = (float)((i & msk) | fix) / size; + for(uint32 i = 0; i < size; i++) + { + ((float*)m.bits)[i] = (float)((i & msk) | fix) / size; + } + + t->Unmap(); } - t.Unmap(); + m_mskfix[hash] = t; } - - m_mskfix.SetAt(hash, t); } - return true; + return t; } -bool GSTextureFX9::SetupIA(const GSVertexHW9* vertices, UINT count, D3DPRIMITIVETYPE prim) +void GSTextureFX9::SetupIA(const void* vertices, int count, int prim) { - m_dev->IASetVertexBuffer(count, vertices); - m_dev->IASetInputLayout(m_il); - m_dev->IASetPrimitiveTopology(prim); + GSDevice9* dev = (GSDevice9*)m_dev; - return true; + dev->IASetVertexBuffer(vertices, sizeof(GSVertexHW9), count); + dev->IASetInputLayout(m_il); + dev->IASetPrimitiveTopology((D3DPRIMITIVETYPE)prim); } -bool GSTextureFX9::SetupVS(VSSelector sel, const VSConstantBuffer* cb) +void GSTextureFX9::SetupVS(VSSelector sel, const VSConstantBuffer* cb) { - CComPtr vs; + GSDevice9* dev = (GSDevice9*)m_dev; - if(CRBMap >::CPair* pair = m_vs.Lookup(sel)) - { - vs = pair->m_value; - } - else - { - CStringA str[4]; + hash_map >::const_iterator i = m_vs.find(sel); - str[0].Format("%d", sel.bppz); - str[1].Format("%d", sel.tme); - str[2].Format("%d", sel.fst); - str[3].Format("%d", sel.logz); + if(i == m_vs.end()) + { + string str[4]; + + str[0] = format("%d", sel.bppz); + str[1] = format("%d", sel.tme); + str[2] = format("%d", sel.fst); + str[3] = format("%d", sel.logz); D3DXMACRO macro[] = { - {"VS_BPPZ", str[0]}, - {"VS_TME", str[1]}, - {"VS_FST", str[2]}, - {"VS_LOGZ", str[3]}, + {"VS_BPPZ", str[0].c_str()}, + {"VS_TME", str[1].c_str()}, + {"VS_FST", str[2].c_str()}, + {"VS_LOGZ", str[3].c_str()}, {NULL, NULL}, }; @@ -125,125 +126,118 @@ bool GSTextureFX9::SetupVS(VSSelector sel, const VSConstantBuffer* cb) }; CComPtr il; + CComPtr vs; - m_dev->CompileShader(IDR_TFX9_FX, "vs_main", macro, &vs, layout, countof(layout), &il); + dev->CompileShader(IDR_TFX_FX, "vs_main", macro, &vs, layout, countof(layout), &il); if(m_il == NULL) { m_il = il; } - m_vs.SetAt(sel, vs); + m_vs[sel] = vs; + + i = m_vs.find(sel); } - m_dev->VSSetShader(vs, (const float*)cb, sizeof(*cb) / sizeof(GSVector4)); - - return true; + dev->VSSetShader(i->second, (const float*)cb, sizeof(*cb) / sizeof(GSVector4)); } -bool GSTextureFX9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, IDirect3DTexture9* tex, IDirect3DTexture9* pal, bool psrr) +void GSTextureFX9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) { - m_dev->PSSetShaderResources(tex, pal); + GSDevice9* dev = (GSDevice9*)m_dev; - if(tex && psrr) + dev->PSSetShaderResources(tex, pal); + + if(tex && (sel.wms == 3 || sel.wmt == 3)) { if(sel.wms == 3) { - D3DSURFACE_DESC desc; - tex->GetLevelDesc(0, &desc); - - GSTexture9 t; - CreateMskFix(t, desc.Width, cb->UMSK, cb->UFIX); - - (*m_dev)->SetTexture(2, t); + if(GSTexture* t = CreateMskFix(tex->GetWidth(), cb->MskFix.x, cb->MskFix.z)) + { + (*dev)->SetTexture(2, *(GSTexture9*)t); + } } if(sel.wmt == 3) { - D3DSURFACE_DESC desc; - tex->GetLevelDesc(0, &desc); - - GSTexture9 t; - CreateMskFix(t, desc.Height, cb->VMSK, cb->VFIX); - - (*m_dev)->SetTexture(3, t); + if(GSTexture* t = CreateMskFix(tex->GetHeight(), cb->MskFix.y, cb->MskFix.w)) + { + (*dev)->SetTexture(3, *(GSTexture9*)t); + } } } - UpdatePS(sel, cb, ssel, psrr); - - return true; + UpdatePS(sel, cb, ssel); } -void GSTextureFX9::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, bool psrr) +void GSTextureFX9::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) { - HRESULT hr; + GSDevice9* dev = (GSDevice9*)m_dev; - if(!psrr) + hash_map >::const_iterator i = m_ps.find(sel); + + if(i == m_ps.end()) { - if(sel.wms == 3) sel.wms = 0; - if(sel.wmt == 3) sel.wmt = 0; - } + string str[13]; - CComPtr ps; - - if(CRBMap >::CPair* pair = m_ps.Lookup(sel)) - { - ps = pair->m_value; - } - else - { - CStringA str[12]; - - str[0].Format("%d", sel.fst); - str[1].Format("%d", sel.wms); - str[2].Format("%d", sel.wmt); - str[3].Format("%d", sel.bpp); - str[4].Format("%d", sel.aem); - str[5].Format("%d", sel.tfx); - str[6].Format("%d", sel.tcc); - str[7].Format("%d", sel.ate); - str[8].Format("%d", sel.atst); - str[9].Format("%d", sel.fog); - str[10].Format("%d", sel.clr1); - str[11].Format("%d", sel.rt); + str[0] = format("%d", sel.fst); + str[1] = format("%d", sel.wms); + str[2] = format("%d", sel.wmt); + str[3] = format("%d", sel.bpp); + str[4] = format("%d", sel.aem); + str[5] = format("%d", sel.tfx); + str[6] = format("%d", sel.tcc); + str[7] = format("%d", sel.ate); + str[8] = format("%d", sel.atst); + str[9] = format("%d", sel.fog); + str[10] = format("%d", sel.clr1); + str[11] = format("%d", sel.rt); + str[12] = format("%d", sel.ltf); D3DXMACRO macro[] = { - {"FST", str[0]}, - {"WMS", str[1]}, - {"WMT", str[2]}, - {"BPP", str[3]}, - {"AEM", str[4]}, - {"TFX", str[5]}, - {"TCC", str[6]}, - {"ATE", str[7]}, - {"ATST", str[8]}, - {"FOG", str[9]}, - {"CLR1", str[10]}, - {"RT", str[11]}, + {"PS_FST", str[0].c_str()}, + {"PS_WMS", str[1].c_str()}, + {"PS_WMT", str[2].c_str()}, + {"PS_BPP", str[3].c_str()}, + {"PS_AEM", str[4].c_str()}, + {"PS_TFX", str[5].c_str()}, + {"PS_TCC", str[6].c_str()}, + {"PS_ATE", str[7].c_str()}, + {"PS_ATST", str[8].c_str()}, + {"PS_FOG", str[9].c_str()}, + {"PS_CLR1", str[10].c_str()}, + {"PS_RT", str[11].c_str()}, + {"PS_LTF", str[12].c_str()}, {NULL, NULL}, }; - hr = m_dev->CompileShader(IDR_TFX9_FX, "ps_main", macro, &ps); + CComPtr ps; - m_ps.SetAt(sel, ps); + dev->CompileShader(IDR_TFX_FX, "ps_main", macro, &ps); + + m_ps[sel] = ps; + + i = m_ps.find(sel); } - m_dev->PSSetShader(ps, (const float*)cb, sizeof(*cb) / sizeof(GSVector4)); + dev->PSSetShader(i->second, (const float*)cb, sizeof(*cb) / sizeof(GSVector4)); Direct3DSamplerState9* ss = NULL; if(sel.tfx != 4) { - if(sel.bpp >= 3 || sel.wms >= 3 || sel.wmt >= 3) + if(!(sel.bpp < 3 && sel.wms < 3 && sel.wmt < 3)) { - ssel.min = ssel.mag = 0; + ssel.ltf = 0; } - if(CRBMap::CPair* pair = m_ps_ss.Lookup(ssel)) + hash_map::const_iterator i = m_ps_ss.find(ssel); + + if(i != m_ps_ss.end()) { - ss = pair->m_value; + ss = i->second; } else { @@ -251,42 +245,42 @@ void GSTextureFX9::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSample memset(ss, 0, sizeof(*ss)); - ss->FilterMin[0] = ssel.min ? D3DTEXF_LINEAR : D3DTEXF_POINT; - ss->FilterMag[0] = ssel.mag ? D3DTEXF_LINEAR : D3DTEXF_POINT; + ss->FilterMin[0] = ssel.ltf ? D3DTEXF_LINEAR : D3DTEXF_POINT; + ss->FilterMag[0] = ssel.ltf ? D3DTEXF_LINEAR : D3DTEXF_POINT; ss->FilterMin[1] = D3DTEXF_POINT; ss->FilterMag[1] = D3DTEXF_POINT; ss->AddressU = ssel.tau ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP; ss->AddressV = ssel.tav ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP; - m_ps_ss.SetAt(ssel, ss); + m_ps_ss[ssel] = ss; } } - m_dev->PSSetSamplerState(ss); + dev->PSSetSamplerState(ss); } -void GSTextureFX9::SetupRS(int w, int h, const RECT& scissor) +void GSTextureFX9::SetupRS(int w, int h, const GSVector4i& scissor) { - m_dev->RSSet(w, h, &scissor); + ((GSDevice9*)m_dev)->RSSet(w, h, &scissor); } -void GSTextureFX9::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, BYTE bf, IDirect3DSurface9* rt, IDirect3DSurface9* ds) +void GSTextureFX9::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds) { - UpdateOM(dssel, bsel, bf); + UpdateOM(dssel, bsel, afix); - m_dev->OMSetRenderTargets(rt, ds); + ((GSDevice9*)m_dev)->OMSetRenderTargets(rt, ds); } -void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, BYTE bf) +void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) { + GSDevice9* dev = (GSDevice9*)m_dev; + Direct3DDepthStencilState9* dss = NULL; - if(CRBMap::CPair* pair = m_om_dss.Lookup(dssel)) - { - dss = pair->m_value; - } - else + hash_map::const_iterator i = m_om_dss.find(dssel); + + if(i == m_om_dss.end()) { dss = new Direct3DDepthStencilState9(); @@ -301,6 +295,7 @@ void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, dss->StencilPassOp = dssel.fba ? D3DSTENCILOP_REPLACE : D3DSTENCILOP_KEEP; dss->StencilFailOp = dssel.fba ? D3DSTENCILOP_ZERO : D3DSTENCILOP_KEEP; dss->StencilDepthFailOp = dssel.fba ? D3DSTENCILOP_ZERO : D3DSTENCILOP_KEEP; + dss->StencilRef = 3; } if(!(dssel.zte && dssel.ztst == 1 && !dssel.zwe)) @@ -318,20 +313,18 @@ void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, dss->DepthFunc = ztst[dssel.ztst]; } - m_om_dss.SetAt(dssel, dss); + m_om_dss[dssel] = dss; + + i = m_om_dss.find(dssel); } - m_dev->OMSetDepthStencilState(dss, 3); + dev->OMSetDepthStencilState(i->second); - Direct3DBlendState9* bs = NULL; - - if(CRBMap::CPair* pair = m_om_bs.Lookup(bsel)) + hash_map::const_iterator j = m_om_bs.find(bsel); + + if(j == m_om_bs.end()) { - bs = pair->m_value; - } - else - { - bs = new Direct3DBlendState9(); + Direct3DBlendState9* bs = new Direct3DBlendState9(); memset(bs, 0, sizeof(*bs)); @@ -457,8 +450,10 @@ void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, if(bsel.wb) bs->RenderTargetWriteMask |= D3DCOLORWRITEENABLE_BLUE; if(bsel.wa) bs->RenderTargetWriteMask |= D3DCOLORWRITEENABLE_ALPHA; - m_om_bs.SetAt(bsel, bs); + m_om_bs[bsel] = bs; + + j = m_om_bs.find(bsel); } - m_dev->OMSetBlendState(bs, 0x010101 * bf); + dev->OMSetBlendState(j->second, afix >= 0x80 ? 0xffffff : 0x020202 * afix); } diff --git a/plugins/GSdx/GSTextureFX9.h b/plugins/GSdx/GSTextureFX9.h index e2811059c9..317037f695 100644 --- a/plugins/GSdx/GSTextureFX9.h +++ b/plugins/GSdx/GSTextureFX9.h @@ -21,153 +21,33 @@ #pragma once +#include "GSTextureFX.h" #include "GSDevice9.h" -class GSTextureFX9 +class GSTextureFX9 : public GSTextureFX { -public: - #pragma pack(push, 1) - - struct VSConstantBuffer - { - GSVector4 VertexScale; - GSVector4 VertexOffset; - GSVector2 TextureScale; - float _pad[2]; - }; - - union VSSelector - { - struct - { - DWORD bppz:2; - DWORD tme:1; - DWORD fst:1; - DWORD logz:1; - }; - - DWORD dw; - - operator DWORD() {return dw & 0x1f;} - }; - - struct PSConstantBuffer - { - GSVector4 FogColor; - float MINU; - float MAXU; - float MINV; - float MAXV; - DWORD UMSK; - DWORD UFIX; - DWORD VMSK; - DWORD VFIX; - float TA0; - float TA1; - float AREF; - float _pad[1]; - GSVector2 WH; - GSVector2 rWrH; - }; - - union PSSelector - { - struct - { - DWORD fst:1; - DWORD wms:2; - DWORD wmt:2; - DWORD bpp:3; - DWORD aem:1; - DWORD tfx:3; - DWORD tcc:1; - DWORD ate:1; - DWORD atst:3; - DWORD fog:1; - DWORD clr1:1; - DWORD rt:1; - }; - - DWORD dw; - - operator DWORD() {return dw & 0xfffff;} - }; - - union PSSamplerSelector - { - struct - { - DWORD tau:1; - DWORD tav:1; - DWORD min:1; - DWORD mag:1; - }; - - DWORD dw; - - operator DWORD() {return dw & 0xf;} - }; - - union OMDepthStencilSelector - { - struct - { - DWORD zte:1; - DWORD ztst:2; - DWORD zwe:1; - DWORD date:1; - DWORD fba:1; - }; - - DWORD dw; - - operator DWORD() {return dw & 0x3f;} - }; - - union OMBlendSelector - { - struct - { - DWORD abe:1; - DWORD a:2; - DWORD b:2; - DWORD c:2; - DWORD d:2; - DWORD wr:1; - DWORD wg:1; - DWORD wb:1; - DWORD wa:1; - }; - - DWORD dw; - - operator DWORD() {return dw & 0x1fff;} - }; - - #pragma pack(pop) - -private: - GSDevice9* m_dev; CComPtr m_il; - CRBMapC > m_vs; + hash_map > m_vs; D3DXHANDLE m_vs_params; - CRBMapC > m_ps; - CRBMapC m_ps_ss; - CRBMapC m_om_dss; - CRBMapC m_om_bs; - CRBMapC m_mskfix; + hash_map > m_ps; + hash_map m_ps_ss; + hash_map m_om_dss; + hash_map m_om_bs; + hash_map m_mskfix; + + GSTexture* CreateMskFix(uint32 size, uint32 msk, uint32 fix); public: GSTextureFX9(); - bool Create(GSDevice9* dev); - bool CreateMskFix(GSTexture9& t, DWORD size, DWORD msk, DWORD fix); + bool Create(GSDevice* dev); - bool SetupIA(const GSVertexHW9* vertices, UINT count, D3DPRIMITIVETYPE prim); - bool SetupVS(VSSelector sel, const VSConstantBuffer* cb); - bool SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, IDirect3DTexture9* tex, IDirect3DTexture9* pal, bool psrr); - void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, bool psrr); - void SetupRS(int w, int h, const RECT& scissor); - void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, BYTE bf, IDirect3DSurface9* rt, IDirect3DSurface9* ds); - void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, BYTE bf); + void SetupIA(const void* vertices, int count, int prim); + void SetupVS(VSSelector sel, const VSConstantBuffer* cb); + void SetupGS(GSSelector sel) {} + void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal); + void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); + void SetupRS(int w, int h, const GSVector4i& scissor); + void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds); + void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); }; diff --git a/plugins/GSdx/GSTextureNull.h b/plugins/GSdx/GSTextureNull.h index 38f21990fe..68cf9b2843 100644 --- a/plugins/GSdx/GSTextureNull.h +++ b/plugins/GSdx/GSTextureNull.h @@ -31,14 +31,12 @@ public: GSTextureNull(); GSTextureNull(int type, int w, int h, int format); - operator bool() {return m_desc.type != 0;} - int GetType() const {return m_desc.type;} int GetWidth() const {return m_desc.w;} int GetHeight() const {return m_desc.h;} int GetFormat() const {return m_desc.format;} - bool Update(const CRect& r, const void* data, int pitch) {return true;} - bool Map(BYTE** bits, int& pitch, const RECT* r = NULL) {return true;} + bool Update(const GSVector4i& r, const void* data, int pitch) {return true;} + bool Map(GSMap& m, const GSVector4i* r) {return false;} void Unmap() {} - bool Save(CString fn, bool dds = false) {return false;} + bool Save(const string& fn, bool dds = false) {return false;} }; diff --git a/plugins/GSdx/GSTextureOGL.cpp b/plugins/GSdx/GSTextureOGL.cpp new file mode 100644 index 0000000000..ca59491c72 --- /dev/null +++ b/plugins/GSdx/GSTextureOGL.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSTextureOGL.h" +#include "GSDeviceOGL.h" + +GSTextureOGL::GSTextureOGL(GLuint texture, int type, int width, int height, int format) + : m_texture(texture) + , m_type(type) + , m_width(width) + , m_height(height) + , m_format(format) +{ + // TODO: offscreen type should be just a memory array, also returned in Map + + glGenBuffers(1, &m_pbo); GSDeviceOGL::CheckError(); +} + +GSTextureOGL::~GSTextureOGL() +{ + if(m_pbo) + { + glDeleteBuffers(1, &m_pbo); GSDeviceOGL::CheckError(); + } + + if(m_texture) + { + switch(m_type) + { + case DepthStencil: + glDeleteRenderbuffers(1, &m_texture); GSDeviceOGL::CheckError(); + break; + default: + glDeleteTextures(1, &m_texture); GSDeviceOGL::CheckError(); + break; + } + } +} + +int GSTextureOGL::GetType() const +{ + return m_type; +} + +int GSTextureOGL::GetWidth() const +{ + return m_width; +} + +int GSTextureOGL::GetHeight() const +{ + return m_height; +} + +int GSTextureOGL::GetFormat() const +{ + return m_format; +} + +bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch) +{ + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pbo); GSDeviceOGL::CheckError(); + + int w = r.width(); + int h = r.height(); + int bpp = 32; // TODO: should be in sync with m_format + int dstpitch = w * bpp >> 3; + + glBufferData(GL_PIXEL_UNPACK_BUFFER, h * dstpitch, NULL, GL_STREAM_DRAW); GSDeviceOGL::CheckError(); + + if(uint8* dst = (uint8*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY)) + { + uint8* src = (uint8*)data; + + for(int i = 0; i < h; i++, src += pitch, dst += dstpitch) + { + memcpy(dst, src, dstpitch); + } + + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); GSDeviceOGL::CheckError(); + } + + glBindTexture(GL_TEXTURE_2D, m_texture); GSDeviceOGL::CheckError(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, r.left, r.top, w, h, GL_RGBA, GL_UNSIGNED_BYTE, 0); GSDeviceOGL::CheckError(); + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); GSDeviceOGL::CheckError(); + + return false; +} + +bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r) +{ + // TODO + + return false; +} + +void GSTextureOGL::Unmap() +{ + // TODO +} + +bool GSTextureOGL::Save(const string& fn, bool dds) +{ + // TODO + + return false; +} diff --git a/plugins/GSdx/GSTextureOGL.h b/plugins/GSdx/GSTextureOGL.h new file mode 100644 index 0000000000..d69581a697 --- /dev/null +++ b/plugins/GSdx/GSTextureOGL.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSTexture.h" + +class GSTextureOGL : public GSTexture +{ + GLuint m_texture; + GLuint m_pbo; + + int m_type; + int m_width; + int m_height; + int m_format; + +public: + GSTextureOGL(GLuint texture, int type, int width, int height, int format = 0); + virtual ~GSTextureOGL(); + + int GetType() const; + int GetWidth() const; + int GetHeight() const; + int GetFormat() const; + + bool Update(const GSVector4i& r, const void* data, int pitch); + bool Map(GSMap& m, const GSVector4i* r); + void Unmap(); + bool Save(const string& fn, bool dds = false); + + operator GLuint() {return m_texture;} +}; diff --git a/plugins/GSdx/GSThread.cpp b/plugins/GSdx/GSThread.cpp new file mode 100644 index 0000000000..8b64fdce55 --- /dev/null +++ b/plugins/GSdx/GSThread.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "StdAfx.h" +#include "GSThread.h" + +GSThread::GSThread() + : m_ThreadId(0) + , m_hThread(NULL) +{ +} + +GSThread::~GSThread() +{ + CloseThread(); +} + +DWORD WINAPI GSThread::StaticThreadProc(LPVOID lpParam) +{ + ((GSThread*)lpParam)->ThreadProc(); + + return 0; +} + +void GSThread::CreateThread() +{ + m_hThread = ::CreateThread(NULL, 0, StaticThreadProc, (LPVOID)this, 0, &m_ThreadId); +} + +void GSThread::CloseThread() +{ + if(m_hThread != NULL) + { + if(WaitForSingleObject(m_hThread, 5000) != WAIT_OBJECT_0) + { + TerminateThread(m_hThread, 1); + } + + CloseHandle(m_hThread); + + m_hThread = NULL; + m_ThreadId = 0; + } +} + diff --git a/plugins/GSdx/GSThread.h b/plugins/GSdx/GSThread.h new file mode 100644 index 0000000000..79dca94f9e --- /dev/null +++ b/plugins/GSdx/GSThread.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +class GSThread +{ + // TODO: linux + + DWORD m_ThreadId; + HANDLE m_hThread; + + static DWORD WINAPI StaticThreadProc(LPVOID lpParam); + +protected: + virtual void ThreadProc() = 0; + + void CreateThread(); + void CloseThread(); + +public: + GSThread(); + virtual ~GSThread(); +}; diff --git a/plugins/GSdx/GSUtil.cpp b/plugins/GSdx/GSUtil.cpp index 4f06fe7fe9..4b38666b5c 100644 --- a/plugins/GSdx/GSUtil.cpp +++ b/plugins/GSdx/GSUtil.cpp @@ -23,10 +23,11 @@ #include "GS.h" #include "GSUtil.h" #include "svnrev.h" +#include "xbyak/xbyak_util.h" static struct GSUtilMaps { - BYTE PrimClassField[8]; + uint8 PrimClassField[8]; bool CompatibleBitsField[64][64]; bool SharedBitsField[64][64]; @@ -72,97 +73,58 @@ static struct GSUtilMaps } s_maps; -GS_PRIM_CLASS GSUtil::GetPrimClass(DWORD prim) +GS_PRIM_CLASS GSUtil::GetPrimClass(uint32 prim) { return (GS_PRIM_CLASS)s_maps.PrimClassField[prim]; } -bool GSUtil::HasSharedBits(DWORD spsm, DWORD dpsm) +bool GSUtil::HasSharedBits(uint32 spsm, uint32 dpsm) { return s_maps.SharedBitsField[spsm][dpsm]; } -bool GSUtil::HasSharedBits(DWORD sbp, DWORD spsm, DWORD dbp, DWORD dpsm) +bool GSUtil::HasSharedBits(uint32 sbp, uint32 spsm, uint32 dbp, uint32 dpsm) { if(sbp != dbp) return false; return HasSharedBits(spsm, dpsm); } -bool GSUtil::HasCompatibleBits(DWORD spsm, DWORD dpsm) +bool GSUtil::HasCompatibleBits(uint32 spsm, uint32 dpsm) { if(spsm == dpsm) return true; return s_maps.CompatibleBitsField[spsm][dpsm]; } -bool GSUtil::IsRectInRect(const CRect& inner, const CRect& outer) +bool GSUtil::IsRectInRect(const GSVector4i& inner, const GSVector4i& outer) { return outer.left <= inner.left && inner.right <= outer.right && outer.top <= inner.top && inner.bottom <= outer.bottom; } -bool GSUtil::IsRectInRectH(const CRect& inner, const CRect& outer) +bool GSUtil::IsRectInRectH(const GSVector4i& inner, const GSVector4i& outer) { return outer.top <= inner.top && inner.bottom <= outer.bottom; } -bool GSUtil::IsRectInRectV(const CRect& inner, const CRect& outer) +bool GSUtil::IsRectInRectV(const GSVector4i& inner, const GSVector4i& outer) { return outer.left <= inner.left && inner.right <= outer.right; } -void GSUtil::FitRect(CRect& r, int aspectratio) -{ - static const int ar[][2] = {{0, 0}, {4, 3}, {16, 9}}; - - if(aspectratio <= 0 || aspectratio >= countof(ar)) - { - return; - } - - int arx = ar[aspectratio][0]; - int ary = ar[aspectratio][1]; - - CRect r2 = r; - - if(arx > 0 && ary > 0) - { - if(r.Width() * ary > r.Height() * arx) - { - int w = r.Height() * arx / ary; - r.left = r.CenterPoint().x - w / 2; - if(r.left & 1) r.left++; - r.right = r.left + w; - } - else - { - int h = r.Width() * ary / arx; - r.top = r.CenterPoint().y - h / 2; - if(r.top & 1) r.top++; - r.bottom = r.top + h; - } - } - - r &= r2; -} - bool GSUtil::CheckDirectX() { - CString str; - - str.Format(_T("d3dx9_%d.dll"), D3DX_SDK_VERSION); - - if(HINSTANCE hDll = LoadLibrary(str)) + if(HINSTANCE hDll = LoadLibrary(format("d3dx9_%d.dll", D3DX_SDK_VERSION).c_str())) { FreeLibrary(hDll); } else { - int res = AfxMessageBox(_T("Please update DirectX!\n\nWould you like to open the download page in your browser?"), MB_YESNO); - - if(res == IDYES) + if(MessageBox(NULL, "You need to update directx, would you like to do it now?", "GSdx", MB_YESNO) == IDYES) { - ShellExecute(NULL, _T("open"), _T("http://www.microsoft.com/downloads/details.aspx?FamilyId=2DA43D38-DB71-4C1B-BC6A-9B6652CD92A3"), NULL, NULL, SW_SHOWNORMAL); + const char* url = "http://www.microsoft.com/downloads/details.aspx?FamilyId=2DA43D38-DB71-4C1B-BC6A-9B6652CD92A3"; + + ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); } return false; @@ -171,37 +133,26 @@ bool GSUtil::CheckDirectX() return true; } -static bool _CheckSSE() -{ - __try - { - static __m128i m; - - #if _M_SSE >= 0x402 - m.m128i_i32[0] = _mm_popcnt_u32(1234); - #elif _M_SSE >= 0x401 - m = _mm_packus_epi32(m, m); - #elif _M_SSE >= 0x301 - m = _mm_alignr_epi8(m, m, 1); - #elif _M_SSE >= 0x200 - m = _mm_packs_epi32(m, m); - #endif - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - return false; - } - - return true; -} - bool GSUtil::CheckSSE() { - if(!_CheckSSE()) + Xbyak::util::Cpu cpu; + Xbyak::util::Cpu::Type type; + + #if _M_SSE >= 0x402 + type = Xbyak::util::Cpu::tSSE42; + #elif _M_SSE >= 0x401 + type = Xbyak::util::Cpu::tSSE41; + #elif _M_SSE >= 0x301 + type = Xbyak::util::Cpu::tSSSE3; + #elif _M_SSE >= 0x200 + type = Xbyak::util::Cpu::tSSE2; + #endif + + if(!cpu.has(type)) { - CString str; - str.Format(_T("This CPU does not support SSE %d.%02d"), _M_SSE >> 8, _M_SSE & 0xff); - AfxMessageBox(str, MB_OK); + string s = format("This CPU does not support SSE %d.%02d", _M_SSE >> 8, _M_SSE & 0xff); + + MessageBox(NULL, s.c_str(), "GSdx", MB_OK); return false; } @@ -221,52 +172,65 @@ bool GSUtil::IsDirect3D10Available() return false; } -char* GSUtil::GetLibName() +bool GSUtil::IsDirect3D11Available() { - CString str; - - str.Format(_T("GSdx %d"), SVN_REV); - - if(SVN_MODS) str += _T("m"); - -#if _M_AMD64 - str += _T(" 64-bit"); -#endif - - CAtlList sl; - -#ifdef __INTEL_COMPILER - CString s; - s.Format(_T("Intel C++ %d.%02d"), __INTEL_COMPILER/100, __INTEL_COMPILER%100); - sl.AddTail(s); -#elif _MSC_VER - CString s; - s.Format(_T("MSVC %d.%02d"), _MSC_VER/100, _MSC_VER%100); - sl.AddTail(s); -#endif - -#if _M_SSE >= 0x402 - sl.AddTail(_T("SSE42")); -#elif _M_SSE >= 0x401 - sl.AddTail(_T("SSE41")); -#elif _M_SSE >= 0x301 - sl.AddTail(_T("SSSE3")); -#elif _M_SSE >= 0x200 - sl.AddTail(_T("SSE2")); -#elif _M_SSE >= 0x100 - sl.AddTail(_T("SSE")); -#endif - - POSITION pos = sl.GetHeadPosition(); - - while(pos) + if(HMODULE hModule = LoadLibrary(_T("d3d11.dll"))) { - if(pos == sl.GetHeadPosition()) str += _T(" ("); - str += sl.GetNext(pos); - str += pos ? _T(", ") : _T(")"); + FreeLibrary(hModule); + + return true; } - static char buff[256]; - strncpy(buff, CStringA(str), min(countof(buff)-1, str.GetLength())); - return buff; + if(HMODULE hModule = LoadLibrary(_T("d3d11_beta.dll"))) + { + FreeLibrary(hModule); + + return true; + } + + return false; +} + +char* GSUtil::GetLibName() +{ + static string str; + + str = format("GSdx %d", SVN_REV); + + if(SVN_MODS) str += "m"; + + #if _M_AMD64 + str += " 64-bit"; + #endif + + list sl; + + // TODO: gcc + + #ifdef __INTEL_COMPILER + sl.push_back(format("Intel C++ %d.%02d", __INTEL_COMPILER / 100, __INTEL_COMPILER % 100)); + #elif _MSC_VER + sl.push_back(format("MSVC %d.%02d", _MSC_VER / 100, _MSC_VER % 100)); + #endif + + #if _M_SSE >= 0x402 + sl.push_back("SSE42"); + #elif _M_SSE >= 0x401 + sl.push_back("SSE41"); + #elif _M_SSE >= 0x301 + sl.push_back("SSSE3"); + #elif _M_SSE >= 0x200 + sl.push_back("SSE2"); + #elif _M_SSE >= 0x100 + sl.push_back("SSE"); + #endif + + for(list::iterator i = sl.begin(); i != sl.end(); ) + { + if(i == sl.begin()) str += " ("; + str += *i; + str += ++i != sl.end() ? ", " : ")"; + } + + return (char*)str.c_str(); } \ No newline at end of file diff --git a/plugins/GSdx/GSUtil.h b/plugins/GSdx/GSUtil.h index 2d0eacb569..f7d81539b4 100644 --- a/plugins/GSdx/GSUtil.h +++ b/plugins/GSdx/GSUtil.h @@ -26,19 +26,17 @@ class GSUtil { public: - static GS_PRIM_CLASS GetPrimClass(DWORD prim); + static GS_PRIM_CLASS GetPrimClass(uint32 prim); - static bool HasSharedBits(DWORD spsm, DWORD dpsm); - static bool HasSharedBits(DWORD sbp, DWORD spsm, DWORD dbp, DWORD dpsm); - static bool HasCompatibleBits(DWORD spsm, DWORD dpsm); + static bool HasSharedBits(uint32 spsm, uint32 dpsm); + static bool HasSharedBits(uint32 sbp, uint32 spsm, uint32 dbp, uint32 dpsm); + static bool HasCompatibleBits(uint32 spsm, uint32 dpsm); - static bool IsRectInRect(const CRect& inner, const CRect& outer); - static bool IsRectInRectH(const CRect& inner, const CRect& outer); - static bool IsRectInRectV(const CRect& inner, const CRect& outer); - - static void FitRect(CRect& r, int aspectratio); + static bool IsRectInRect(const GSVector4i& inner, const GSVector4i& outer); + static bool IsRectInRectH(const GSVector4i& inner, const GSVector4i& outer); + static bool IsRectInRectV(const GSVector4i& inner, const GSVector4i& outer); - static int EncodePSM(int psm) + static uint32 EncodePSM(uint32 psm) { switch(psm) { @@ -62,6 +60,7 @@ public: static bool CheckSSE(); static bool IsDirect3D10Available(); + static bool IsDirect3D11Available(); static char* GetLibName(); }; diff --git a/plugins/GSdx/GSVector.cpp b/plugins/GSdx/GSVector.cpp index 18a2e9fcc1..d7f6e7ec77 100644 --- a/plugins/GSdx/GSVector.cpp +++ b/plugins/GSdx/GSVector.cpp @@ -27,16 +27,16 @@ const GSVector4 GSVector4::m_ps4567(4.0f, 5.0f, 6.0f, 7.0f); const GSVector4 GSVector4::m_x3f800000(_mm_castsi128_ps(_mm_set1_epi32(0x3f800000))); const GSVector4 GSVector4::m_x4b000000(_mm_castsi128_ps(_mm_set1_epi32(0x4b000000))); -void GSVector4::operator = (const GSVector4i& v) -{ - m = _mm_cvtepi32_ps(v); -} - -void GSVector4i::operator = (const GSVector4& v) +GSVector4i::GSVector4i(const GSVector4& v) { m = _mm_cvttps_epi32(v); } +GSVector4::GSVector4(const GSVector4i& v) +{ + m = _mm_cvtepi32_ps(v); +} + GSVector4i GSVector4i::cast(const GSVector4& v) { return GSVector4i(_mm_castps_si128(v.m)); @@ -46,3 +46,55 @@ GSVector4 GSVector4::cast(const GSVector4i& v) { return GSVector4(_mm_castsi128_ps(v.m)); } + +GSVector4i GSVector4i::fit(int arx, int ary) const +{ + GSVector4i r = *this; + + if(arx > 0 && ary > 0) + { + int w = width(); + int h = height(); + + if(w * ary > h * arx) + { + w = h * arx / ary; + r.left = (r.left + r.right - w) >> 1; + if(r.left & 1) r.left++; + r.right = r.left + w; + } + else + { + h = w * ary / arx; + r.top = (r.top + r.bottom - h) >> 1; + if(r.top & 1) r.top++; + r.bottom = r.top + h; + } + + r = r.rintersect(*this); + } + else + { + r = *this; + } + + return r; +} + +GSVector4i GSVector4i::fit(int preset) const +{ + GSVector4i r; + + static const int ar[][2] = {{0, 0}, {4, 3}, {16, 9}}; + + if(preset > 0 && preset < countof(ar)) + { + r = fit(ar[preset][0], ar[preset][1]); + } + else + { + r = *this; + } + + return r; +} diff --git a/plugins/GSdx/GSVector.h b/plugins/GSdx/GSVector.h index 1d98b97822..2b6455e273 100644 --- a/plugins/GSdx/GSVector.h +++ b/plugins/GSdx/GSVector.h @@ -29,14 +29,21 @@ public: *this = v; } - void operator = (const GSVector2T& v) + const GSVector2T& operator = (const GSVector2T& v) { _mm_storel_epi64((__m128i*)this, _mm_loadl_epi64((__m128i*)&v)); + + return *this; + } + + bool operator == (const GSVector2T& v) const + { + return x == v.x && y == v.y; } }; -typedef __declspec(align(8)) GSVector2T GSVector2; -typedef __declspec(align(8)) GSVector2T GSVector2i; +typedef GSVector2T GSVector2; +typedef GSVector2T GSVector2i; class GSVector4; @@ -47,16 +54,17 @@ public: { struct {int x, y, z, w;}; struct {int r, g, b, a;}; + struct {int left, top, right, bottom;}; int v[4]; float f32[4]; - unsigned __int64 u64[2]; - __int8 i8[16]; - __int16 i16[8]; - __int32 i32[4]; - __int64 i64[2]; - unsigned __int8 u8[16]; - unsigned __int16 u16[8]; - unsigned __int32 u32[4]; + int8 i8[16]; + int16 i16[8]; + int32 i32[4]; + int64 i64[2]; + uint8 u8[16]; + uint16 u16[8]; + uint32 u32[4]; + uint64 u64[2]; __m128i m; }; @@ -113,23 +121,13 @@ public: this->m = m; } - explicit GSVector4i(const CRect& r) - { - *this = GSVector4i(r.left, r.top, r.right, r.bottom); - } - - explicit GSVector4i(const GSVector4& v) - { - *this = v; - } + explicit GSVector4i(const GSVector4& v); void operator = (const GSVector4i& v) { m = v.m; } - void operator = (const GSVector4& v); - void operator = (int i) { m = _mm_set1_epi32(i); @@ -140,29 +138,118 @@ public: this->m = m; } - void operator = (const CRect& r) - { - m = GSVector4i(r); - } - operator __m128i() const { return m; } - operator CRect() const + // rect + + int width() const { - return *(CRect*)&m; + return right - left; } - UINT32 rgba32() const + int height() const + { + return bottom - top; + } + + GSVector4i rsize() const + { + return *this - xyxy(); // same as GSVector4i(0, 0, width(), height()); + } + + bool rempty() const + { + return (*this < zwzw()).mask() != 0x00ff; + } + + GSVector4i runion(const GSVector4i& a) const + { + int i = (upl64(a) < uph64(a)).mask(); + + if(i == 0xffff) + { + #if _M_SSE >= 0x401 + + return min_i32(a).upl64(max_i32(a).srl<8>()); + + #else + + return GSVector4i(min(x, a.x), min(y, a.y), max(z, a.z), max(w, a.w)); + + #endif + } + + if((i & 0x00ff) == 0x00ff) + { + return *this; + } + + if((i & 0xff00) == 0xff00) + { + return a; + } + + return GSVector4i::zero(); + } + + GSVector4i rintersect(const GSVector4i& a) const + { + return sat_i32(a); + } + + enum RoundMode {Outside, Inside, NegInf, PosInf}; + + template GSVector4i ralign(const GSVector2i& a) const + { + // a must be 1 << n + + GSVector4i mask = GSVector4i(a) - GSVector4i(1, 1); + + GSVector4i v; + + switch(mode) + { + case Inside: v = *this + mask; break; + case Outside: v = *this + mask.zwxy(); break; + case NegInf: v = *this; break; + case PosInf: v = *this + mask.zwzw(); break; + default: ASSERT(0); break; + } + + return v.andnot(mask.xyxy()); + } + + GSVector4i fit(int arx, int ary) const; + + GSVector4i fit(int preset) const; + + #ifdef _WINDOWS + + operator LPCRECT() const + { + return (LPCRECT)this; + } + + operator LPRECT() + { + return (LPRECT)this; + } + + #endif + + // + + uint32 rgba32() const { GSVector4i v = *this; v = v.ps32(v); v = v.pu16(v); - return (UINT32)store(v); + return (uint32)store(v); } static GSVector4i cast(const GSVector4& v); @@ -203,6 +290,32 @@ public: return max_i32(a.xyxy()).min_i32(a.zwzw()); } + #else + + GSVector4i sat_i32(const GSVector4i& a, const GSVector4i& b) const + { + GSVector4i v; + + v.x = min(max(x, a.x), b.x); + v.y = min(max(y, a.y), b.y); + v.z = min(max(z, a.z), b.z); + v.w = min(max(w, a.w), b.w); + + return v; + } + + GSVector4i sat_i32(const GSVector4i& a) const + { + GSVector4i v; + + v.x = min(max(x, a.x), a.z); + v.y = min(max(y, a.y), a.w); + v.z = min(max(z, a.x), a.z); + v.w = min(max(w, a.y), a.w); + + return v; + } + #endif GSVector4i sat_u8(const GSVector4i& a, const GSVector4i& b) const @@ -841,6 +954,18 @@ public: return sll16(shift + 1).mul16hs(f); } + bool eq(const GSVector4i& v) const + { + #if _M_SSE >= 0x401 + // pxor, ptest, je + GSVector4i t = *this ^ v; + return _mm_testz_si128(t, t) != 0; + #else + // pcmpeqd, pmovmskb, cmp, je + return eq32(v).alltrue(); + #endif + } + GSVector4i eq8(const GSVector4i& v) const { return GSVector4i(_mm_cmpeq_epi8(m, v.m)); @@ -972,14 +1097,14 @@ public: #if _M_SSE >= 0x401 - template GSVector4i insert64(__int64 a) const + template GSVector4i insert64(int64 a) const { return GSVector4i(_mm_insert_epi64(m, a, i)); } #endif - template __int64 extract64() const + template int64 extract64() const { if(i == 0) return GSVector4i::storeq(*this); #if _M_SSE >= 0x401 @@ -1263,8 +1388,8 @@ public: { GSVector4i v; - v = loadq((__int64)ptr[extract8() & 0xf]); - v = v.insert64<1>((__int64)ptr[extract8() >> 4]); + v = loadq((int64)ptr[extract8() & 0xf]); + v = v.insert64<1>((int64)ptr[extract8() >> 4]); return v; } @@ -1273,8 +1398,8 @@ public: { GSVector4i v; - v = loadq((__int64)ptr[extract8()]); - v = v.insert64<1>((__int64)ptr[extract8()]); + v = loadq((int64)ptr[extract8()]); + v = v.insert64<1>((int64)ptr[extract8()]); return v; } @@ -1283,8 +1408,8 @@ public: { GSVector4i v; - v = loadq((__int64)ptr[extract16()]); - v = v.insert64<1>((__int64)ptr[extract16()]); + v = loadq((int64)ptr[extract16()]); + v = v.insert64<1>((int64)ptr[extract16()]); return v; } @@ -1293,8 +1418,8 @@ public: { GSVector4i v; - v = loadq((__int64)ptr[extract32()]); - v = v.insert64<1>((__int64)ptr[extract32()]); + v = loadq((int64)ptr[extract32()]); + v = v.insert64<1>((int64)ptr[extract32()]); return v; } @@ -1303,8 +1428,8 @@ public: { GSVector4i v; - v = loadq((__int64)ptr[extract64<0>()]); - v = v.insert64<1>((__int64)ptr[extract64<1>()]); + v = loadq((int64)ptr[extract64<0>()]); + v = v.insert64<1>((int64)ptr[extract64<1>()]); return v; } @@ -1357,7 +1482,7 @@ public: dst[1] = gather8_4<8>(ptr); } - __forceinline void gather8_8(const BYTE* RESTRICT ptr, GSVector4i* RESTRICT dst) const + __forceinline void gather8_8(const uint8* RESTRICT ptr, GSVector4i* RESTRICT dst) const { dst[0] = gather8_8<>(ptr); } @@ -1469,14 +1594,18 @@ public: #endif - #if _M_SSE >= 0x401 - static GSVector4i loadnt(const void* p) { - return GSVector4i(_mm_stream_load_si128((__m128i*)p)); - } + #if _M_SSE >= 0x401 - #endif + return GSVector4i(_mm_stream_load_si128((__m128i*)p)); + + #else + + return GSVector4i(_mm_load_si128((__m128i*)p)); + + #endif + } static GSVector4i loadl(const void* p) { @@ -1518,7 +1647,7 @@ public: #ifdef _M_AMD64 - static GSVector4i loadq(__int64 i) + static GSVector4i loadq(int64 i) { return GSVector4i(_mm_cvtsi64_si128(i)); } @@ -1559,13 +1688,38 @@ public: #ifdef _M_AMD64 - static __int64 storeq(const GSVector4i& v) + static int64 storeq(const GSVector4i& v) { return _mm_cvtsi128_si64(v.m); } #endif + static void storent(void* RESTRICT dst, const void* RESTRICT src, size_t size) + { + const GSVector4i* s = (const GSVector4i*)src; + GSVector4i* d = (GSVector4i*)dst; + + if(size == 0) return; + + size_t i = 0; + size_t j = size >> 6; + + for(; i < j; i++, s += 4, d += 4) + { + storent(&d[0], s[0]); + storent(&d[1], s[1]); + storent(&d[2], s[2]); + storent(&d[3], s[3]); + } + + size &= 63; + + if(size == 0) return; + + memcpy(d, s, size); + } + __forceinline static void transpose(GSVector4i& a, GSVector4i& b, GSVector4i& c, GSVector4i& d) { _MM_TRANSPOSE4_SI128(a.m, b.m, c.m, d.m); @@ -1663,6 +1817,11 @@ public: GSVector4i* s = (GSVector4i*)src; GSVector4i* d = (GSVector4i*)dst; + if(!d[0].eq(s[0])) + { + return false; + } + GSVector4i v = GSVector4i::xffffffff(); for(int i = 0; i < size; i++) @@ -2077,16 +2236,17 @@ public: { struct {float x, y, z, w;}; struct {float r, g, b, a;}; + struct {float left, top, right, bottom;}; float v[4]; float f32[4]; - unsigned __int64 u64[2]; - __int8 i8[16]; - __int16 i16[8]; - __int32 i32[4]; - __int64 i64[2]; - unsigned __int8 u8[16]; - unsigned __int16 u16[8]; - unsigned __int32 u32[4]; + int8 i8[16]; + int16 i16[8]; + int32 i32[4]; + int64 i64[2]; + uint8 u8[16]; + uint16 u16[8]; + uint32 u32[4]; + uint64 u64[2]; __m128 m; }; @@ -2112,7 +2272,9 @@ public: GSVector4(int x, int y, int z, int w) { - m = _mm_cvtepi32_ps(_mm_set_epi32(w, z, y, x)); + GSVector4i v(x, y, z, w); + + m = _mm_cvtepi32_ps(v.m); } GSVector4(int x, int y) @@ -2130,6 +2292,11 @@ public: m = _mm_castsi128_ps(_mm_loadl_epi64((__m128i*)&v)); } + explicit GSVector4(const GSVector2i& v) + { + m = _mm_cvtepi32_ps(_mm_loadl_epi64((__m128i*)&v)); + } + explicit GSVector4(float f) { m = _mm_set1_ps(f); @@ -2140,28 +2307,18 @@ public: this->m = m; } - explicit GSVector4(CRect r) + explicit GSVector4(uint32 u32) { - m = _mm_set_ps((float)r.bottom, (float)r.right, (float)r.top, (float)r.left); + *this = GSVector4(GSVector4i::load((int)u32).u8to32()); } - explicit GSVector4(DWORD dw) - { - *this = GSVector4(GSVector4i::load((int)dw).u8to32()); - } - - explicit GSVector4(const GSVector4i& v) - { - *this = v; - } + explicit GSVector4(const GSVector4i& v); void operator = (const GSVector4& v) { m = v.m; } - void operator = (const GSVector4i& v); - void operator = (float f) { m = _mm_set1_ps(f); @@ -2172,14 +2329,9 @@ public: this->m = m; } - void operator = (DWORD dw) + void operator = (uint32 u32) { - *this = GSVector4(GSVector4i::load((int)dw).u8to32()); - } - - void operator = (CRect r) - { - *this = GSVector4(GSVector4i(r.left, r.top, r.right, r.bottom)); + *this = GSVector4(GSVector4i::load((int)u32).u8to32()); } operator __m128() const @@ -2187,7 +2339,7 @@ public: return m; } - UINT32 rgba32() const + uint32 rgba32() const { return GSVector4i(*this).rgba32(); } @@ -2468,10 +2620,10 @@ public: { GSVector4i mask = GSVector4i::x000000ff(); - a = v & mask; - b = (v >> 8) & mask; - c = (v >> 16) & mask; - d = (v >> 24); + a = GSVector4(v & mask); + b = GSVector4((v >> 8) & mask); + c = GSVector4((v >> 16) & mask); + d = GSVector4((v >> 24)); } __forceinline static void transpose(GSVector4& a, GSVector4& b, GSVector4& c, GSVector4& d) diff --git a/plugins/GSdx/GSVertex.h b/plugins/GSdx/GSVertex.h index bfe77ee796..9634a61aef 100644 --- a/plugins/GSdx/GSVertex.h +++ b/plugins/GSdx/GSVertex.h @@ -35,20 +35,20 @@ __declspec(align(16)) struct GSVertex struct { GIFRegST ST; - GIFRegXYZ XYZ; GIFRegRGBAQ RGBAQ; + GIFRegXYZ XYZ; GIFRegFOG FOG; }; - struct {__m128i m128i[2];}; - struct {__m128 m128[2];}; + struct {GSVector4i vi[2];}; + struct {GSVector4 vf[2];}; }; GIFRegUV UV; GSVertex() {memset(this, 0, sizeof(*this));} - GSVector4 GetUV() const {return GSVector4(GSVector4i::load(UV.ai32[0]).upl16());} + GSVector4 GetUV() const {return GSVector4(GSVector4i::load(UV.u32[0]).upl16());} }; struct GSVertexOld diff --git a/plugins/GSdx/GSVertexHW.h b/plugins/GSdx/GSVertexHW.h index add5e9eeeb..6314d31f39 100644 --- a/plugins/GSdx/GSVertexHW.h +++ b/plugins/GSdx/GSVertexHW.h @@ -21,6 +21,7 @@ #pragma once +#include "GS.h" #include "GSVector.h" #pragma pack(push, 1) @@ -29,19 +30,29 @@ __declspec(align(16)) union GSVertexHW9 { struct { - GSVector2 t; - union {struct {BYTE r, g, b, a;}; DWORD c0;}; - union {struct {BYTE ta0, ta1, res, f;}; DWORD c1;}; + union + { + struct + { + GSVector4 t; + }; + + struct + { + uint32 _pad[2]; + union {struct {uint8 r, g, b, a;}; uint32 c0;}; + union {struct {uint8 ta0, ta1, res, f;}; uint32 c1;}; + }; + }; + GSVector4 p; }; + + struct {GSVector4i vi[2];}; + struct {GSVector4 vf[2];}; + + GSVertexHW9& operator = (GSVertexHW9& v) {vi[0] = v.vi[0]; vi[1] = v.vi[1]; return *this;} - struct {__m128i m128i[2];}; - struct {__m128 m128[2];}; - -#if _M_SSE >= 0x200 - GSVertexHW9& operator = (GSVertexHW9& v) {m128i[0] = v.m128i[0]; m128i[1] = v.m128i[1]; return *this;} -#endif - float GetQ() {return p.w;} }; @@ -55,33 +66,35 @@ __declspec(align(16)) union GSVertexHW10 GIFRegST ST; }; - union - { - struct {union {struct {WORD x, y;}; DWORD xy;}; DWORD z;} p; - GIFRegXYZ XYZ; - }; - union { - union {struct {BYTE r, g, b, a; float q;}; DWORD c0;}; + union {struct {uint8 r, g, b, a; float q;}; uint32 c0;}; GIFRegRGBAQ RGBAQ; }; + + union + { + struct {union {struct {uint16 x, y;}; uint32 xy;}; uint32 z;} p; + GIFRegXYZ XYZ; + }; union { - struct {DWORD _pad[1]; union {struct {BYTE ta0, ta1, res, f;}; DWORD c1;};}; + struct {uint32 _pad; union {struct {uint8 ta0, ta1, res, f;}; uint32 c1;};}; GIFRegFOG FOG; }; }; - - struct {__m128i m128i[2];}; - struct {__m128 m128[2];}; -#if _M_SSE >= 0x200 - GSVertexHW10& operator = (GSVertexHW10& v) {m128i[0] = v.m128i[0]; m128i[1] = v.m128i[1]; return *this;} -#endif + struct {GSVector4i vi[2];}; + struct {GSVector4 vf[2];}; + + GSVertexHW10& operator = (GSVertexHW10& v) {vi[0] = v.vi[0]; vi[1] = v.vi[1]; return *this;} float GetQ() {return q;} }; +typedef GSVertexHW10 GSVertexHW11; // TODO + +typedef GSVertexHW9 GSVertexOGL; // TODO + #pragma pack(pop) diff --git a/plugins/GSdx/GSVertexList.h b/plugins/GSdx/GSVertexList.h index c7152a8ff0..c6edc3dc61 100644 --- a/plugins/GSdx/GSVertexList.h +++ b/plugins/GSdx/GSVertexList.h @@ -25,7 +25,7 @@ template class GSVertexList { void* m_base; Vertex* m_v[3]; - DWORD m_count; + int m_count; public: GSVertexList() @@ -80,7 +80,7 @@ public: v = *m_v[i]; } - DWORD GetCount() + int GetCount() { return m_count; } diff --git a/plugins/GSdx/GSVertexSW.cpp b/plugins/GSdx/GSVertexSW.cpp index a8fbefd0c5..0706fa00f8 100644 --- a/plugins/GSdx/GSVertexSW.cpp +++ b/plugins/GSdx/GSVertexSW.cpp @@ -23,146 +23,3 @@ #include "stdafx.h" #include "GSVertexSW.h" - -using namespace Xbyak; - -GSVertexTrace::GSVertexTraceCodeGenerator::GSVertexTraceCodeGenerator(DWORD key, void* ptr, size_t maxsize) - : CodeGenerator(maxsize, ptr) -{ - #if _M_AMD64 - #error TODO - #endif - - const int params = 0; - - DWORD primclass = (key >> 0) & 3; - DWORD iip = (key >> 2) & 1; - DWORD tme = (key >> 3) & 1; - DWORD tfx = (key >> 4) & 3; - DWORD color = !(tme && tfx == TFX_DECAL); - - int n = 1; - - switch(primclass) - { - case GS_POINT_CLASS: - n = 1; - break; - case GS_LINE_CLASS: - case GS_SPRITE_CLASS: - n = 2; - break; - case GS_TRIANGLE_CLASS: - n = 3; - break; - } - - const int _v = params + 4; - const int _count = params + 8; - const int _min = params + 12; - const int _max = params + 16; - - // - - static const float fmin = -FLT_MAX; - static const float fmax = FLT_MAX; - - movss(xmm0, xmmword[&fmax]); - shufps(xmm0, xmm0, _MM_SHUFFLE(0, 0, 0, 0)); - - movss(xmm1, xmmword[&fmin]); - shufps(xmm1, xmm1, _MM_SHUFFLE(0, 0, 0, 0)); - - if(color) - { - // min.c = FLT_MAX; - // max.c = -FLT_MAX; - - movaps(xmm2, xmm0); - movaps(xmm3, xmm1); - } - - // min.p = FLT_MAX; - // max.p = -FLT_MAX; - - movaps(xmm4, xmm0); - movaps(xmm5, xmm1); - - if(tme) - { - // min.t = FLT_MAX; - // max.t = -FLT_MAX; - - movaps(xmm6, xmm0); - movaps(xmm7, xmm1); - } - - // for(int i = 0; i < count; i += step) { - - mov(edx, dword[esp + _v]); - mov(ecx, dword[esp + _count]); - - align(16); - -L("loop"); - - for(int j = 0; j < n; j++) - { - if(color && (iip || j == n - 1)) - { - // min.c = min.c.minv(v[i + j].c); - // max.c = max.c.maxv(v[i + j].c); - - movaps(xmm0, xmmword[edx + j * sizeof(GSVertexSW)]); - - minps(xmm2, xmm0); - maxps(xmm3, xmm0); - } - - // min.p = min.p.minv(v[i + j].p); - // max.p = max.p.maxv(v[i + j].p); - - movaps(xmm0, xmmword[edx + j * sizeof(GSVertexSW) + 16]); - - minps(xmm4, xmm0); - maxps(xmm5, xmm0); - - if(tme) - { - // min.t = min.t.minv(v[i + j].t); - // max.t = max.t.maxv(v[i + j].t); - - movaps(xmm0, xmmword[edx + j * sizeof(GSVertexSW) + 32]); - - minps(xmm6, xmm0); - maxps(xmm7, xmm0); - } - } - - add(edx, n * sizeof(GSVertexSW)); - sub(ecx, n); - - jg("loop"); - - // } - - mov(eax, dword[esp + _min]); - mov(edx, dword[esp + _max]); - - if(color) - { - movaps(xmmword[eax], xmm2); - movaps(xmmword[edx], xmm3); - } - - movaps(xmmword[eax + 16], xmm4); - movaps(xmmword[edx + 16], xmm5); - - if(tme) - { - movaps(xmmword[eax + 32], xmm6); - movaps(xmmword[edx + 32], xmm7); - } - - ret(); -} diff --git a/plugins/GSdx/GSVertexSW.h b/plugins/GSdx/GSVertexSW.h index 44e0d0ca25..e3e181d0ef 100644 --- a/plugins/GSdx/GSVertexSW.h +++ b/plugins/GSdx/GSVertexSW.h @@ -214,72 +214,3 @@ __forceinline GSVertexSW operator / (const GSVertexSW& v, float f) return v0; } -#include "GSFunctionMap.h" -#include "xbyak/xbyak.h" - -__declspec(align(16)) class GSVertexTrace -{ - class GSVertexTraceCodeGenerator : public Xbyak::CodeGenerator - { - public: - GSVertexTraceCodeGenerator(DWORD key, void* ptr, size_t maxsize); - }; - - typedef void (*VertexTracePtr)(const GSVertexSW* v, int count, GSVertexSW& min, GSVertexSW& max); - - class GSVertexTraceMap : public GSCodeGeneratorFunctionMap - { - public: - GSVertexTraceMap() : GSCodeGeneratorFunctionMap("VertexTrace") {} - GSVertexTraceCodeGenerator* Create(DWORD key, void* ptr, size_t maxsize) {return new GSVertexTraceCodeGenerator(key, ptr, maxsize);} - } m_map; - -public: - GSVertexSW m_min, m_max; - - union - { - DWORD value; - struct {DWORD x:1, y:1, z:1, f:1, s:1, t:1, q:1, _pad:1, r:1, g:1, b:1, a:1;}; - struct {DWORD xyzf:4, stq:4, rgba:4;}; - } m_eq; - - void Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass, DWORD iip, DWORD tme, DWORD tfx) - { - if(!tme) tfx = 0; - - DWORD key = primclass | (iip << 2) | (tme << 3) | (tfx << 4); - - m_map.Lookup(key)(v, count, m_min, m_max); - - m_eq.value = (m_min.p == m_max.p).mask() | ((m_min.t == m_max.t).mask() << 4) | ((m_min.c == m_max.c).mask() << 8); - } -/* -*/ - void Update(const GSVertexSW* v, int count) - { - GSVertexSW min, max; - - min.c = v[0].c; - max.c = v[0].c; - min.t = v[0].t; - max.t = v[0].t; - min.p = v[0].p; - max.p = v[0].p; - - for(int i = 1; i < count; i++) - { - min.c = min.c.minv(v[i].c); - max.c = max.c.maxv(v[i].c); - min.p = min.p.minv(v[i].p); - max.p = max.p.maxv(v[i].p); - min.t = min.t.minv(v[i].t); - max.t = max.t.maxv(v[i].t); - } - - m_min = min; - m_max = max; - - m_eq.value = (min.p == max.p).mask() | ((min.t == max.t).mask() << 4) | ((min.c == max.c).mask() << 8); - } -}; diff --git a/plugins/GSdx/GSVertexTrace.cpp b/plugins/GSdx/GSVertexTrace.cpp new file mode 100644 index 0000000000..2f58e9a555 --- /dev/null +++ b/plugins/GSdx/GSVertexTrace.cpp @@ -0,0 +1,670 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "stdafx.h" +#include "GSVertexTrace.h" + +void GSVertexTrace::Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass, const GIFRegPRIM* PRIM, const GSDrawingContext* context) +{ + uint32 key = primclass | (PRIM->IIP << 2) | (PRIM->TME << 3) | (PRIM->FST << 4); + + if(!(PRIM->TME && context->TEX0.TFX == TFX_DECAL && context->TEX0.TCC)) + { + key |= 1 << 5; + } + + m_map_sw[key](v, count, m_min, m_max); + + m_eq.value = (m_min.c == m_max.c).mask() | ((m_min.p == m_max.p).mask() << 16) | ((m_min.t == m_max.t).mask() << 20); + + m_alpha.valid = false; +} + +void GSVertexTrace::Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primclass, const GIFRegPRIM* PRIM, const GSDrawingContext* context) +{ + uint32 key = primclass | (PRIM->IIP << 2) | (PRIM->TME << 3) | (PRIM->FST << 4); + + if(!(PRIM->TME && context->TEX0.TFX == TFX_DECAL && context->TEX0.TCC)) + { + key |= 1 << 5; + } + + m_map_hw9[key](v, count, m_min, m_max); + + GSVector4 o(context->XYOFFSET); + GSVector4 s(1.0f / 16, 1.0f / 16, 1.0f, 1.0f); + + m_min.p = (m_min.p - o) * s; + m_max.p = (m_max.p - o) * s; + + if(PRIM->TME) + { + if(PRIM->FST) + { + s = GSVector4(1 << (16 - 4), 1).xxyy(); + } + else + { + s = GSVector4(0x10000 << context->TEX0.TW, 0x10000 << context->TEX0.TH, 1, 1); + } + + m_min.t *= s; + m_max.t *= s; + } + + m_eq.value = (m_min.c == m_max.c).mask() | ((m_min.p == m_max.p).mask() << 16) | ((m_min.t == m_max.t).mask() << 20); + + m_alpha.valid = false; +} + +void GSVertexTrace::Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primclass, const GIFRegPRIM* PRIM, const GSDrawingContext* context) +{ + uint32 key = primclass | (PRIM->IIP << 2) | (PRIM->TME << 3) | (PRIM->FST << 4); + + if(!(PRIM->TME && context->TEX0.TFX == TFX_DECAL && context->TEX0.TCC)) + { + key |= 1 << 5; + } + + m_map_hw10[key](v, count, m_min, m_max); + + GSVector4 o(context->XYOFFSET); + GSVector4 s(1.0f / 16, 1.0f / 16, 2.0f, 1.0f); + + m_min.p = (m_min.p - o) * s; + m_max.p = (m_max.p - o) * s; + + if(PRIM->TME) + { + if(PRIM->FST) + { + s = GSVector4(1 << (16 - 4), 1).xxyy(); + } + else + { + s = GSVector4(0x10000 << context->TEX0.TW, 0x10000 << context->TEX0.TH, 1, 1); + } + + m_min.t *= s; + m_max.t *= s; + } + + m_eq.value = (m_min.c == m_max.c).mask() | ((m_min.p == m_max.p).mask() << 16) | ((m_min.t == m_max.t).mask() << 20); + + m_alpha.valid = false; +} + +using namespace Xbyak; + +GSVertexTrace::CGSW::CGSW(uint32 key, void* ptr, size_t maxsize) + : CodeGenerator(maxsize, ptr) +{ + #if _M_AMD64 + #error TODO + #endif + + const int params = 0; + + uint32 primclass = (key >> 0) & 3; + uint32 iip = (key >> 2) & 1; + uint32 tme = (key >> 3) & 1; + uint32 fst = (key >> 4) & 1; + uint32 color = (key >> 5) & 1; + + int n = 1; + + switch(primclass) + { + case GS_POINT_CLASS: + n = 1; + break; + case GS_LINE_CLASS: + case GS_SPRITE_CLASS: + n = 2; + break; + case GS_TRIANGLE_CLASS: + n = 3; + break; + } + + const int _v = params + 4; + const int _count = params + 8; + const int _min = params + 12; + const int _max = params + 16; + + // + + static const float fmin = -FLT_MAX; + static const float fmax = FLT_MAX; + + movss(xmm0, xmmword[&fmax]); + shufps(xmm0, xmm0, _MM_SHUFFLE(0, 0, 0, 0)); + + movss(xmm1, xmmword[&fmin]); + shufps(xmm1, xmm1, _MM_SHUFFLE(0, 0, 0, 0)); + + if(color) + { + // min.c = FLT_MAX; + // max.c = -FLT_MAX; + + movaps(xmm2, xmm0); + movaps(xmm3, xmm1); + } + + // min.p = FLT_MAX; + // max.p = -FLT_MAX; + + movaps(xmm4, xmm0); + movaps(xmm5, xmm1); + + if(tme) + { + // min.t = FLT_MAX; + // max.t = -FLT_MAX; + + movaps(xmm6, xmm0); + movaps(xmm7, xmm1); + } + + // for(int i = 0; i < count; i += step) { + + mov(edx, dword[esp + _v]); + mov(ecx, dword[esp + _count]); + + align(16); + +L("loop"); + + if(tme && !fst && primclass == GS_SPRITE_CLASS) + { + movaps(xmm1, xmmword[edx + 1 * sizeof(GSVertexSW) + 32]); + shufps(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2)); + } + + for(int j = 0; j < n; j++) + { + if(color && (iip || j == n - 1)) + { + // min.c = min.c.minv(v[i + j].c); + // max.c = max.c.maxv(v[i + j].c); + + movaps(xmm0, xmmword[edx + j * sizeof(GSVertexSW)]); + + minps(xmm2, xmm0); + maxps(xmm3, xmm0); + } + + // min.p = min.p.minv(v[i + j].p); + // max.p = max.p.maxv(v[i + j].p); + + movaps(xmm0, xmmword[edx + j * sizeof(GSVertexSW) + 16]); + + minps(xmm4, xmm0); + maxps(xmm5, xmm0); + + if(tme) + { + // min.t = min.t.minv(v[i + j].t); + // max.t = max.t.maxv(v[i + j].t); + + movaps(xmm0, xmmword[edx + j * sizeof(GSVertexSW) + 32]); + + if(!fst) + { + if(primclass != GS_SPRITE_CLASS) + { + movaps(xmm1, xmm0); + shufps(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2)); + } + + divps(xmm0, xmm1); + shufps(xmm0, xmm1, _MM_SHUFFLE(3, 2, 1, 0)); + } + + minps(xmm6, xmm0); + maxps(xmm7, xmm0); + } + } + + add(edx, n * sizeof(GSVertexSW)); + sub(ecx, n); + + jg("loop"); + + // } + + mov(eax, dword[esp + _min]); + mov(edx, dword[esp + _max]); + + if(color) + { + cvttps2dq(xmm2, xmm2); + psrld(xmm2, 7); + movaps(xmmword[eax], xmm2); + + cvttps2dq(xmm3, xmm3); + psrld(xmm3, 7); + movaps(xmmword[edx], xmm3); + } + + movaps(xmmword[eax + 16], xmm4); + movaps(xmmword[edx + 16], xmm5); + + if(tme) + { + movaps(xmmword[eax + 32], xmm6); + movaps(xmmword[edx + 32], xmm7); + } + + ret(); +} + +GSVertexTrace::CGHW9::CGHW9(uint32 key, void* ptr, size_t maxsize) + : CodeGenerator(maxsize, ptr) +{ + #if _M_AMD64 + #error TODO + #endif + + const int params = 0; + + uint32 primclass = (key >> 0) & 3; + uint32 iip = (key >> 2) & 1; + uint32 tme = (key >> 3) & 1; + uint32 fst = (key >> 4) & 1; + uint32 color = (key >> 5) & 1; + + int n = 1; + + switch(primclass) + { + case GS_POINT_CLASS: + n = 1; + break; + case GS_LINE_CLASS: + n = 2; + break; + case GS_TRIANGLE_CLASS: + n = 3; + break; + case GS_SPRITE_CLASS: + n = 6; + break; + } + + const int _v = params + 4; + const int _count = params + 8; + const int _min = params + 12; + const int _max = params + 16; + + // + + static const float fmin = -FLT_MAX; + static const float fmax = FLT_MAX; + + movss(xmm0, xmmword[&fmax]); + shufps(xmm0, xmm0, _MM_SHUFFLE(0, 0, 0, 0)); + + movss(xmm1, xmmword[&fmin]); + shufps(xmm1, xmm1, _MM_SHUFFLE(0, 0, 0, 0)); + + if(color) + { + // min.c = 0xffffffff; + // max.c = 0; + + pcmpeqd(xmm2, xmm2); + pxor(xmm3, xmm3); + } + + // min.p = FLT_MAX; + // max.p = -FLT_MAX; + + movaps(xmm4, xmm0); + movaps(xmm5, xmm1); + + if(tme) + { + // min.t = FLT_MAX; + // max.t = -FLT_MAX; + + movaps(xmm6, xmm0); + movaps(xmm7, xmm1); + } + + // for(int i = 0; i < count; i += step) { + + mov(edx, dword[esp + _v]); + mov(ecx, dword[esp + _count]); + + align(16); + +L("loop"); + + if(tme && !fst && primclass == GS_SPRITE_CLASS) + { + movaps(xmm1, xmmword[edx + 5 * sizeof(GSVertexHW9) + 16]); + shufps(xmm1, xmm1, _MM_SHUFFLE(3, 3, 3, 3)); + } + + for(int j = 0; j < n; j++) + { + // min.p = min.p.minv(v[i + j].p); + // max.p = max.p.maxv(v[i + j].p); + + movaps(xmm0, xmmword[edx + j * sizeof(GSVertexHW9) + 16]); + + minps(xmm4, xmm0); + maxps(xmm5, xmm0); + + if(tme && !fst && primclass != GS_SPRITE_CLASS) + { + movaps(xmm1, xmm0); + shufps(xmm1, xmm1, _MM_SHUFFLE(3, 3, 3, 3)); + } + + if(color && (iip || j == n - 1) || tme) + { + movaps(xmm0, xmmword[edx + j * sizeof(GSVertexHW9)]); + } + + if(color && (iip || j == n - 1)) + { + // min.c = min.c.min_u8(v[i + j].c); + // max.c = max.c.min_u8(v[i + j].c); + + pminub(xmm2, xmm0); + pmaxub(xmm3, xmm0); + } + + if(tme) + { + shufps(xmm0, xmm0, _MM_SHUFFLE(1, 0, 1, 0)); // avoid FP assist, high part is integral + + if(!fst) + { + // t /= p.wwww(); + + divps(xmm0, xmm1); + } + + // min.t = min.t.minv(v[i + j].t); + // max.t = max.t.maxv(v[i + j].t); + + minps(xmm6, xmm0); + maxps(xmm7, xmm0); + } + } + + add(edx, n * sizeof(GSVertexHW9)); + sub(ecx, n); + + jg("loop"); + + // } + + mov(eax, dword[esp + _min]); + mov(edx, dword[esp + _max]); + + if(color) + { + // m_min.c = cmin.zzzz().u8to32(); + // m_max.c = cmax.zzzz().u8to32(); + + if(m_cpu.has(util::Cpu::tSSE41)) + { + pshufd(xmm2, xmm2, _MM_SHUFFLE(2, 2, 2, 2)); + pmovzxbd(xmm2, xmm2); + + pshufd(xmm3, xmm3, _MM_SHUFFLE(2, 2, 2, 2)); + pmovzxbd(xmm3, xmm3); + } + else + { + pxor(xmm0, xmm0); + + punpckhbw(xmm2, xmm0); + punpcklwd(xmm2, xmm0); + + punpckhbw(xmm3, xmm0); + punpcklwd(xmm3, xmm0); + } + + movaps(xmmword[eax], xmm2); + movaps(xmmword[edx], xmm3); + } + + // m_min.p = pmin; + // m_max.p = pmax; + + movaps(xmmword[eax + 16], xmm4); + movaps(xmmword[edx + 16], xmm5); + + if(tme) + { + // m_min.t = tmin.xyww(pmin); + // m_max.t = tmax.xyww(pmax); + + shufps(xmm6, xmm4, _MM_SHUFFLE(3, 3, 1, 0)); + shufps(xmm7, xmm5, _MM_SHUFFLE(3, 3, 1, 0)); + + movaps(xmmword[eax + 32], xmm6); + movaps(xmmword[edx + 32], xmm7); + } + + ret(); +} + +GSVertexTrace::CGHW10::CGHW10(uint32 key, void* ptr, size_t maxsize) + : CodeGenerator(maxsize, ptr) +{ + #if _M_AMD64 + #error TODO + #endif + + const int params = 0; + + uint32 primclass = (key >> 0) & 3; + uint32 iip = (key >> 2) & 1; + uint32 tme = (key >> 3) & 1; + uint32 fst = (key >> 4) & 1; + uint32 color = (key >> 5) & 1; + + int n = 1; + + switch(primclass) + { + case GS_POINT_CLASS: + n = 1; + break; + case GS_LINE_CLASS: + case GS_SPRITE_CLASS: + n = 2; + break; + case GS_TRIANGLE_CLASS: + n = 3; + break; + } + + const int _v = params + 4; + const int _count = params + 8; + const int _min = params + 12; + const int _max = params + 16; + + // + + static const float fmin = -FLT_MAX; + static const float fmax = FLT_MAX; + + movss(xmm0, xmmword[&fmax]); + shufps(xmm0, xmm0, _MM_SHUFFLE(0, 0, 0, 0)); + + movss(xmm1, xmmword[&fmin]); + shufps(xmm1, xmm1, _MM_SHUFFLE(0, 0, 0, 0)); + + if(color) + { + // min.c = 0xffffffff; + // max.c = 0; + + pcmpeqd(xmm2, xmm2); + pxor(xmm3, xmm3); + } + + // min.p = FLT_MAX; + // max.p = -FLT_MAX; + + movaps(xmm4, xmm0); + movaps(xmm5, xmm1); + + if(tme) + { + // min.t = FLT_MAX; + // max.t = -FLT_MAX; + + movaps(xmm6, xmm0); + movaps(xmm7, xmm1); + } + + // for(int i = 0; i < count; i += step) { + + mov(edx, dword[esp + _v]); + mov(ecx, dword[esp + _count]); + + align(16); + +L("loop"); + + for(int j = 0; j < n; j++) + { + if(color && (iip || j == n - 1) || tme) + { + movaps(xmm0, xmmword[edx + j * sizeof(GSVertexHW10)]); + } + + if(color && (iip || j == n - 1)) + { + pminub(xmm2, xmm0); + pmaxub(xmm3, xmm0); + } + + if(tme) + { + if(!fst) + { + movaps(xmm1, xmm0); + } + + shufps(xmm0, xmm0, _MM_SHUFFLE(3, 3, 1, 0)); // avoid FP assist, third dword is integral + + if(!fst) + { + shufps(xmm1, xmm1, _MM_SHUFFLE(3, 3, 3, 3)); + divps(xmm0, xmm1); + shufps(xmm0, xmm1, _MM_SHUFFLE(3, 3, 1, 0)); // restore q + } + + minps(xmm6, xmm0); + maxps(xmm7, xmm0); + } + + movdqa(xmm0, xmmword[edx + j * sizeof(GSVertexHW10) + 16]); + + if(m_cpu.has(util::Cpu::tSSE41)) + { + pmovzxwd(xmm1, xmm0); + } + else + { + movdqa(xmm1, xmm0); + punpcklwd(xmm1, xmm1); + psrld(xmm1, 16); + } + + psrld(xmm0, 1); + punpcklqdq(xmm1, xmm0); + cvtdq2ps(xmm1, xmm1); + + minps(xmm4, xmm1); + maxps(xmm5, xmm1); + } + + add(edx, n * sizeof(GSVertexHW10)); + sub(ecx, n); + + jg("loop"); + + // } + + mov(eax, dword[esp + _min]); + mov(edx, dword[esp + _max]); + + if(color) + { + // m_min.c = cmin.zzzz().u8to32(); + // m_max.c = cmax.zzzz().u8to32(); + + if(m_cpu.has(util::Cpu::tSSE41)) + { + pshufd(xmm2, xmm2, _MM_SHUFFLE(2, 2, 2, 2)); + pmovzxbd(xmm2, xmm2); + + pshufd(xmm3, xmm3, _MM_SHUFFLE(2, 2, 2, 2)); + pmovzxbd(xmm3, xmm3); + } + else + { + pxor(xmm0, xmm0); + + punpckhbw(xmm2, xmm0); + punpcklwd(xmm2, xmm0); + + punpckhbw(xmm3, xmm0); + punpcklwd(xmm3, xmm0); + } + + movaps(xmmword[eax], xmm2); + movaps(xmmword[edx], xmm3); + } + + // m_min.p = pmin.xyww(); + // m_max.p = pmax.xyww(); + + shufps(xmm4, xmm4, _MM_SHUFFLE(3, 3, 1, 0)); + shufps(xmm5, xmm5, _MM_SHUFFLE(3, 3, 1, 0)); + + movaps(xmmword[eax + 16], xmm4); + movaps(xmmword[edx + 16], xmm5); + + if(tme) + { + // m_min.t = tmin; + // m_max.t = tmax; + + movaps(xmmword[eax + 32], xmm6); + movaps(xmmword[edx + 32], xmm7); + } + + ret(); +} \ No newline at end of file diff --git a/plugins/GSdx/GSVertexTrace.h b/plugins/GSdx/GSVertexTrace.h new file mode 100644 index 0000000000..802513fe2a --- /dev/null +++ b/plugins/GSdx/GSVertexTrace.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSDrawingContext.h" +#include "GSVertexSW.h" +#include "GSVertexHW.h" +#include "GSFunctionMap.h" +#include "xbyak/xbyak.h" +#include "xbyak/xbyak_util.h" + +__declspec(align(16)) class GSVertexTrace +{ + struct Vertex {GSVector4i c; GSVector4 p, t;}; + struct VertexAlpha {int min, max; bool valid;}; + + typedef void (*VertexTracePtr)(const void* v, int count, Vertex& min, Vertex& max); + + class CGSW : public Xbyak::CodeGenerator + { + public: + CGSW(uint32 key, void* ptr, size_t maxsize); + }; + + class GSVertexTraceMapSW : public GSCodeGeneratorFunctionMap + { + public: + GSVertexTraceMapSW() : GSCodeGeneratorFunctionMap("VertexTraceSW") {} + CGSW* Create(uint32 key, void* ptr, size_t maxsize) {return new CGSW(key, ptr, maxsize);} + }; + + class CGHW9 : public Xbyak::CodeGenerator + { + Xbyak::util::Cpu m_cpu; + + public: + CGHW9(uint32 key, void* ptr, size_t maxsize); + }; + + class GSVertexTraceMapHW9 : public GSCodeGeneratorFunctionMap + { + public: + GSVertexTraceMapHW9() : GSCodeGeneratorFunctionMap("VertexTraceHW9") {} + CGHW9* Create(uint32 key, void* ptr, size_t maxsize) {return new CGHW9(key, ptr, maxsize);} + }; + + class CGHW10 : public Xbyak::CodeGenerator + { + Xbyak::util::Cpu m_cpu; + + public: + CGHW10(uint32 key, void* ptr, size_t maxsize); + }; + + class GSVertexTraceMapHW10 : public GSCodeGeneratorFunctionMap + { + public: + GSVertexTraceMapHW10() : GSCodeGeneratorFunctionMap("VertexTraceHW10") {} + CGHW10* Create(uint32 key, void* ptr, size_t maxsize) {return new CGHW10(key, ptr, maxsize);} + }; + + GSVertexTraceMapSW m_map_sw; + GSVertexTraceMapHW9 m_map_hw9; + GSVertexTraceMapHW10 m_map_hw10; + +public: + Vertex m_min, m_max; // t.xy * 0x10000 + VertexAlpha m_alpha; // source alpha range after tfx, GSRenderer::GetAlphaMinMax() updates it + + union + { + uint32 value; + struct {uint32 r:4, g:4, b:4, a:4, x:1, y:1, z:1, f:1, s:1, t:1, q:1, _pad:1;}; + struct {uint32 rgba:16, xyzf:4, stq:4;}; + } m_eq; + + void Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass, const GIFRegPRIM* PRIM, const GSDrawingContext* context); + void Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primclass, const GIFRegPRIM* PRIM, const GSDrawingContext* context); + void Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primclass, const GIFRegPRIM* PRIM, const GSDrawingContext* context); +}; diff --git a/plugins/GSdx/GSWnd.cpp b/plugins/GSdx/GSWnd.cpp index f2d195a99c..3f148dbc6b 100644 --- a/plugins/GSdx/GSWnd.cpp +++ b/plugins/GSdx/GSWnd.cpp @@ -20,57 +20,155 @@ */ #include "StdAfx.h" +#include "GSdx.h" #include "GSWnd.h" -BEGIN_MESSAGE_MAP(GSWnd, CWnd) - ON_WM_CLOSE() -END_MESSAGE_MAP() - GSWnd::GSWnd() + : m_hWnd(NULL) { } GSWnd::~GSWnd() { - DestroyWindow(); } -bool GSWnd::Create(LPCTSTR title) +LRESULT CALLBACK GSWnd::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - CRect r; + GSWnd* wnd = NULL; - GetDesktopWindow()->GetWindowRect(r); + if(message == WM_NCCREATE) + { + wnd = (GSWnd*)((LPCREATESTRUCT)lParam)->lpCreateParams; - CSize s(r.Width() / 3, r.Width() / 4); + SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)wnd); + + wnd->m_hWnd = hWnd; + } + else + { + wnd = (GSWnd*)GetWindowLongPtr(hWnd, GWL_USERDATA); + } + + if(wnd == NULL) + { + return DefWindowProc(hWnd, message, wParam, lParam); + } + + return wnd->OnMessage(message, wParam, lParam); +} + +LRESULT GSWnd::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case WM_CLOSE: + Hide(); + // DestroyWindow(m_hWnd); + return 0; + case WM_DESTROY: + PostQuitMessage(0); + return 0; + default: + break; + } + + return DefWindowProc(m_hWnd, message, wParam, lParam); +} + +bool GSWnd::Create(const string& title) +{ + GSVector4i r; + + GetWindowRect(GetDesktopWindow(), r); + + int w = r.width() / 3; + int h = r.width() / 4; if(!GetSystemMetrics(SM_REMOTESESSION)) { - s.cx *= 2; - s.cy *= 2; + w *= 2; + h *= 2; } - r = CRect(r.CenterPoint() - CSize(s.cx / 2, s.cy / 2), s); + int x = (r.left + r.right - w) / 2; + int y = (r.top + r.bottom - h) / 2; - LPCTSTR wc = AfxRegisterWndClass(CS_VREDRAW|CS_HREDRAW|CS_DBLCLKS, AfxGetApp()->LoadStandardCursor(IDC_ARROW), 0, 0); + WNDCLASS wc; - return !!CreateEx(0, wc, title, WS_OVERLAPPEDWINDOW, r, NULL, 0); + memset(&wc, 0, sizeof(wc)); + + wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + wc.lpfnWndProc = WndProc; + wc.hInstance = theApp.GetModuleHandle(); + // TODO: wc.hIcon = ; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wc.lpszClassName = "GSWnd"; + + if(!GetClassInfo(wc.hInstance, wc.lpszClassName, &wc)) + { + if(!RegisterClass(&wc)) + { + return false; + } + } + + DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW | WS_BORDER; + + m_hWnd = CreateWindow(wc.lpszClassName, title.c_str(), style, x, y, w, h, NULL, NULL, wc.hInstance, (LPVOID)this); + + if(!m_hWnd) + { + return false; + } + + return true; +} + +bool GSWnd::Attach(HWND hWnd) +{ + // TODO: subclass + + m_hWnd = hWnd; + + return true; +} + +GSVector4i GSWnd::GetClientRect() +{ + GSVector4i r; + + ::GetClientRect(m_hWnd, r); + + return r; +} + +void GSWnd::SetWindowText(const char* title) +{ + ::SetWindowText(m_hWnd, title); } void GSWnd::Show() { - SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); - SetForegroundWindow(); - ShowWindow(SW_SHOWNORMAL); + //SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + + SetForegroundWindow(m_hWnd); + + ShowWindow(m_hWnd, SW_SHOWNORMAL); + + UpdateWindow(m_hWnd); } void GSWnd::Hide() { - ShowWindow(SW_HIDE); + ShowWindow(m_hWnd, SW_HIDE); } -void GSWnd::OnClose() +void GSWnd::HideFrame() { - Hide(); - - PostMessage(WM_QUIT); -} \ No newline at end of file + SetWindowLong(m_hWnd, GWL_STYLE, GetWindowLong(m_hWnd, GWL_STYLE) & ~(WS_CAPTION|WS_THICKFRAME)); + + SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + + SetMenu(m_hWnd, NULL); +} diff --git a/plugins/GSdx/GSWnd.h b/plugins/GSdx/GSWnd.h index aa76393b6f..ce5a0bebcf 100644 --- a/plugins/GSdx/GSWnd.h +++ b/plugins/GSdx/GSWnd.h @@ -21,17 +21,30 @@ #pragma once -class GSWnd : public CWnd +#include "GSVector.h" + +class GSWnd { - DECLARE_MESSAGE_MAP() + HWND m_hWnd; + + static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); public: GSWnd(); virtual ~GSWnd(); - virtual bool Create(LPCTSTR title); + bool Create(const string& title); + bool Attach(HWND hWnd); + + void* GetHandle() {return m_hWnd;} + + GSVector4i GetClientRect(); + + void SetWindowText(const char* title); void Show(); void Hide(); - void OnClose(); + + void HideFrame(); }; diff --git a/plugins/GSdx/GSdx.cpp b/plugins/GSdx/GSdx.cpp index 799d55ea5c..d5fe5c69d4 100644 --- a/plugins/GSdx/GSdx.cpp +++ b/plugins/GSdx/GSdx.cpp @@ -22,76 +22,57 @@ #include "stdafx.h" #include "GSdx.h" -// -// Note! -// -// If this DLL is dynamically linked against the MFC -// DLLs, any functions exported from this DLL which -// call into MFC must have the AFX_MANAGE_STATE macro -// added at the very beginning of the function. -// -// For example: -// -// extern "C" BOOL PASCAL EXPORT ExportedFunction() -// { -// AFX_MANAGE_STATE(AfxGetStaticModuleState()); -// // normal function body here -// } -// -// It is very important that this macro appear in each -// function, prior to any calls into MFC. This means that -// it must appear as the first statement within the -// function, even before any object variable declarations -// as their constructors may generate calls into the MFC -// DLL. -// -// Please see MFC Technical Notes 33 and 58 for additional -// details. -// +static HMODULE s_hModule; -BEGIN_MESSAGE_MAP(GSdxApp, CWinApp) -END_MESSAGE_MAP() +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + switch(ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + s_hModule = hModule; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} + +GSdxApp theApp; + +const char* GSdxApp::m_ini = "inis/GSdx.ini"; +const char* GSdxApp::m_section = "Settings"; GSdxApp::GSdxApp() { } -GSdxApp theApp; - -BOOL GSdxApp::InitInstance() +HMODULE GSdxApp::GetModuleHandle() { - __super::InitInstance(); + return s_hModule; +} - SetRegistryKey(_T("Gabest")); +string GSdxApp::GetConfig(const char* entry, const char* value) +{ + char buff[4096] = {0}; + GetPrivateProfileString(m_section, entry, value, buff, countof(buff), m_ini); + return string(buff); +} - CString str; - GetModuleFileName(AfxGetInstanceHandle(), str.GetBuffer(MAX_PATH), MAX_PATH); - str.ReleaseBuffer(); +void GSdxApp::SetConfig(const char* entry, const char* value) +{ + WritePrivateProfileString(m_section, entry, value, m_ini); +} - CPath path(str); - path.RenameExtension(_T(".ini")); - - CPath fn = path; - fn.StripPath(); +int GSdxApp::GetConfig(const char* entry, int value) +{ + return GetPrivateProfileInt(m_section, entry, value, m_ini); +} - path.RemoveFileSpec(); - path.Append(_T("..\\inis")); - CreateDirectory(path, NULL); - path.Append(fn); - - if(m_pszRegistryKey) - { - free((void*)m_pszRegistryKey); - } - - m_pszRegistryKey = NULL; - - if(m_pszProfileName) - { - free((void*)m_pszProfileName); - } - - m_pszProfileName = _tcsdup((LPCTSTR)path); - - return TRUE; -} \ No newline at end of file +void GSdxApp::SetConfig(const char* entry, int value) +{ + char buff[32] = {0}; + itoa(value, buff, 10); + SetConfig(entry, buff); +} diff --git a/plugins/GSdx/GSdx.h b/plugins/GSdx/GSdx.h index 5d3be89e27..6b1f73b1ab 100644 --- a/plugins/GSdx/GSdx.h +++ b/plugins/GSdx/GSdx.h @@ -21,17 +21,20 @@ #pragma once -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -class GSdxApp : public CWinApp +class GSdxApp { + static const char* m_ini; + static const char* m_section; + public: GSdxApp(); -public: - virtual BOOL InitInstance(); + HMODULE GetModuleHandle(); - DECLARE_MESSAGE_MAP() + string GetConfig(const char* entry, const char* value); + void SetConfig(const char* entry, const char* value); + int GetConfig(const char* entry, int value); + void SetConfig(const char* entry, int value); }; + +extern GSdxApp theApp; \ No newline at end of file diff --git a/plugins/GSdx/GSdx.rc b/plugins/GSdx/GSdx.rc index 58ba4fc312..7b3a3e42fb 100644 --- a/plugins/GSdx/GSdx.rc +++ b/plugins/GSdx/GSdx.rc @@ -82,7 +82,7 @@ IDB_LOGO10 BITMAP "res\\logo10.bmp" // Dialog // -IDD_CONFIG DIALOGEX 0, 0, 189, 248 +IDD_CONFIG DIALOGEX 0, 0, 189, 233 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Settings..." FONT 8, "MS Shell Dlg", 400, 0, 0x1 @@ -90,33 +90,30 @@ BEGIN CONTROL 2022,IDC_LOGO10,"Static",SS_BITMAP,7,7,175,44 CONTROL 2021,IDC_LOGO9,"Static",SS_BITMAP,7,7,175,44 LTEXT "Resolution:",IDC_STATIC,7,59,37,8 - COMBOBOX IDC_COMBO3,71,57,111,125,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_RESOLUTION,71,57,111,125,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Renderer:",IDC_STATIC,7,74,34,8 - COMBOBOX IDC_COMBO1,71,72,111,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Shader:",IDC_STATIC,7,89,26,8 - COMBOBOX IDC_COMBO4,71,87,111,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Interlacing (F5):",IDC_STATIC,7,105,53,8 - COMBOBOX IDC_COMBO2,71,102,111,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Aspect Ratio (F6):",IDC_STATIC,7,120,60,8 - COMBOBOX IDC_COMBO5,71,117,111,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "D3D internal res:",IDC_STATIC,7,135,55,8 - EDITTEXT IDC_EDIT1,71,132,35,13,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,99,135,11,14 - EDITTEXT IDC_EDIT2,109,132,35,13,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,133,135,11,14 - CONTROL "Native",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,149,134,33,10 - LTEXT "SW rend. threads:",IDC_STATIC,7,149,60,8 - EDITTEXT IDC_EDIT3,71,147,35,13,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SPIN3,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,99,150,11,14 - CONTROL "Texture filtering",IDC_CHECK4,"Button",BS_AUTO3STATE | WS_TABSTOP,7,167,67,10 - CONTROL "Logarithmic Z",IDC_CHECK5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,80,168,58,10 - CONTROL "Wait vsync",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,180,51,10 - CONTROL "Alpha correction (FBA)",IDC_CHECK7,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,80,181,102,10 - CONTROL "Edge anti-aliasing (AA1, sw-mode only)",IDC_CHECK8, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,194,141,10 - CONTROL "Enable output merger blur effect",IDC_CHECK9,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,208,121,10 - DEFPUSHBUTTON "OK",IDOK,43,227,50,14 - PUSHBUTTON "Cancel",IDCANCEL,96,227,50,14 + COMBOBOX IDC_RENDERER,71,72,111,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Interlacing (F5):",IDC_STATIC,7,90,53,8 + COMBOBOX IDC_INTERLACE,71,87,111,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Aspect Ratio (F6):",IDC_STATIC,7,105,60,8 + COMBOBOX IDC_ASPECTRATIO,71,102,111,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "D3D internal res:",IDC_STATIC,7,120,55,8 + EDITTEXT IDC_RESX_EDIT,71,117,35,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_RESX,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,99,120,11,14 + EDITTEXT IDC_RESY_EDIT,109,117,35,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_RESY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,133,120,11,14 + CONTROL "Native",IDC_NATIVERES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,149,119,33,10 + LTEXT "SW rend. threads:",IDC_STATIC,7,134,60,8 + EDITTEXT IDC_SWTHREADS_EDIT,71,132,35,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,99,135,11,14 + CONTROL "Texture filtering",IDC_FILTER,"Button",BS_AUTO3STATE | WS_TABSTOP,7,152,67,10 + CONTROL "Logarithmic Z",IDC_LOGZ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,80,153,58,10 + CONTROL "Wait vsync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,165,51,10 + CONTROL "Alpha correction (FBA)",IDC_FBA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,80,166,102,10 + CONTROL "Edge anti-aliasing (AA1, sw-mode only)",IDC_AA1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,179,141,10 + CONTROL "Enable output merger blur effect",IDC_BLUR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,193,121,10 + DEFPUSHBUTTON "OK",IDOK,43,212,50,14 + PUSHBUTTON "Cancel",IDCANCEL,96,212,50,14 END IDD_CAPTURE DIALOGEX 0, 0, 279, 71 @@ -124,43 +121,41 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSM CAPTION "Capture settings" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - EDITTEXT IDC_EDIT1,7,7,207,14,ES_AUTOHSCROLL - PUSHBUTTON "Browse...",IDC_BUTTON1,222,7,50,14 - COMBOBOX IDC_COMBO1,7,27,207,122,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Config...",IDC_BUTTON2,222,26,50,14 + EDITTEXT IDC_FILENAME,7,7,207,14,ES_AUTOHSCROLL + PUSHBUTTON "Browse...",IDC_BROWSE,222,7,50,14 + COMBOBOX IDC_CODECS,7,27,207,122,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Config...",IDC_CONFIGURE,222,26,50,14 LTEXT "Size:",IDC_STATIC,6,50,16,8 - EDITTEXT IDC_EDIT2,30,47,31,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER - EDITTEXT IDC_EDIT4,64,47,31,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_WIDTH,30,47,31,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_HEIGHT,64,47,31,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER PUSHBUTTON "Cancel",IDCANCEL,169,47,50,14 DEFPUSHBUTTON "OK",IDOK,221,47,50,14 END -IDD_GPUCONFIG DIALOGEX 0, 0, 189, 235 +IDD_GPUCONFIG DIALOGEX 0, 0, 189, 199 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Settings..." FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN CONTROL 2021,IDC_LOGO9,"Static",SS_BITMAP,7,7,175,44 LTEXT "Resolution:",IDC_STATIC,7,59,37,8 - COMBOBOX IDC_COMBO3,78,57,104,125,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_RESOLUTION,78,57,104,125,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Renderer:",IDC_STATIC,7,74,34,8 - COMBOBOX IDC_COMBO1,78,72,104,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Shader:",IDC_STATIC,7,89,26,8 - COMBOBOX IDC_COMBO4,78,87,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Texture Filter (Del):",IDC_STATIC,7,105,64,8 - COMBOBOX IDC_COMBO2,78,102,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Dithering (End):",IDC_STATIC,7,120,52,8 - COMBOBOX IDC_COMBO5,78,117,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Aspect Ratio (PgDn):",IDC_STATIC,7,135,68,8 - COMBOBOX IDC_COMBO6,78,132,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Rendering Threads:",IDC_STATIC,7,165,64,8 - EDITTEXT IDC_EDIT3,78,163,35,13,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SPIN3,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,99,169,11,14 - DEFPUSHBUTTON "OK",IDOK,43,214,50,14 - PUSHBUTTON "Cancel",IDCANCEL,96,214,50,14 - CONTROL 2022,IDC_LOGO10,"Static",SS_BITMAP,7,7,175,44 - LTEXT "Internal Resolution:",IDC_STATIC,7,150,64,8 - COMBOBOX IDC_COMBO7,78,147,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_RENDERER,78,72,104,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Texture Filter (Del):",IDC_STATIC,7,90,64,8 + COMBOBOX IDC_FILTER,78,87,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Dithering (End):",IDC_STATIC,7,105,52,8 + COMBOBOX IDC_DITHERING,78,102,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Aspect Ratio (PgDn):",IDC_STATIC,7,120,68,8 + COMBOBOX IDC_ASPECTRATIO,78,117,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Rendering Threads:",IDC_STATIC,7,150,64,8 + EDITTEXT IDC_SWTHREADS_EDIT,78,148,35,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,99,154,11,14 + DEFPUSHBUTTON "OK",IDOK,43,178,50,14 + PUSHBUTTON "Cancel",IDCANCEL,96,178,50,14 + CONTROL 2022,IDC_LOGO10,"Static",SS_BITMAP,7,7,173,42 + LTEXT "Internal Resolution:",IDC_STATIC,7,135,64,8 + COMBOBOX IDC_SCALE,78,132,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -180,7 +175,7 @@ BEGIN VERTGUIDE, 80 VERTGUIDE, 182 TOPMARGIN, 7 - BOTTOMMARGIN, 241 + BOTTOMMARGIN, 226 END IDD_CAPTURE, DIALOG @@ -198,7 +193,7 @@ BEGIN VERTGUIDE, 78 VERTGUIDE, 182 TOPMARGIN, 7 - BOTTOMMARGIN, 228 + BOTTOMMARGIN, 192 END END #endif // APSTUDIO_INVOKED diff --git a/plugins/GSdx/GSdx_vs2008.vcproj b/plugins/GSdx/GSdx_vs2008.vcproj index 8fa577240e..8e0616484d 100644 --- a/plugins/GSdx/GSdx_vs2008.vcproj +++ b/plugins/GSdx/GSdx_vs2008.vcproj @@ -19,139 +19,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -248,8 +120,8 @@ /> @@ -312,8 +184,8 @@ /> @@ -502,8 +374,8 @@ /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1144,6 +1130,10 @@ RelativePath=".\GSDevice10.cpp" > + + @@ -1156,6 +1146,14 @@ RelativePath=".\GSDeviceNull.cpp" > + + + + @@ -1227,6 +1225,14 @@ AssemblerOutput="4" /> + + + @@ -1252,7 +1258,7 @@ /> + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + @@ -1376,6 +1394,10 @@ RelativePath=".\GSTexture10.cpp" > + + @@ -1387,18 +1409,46 @@ + + + + + + + + + + + + + + @@ -1420,6 +1474,14 @@ RelativePath=".\GSTextureNull.cpp" > + + + + @@ -1444,6 +1506,10 @@ RelativePath=".\GSVertexSW.cpp" > + + @@ -1451,22 +1517,6 @@ - - - - - - @@ -1515,22 +1565,6 @@ UsePrecompiledHeader="1" /> - - - - - - @@ -1579,6 +1613,22 @@ UsePrecompiledHeader="1" /> + + + + + + + + @@ -1686,6 +1740,14 @@ RelativePath=".\GSDeviceNull.h" > + + + + @@ -1734,22 +1796,34 @@ RelativePath=".\GSRenderer.h" > + + + + + + + + - - - - + + @@ -1786,6 +1860,10 @@ RelativePath=".\GSTexture10.h" > + + @@ -1802,18 +1880,34 @@ RelativePath=".\GSTextureCache10.h" > + + + + + + + + @@ -1822,6 +1916,14 @@ RelativePath=".\GSTextureNull.h" > + + + + @@ -1847,11 +1949,11 @@ > - - - - - - - - @@ -1939,22 +2025,6 @@ - - - - - - @@ -2003,22 +2073,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -2067,6 +2121,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -2139,22 +2193,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -2203,6 +2241,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -2275,22 +2313,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -2339,6 +2361,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -2411,22 +2433,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -2475,6 +2481,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -2547,22 +2553,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -2611,6 +2601,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -2683,22 +2673,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -2747,6 +2721,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -2835,22 +2809,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -2899,6 +2857,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -2971,22 +2929,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -3035,6 +2977,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -3107,22 +3049,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -3171,6 +3097,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -3243,22 +3169,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -3307,6 +3217,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -3379,22 +3289,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -3443,6 +3337,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -3519,22 +3413,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -3583,6 +3461,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -3655,22 +3533,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -3719,6 +3581,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -3791,22 +3653,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -3855,6 +3701,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -3927,22 +3773,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -3991,6 +3821,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -4067,22 +3897,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -4131,6 +3945,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -4203,22 +4017,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -4267,6 +4065,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -4339,22 +4137,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -4403,6 +4185,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -4475,22 +4257,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -4539,6 +4305,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -4611,22 +4377,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -4675,6 +4425,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -4747,22 +4497,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -4811,6 +4545,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -4883,22 +4617,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -4947,6 +4665,22 @@ UsePrecompiledHeader="0" /> + + + + + + - - - - - - @@ -5019,22 +4737,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -5083,6 +4785,22 @@ UsePrecompiledHeader="0" /> + + + + + + + + + Debug SSE2 + Win32 + + + Debug SSE2 + Win32 + + + Debug SSE2 + x64 + + + Debug SSE2 + x64 + + + Debug SSE4 + Win32 + + + Debug SSE4 + Win32 + + + Debug SSE4 + x64 + + + Debug SSE4 + x64 + + + Debug SSSE3 + Win32 + + + Debug SSSE3 + Win32 + + + Debug SSSE3 + x64 + + + Debug SSSE3 + x64 + + + Debug + Win32 + + + Debug + Win32 + + + Debug + x64 + + + Debug + x64 + + + Release SSE2 + Win32 + + + Release SSE2 + Win32 + + + Release SSE2 + x64 + + + Release SSE2 + x64 + + + Release SSE4 + Win32 + + + Release SSE4 + Win32 + + + Release SSE4 + x64 + + + Release SSE4 + x64 + + + Release SSSE3 + Win32 + + + Release SSSE3 + Win32 + + + Release SSSE3 + x64 + + + Release SSSE3 + x64 + + + Release + Win32 + + + Release + Win32 + + + Release + x64 + + + Release + x64 + + + + GSdx + {18E42F6F-3A62-41EE-B42F-79366C4F1E95} + GSdx + Win32Proj + + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + MultiByte + true + + + DynamicLibrary + Static + MultiByte + + + DynamicLibrary + Static + MultiByte + true + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + Static + MultiByte + false + + + DynamicLibrary + false + MultiByte + true + + + DynamicLibrary + Static + MultiByte + true + + + DynamicLibrary + false + MultiByte + true + + + DynamicLibrary + Static + MultiByte + true + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + Static + MultiByte + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + Static + MultiByte + + + DynamicLibrary + false + MultiByte + true + + + DynamicLibrary + Static + MultiByte + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.20506.1 + + + + Use + + + .\GSdx.def + + + MachineX86 + + + + + X64 + + + Use + + + + + + + MachineX64 + + + + + Use + + + .\GSdx.def + + + MachineX86 + + + + + X64 + + + Use + + + + + + + MachineX64 + + + + + Use + + + .\GSdx.def + + + MachineX86 + + + + + Use + + + + + MachineX64 + + + + + Use + + + .\GSdx.def + + + MachineX86 + + + + + Use + + + + + MachineX64 + + + + + Use + + + .\GSdx.def + + + MachineX86 + + + + + Use + + + + + MachineX64 + + + + + Use + + + .\GSdx.def + + + MachineX86 + + + + + Use + + + + + MachineX64 + + + + + Use + + + .\GSdx.def + + + MachineX86 + + + + + X64 + + + Use + + + + + MachineX64 + + + + + Use + + + .\GSdx.def + + + MachineX86 + + + + + X64 + + + Use + + + + + MachineX64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + Create + Create + Create + Create + Create + Create + Create + Create + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/GSdx/GSdx_vs2010.vcxproj.filters b/plugins/GSdx/GSdx_vs2010.vcxproj.filters new file mode 100644 index 0000000000..4ca7e0481a --- /dev/null +++ b/plugins/GSdx/GSdx_vs2010.vcxproj.filters @@ -0,0 +1,697 @@ + + + + + {14a43ae4-91f3-4405-a71c-c8f2d790e36b} + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + {e281bf48-1466-4355-b176-a117cc2dce40} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {62920db0-8592-425e-aa2f-9a2a7e85d851} + + + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Baseclasses + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Resource Files + + + Header Files + + + Header Files + + + Xbyak + + + Xbyak + + + Xbyak + + + Xbyak + + + + + Baseclasses + + + Baseclasses + + + Source Files + + + Shaders + + + Resource Files + + + Shaders + + + Resource Files + + + Resource Files + + + Shaders + + + Shaders + + + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/GSdx/res/GSdx.rc2 b/plugins/GSdx/res/GSdx.rc2 index 45a9aad126..793e0342dd 100644 --- a/plugins/GSdx/res/GSdx.rc2 +++ b/plugins/GSdx/res/GSdx.rc2 @@ -10,13 +10,9 @@ ///////////////////////////////////////////////////////////////////////////// // Add manually edited resources here... -IDR_CONVERT9_FX RCDATA "res\\convert9.fx" -IDR_TFX9_FX RCDATA "res\\tfx9.fx" -IDR_MERGE9_FX RCDATA "res\\merge9.fx" -IDR_INTERLACE9_FX RCDATA "res\\interlace9.fx" -IDR_CONVERT10_FX RCDATA "res\\convert10.fx" -IDR_TFX10_FX RCDATA "res\\tfx10.fx" -IDR_MERGE10_FX RCDATA "res\\merge10.fx" -IDR_INTERLACE10_FX RCDATA "res\\interlace10.fx" +IDR_CONVERT_FX RCDATA "res\\convert.fx" +IDR_TFX_FX RCDATA "res\\tfx.fx" +IDR_MERGE_FX RCDATA "res\\merge.fx" +IDR_INTERLACE_FX RCDATA "res\\interlace.fx" ///////////////////////////////////////////////////////////////////////////// diff --git a/plugins/GSdx/res/convert.fx b/plugins/GSdx/res/convert.fx new file mode 100644 index 0000000000..9749476e6d --- /dev/null +++ b/plugins/GSdx/res/convert.fx @@ -0,0 +1,184 @@ +#if SHADER_MODEL >= 0x400 + +struct VS_INPUT +{ + float4 p : POSITION; + float2 t : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 p : SV_Position; + float2 t : TEXCOORD0; +}; + +VS_OUTPUT vs_main(VS_INPUT input) +{ + VS_OUTPUT output; + + output.p = input.p; + output.t = input.t; + + return output; +} + +Texture2D Texture; +SamplerState Sampler; + +struct PS_INPUT +{ + float4 p : SV_Position; + float2 t : TEXCOORD0; +}; + +float4 ps_main0(PS_INPUT input) : SV_Target0 +{ + return Texture.Sample(Sampler, input.t); +} + +uint ps_main1(PS_INPUT input) : SV_Target0 +{ + float4 f = Texture.Sample(Sampler, input.t); + + f.a *= 256.0f/127; // hm, 0.5 won't give us 1.0 if we just multiply with 2 + + uint4 i = f * float4(0x001f, 0x03e0, 0x7c00, 0x8000); + + return (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000); +} + +float4 ps_main2(PS_INPUT input) : SV_Target0 +{ + clip(Texture.Sample(Sampler, input.t).a - (0.5 - 0.9f/256)); + + return 0; +} + +float4 ps_main3(PS_INPUT input) : SV_Target0 +{ + clip((0.5 - 0.9f/256) - Texture.Sample(Sampler, input.t).a); + + return 0; +} + +float4 ps_main4(PS_INPUT input) : SV_Target0 +{ + float4 c = Texture.Sample(Sampler, input.t); + + return fmod(c * 255 + 0.5f, 256) / 255; +} + +float4 ps_crt(PS_INPUT input, uint i) +{ + float4 mask[4] = + { + float4(1, 0, 0, 0), + float4(0, 1, 0, 0), + float4(0, 0, 1, 0), + float4(1, 1, 1, 0) + }; + + return Texture.Sample(Sampler, input.t) * saturate(mask[i] + 0.5f); +} + +float4 ps_main5(PS_INPUT input) : SV_Target0 // triangular +{ + uint4 p = (uint4)input.p; + + // return ps_crt(input, ((p.x + (p.y & 1) * 3) >> 1) % 3); + return ps_crt(input, ((p.x + ((p.y >> 1) & 1) * 3) >> 1) % 3); +} + +float4 ps_main6(PS_INPUT input) : SV_Target0 // diagonal +{ + uint4 p = (uint4)input.p; + + return ps_crt(input, (p.x + (p.y % 3)) % 3); +} + +#elif SHADER_MODEL <= 0x300 + +struct VS_INPUT +{ + float4 p : POSITION; + float2 t : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 p : POSITION; + float2 t : TEXCOORD0; +}; + +VS_OUTPUT vs_main(VS_INPUT input) +{ + VS_OUTPUT output; + + output.p = input.p; + output.t = input.t; + + return output; +} + +sampler Texture : register(s0); + +float4 ps_main0(float2 t : TEXCOORD0) : COLOR +{ + return tex2D(Texture, t); +} + +float4 ps_main1(float2 t : TEXCOORD0) : COLOR +{ + float4 c = tex2D(Texture, t); + c.a *= 128.0f / 255; // *= 0.5f is no good here, need to do this in order to get 0x80 for 1.0f (instead of 0x7f) + return c; +} + +float4 ps_main2(float2 t : TEXCOORD0) : COLOR +{ + clip(tex2D(Texture, t).a - (1.0f - 0.9f/256)); + + return 0; +} + +float4 ps_main3(float2 t : TEXCOORD0) : COLOR +{ + clip((1.0f - 0.9f/256) - tex2D(Texture, t).a); + + return 0; +} + +float4 ps_main4() : COLOR +{ + return 1; +} + +float4 ps_crt(float2 t, int i) +{ + float4 mask[4] = + { + float4(1, 0, 0, 0), + float4(0, 1, 0, 0), + float4(0, 0, 1, 0), + float4(1, 1, 1, 0) + }; + + return tex2D(Texture, t) * saturate(mask[i] + 0.5f); +} + +float4 ps_main5(float2 t : TEXCOORD0, float4 vPos : VPOS) : COLOR // triangular +{ + int4 p = (int4)vPos; + + // return ps_crt(t, ((p.x + (p.y % 2) * 3) / 2) % 3); + return ps_crt(t, ((p.x + ((p.y / 2) % 2) * 3) / 2) % 3); +} + +float4 ps_main6(float2 t : TEXCOORD0, float4 vPos : VPOS) : COLOR // diagonal +{ + int4 p = (int4)vPos; + + return ps_crt(t, (p.x + (p.y % 3)) % 3); +} + +#endif \ No newline at end of file diff --git a/plugins/GSdx/res/convert10.fx b/plugins/GSdx/res/convert10.fx deleted file mode 100644 index 05044323cc..0000000000 --- a/plugins/GSdx/res/convert10.fx +++ /dev/null @@ -1,67 +0,0 @@ -struct VS_INPUT -{ - float4 p : POSITION; - float2 t : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 p : SV_Position; - float2 t : TEXCOORD0; -}; - -VS_OUTPUT vs_main(VS_INPUT input) -{ - VS_OUTPUT output; - - output.p = input.p; - output.t = input.t; - - return output; -} - -Texture2D Texture; -SamplerState Sampler; - -struct PS_INPUT -{ - float4 p : SV_Position; - float2 t : TEXCOORD0; -}; - -float4 ps_main0(PS_INPUT input) : SV_Target0 -{ - return Texture.Sample(Sampler, input.t); -} - -uint ps_main1(PS_INPUT input) : SV_Target0 -{ - float4 f = Texture.Sample(Sampler, input.t); - - f.a *= 256.0f/127; // hm, 0.5 won't give us 1.0 if we just multiply with 2 - - uint4 i = f * float4(0x001f, 0x03e0, 0x7c00, 0x8000); - - return (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000); -} - -float4 ps_main2(PS_INPUT input) : SV_Target0 -{ - clip(Texture.Sample(Sampler, input.t).a - (0.5 - 0.9f/256)); - - return 0; -} - -float4 ps_main3(PS_INPUT input) : SV_Target0 -{ - clip((0.5 - 0.9f/256) - Texture.Sample(Sampler, input.t).a); - - return 0; -} - -float4 ps_main4(PS_INPUT input) : SV_Target0 -{ - float4 c = Texture.Sample(Sampler, input.t); - - return fmod(c * 255 + 0.5f, 256) / 255; -} diff --git a/plugins/GSdx/res/convert9.fx b/plugins/GSdx/res/convert9.fx deleted file mode 100644 index 4f1f8be5da..0000000000 --- a/plugins/GSdx/res/convert9.fx +++ /dev/null @@ -1,55 +0,0 @@ -struct VS_INPUT -{ - float4 p : POSITION; - float2 t : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 p : POSITION; - float2 t : TEXCOORD0; -}; - -VS_OUTPUT vs_main(VS_INPUT input) -{ - VS_OUTPUT output; - - output.p = input.p; - output.t = input.t; - - return output; -} - -sampler Texture : register(s0); - -float4 ps_main0(float2 t : TEXCOORD0) : COLOR -{ - return tex2D(Texture, t); -} - -float4 ps_main1(float2 t : TEXCOORD0) : COLOR -{ - float4 c = tex2D(Texture, t); - c.a *= 128.0f / 255; // *= 0.5f is no good here, need to do this in order to get 0x80 for 1.0f (instead of 0x7f) - return c; -} - -float4 ps_main2(float2 t : TEXCOORD0) : COLOR -{ - clip(tex2D(Texture, t).a - (1.0f - 0.9f/256)); - - return 0; -} - -float4 ps_main3(float2 t : TEXCOORD0) : COLOR -{ - clip((1.0f - 0.9f/256) - tex2D(Texture, t).a); - - return 0; -} - -float4 ps_main4() : COLOR -{ - return 1; -} - diff --git a/plugins/GSdx/res/interlace10.fx b/plugins/GSdx/res/interlace.fx similarity index 50% rename from plugins/GSdx/res/interlace10.fx rename to plugins/GSdx/res/interlace.fx index 86fa44dd75..f726051260 100644 --- a/plugins/GSdx/res/interlace10.fx +++ b/plugins/GSdx/res/interlace.fx @@ -1,3 +1,4 @@ +#if SHADER_MODEL >= 0x400 Texture2D Texture; SamplerState Sampler; @@ -41,3 +42,42 @@ float4 ps_main3(PS_INPUT input) : SV_Target0 { return Texture.Sample(Sampler, input.t); } + +#elif SHADER_MODEL <= 0x300 + +sampler s0 : register(s0); + +float4 Params1 : register(c0); + +#define ZrH (Params1.xy) +#define hH (Params1.z) + +float4 ps_main0(float2 tex : TEXCOORD0) : COLOR +{ + clip(frac(tex.y * hH) - 0.5); + + return tex2D(s0, tex); +} + +float4 ps_main1(float2 tex : TEXCOORD0) : COLOR +{ + clip(0.5 - frac(tex.y * hH)); + + return tex2D(s0, tex); +} + +float4 ps_main2(float2 tex : TEXCOORD0) : COLOR +{ + float4 c0 = tex2D(s0, tex - ZrH); + float4 c1 = tex2D(s0, tex); + float4 c2 = tex2D(s0, tex + ZrH); + + return (c0 + c1 * 2 + c2) / 4; +} + +float4 ps_main3(float2 tex : TEXCOORD0) : COLOR +{ + return tex2D(s0, tex); +} + +#endif diff --git a/plugins/GSdx/res/interlace9.fx b/plugins/GSdx/res/interlace9.fx deleted file mode 100644 index 5f5db8bf9c..0000000000 --- a/plugins/GSdx/res/interlace9.fx +++ /dev/null @@ -1,35 +0,0 @@ - -sampler s0 : register(s0); - -float4 Params1 : register(c0); - -#define ZrH (Params1.xy) -#define hH (Params1.z) - -float4 ps_main0(float2 tex : TEXCOORD0) : COLOR -{ - clip(frac(tex.y * hH) - 0.5); - - return tex2D(s0, tex); -} - -float4 ps_main1(float2 tex : TEXCOORD0) : COLOR -{ - clip(0.5 - frac(tex.y * hH)); - - return tex2D(s0, tex); -} - -float4 ps_main2(float2 tex : TEXCOORD0) : COLOR -{ - float4 c0 = tex2D(s0, tex - ZrH); - float4 c1 = tex2D(s0, tex); - float4 c2 = tex2D(s0, tex + ZrH); - - return (c0 + c1 * 2 + c2) / 4; -} - -float4 ps_main3(float2 tex : TEXCOORD0) : COLOR -{ - return tex2D(s0, tex); -} diff --git a/plugins/GSdx/res/merge.fx b/plugins/GSdx/res/merge.fx new file mode 100644 index 0000000000..fc014c4a4e --- /dev/null +++ b/plugins/GSdx/res/merge.fx @@ -0,0 +1,58 @@ +#if SHADER_MODEL >= 0x400 + +Texture2D Texture; +SamplerState Sampler; + +cbuffer cb0 +{ + float4 BGColor; +}; + +struct PS_INPUT +{ + float4 p : SV_Position; + float2 t : TEXCOORD0; +}; + +float4 ps_main0(PS_INPUT input) : SV_Target0 +{ + float4 c = Texture.Sample(Sampler, input.t); + c.a = min(c.a * 2, 1); + return c; +} + +float4 ps_main1(PS_INPUT input) : SV_Target0 +{ + float4 c = Texture.Sample(Sampler, input.t); + c.a = BGColor.a; + return c; +} + +#elif SHADER_MODEL <= 0x300 + +sampler Texture : register(s0); + +float4 g_params[1]; + +#define BGColor (g_params[0]) + +struct PS_INPUT +{ + float2 t : TEXCOORD0; +}; + +float4 ps_main0(PS_INPUT input) : COLOR +{ + float4 c = tex2D(Texture, input.t); + // a = ; + return c.bgra; +} + +float4 ps_main1(PS_INPUT input) : COLOR +{ + float4 c = tex2D(Texture, input.t); + c.a = BGColor.a; + return c.bgra; +} + +#endif \ No newline at end of file diff --git a/plugins/GSdx/res/merge10.fx b/plugins/GSdx/res/merge10.fx deleted file mode 100644 index 1f91fe3e8f..0000000000 --- a/plugins/GSdx/res/merge10.fx +++ /dev/null @@ -1,27 +0,0 @@ -Texture2D Texture; -SamplerState Sampler; - -cbuffer cb0 -{ - float4 BGColor; -}; - -struct PS_INPUT -{ - float4 p : SV_Position; - float2 t : TEXCOORD0; -}; - -float4 ps_main0(PS_INPUT input) : SV_Target0 -{ - float4 c = Texture.Sample(Sampler, input.t); - c.a = min(c.a * 2, 1); - return c; -} - -float4 ps_main1(PS_INPUT input) : SV_Target0 -{ - float4 c = Texture.Sample(Sampler, input.t); - c.a = BGColor.a; - return c; -} \ No newline at end of file diff --git a/plugins/GSdx/res/merge9.fx b/plugins/GSdx/res/merge9.fx deleted file mode 100644 index dbb210660f..0000000000 --- a/plugins/GSdx/res/merge9.fx +++ /dev/null @@ -1,25 +0,0 @@ -sampler Texture : register(s0); - -float4 g_params[1]; - -#define BGColor (g_params[0]) - -struct PS_INPUT -{ - float2 t : TEXCOORD0; -}; - -float4 ps_main0(PS_INPUT input) : COLOR -{ - float4 c = tex2D(Texture, input.t); - // a = ; - return c.bgra; -} - -float4 ps_main1(PS_INPUT input) : COLOR -{ - float4 c = tex2D(Texture, input.t); - c.a = BGColor.a; - return c.bgra; -} - diff --git a/plugins/GSdx/res/tfx.fx b/plugins/GSdx/res/tfx.fx new file mode 100644 index 0000000000..2bb2b3b968 --- /dev/null +++ b/plugins/GSdx/res/tfx.fx @@ -0,0 +1,717 @@ +#if SHADER_MODEL >= 0x400 + +#ifndef VS_BPPZ +#define VS_BPPZ 0 +#define VS_TME 1 +#define VS_FST 1 +#define VS_PRIM 0 +#endif + +#ifndef GS_IIP +#define GS_IIP 0 +#define GS_PRIM 3 +#endif + +#ifndef PS_FST +#define PS_FST 0 +#define PS_WMS 3 +#define PS_WMT 3 +#define PS_BPP 0 +#define PS_AEM 0 +#define PS_TFX 0 +#define PS_TCC 1 +#define PS_ATE 0 +#define PS_ATST 4 +#define PS_FOG 0 +#define PS_CLR1 0 +#define PS_FBA 0 +#define PS_AOUT 0 +#define PS_LTF 1 +#endif + +struct VS_INPUT +{ + uint2 p : POSITION0; + uint z : POSITION1; + float2 t : TEXCOORD0; + float q : TEXCOORD1; + float4 c : COLOR0; + float4 f : COLOR1; +}; + +struct VS_OUTPUT +{ + float4 p : SV_Position; + float4 t : TEXCOORD0; + float4 c : COLOR0; +}; + +struct PS_INPUT +{ + float4 p : SV_Position; + float4 t : TEXCOORD0; + float4 c : COLOR0; +}; + +struct PS_OUTPUT +{ + float4 c0 : SV_Target0; + float4 c1 : SV_Target1; +}; + +Texture2D Texture; +Texture2D Palette; +SamplerState TextureSampler; +SamplerState PaletteSampler; + +cbuffer cb0 +{ + float4 VertexScale; + float4 VertexOffset; + float2 TextureScale; +}; + +cbuffer cb1 +{ + float3 FogColor; + float AREF; + float4 HalfTexel; + float4 WH; + float4 MinMax; + float2 MinF; + float2 TA; + uint4 MskFix; +}; + +#elif SHADER_MODEL <= 0x300 + +#ifndef VS_BPPZ +#define VS_BPPZ 0 +#define VS_TME 1 +#define VS_FST 1 +#define VS_LOGZ 1 +#endif + +#ifndef PS_FST +#define PS_FST 0 +#define PS_WMS 3 +#define PS_WMT 3 +#define PS_BPP 0 +#define PS_AEM 0 +#define PS_TFX 0 +#define PS_TCC 1 +#define PS_ATE 0 +#define PS_ATST 4 +#define PS_FOG 0 +#define PS_CLR1 0 +#define PS_RT 0 +#define PS_LTF 0 +#endif + +struct VS_INPUT +{ + float4 p : POSITION0; + float2 t : TEXCOORD0; + float4 c : COLOR0; + float4 f : COLOR1; +}; + +struct VS_OUTPUT +{ + float4 p : POSITION; + float4 t : TEXCOORD0; + float4 c : COLOR0; +}; + +struct PS_INPUT +{ + float4 t : TEXCOORD0; + float4 c : COLOR0; +}; + +sampler Texture : register(s0); +sampler1D Palette : register(s1); +sampler1D UMSKFIX : register(s2); +sampler1D VMSKFIX : register(s3); + +float4 vs_params[3]; + +#define VertexScale vs_params[0] +#define VertexOffset vs_params[1] +#define TextureScale vs_params[2].xy + +float4 ps_params[5]; + +#define FogColor ps_params[0].bgr +#define AREF ps_params[0].a +#define HalfTexel ps_params[1] +#define WH ps_params[2] +#define MinMax ps_params[3] +#define MinF ps_params[4].xy +#define TA0 ps_params[4].z +#define TA1 ps_params[4].w + +#endif + +float4 wrapuv(float4 uv) +{ + if(PS_WMS == PS_WMT) + { + if(PS_WMS == 0) + { + uv = frac(uv); + } + else if(PS_WMS == 1) + { + uv = saturate(uv); + } + else if(PS_WMS == 2) + { + uv = clamp(uv, MinMax.xyxy, MinMax.zwzw); + } + else if(PS_WMS == 3) + { + #if SHADER_MODEL >= 0x400 + uv = (float4)(((int4)(uv * WH.xyxy) & MskFix.xyxy) | MskFix.zwzw) / WH.xyxy; + #elif SHADER_MODEL <= 0x300 + uv.x = tex1D(UMSKFIX, uv.x); + uv.y = tex1D(VMSKFIX, uv.y); + uv.z = tex1D(UMSKFIX, uv.z); + uv.w = tex1D(VMSKFIX, uv.w); + #endif + } + } + else + { + if(PS_WMS == 0) + { + uv.xz = frac(uv.xz); + } + else if(PS_WMS == 1) + { + uv.xz = saturate(uv.xz); + } + else if(PS_WMS == 2) + { + uv.xz = clamp(uv.xz, MinMax.xx, MinMax.zz); + } + else if(PS_WMS == 3) + { + #if SHADER_MODEL >= 0x400 + uv.xz = (float2)(((int2)(uv * WH.xyxy).xz & MskFix.xx) | MskFix.zz) / WH.xy; + #elif SHADER_MODEL <= 0x300 + uv.x = tex1D(UMSKFIX, uv.x); + uv.z = tex1D(UMSKFIX, uv.z); + #endif + } + + if(PS_WMT == 0) + { + uv.yw = frac(uv.yw); + } + else if(PS_WMT == 1) + { + uv.yw = saturate(uv.yw); + } + else if(PS_WMT == 2) + { + uv.yw = clamp(uv.yw, MinMax.yy, MinMax.ww); + } + else if(PS_WMT == 3) + { + #if SHADER_MODEL >= 0x400 + uv.yw = (float2)(((int2)(uv * WH.xyxy).yw & MskFix.yy) | MskFix.ww) / WH.xy; + #elif SHADER_MODEL <= 0x300 + uv.y = tex1D(VMSKFIX, uv.y); + uv.w = tex1D(VMSKFIX, uv.w); + #endif + } + } + + return uv; +} + +float2 clampuv(float2 uv) +{ + if(PS_WMS == 2 && PS_WMT == 2) + { + uv = clamp(uv, MinF, MinMax.zw); + } + else if(PS_WMS == 2) + { + uv.x = clamp(uv.x, MinF.x, MinMax.z); + } + else if(PS_WMT == 2) + { + uv.y = clamp(uv.y, MinF.y, MinMax.w); + } + + return uv; +} + +float4 tfx(float4 t, float4 c) +{ + if(PS_TFX == 0) + { + if(PS_TCC == 0) + { + c.rgb = c.rgb * t.rgb * 255.0f / 128; + } + else + { + c = c * t * 255.0f / 128; + } + } + else if(PS_TFX == 1) + { + if(PS_TCC == 0) + { + c.rgb = t.rgb; + } + else + { + c = t; + } + } + else if(PS_TFX == 2) + { + c.rgb = c.rgb * t.rgb * 255.0f / 128 + c.a; + + if(PS_TCC == 1) + { + c.a += t.a; + } + } + else if(PS_TFX == 3) + { + c.rgb = c.rgb * t.rgb * 255.0f / 128 + c.a; + + if(PS_TCC == 1) + { + c.a = t.a; + } + } + + return saturate(c); +} + +void atst(float4 c) +{ + if(PS_ATE == 1) + { + if(PS_ATST == 0) + { + discard; + } + else if(PS_ATST == 2 || PS_ATST == 3) // l, le + { + clip(AREF - c.a); + } + else if(PS_ATST == 4) // e + { + clip(0.6f / 255 - abs(c.a - AREF)); // FIXME: 0.5f is too small + } + else if(PS_ATST == 5 || PS_ATST == 6) // ge, g + { + clip(c.a - AREF); + } + else if(PS_ATST == 7) // ne + { + clip(abs(c.a - AREF) - 0.4f / 255); // FIXME: 0.5f is too much + } + } +} + +float4 fog(float4 c, float f) +{ + if(PS_FOG == 1) + { + c.rgb = lerp(FogColor, c.rgb, f); + } + + return c; +} + +#if SHADER_MODEL >= 0x400 + +VS_OUTPUT vs_main(VS_INPUT input) +{ + if(VS_BPPZ == 1) // 24 + { + input.z = input.z & 0xffffff; + } + else if(VS_BPPZ == 2) // 16 + { + input.z = input.z & 0xffff; + } + + if(VS_PRIM == 3) // sprite + { + //input.p.xy = (input.p.xy + 15) & ~15; // HACK + } + + VS_OUTPUT output; + + // pos -= 0.05 (1/320 pixel) helps avoiding rounding problems (integral part of pos is usually 5 digits, 0.05 is about as low as we can go) + // example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty + // input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel + // example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133 + + float4 p = float4(input.p, input.z, 0) - float4(0.05f, 0.05f, 0, 0); + + output.p = p * VertexScale - VertexOffset; + + if(VS_TME == 1) + { + if(VS_FST == 1) + { + output.t.xy = input.t * TextureScale; + output.t.w = 1.0f; + } + else + { + output.t.xy = input.t; + output.t.w = input.q; + } + } + else + { + output.t.xy = 0; + output.t.w = 1.0f; + } + + output.c = input.c; + output.t.z = input.f.a; + + return output; +} + +#if GS_PRIM == 0 + +[maxvertexcount(1)] +void gs_main(point VS_OUTPUT input[1], inout PointStream stream) +{ + stream.Append(input[0]); +} + +#elif GS_PRIM == 1 + +[maxvertexcount(2)] +void gs_main(line VS_OUTPUT input[2], inout LineStream stream) +{ + #if GS_IIP == 0 + input[0].c = input[1].c; + #endif + + stream.Append(input[0]); + stream.Append(input[1]); +} + +#elif GS_PRIM == 2 + +[maxvertexcount(3)] +void gs_main(triangle VS_OUTPUT input[3], inout TriangleStream stream) +{ + #if GS_IIP == 0 + input[0].c = input[2].c; + input[1].c = input[2].c; + #endif + + stream.Append(input[0]); + stream.Append(input[1]); + stream.Append(input[2]); +} + +#elif GS_PRIM == 3 + +[maxvertexcount(4)] +void gs_main(line VS_OUTPUT input[2], inout TriangleStream stream) +{ + input[0].p.z = input[1].p.z; + input[0].t.zw = input[1].t.zw; + + #if GS_IIP == 0 + input[0].c = input[1].c; + #endif + + VS_OUTPUT lb = input[1]; + + lb.p.x = input[0].p.x; + lb.t.x = input[0].t.x; + + VS_OUTPUT rt = input[1]; + + rt.p.y = input[0].p.y; + rt.t.y = input[0].t.y; + + stream.Append(input[0]); + stream.Append(lb); + stream.Append(rt); + stream.Append(input[1]); +} + +#endif + +float4 sample(float2 tc, float w) +{ + if(PS_FST == 0) + { + tc /= w; + } + + float4 t; +/* + if(PS_BPP < 3 && PS_WMS < 2 && PS_WMT < 2) + { + t = Texture.Sample(TextureSampler, tc); + } +*/ + if(PS_BPP < 3 && PS_WMS < 3 && PS_WMT < 3) + { + t = Texture.Sample(TextureSampler, clampuv(tc)); + } + else + { + float w, h; + Texture.GetDimensions(w, h); + + float4 uv2 = tc.xyxy + HalfTexel; + float2 dd = frac(uv2.xy * float2(w, h)); // * WH.zw + float4 uv = wrapuv(uv2); + + float4 t00, t01, t10, t11; + + if(PS_BPP == 3) // 8HP + { + float4 a; + + a.x = Texture.Sample(TextureSampler, uv.xy).a; + a.y = Texture.Sample(TextureSampler, uv.zy).a; + a.z = Texture.Sample(TextureSampler, uv.xw).a; + a.w = Texture.Sample(TextureSampler, uv.zw).a; + + t00 = Palette.Sample(PaletteSampler, a.x); + t01 = Palette.Sample(PaletteSampler, a.y); + t10 = Palette.Sample(PaletteSampler, a.z); + t11 = Palette.Sample(PaletteSampler, a.w); + } + else + { + t00 = Texture.Sample(TextureSampler, uv.xy); + t01 = Texture.Sample(TextureSampler, uv.zy); + t10 = Texture.Sample(TextureSampler, uv.xw); + t11 = Texture.Sample(TextureSampler, uv.zw); + } + + if(PS_LTF) + { + t = lerp(lerp(t00, t01, dd.x), lerp(t10, t11, dd.x), dd.y); + } + else + { + t = t00; + } + } + + if(PS_BPP == 1) // 24 + { + t.a = PS_AEM == 0 || any(t.rgb) ? TA.x : 0; + } + else if(PS_BPP == 2) // 16 + { + // a bit incompatible with up-scaling because the 1 bit alpha is interpolated + + t.a = t.a >= 0.5 ? TA.y : PS_AEM == 0 || any(t.rgb) ? TA.x : 0; + } + + return t; +} + +PS_OUTPUT ps_main(PS_INPUT input) +{ + float4 t = sample(input.t.xy, input.t.w); + + float4 c = tfx(t, input.c); + + atst(c); + + c = fog(c, input.t.z); + + if(PS_CLR1 == 1) // needed for Cd * (As/Ad/F + 1) blending modes + { + c.rgb = 1; + } + + PS_OUTPUT output; + + output.c1 = c.a * 2; // used for alpha blending + + if(PS_AOUT == 1) // 16 bit output + { + float a = 128.0f / 255; // alpha output will be 0x80 + + c.a = PS_FBA == 1 ? a : step(0.5, c.a) * a; + } + else if(PS_FBA == 1) + { + if(c.a < 0.5) c.a += 0.5; + } + + output.c0 = c; + + return output; +} + +#elif SHADER_MODEL <= 0x300 + +VS_OUTPUT vs_main(VS_INPUT input) +{ + if(VS_BPPZ == 1) // 24 + { + input.p.z = fmod(input.p.z, 0x1000000); + } + else if(VS_BPPZ == 2) // 16 + { + input.p.z = fmod(input.p.z, 0x10000); + } + + VS_OUTPUT output; + + // pos -= 0.05 (1/320 pixel) helps avoiding rounding problems (integral part of pos is usually 5 digits, 0.05 is about as low as we can go) + // example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty + // input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel + // example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133 + + float4 p = input.p - float4(0.05f, 0.05f, 0, 0); + + output.p = p * VertexScale - VertexOffset; + + if(VS_LOGZ == 1) + { + output.p.z = log2(1.0f + input.p.z) / 32; + } + + if(VS_TME == 1) + { + if(VS_FST == 1) + { + output.t.xy = input.t * TextureScale; + output.t.w = 1.0f; + } + else + { + output.t.xy = input.t; + output.t.w = input.p.w; + } + } + else + { + output.t.xy = 0; + output.t.w = 1.0f; + } + + output.c = input.c; + output.t.z = input.f.a; + + return output; +} + +float4 sample(float2 tc, float w) +{ + if(PS_FST == 0) + { + tc /= w; + } + + float4 t; +/* + if(PS_BPP < 3 && PS_WMS < 2 && PS_WMT < 2) + { + t = tex2D(Texture, tc); + } +*/ + if(PS_BPP < 3 && PS_WMS < 3 && PS_WMT < 3) + { + t = tex2D(Texture, clampuv(tc)); + } + else + { + float4 uv2 = tc.xyxy + HalfTexel; + float2 dd = frac(uv2.xy * WH.zw); + float4 uv = wrapuv(uv2); + + float4 t00, t01, t10, t11; + + if(PS_BPP == 3) // 8HP + { + float4 a; + + a.x = tex2D(Texture, uv.xy).a; + a.y = tex2D(Texture, uv.zy).a; + a.z = tex2D(Texture, uv.xw).a; + a.w = tex2D(Texture, uv.zw).a; + + if(PS_RT == 1) a *= 0.5; + + t00 = tex1D(Palette, a.x); + t01 = tex1D(Palette, a.y); + t10 = tex1D(Palette, a.z); + t11 = tex1D(Palette, a.w); + } + else + { + t00 = tex2D(Texture, uv.xy); + t01 = tex2D(Texture, uv.zy); + t10 = tex2D(Texture, uv.xw); + t11 = tex2D(Texture, uv.zw); + } + + if(PS_LTF) + { + t = lerp(lerp(t00, t01, dd.x), lerp(t10, t11, dd.x), dd.y); + } + else + { + t = t00; + } + } + + if(PS_BPP == 0) // 32 + { + if(PS_RT == 1) t.a *= 0.5; + } + else if(PS_BPP == 1) // 24 + { + t.a = PS_AEM == 0 || any(t.rgb) ? TA0 : 0; + } + else if(PS_BPP == 2) // 16 + { + // a bit incompatible with up-scaling because the 1 bit alpha is interpolated + + t.a = t.a >= 0.5 ? TA1 : PS_AEM == 0 || any(t.rgb) ? TA0 : 0; + } + + return t; +} + +float4 ps_main(PS_INPUT input) : COLOR +{ + float4 t = sample(input.t.xy, input.t.w); + + float4 c = tfx(t, input.c); + + atst(c); + + c = fog(c, input.t.z); + + if(PS_CLR1 == 1) // needed for Cd * (As/Ad/F + 1) blending modes + { + c.rgb = 1; + } + + c.a *= 2; + + return c; +} + +#endif \ No newline at end of file diff --git a/plugins/GSdx/res/tfx10.fx b/plugins/GSdx/res/tfx10.fx deleted file mode 100644 index fe101d1674..0000000000 --- a/plugins/GSdx/res/tfx10.fx +++ /dev/null @@ -1,501 +0,0 @@ -cbuffer cb0 -{ - float4 VertexScale; - float4 VertexOffset; - float2 TextureScale; -}; - -struct VS_INPUT -{ - uint2 p : POSITION0; - uint z : POSITION1; - float2 t : TEXCOORD0; - float q : TEXCOORD1; - float4 c : COLOR0; - float4 f : COLOR1; -}; - -struct VS_OUTPUT -{ - float4 p : SV_Position; - float4 t : TEXCOORD0; - float4 c : COLOR0; -}; - -#ifndef VS_BPP -#define VS_BPP 0 -#define VS_BPPZ 0 -#define VS_TME 1 -#define VS_FST 1 -#define VS_PRIM 0 -#endif - -VS_OUTPUT vs_main(VS_INPUT input) -{ - if(VS_BPPZ == 1) // 24 - { - input.z = input.z & 0xffffff; - } - else if(VS_BPPZ == 2) // 16 - { - input.z = input.z & 0xffff; - } - - if(VS_PRIM == 6) // sprite - { - //input.p.xy = (input.p.xy + 15) & ~15; // HACK - } - - VS_OUTPUT output; - - float4 p = float4(input.p, input.z, 0); - - // FIXME: - // A litte accuracy problem in many games where the screen is copied in columns and the sides have a half pixel gap for some reason - // (probably to avoid page breaks with linear filtering). That half pixel coordinate gets multiplied by 2 (VertexScale) and occasionally - // ends on .9999999, which the rasterizer floors to 1 less pixel we need, leaving a visible gap after drawing. - - p += float4(0.5f, 0.5f, 0, 0); // add 1/32 pixel - - output.p = p * VertexScale - VertexOffset; - - if(VS_TME == 1) - { - if(VS_FST == 1) - { - output.t.xy = input.t * TextureScale; - output.t.w = 1.0f; - } - else - { - output.t.xy = input.t; - output.t.w = input.q; - } - } - else - { - output.t.xy = 0; - output.t.w = 1.0f; - } - - output.c = input.c; - output.t.z = input.f.a; - - return output; -} - -#ifndef IIP -#define IIP 0 -#define PRIM 3 -#endif - -#if PRIM == 0 - -[maxvertexcount(1)] -void gs_main(point VS_OUTPUT input[1], inout PointStream stream) -{ - stream.Append(input[0]); -} - -#elif PRIM == 1 - -[maxvertexcount(2)] -void gs_main(line VS_OUTPUT input[2], inout LineStream stream) -{ - #if IIP == 0 - input[0].c = input[1].c; - #endif - - stream.Append(input[0]); - stream.Append(input[1]); -} - -#elif PRIM == 2 - -[maxvertexcount(3)] -void gs_main(triangle VS_OUTPUT input[3], inout TriangleStream stream) -{ - #if IIP == 0 - input[0].c = input[2].c; - input[1].c = input[2].c; - #endif - - stream.Append(input[0]); - stream.Append(input[1]); - stream.Append(input[2]); -} - -#elif PRIM == 3 - -[maxvertexcount(4)] -void gs_main(line VS_OUTPUT input[2], inout TriangleStream stream) -{ - input[0].p.z = input[1].p.z; - input[0].t.zw = input[1].t.zw; - - #if IIP == 0 - input[0].c = input[1].c; - #endif - - VS_OUTPUT lb = input[1]; - - lb.p.x = input[0].p.x; - lb.t.x = input[0].t.x; - - VS_OUTPUT rt = input[1]; - - rt.p.y = input[0].p.y; - rt.t.y = input[0].t.y; - - stream.Append(input[0]); - stream.Append(lb); - stream.Append(rt); - stream.Append(input[1]); -} - -#endif - -Texture2D Texture; -Texture2D Palette; -SamplerState TextureSampler; -SamplerState PaletteSampler; - -cbuffer cb1 -{ - float4 FogColor; - float MINU; - float MAXU; - float MINV; - float MAXV; - uint UMSK; - uint UFIX; - uint VMSK; - uint VFIX; - float TA0; - float TA1; - float AREF; - float _pad; - float2 WH; - float2 rWrH; -}; - -struct PS_INPUT -{ - float4 p : SV_Position; - float4 t : TEXCOORD0; - float4 c : COLOR0; -}; - -struct PS_OUTPUT -{ - float4 c0 : SV_Target0; - float4 c1 : SV_Target1; -}; - -#ifndef FST -#define FST 0 -#define WMS 3 -#define WMT 3 -#define BPP 0 -#define AEM 0 -#define TFX 0 -#define TCC 1 -#define ATE 0 -#define ATST 2 -#define FOG 0 -#define CLR1 0 -#define FBA 0 -#define AOUT 0 -#endif - -float4 Normalize16(float4 f) -{ - return f / float4(0x001f, 0x03e0, 0x7c00, 0x8000); -} - -float4 Extract16(uint i) -{ - float4 f; - - f.r = i & 0x001f; - f.g = i & 0x03e0; - f.b = i & 0x7c00; - f.a = i & 0x8000; - - return f; -} - -int repeatu(int tc) -{ - return WMS == 3 ? ((tc & UMSK) | UFIX) : tc; -} - -int repeatv(int tc) -{ - return WMT == 3 ? ((tc & VMSK) | VFIX) : tc; -} - -float4 sample(float2 tc) -{ - float4 t; - - // if(WMS >= 2 || WMT >= 2) - if(WMS >= 3 || WMT >= 3) - { - int4 itc = tc.xyxy * WH.xyxy; - - float4 tc01; - - tc01.x = repeatu(itc.x); - tc01.y = repeatv(itc.y); - tc01.z = repeatu(itc.z + 1); - tc01.w = repeatv(itc.w + 1); - - tc01 *= rWrH.xyxy; - - float4 t00 = Texture.Sample(TextureSampler, tc01.xy); - float4 t01 = Texture.Sample(TextureSampler, tc01.zy); - float4 t10 = Texture.Sample(TextureSampler, tc01.xw); - float4 t11 = Texture.Sample(TextureSampler, tc01.zw); - - float2 dd = frac(tc * WH); - - t = lerp(lerp(t00, t01, dd.x), lerp(t10, t11, dd.x), dd.y); - } - else - { - t = Texture.Sample(TextureSampler, tc); - } - - return t; -} - -float4 sample8hp(float2 tc) -{ - float4 tc01; - - // if(WMS >= 2 || WMT >= 2) - if(WMS >= 3 || WMT >= 3) - { - int4 itc = tc.xyxy * WH.xyxy; - - tc01.x = repeatu(itc.x); - tc01.y = repeatv(itc.y); - tc01.z = repeatu(itc.z + 1); - tc01.w = repeatv(itc.w + 1); - - tc01 *= rWrH.xyxy; - } - else - { - tc01.x = tc.x; - tc01.y = tc.y; - tc01.z = tc.x + rWrH.x; - tc01.w = tc.y + rWrH.y; - } - - float4 t; - - t.x = Texture.Sample(TextureSampler, tc01.xy).a; - t.y = Texture.Sample(TextureSampler, tc01.zy).a; - t.z = Texture.Sample(TextureSampler, tc01.xw).a; - t.w = Texture.Sample(TextureSampler, tc01.zw).a; - - float4 t00 = Palette.Sample(PaletteSampler, t.x); - float4 t01 = Palette.Sample(PaletteSampler, t.y); - float4 t10 = Palette.Sample(PaletteSampler, t.z); - float4 t11 = Palette.Sample(PaletteSampler, t.w); - - float2 dd = frac(tc * WH); - - return lerp(lerp(t00, t01, dd.x), lerp(t10, t11, dd.x), dd.y); -} - -float4 sample16p(float2 tc) -{ - float4 t; - - float4 tc01; - - // if(WMS >= 2 || WMT >= 2) - if(WMS >= 3 || WMT >= 3) - { - int4 itc = tc.xyxy * WH.xyxy; - - tc01.x = repeatu(itc.x); - tc01.y = repeatv(itc.y); - tc01.z = repeatu(itc.z + 1); - tc01.w = repeatv(itc.w + 1); - - tc01 *= rWrH.xyxy; - } - else - { - tc01.x = tc.x; - tc01.y = tc.y; - tc01.z = tc.x + rWrH.x; - tc01.w = tc.y + rWrH.y; - } - - t.x = Texture.Sample(TextureSampler, tc01.xy).r; - t.y = Texture.Sample(TextureSampler, tc01.zy).r; - t.z = Texture.Sample(TextureSampler, tc01.xw).r; - t.w = Texture.Sample(TextureSampler, tc01.zw).r; - - uint4 i = t * 65535; - - float4 t00 = Extract16(i.x); - float4 t01 = Extract16(i.y); - float4 t10 = Extract16(i.z); - float4 t11 = Extract16(i.w); - - float2 dd = frac(tc * WH); - - return Normalize16(lerp(lerp(t00, t01, dd.x), lerp(t10, t11, dd.x), dd.y)); -} - -PS_OUTPUT ps_main(PS_INPUT input) -{ - float2 tc = input.t.xy; - - if(FST == 0) - { - tc /= input.t.w; - } - - tc -= rWrH / 2; - - if(WMS == 2) - { - tc.x = clamp(tc.x, MINU, MAXU); - } - - if(WMT == 2) - { - tc.y = clamp(tc.y, MINV, MAXV); - } - - float4 t; - - if(BPP == 0) // 32 - { - t = sample(tc); - } - else if(BPP == 1) // 24 - { - t = sample(tc); - - t.a = AEM == 0 || any(t.rgb) ? TA0 : 0; - } - else if(BPP == 2) // 16 - { - t = sample(tc); - - t.a = t.a >= 0.5 ? TA1 : AEM == 0 || any(t.rgb) ? TA0 : 0; // a bit incompatible with up-scaling because the 1 bit alpha is interpolated - } - else if(BPP == 3) // 8HP / 32-bit palette - { - t = sample8hp(tc); - } - else if(BPP == 4) // 8HP / 16-bit palette - { - // TODO: yuck, just pre-convert the palette to 32-bit - } - else if(BPP == 5) // 16P - { - t = sample16p(tc); - - t.a = t.a >= 0.5 ? TA1 : AEM == 0 || any(t.rgb) ? TA0 : 0; // a bit incompatible with up-scaling because the 1 bit alpha is interpolated - } - - float4 c = input.c; - - if(TFX == 0) - { - if(TCC == 0) - { - c.rgb = c.rgb * t.rgb * 2; - } - else - { - c = c * t * 2; - } - } - else if(TFX == 1) - { - c = t; - } - else if(TFX == 2) - { - c.rgb = c.rgb * t.rgb * 2 + c.a; - - if(TCC == 1) - { - c.a += t.a; - } - } - else if(TFX == 3) - { - c.rgb = c.rgb * t.rgb * 2 + c.a; - - if(TCC == 1) - { - c.a = t.a; - } - } - - c = saturate(c); - - if(ATE == 1) - { - if(ATST == 0) - { - discard; - } - else if(ATST == 2 || ATST == 3) // l, le - { - clip(AREF - c.a); - } - else if(ATST == 4) // e - { - clip(0.6f / 255 - abs(c.a - AREF)); // FIXME: 0.5f is too small - } - else if(ATST == 5 || ATST == 6) // ge, g - { - clip(c.a - AREF); - } - else if(ATST == 7) // ne - { - clip(abs(c.a - AREF) - 0.4f / 255); // FIXME: 0.5f is too much - } - } - - if(FOG == 1) - { - c.rgb = lerp(FogColor.rgb, c.rgb, input.t.z); - } - - if(CLR1 == 1) // needed for Cd * (As/Ad/F + 1) blending modes - { - c.rgb = 1; - } - - PS_OUTPUT output; - - output.c1 = c.a * 2; // used for alpha blending - - if(AOUT == 1) // 16 bit output - { - float a = 128.0f / 255; // alpha output will be 0x80 - - c.a = FBA == 1 ? a : step(0.5, c.a) * a; - } - else if(FBA == 1) - { - if(c.a < 0.5) c.a += 0.5; - } - - output.c0 = c; - - return output; -} diff --git a/plugins/GSdx/res/tfx9.fx b/plugins/GSdx/res/tfx9.fx deleted file mode 100644 index d3c9d05d85..0000000000 --- a/plugins/GSdx/res/tfx9.fx +++ /dev/null @@ -1,313 +0,0 @@ -struct VS_INPUT -{ - float4 p : POSITION0; - float2 t : TEXCOORD0; - float4 c : COLOR0; - float4 f : COLOR1; -}; - -struct VS_OUTPUT -{ - float4 p : POSITION; - float4 t : TEXCOORD0; - float4 c : COLOR0; -}; - -float4 vs_params[3]; - -#define VertexScale vs_params[0] -#define VertexOffset vs_params[1] -#define TextureScale vs_params[2].xy - -#ifndef VS_BPPZ -#define VS_BPPZ 0 -#define VS_TME 1 -#define VS_FST 1 -#define VS_LOGZ 1 -#endif - -VS_OUTPUT vs_main(VS_INPUT input) -{ - if(VS_BPPZ == 1) // 24 - { - input.p.z = fmod(input.p.z, 0x1000000); - } - else if(VS_BPPZ == 2) // 16 - { - input.p.z = fmod(input.p.z, 0x10000); - } - - VS_OUTPUT output; - - output.p = input.p * VertexScale - VertexOffset; - - if(VS_LOGZ == 1) - { - output.p.z = log2(1.0f + input.p.z) / 32; - } - - if(VS_TME == 1) - { - if(VS_FST == 1) - { - output.t.xy = input.t * TextureScale; - output.t.w = 1.0f; - } - else - { - output.t.xy = input.t; - output.t.w = input.p.w; - } - } - else - { - output.t.xy = 0; - output.t.w = 1.0f; - } - - output.c = input.c; - output.t.z = input.f.a; - - return output; -} - -float4 ps_params[5]; - -#define FogColor ps_params[0].bgra -#define MINU ps_params[1].x -#define MAXU ps_params[1].y -#define MINV ps_params[1].z -#define MAXV ps_params[1].w -#define UMSK ps_params[2].x -#define UFIX ps_params[2].y -#define VMSK ps_params[2].z -#define VFIX ps_params[2].w -#define TA0 ps_params[3].x -#define TA1 ps_params[3].y -#define AREF ps_params[3].z -#define WH ps_params[4].xy -#define rWrH ps_params[4].zw - -struct PS_INPUT -{ - float4 t : TEXCOORD0; - float4 c : COLOR0; -}; - -#ifndef FST -#define FST 0 -#define WMS 3 -#define WMT 3 -#define BPP 0 -#define AEM 0 -#define TFX 0 -#define TCC 1 -#define ATE 0 -#define ATST 0 -#define FOG 0 -#define CLR1 0 -#define RT 0 -#endif - -sampler Texture : register(s0); -sampler1D Palette : register(s1); -sampler1D UMSKFIX : register(s2); -sampler1D VMSKFIX : register(s3); - -float repeatu(float tc) -{ - return WMS == 3 ? tex1D(UMSKFIX, tc) : tc; -} - -float repeatv(float tc) -{ - return WMT == 3 ? tex1D(VMSKFIX, tc) : tc; -} - -float4 sample(float2 tc) -{ - float4 t; - - // if(WMS >= 2 || WMT >= 2) - if(WMS >= 3 || WMT >= 3) - { - tc -= rWrH / 2; - - int4 itc = tc.xyxy * WH.xyxy; - - float4 tc01; - - tc01.x = repeatu(itc.x); - tc01.y = repeatv(itc.y); - tc01.z = repeatu(itc.z + 1); - tc01.w = repeatv(itc.w + 1); - - tc01 *= rWrH.xyxy; - - float4 t00 = tex2D(Texture, tc01.xy); - float4 t01 = tex2D(Texture, tc01.zy); - float4 t10 = tex2D(Texture, tc01.xw); - float4 t11 = tex2D(Texture, tc01.zw); - - float2 dd = frac(tc * WH); - - t = lerp(lerp(t00, t01, dd.x), lerp(t10, t11, dd.x), dd.y); - } - else - { - t = tex2D(Texture, tc); - } - - return t; -} - -float4 sample8hp(float2 tc) -{ - tc -= rWrH / 2; - - float4 tc01; - - tc01.x = tc.x; - tc01.y = tc.y; - tc01.z = tc.x + rWrH.x; - tc01.w = tc.y + rWrH.y; - - float4 t; - - t.x = tex2D(Texture, tc01.xy).a; - t.y = tex2D(Texture, tc01.zy).a; - t.z = tex2D(Texture, tc01.xw).a; - t.w = tex2D(Texture, tc01.zw).a; - - if(RT == 1) t *= 0.5; - - float4 t00 = tex1D(Palette, t.x); - float4 t01 = tex1D(Palette, t.y); - float4 t10 = tex1D(Palette, t.z); - float4 t11 = tex1D(Palette, t.w); - - float2 dd = frac(tc * WH); - - return lerp(lerp(t00, t01, dd.x), lerp(t10, t11, dd.x), dd.y); -} - -float4 ps_main(PS_INPUT input) : COLOR -{ - float2 tc = input.t.xy; - - if(FST == 0) - { - tc /= input.t.w; - } - - if(WMS == 2) - { - tc.x = clamp(tc.x, MINU, MAXU); - } - - if(WMT == 2) - { - tc.y = clamp(tc.y, MINV, MAXV); - } - - float4 t; - - if(BPP == 0) // 32 - { - t = sample(tc); - - if(RT == 1) t.a *= 0.5; - } - else if(BPP == 1) // 24 - { - t = sample(tc); - - t.a = AEM == 0 || any(t.rgb) ? TA0 : 0; - } - else if(BPP == 2) // 16 - { - t = sample(tc); - - t.a = t.a >= 0.5 ? TA1 : AEM == 0 || any(t.rgb) ? TA0 : 0; // a bit incompatible with up-scaling because the 1 bit alpha is interpolated - } - else if(BPP == 3) // 8HP ln - { - t = sample8hp(tc); - } - - float4 c = input.c; - - if(TFX == 0) - { - if(TCC == 0) - { - c.rgb = c.rgb * t.rgb * 2; - } - else - { - c = c * t * 2; - } - } - else if(TFX == 1) - { - c = t; - } - else if(TFX == 2) - { - c.rgb = c.rgb * t.rgb * 2 + c.a; - - if(TCC == 1) - { - c.a += t.a; - } - } - else if(TFX == 3) - { - c.rgb = c.rgb * t.rgb * 2 + c.a; - - if(TCC == 1) - { - c.a = t.a; - } - } - - c = saturate(c); - - if(ATE == 1) - { - if(ATST == 0) - { - discard; - } - else if(ATST == 2 || ATST == 3) // l, le - { - clip(AREF - c.a); - } - else if(ATST == 4) // e - { - clip(0.6f / 256 - abs(c.a - AREF)); // FIXME: 0.5f is too small - } - else if(ATST == 5 || ATST == 6) // ge, g - { - clip(c.a - AREF); - } - else if(ATST == 7) // ne - { - clip(abs(c.a - AREF) - 0.4f / 255); // FIXME: 0.5f is too much - } - } - - if(FOG == 1) - { - c.rgb = lerp(FogColor.rgb, c.rgb, input.t.z); - } - - if(CLR1 == 1) // needed for Cd * (As/Ad/F + 1) blending modes - { - c.rgb = 1; - } - - c.a *= 2; - - return c; -} diff --git a/plugins/GSdx/resource.h b/plugins/GSdx/resource.h index 48d4b60446..409840b67e 100644 --- a/plugins/GSdx/resource.h +++ b/plugins/GSdx/resource.h @@ -2,56 +2,56 @@ // Microsoft Visual C++ generated include file. // Used by GSdx.rc // -#define IDC_CHECK1 2001 -#define IDC_CHECK2 2002 +#define IDC_NATIVERES 2001 +#define IDC_VSYNC 2002 #define IDC_CHECK3 2003 -#define IDC_CHECK5 2004 +#define IDC_LOGZ 2004 #define IDC_CHECK6 2005 -#define IDC_COMBO1 2006 -#define IDC_COMBO3 2007 -#define IDC_COMBO4 2008 -#define IDC_EDIT1 2009 -#define IDC_EDIT2 2010 -#define IDC_BUTTON1 2011 -#define IDC_CHECK8 2011 -#define IDC_BUTTON2 2012 -#define IDC_EDIT3 2012 +#define IDC_CODECS 2006 +#define IDC_RESOLUTION 2007 +#define IDC_SHADER 2008 +#define IDC_RESX_EDIT 2009 +#define IDC_RESY_EDIT 2010 +#define IDC_AA1 2011 +#define IDC_SWTHREADS_EDIT 2012 #define IDC_CUSTOM1 2013 #define IDC_CHECK4 2014 -#define IDC_COMBO2 2015 -#define IDC_COMBO5 2016 +#define IDC_FILTER 2015 +#define IDC_DITHERING 2016 #define IDC_RADIO1 2017 -#define IDC_COMBO6 2017 -#define IDC_SPIN1 2018 -#define IDC_COMBO7 2018 -#define IDC_SPIN2 2019 +#define IDC_RESX 2018 +#define IDC_RESY 2019 #define IDD_CONFIG 2020 -#define IDC_SPIN3 2020 #define IDB_LOGO9 2021 #define IDB_LOGO10 2022 -#define IDC_CHECK7 2023 +#define IDC_FBA 2023 #define IDC_LOGO9 2024 #define IDC_LOGO10 2025 #define IDD_CAPTURE 2026 -#define IDC_EDIT4 2027 #define IDD_GPUCONFIG 2027 -#define IDC_CHECK9 2028 -#define IDR_CONVERT9_FX 10000 -#define IDR_TFX9_FX 10001 -#define IDR_MERGE9_FX 10002 -#define IDR_INTERLACE9_FX 10003 -#define IDR_CONVERT10_FX 10004 -#define IDR_TFX10_FX 10005 -#define IDR_MERGE10_FX 10006 -#define IDR_INTERLACE10_FX 10007 +#define IDC_BLUR 2028 +#define IDC_RENDERER 2029 +#define IDC_INTERLACE 2030 +#define IDC_ASPECTRATIO 2031 +#define IDC_SWTHREADS 2032 +#define IDC_SCALE 2033 +#define IDC_BROWSE 2034 +#define IDC_FILENAME 2035 +#define IDC_WIDTH 2036 +#define IDC_HEIGHT 2037 +#define IDC_CONFIGURE 2038 +#define IDR_CONVERT_FX 10000 +#define IDR_TFX_FX 10001 +#define IDR_MERGE_FX 10002 +#define IDR_INTERLACE_FX 10003 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 10009 +#define _APS_NEXT_RESOURCE_VALUE 10004 #define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 2029 +#define _APS_NEXT_CONTROL_VALUE 2039 #define _APS_NEXT_SYMED_VALUE 5000 #endif #endif diff --git a/plugins/GSdx/sse.h b/plugins/GSdx/sse.h deleted file mode 100644 index d1b35dd2d7..0000000000 --- a/plugins/GSdx/sse.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2007-2009 Gabest - * http://www.gabest.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#pragma once - -// sse2 - -#if _M_SSE >= 0x200 - - #include - #include - - #ifndef _MM_DENORMALS_ARE_ZERO - #define _MM_DENORMALS_ARE_ZERO 0x0040 - #endif - - #define MXCSR (_MM_DENORMALS_ARE_ZERO | _MM_MASK_MASK | _MM_ROUND_NEAREST | _MM_FLUSH_ZERO_ON) - - #if _MSC_VER < 1500 - - __forceinline __m128i _mm_castps_si128(__m128 a) {return *(__m128i*)&a;} - __forceinline __m128 _mm_castsi128_ps(__m128i a) {return *(__m128*)&a;} - __forceinline __m128i _mm_castpd_si128(__m128d a) {return *(__m128i*)&a;} - __forceinline __m128d _mm_castsi128_pd(__m128i a) {return *(__m128d*)&a;} - __forceinline __m128d _mm_castps_pd(__m128 a) {return *(__m128d*)&a;} - __forceinline __m128 _mm_castpd_ps(__m128d a) {return *(__m128*)&a;} - - #endif - - #define _MM_TRANSPOSE4_SI128(row0, row1, row2, row3) \ - { \ - __m128 tmp0 = _mm_shuffle_ps(_mm_castsi128_ps(row0), _mm_castsi128_ps(row1), 0x44); \ - __m128 tmp2 = _mm_shuffle_ps(_mm_castsi128_ps(row0), _mm_castsi128_ps(row1), 0xEE); \ - __m128 tmp1 = _mm_shuffle_ps(_mm_castsi128_ps(row2), _mm_castsi128_ps(row3), 0x44); \ - __m128 tmp3 = _mm_shuffle_ps(_mm_castsi128_ps(row2), _mm_castsi128_ps(row3), 0xEE); \ - (row0) = _mm_castps_si128(_mm_shuffle_ps(tmp0, tmp1, 0x88)); \ - (row1) = _mm_castps_si128(_mm_shuffle_ps(tmp0, tmp1, 0xDD)); \ - (row2) = _mm_castps_si128(_mm_shuffle_ps(tmp2, tmp3, 0x88)); \ - (row3) = _mm_castps_si128(_mm_shuffle_ps(tmp2, tmp3, 0xDD)); \ - } - -#else - -#error TODO: GSVector4 and GSRasterizer needs SSE2 - -#endif - -// sse3 - -#if _M_SSE >= 0x301 - - #include - -#endif - -// sse4 - -#if _M_SSE >= 0x401 - - #include - -#endif diff --git a/plugins/GSdx/stdafx.cpp b/plugins/GSdx/stdafx.cpp index bda8426831..7811c93b2e 100644 --- a/plugins/GSdx/stdafx.cpp +++ b/plugins/GSdx/stdafx.cpp @@ -6,3 +6,34 @@ // TODO: reference any additional headers you need in STDAFX.H // and not in this file + +string format(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + + int result = -1, length = 256; + + char* buffer = NULL; + + while(result == -1) + { + if(buffer) delete [] buffer; + + buffer = new char[length + 1]; + + memset(buffer, 0, length + 1); + + result = _vsnprintf(buffer, length, fmt, args); + + length *= 2; + } + + va_end(args); + + string s(buffer); + + delete [] buffer; + + return s; +} diff --git a/plugins/GSdx/stdafx.h b/plugins/GSdx/stdafx.h index 826f5a6029..375fb8d206 100644 --- a/plugins/GSdx/stdafx.h +++ b/plugins/GSdx/stdafx.h @@ -4,104 +4,189 @@ #pragma once -#pragma warning(disable: 4996) +#pragma warning(disable: 4996 4995 4324 4100 4101 4201) -#ifndef VC_EXTRALEAN -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers -#endif +#ifdef _WINDOWS + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. // Modify the following defines if you have to target a platform prior to the ones specified below. // Refer to MSDN for the latest info on corresponding values for different platforms. -#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. -#define WINVER 0x0510 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. + +#ifndef WINVER // Specifies that the minimum required platform is Windows Vista. +#define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows. #endif -#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. -#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 2000 or later. -#endif +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif -#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98. #define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. #endif -#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. -#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later. +#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0. +#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE. #endif -#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#include // MFC core and standard components -//#include // MFC extensions -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT -//#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#if !defined(_M_SSE) && (defined(_M_AMD64) || defined(_M_IX86_FP) && _M_IX86_FP >= 2) -#define _M_SSE 0x200 #endif -#include "sse.h" +// stdc -#define countof(a) (sizeof(a)/sizeof(a[0])) +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace std; +using namespace stdext; + +extern string format(const char* fmt, ...); + +// syntactic sugar + +// put these into vc9/common7/ide/usertype.dat to have them highlighted + +typedef unsigned char uint8; +typedef signed char int8; +typedef unsigned short uint16; +typedef signed short int16; +typedef unsigned int uint32; +typedef signed int int32; +typedef unsigned long long uint64; +typedef signed long long int64; + +#define countof(a) (sizeof(a) / sizeof(a[0])) #define EXPORT_C extern "C" __declspec(dllexport) void __stdcall #define EXPORT_C_(type) extern "C" __declspec(dllexport) type __stdcall +#define ALIGN_STACK(n) __declspec(align(n)) int __dummy; + #ifndef RESTRICT #ifdef __INTEL_COMPILER #define RESTRICT restrict - #elif _MSC_VER >= 1400 + #elif _MSC_VER >= 1400 // TODO: gcc #define RESTRICT __restrict #else #define RESTRICT #endif #endif -#pragma warning(disable : 4995 4324 4100) +#if defined(_DEBUG) && defined(_MSC_VER) + #include + #define ASSERT assert +#else + #define ASSERT(exp) ((void)0) +#endif -#define D3DCOLORWRITEENABLE_RGB (D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE) -#define D3DCOLORWRITEENABLE_RGBA (D3DCOLORWRITEENABLE_RGB|D3DCOLORWRITEENABLE_ALPHA) +#ifdef __x86_64__ + #define _M_AMD64 +#endif -#define QI(i) (riid == __uuidof(i)) ? GetInterface((i*)this, ppv) : +#ifdef _WINDOWS -template class CRBMapC : public CRBMap -{ - // CRBMap + a cache for the last value (simple, but already a lot better) +// directx - CPair* m_pair; +#include +#include +#include +#include +#include +#include +#include -public: - CRBMapC() : m_pair(NULL) {} +#define D3DCOLORWRITEENABLE_RGBA (D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA) - CPair* Lookup(KINARGTYPE key) - { - if(m_pair && key == m_pair->m_key) - { - return m_pair; - } +// dxsdk beta missing these: +#define D3D11_SHADER_MACRO D3D10_SHADER_MACRO +#define ID3D11Blob ID3D10Blob - m_pair = __super::Lookup(key); +#endif - return m_pair; +// opengl + +#include +#include +#include +#include + +#ifdef _WINDOWS +#include +#endif + +// sse + +#if !defined(_M_SSE) && (defined(_M_AMD64) || defined(_M_IX86_FP) && _M_IX86_FP >= 2) + + #define _M_SSE 0x200 + +#endif + +#if _M_SSE >= 0x200 + + #include + #include + + #ifndef _MM_DENORMALS_ARE_ZERO + #define _MM_DENORMALS_ARE_ZERO 0x0040 + #endif + + #define MXCSR (_MM_DENORMALS_ARE_ZERO | _MM_MASK_MASK | _MM_ROUND_NEAREST | _MM_FLUSH_ZERO_ON) + + #if _MSC_VER < 1500 + + __forceinline __m128i _mm_castps_si128(__m128 a) {return *(__m128i*)&a;} + __forceinline __m128 _mm_castsi128_ps(__m128i a) {return *(__m128*)&a;} + __forceinline __m128i _mm_castpd_si128(__m128d a) {return *(__m128i*)&a;} + __forceinline __m128d _mm_castsi128_pd(__m128i a) {return *(__m128d*)&a;} + __forceinline __m128d _mm_castps_pd(__m128 a) {return *(__m128d*)&a;} + __forceinline __m128 _mm_castpd_ps(__m128d a) {return *(__m128*)&a;} + + #endif + + #define _MM_TRANSPOSE4_SI128(row0, row1, row2, row3) \ + { \ + __m128 tmp0 = _mm_shuffle_ps(_mm_castsi128_ps(row0), _mm_castsi128_ps(row1), 0x44); \ + __m128 tmp2 = _mm_shuffle_ps(_mm_castsi128_ps(row0), _mm_castsi128_ps(row1), 0xEE); \ + __m128 tmp1 = _mm_shuffle_ps(_mm_castsi128_ps(row2), _mm_castsi128_ps(row3), 0x44); \ + __m128 tmp3 = _mm_shuffle_ps(_mm_castsi128_ps(row2), _mm_castsi128_ps(row3), 0xEE); \ + (row0) = _mm_castps_si128(_mm_shuffle_ps(tmp0, tmp1, 0x88)); \ + (row1) = _mm_castps_si128(_mm_shuffle_ps(tmp0, tmp1, 0xDD)); \ + (row2) = _mm_castps_si128(_mm_shuffle_ps(tmp2, tmp3, 0x88)); \ + (row3) = _mm_castps_si128(_mm_shuffle_ps(tmp2, tmp3, 0xDD)); \ } - POSITION SetAt(KINARGTYPE key, VINARGTYPE value) - { - POSITION pos = __super::SetAt(key, value); +#else - m_pair = __super::GetAt(pos); +#error TODO: GSVector4 and GSRasterizer needs SSE2 - return pos; - } -}; +#endif +#if _M_SSE >= 0x301 + + #include + +#endif + +#if _M_SSE >= 0x401 + + #include + +#endif diff --git a/plugins/GSdx/vsprops/ProjectRootDir.props b/plugins/GSdx/vsprops/ProjectRootDir.props new file mode 100644 index 0000000000..fd31a6334d --- /dev/null +++ b/plugins/GSdx/vsprops/ProjectRootDir.props @@ -0,0 +1,25 @@ + + + $(ProjectDir). + $(ProjectRootDir)\..\.. + $(SvnRootDir)\common + plugins + + + <_PropertySheetDisplayName>ProjectRootDir + + + + $(ProjectRootDir) + + + $(SvnRootDir) + + + $(SvnCommonDir) + + + $(PcsxSubsection) + + + \ No newline at end of file diff --git a/plugins/GSdx/vsprops/common.props b/plugins/GSdx/vsprops/common.props new file mode 100644 index 0000000000..0edc67dee6 --- /dev/null +++ b/plugins/GSdx/vsprops/common.props @@ -0,0 +1,32 @@ + + + <_PropertySheetDisplayName>common + $(SolutionDir)\bin\$(PcsxSubsection)\ + $(PlatformName)\$(Configuration)\ + + + + true + WIN32;_WINDOWS;_WIN32_WINNT=0x500;%(PreprocessorDefinitions) + Fast + false + Level4 + ProgramDatabase + 4995;4324;%(DisableSpecificWarnings) + + + JITProfiling.lib;d3d11_beta.lib;d3dx11.lib;d3d10.lib;d3dx10.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;winmm.lib;strmiids.lib;xinput.lib;cg.lib;cgGL.lib;glut32.lib;glew32.lib;%(AdditionalDependencies) + ./vtune;%(AdditionalLibraryDirectories) + d3d9.dll;d3dx9_41.dll;d3d10.dll;d3dx10_41.dll;d3d11.dll;d3d11_beta.dll;d3dx11_41.dll;%(DelayLoadDLLs) + true + Windows + false + + + .\postBuild.cmd "$(TargetPath)" "$(TargetName)" $(TargetExt) $(PcsxSubsection) + + + "$(SvnCommonDir)\vsprops\preBuild.cmd" "$(ProjectRootDir)" + + + \ No newline at end of file diff --git a/plugins/GSdx/vsprops/common.vsprops b/plugins/GSdx/vsprops/common.vsprops index 002a838f84..3a9d3ab82a 100644 --- a/plugins/GSdx/vsprops/common.vsprops +++ b/plugins/GSdx/vsprops/common.vsprops @@ -3,6 +3,7 @@ ProjectType="Visual C++" Version="8.00" Name="common" + OutputDirectory="$(SolutionDir)\bin\$(PcsxSubsection)" IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" > + diff --git a/plugins/GSdx/vsprops/debug.props b/plugins/GSdx/vsprops/debug.props new file mode 100644 index 0000000000..4eabec6606 --- /dev/null +++ b/plugins/GSdx/vsprops/debug.props @@ -0,0 +1,15 @@ + + + <_PropertySheetDisplayName>debug + true + + + + Disabled + _DEBUG;%(PreprocessorDefinitions) + true + StackFrameRuntimeCheck + MultiThreadedDebug + + + \ No newline at end of file diff --git a/plugins/GSdx/vsprops/debug.vsprops b/plugins/GSdx/vsprops/debug.vsprops index 9d5c60bf96..b7506beeec 100644 --- a/plugins/GSdx/vsprops/debug.vsprops +++ b/plugins/GSdx/vsprops/debug.vsprops @@ -10,7 +10,7 @@ PreprocessorDefinitions="_DEBUG" MinimalRebuild="true" BasicRuntimeChecks="1" - RuntimeLibrary="1" + RuntimeLibrary="3" /> + + <_PropertySheetDisplayName>release + false + + + + MaxSpeed + AnySuitable + true + Speed + true + true + NDEBUG;_SECURE_SCL=0;%(PreprocessorDefinitions) + true + false + + + true + true + + + \ No newline at end of file diff --git a/plugins/GSdx/vsprops/release.vsprops b/plugins/GSdx/vsprops/release.vsprops index 5cc40308ee..c9fd3740b2 100644 --- a/plugins/GSdx/vsprops/release.vsprops +++ b/plugins/GSdx/vsprops/release.vsprops @@ -12,8 +12,9 @@ FavorSizeOrSpeed="1" OmitFramePointers="true" WholeProgramOptimization="true" - PreprocessorDefinitions="NDEBUG" + PreprocessorDefinitions="NDEBUG;_SECURE_SCL=0" StringPooling="true" + RuntimeLibrary="2" BufferSecurityCheck="false" /> + + <_PropertySheetDisplayName>sse2 + + + + StreamingSIMDExtensions2 + _M_SSE=0x200;%(PreprocessorDefinitions) + + + \ No newline at end of file diff --git a/plugins/GSdx/vsprops/sse2.vsprops b/plugins/GSdx/vsprops/sse2.vsprops index 1ab36cb277..9211140cc0 100644 --- a/plugins/GSdx/vsprops/sse2.vsprops +++ b/plugins/GSdx/vsprops/sse2.vsprops @@ -6,7 +6,11 @@ > + diff --git a/plugins/GSdx/vsprops/sse4.props b/plugins/GSdx/vsprops/sse4.props new file mode 100644 index 0000000000..273b626cee --- /dev/null +++ b/plugins/GSdx/vsprops/sse4.props @@ -0,0 +1,11 @@ + + + <_PropertySheetDisplayName>sse4 + + + + _M_SSE=0x401;%(PreprocessorDefinitions) + StreamingSIMDExtensions2 + + + \ No newline at end of file diff --git a/plugins/GSdx/vsprops/sse4.vsprops b/plugins/GSdx/vsprops/sse4.vsprops index 601b39f585..da3ee6c270 100644 --- a/plugins/GSdx/vsprops/sse4.vsprops +++ b/plugins/GSdx/vsprops/sse4.vsprops @@ -9,4 +9,8 @@ PreprocessorDefinitions="_M_SSE=0x401" EnableEnhancedInstructionSet="2" /> + diff --git a/plugins/GSdx/vsprops/ssse3.props b/plugins/GSdx/vsprops/ssse3.props new file mode 100644 index 0000000000..0d1131f6a8 --- /dev/null +++ b/plugins/GSdx/vsprops/ssse3.props @@ -0,0 +1,11 @@ + + + <_PropertySheetDisplayName>sse3 + + + + StreamingSIMDExtensions2 + _M_SSE=0x301;%(PreprocessorDefinitions) + + + \ No newline at end of file diff --git a/plugins/GSdx/vsprops/ssse3.vsprops b/plugins/GSdx/vsprops/ssse3.vsprops index ac7fa1a064..fc76dac7f5 100644 --- a/plugins/GSdx/vsprops/ssse3.vsprops +++ b/plugins/GSdx/vsprops/ssse3.vsprops @@ -6,7 +6,11 @@ > + diff --git a/plugins/GSdx/xbyak/xbyak.h b/plugins/GSdx/xbyak/xbyak.h index 6282d9b4bd..564cca6262 100644 --- a/plugins/GSdx/xbyak/xbyak.h +++ b/plugins/GSdx/xbyak/xbyak.h @@ -62,7 +62,7 @@ enum { DEFAULT_MAX_CODE_SIZE = 2048, VERSION = 0x2070, /* 0xABCD = A.BC(D) */ }; - +/* #ifndef MIE_DEFINED_UINT32 #define MIE_DEFINED_UINT32 #ifdef _MSC_VER @@ -81,7 +81,7 @@ enum { #endif #endif #endif - +*/ enum Error { ERR_NONE = 0, ERR_BAD_ADDRESSING, diff --git a/plugins/GSnull/GS.cpp b/plugins/GSnull/GS.cpp new file mode 100644 index 0000000000..b524ce8349 --- /dev/null +++ b/plugins/GSnull/GS.cpp @@ -0,0 +1,259 @@ +/* GSnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#include +#include + +using namespace std; + +#include "GS.h" +#include "null/GSnull.h" + +const unsigned char version = PS2E_GS_VERSION; +const unsigned char revision = 0; +const unsigned char build = 1; // increase that with each version + +static char *libraryName = "GSnull Driver"; +FILE *gsLog; +Config conf; +u32 GSKeyEvent = 0; +bool GSShift = false, GSAlt = false; + +string s_strIniPath="inis/GSnull.ini"; +void (*GSirq)(); + +EXPORT_C_(u32) PS2EgetLibType() +{ + return PS2E_LT_GS; +} + +EXPORT_C_(char*) PS2EgetLibName() +{ + return libraryName; +} + +EXPORT_C_(u32) PS2EgetLibVersion2(u32 type) +{ + return (version<<16) | (revision<<8) | build; +} + +void __Log(char *fmt, ...) +{ + va_list list; + + if (!conf.Log || gsLog == NULL) return; + + va_start(list, fmt); + vfprintf(gsLog, fmt, list); + va_end(list); +} + +EXPORT_C_(void) GSprintf(int timeout, char *fmt, ...) +{ + va_list list; + char msg[512]; + + va_start(list, fmt); + vsprintf(msg, fmt, list); + va_end(list); + + GS_LOG("GSprintf:%s", msg); + printf("GSprintf:%s", msg); +} + +void SysPrintf(const char *fmt, ...) +{ + va_list list; + char msg[512]; + + va_start(list, fmt); + vsprintf(msg, fmt, list); + va_end(list); + + GS_LOG(msg); + printf("GSnull:%s", msg); +} + +// basic funcs + +EXPORT_C_(s32) GSinit() +{ + LoadConfig(); + +#ifdef GS_LOG + gsLog = fopen("logs/gsLog.txt", "w"); + if (gsLog) setvbuf(gsLog, NULL, _IONBF, 0); + GS_LOG("GSnull plugin version %d,%d\n",revision,build); + GS_LOG("GS init\n"); +#endif + + SysPrintf("Initializing GSnull\n"); + return 0; +} + +EXPORT_C_(void) GSshutdown() +{ +#ifdef GS_LOG + if (gsLog) fclose(gsLog); +#endif + + SysPrintf("Shutting down GSnull\n"); +} + +EXPORT_C_(s32) GSopen(void *pDsp, char *Title, int multithread) +{ + int err = 0; +#ifdef GS_LOG + GS_LOG("GS open\n"); +#endif + //assert( GSirq != NULL ); + + err = GSOpenWindow(pDsp, Title); + + SysPrintf("Opening GSnull\n"); + return err; +} + +EXPORT_C_(void) GSclose() +{ + SysPrintf("Closing GSnull\n"); + GSCloseWindow(); +} + +EXPORT_C_(void) GSirqCallback(void (*callback)()) +{ + GSirq = callback; +} + +EXPORT_C_(s32) GSfreeze(int mode, freezeData *data) +{ + return 0; +} + +EXPORT_C_(s32) GStest() +{ + SysPrintf("Testing GSnull\n"); + return 0; +} + +EXPORT_C_(void) GSvsync(int field) +{ + GSProcessMessages(); +} + +EXPORT_C_(void) GSgifTransfer1(u32 *pMem, u32 addr) +{ + _GSgifTransfer1(pMem, addr); +} + +EXPORT_C_(void) GSgifTransfer2(u32 *pMem, u32 size) +{ + _GSgifTransfer2(pMem, size); +} + +EXPORT_C_(void) GSgifTransfer3(u32 *pMem, u32 size) +{ + _GSgifTransfer3(pMem, size); +} + + // returns the last tag processed (64 bits) +EXPORT_C_(void) GSgetLastTag(u64* ptag) +{ +} + +EXPORT_C_(void) GSgifSoftReset(u32 mask) +{ + SysPrintf("Doing a soft reset of the GS plugin.\n"); +} + +EXPORT_C_(void) GSreadFIFO(u64 *mem) +{ +} + +EXPORT_C_(void) GSreadFIFO2(u64 *mem, int qwc) +{ +} + +// extended funcs + +// GSkeyEvent gets called when there is a keyEvent from the PAD plugin +EXPORT_C_(void) GSkeyEvent(keyEvent *ev) +{ + HandleKeyEvent(ev); +} + +EXPORT_C_(void) GSchangeSaveState(int, const char* filename) +{ +} + +EXPORT_C_(void) GSmakeSnapshot(char *path) +{ + + SysPrintf("Taking a snapshot.\n"); +} + +EXPORT_C_(void) GSmakeSnapshot2(char *pathname, int* snapdone, int savejpg) +{ + SysPrintf("Taking a snapshot to %s.\n", pathname); +} + +EXPORT_C_(void) GSsetBaseMem(void*) +{ +} + +EXPORT_C_(void) GSsetGameCRC(int crc, int gameoptions) +{ + SysPrintf("Setting the crc to '%x' with 0x%x for options.\n", crc, gameoptions); +} + +// controls frame skipping in the GS, if this routine isn't present, frame skipping won't be done +EXPORT_C_(void) GSsetFrameSkip(int frameskip) +{ + SysPrintf("Frameskip set to %d.\n", frameskip); +} + +// if start is 1, starts recording spu2 data, else stops +// returns a non zero value if successful +// for now, pData is not used +EXPORT_C_(int) GSsetupRecording(int start, void* pData) +{ + if (start) + SysPrintf("Pretending to record.\n"); + else + SysPrintf("Pretending to stop recording.\n"); + + return 1; +} + +EXPORT_C_(void) GSreset() +{ + SysPrintf("Doing a reset of the GS plugin."); +} + +EXPORT_C_(void) GSwriteCSR(u32 value) +{ +} + +EXPORT_C_(void) GSgetDriverInfo(GSdriverInfo *info) +{ +} diff --git a/plugins/GSnull/GS.h b/plugins/GSnull/GS.h new file mode 100644 index 0000000000..cd2dd0c071 --- /dev/null +++ b/plugins/GSnull/GS.h @@ -0,0 +1,77 @@ +/* GSnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __GS_H__ +#define __GS_H__ + +#include + +#ifdef _WIN32 +#include "Windows/GSwin.h" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif +#define GSdefs +#include "PS2Edefs.h" +#ifdef __cplusplus +} +#endif + +#ifdef __LINUX__ +#include "Linux/GSLinux.h" +#endif + +#include "GifTransfer.h" +#include "null/GSnull.h" + +/*#ifdef _MSC_VER +#define EXPORT_C_(type) extern "C" __declspec(dllexport) type CALLBACK +#else +#define EXPORT_C_(type) extern "C" type +#endif*/ + +#ifdef _MSC_VER +#define EXPORT_C_(type) extern "C" type CALLBACK +#else +#define EXPORT_C_(type) extern "C" type +#endif + +#define GS_LOG __Log + +typedef struct +{ + int Log; +} Config; + +extern Config conf; +extern FILE *gsLog; +extern u32 GSKeyEvent; +extern bool GSShift, GSAlt; + +extern void (*GSirq)(); + +extern void __Log(char *fmt, ...); +extern void SysMessage(char *fmt, ...); +extern void SysPrintf(const char *fmt, ...); +extern void SaveConfig(); +extern void LoadConfig(); + +#endif \ No newline at end of file diff --git a/plugins/GSnull/GifTransfer.cpp b/plugins/GSnull/GifTransfer.cpp new file mode 100644 index 0000000000..1d81988b07 --- /dev/null +++ b/plugins/GSnull/GifTransfer.cpp @@ -0,0 +1,261 @@ +/* GSnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + // Processes a GIFtag & packet, and throws out some gsIRQs as needed. +// Used to keep interrupts in sync with the EE, while the GS itself +// runs potentially several frames behind. +// size - size of the packet in simd128's + +#include "GS.h" +#include "GifTransfer.h" + +using namespace std; + +u32 CSRw; +GIFPath m_path[3]; +bool Path3transfer; + +PCSX2_ALIGNED16( u8 g_RealGSMem[0x2000] ); +#define GSCSRr *((u64*)(g_RealGSMem+0x1000)) +#define GSIMR *((u32*)(g_RealGSMem+0x1010)) +#define GSSIGLBLID ((GSRegSIGBLID*)(g_RealGSMem+0x1080)) + +static void RegHandlerSIGNAL(const u32* data) +{ + GSSIGLBLID->SIGID = (GSSIGLBLID->SIGID&~data[1])|(data[0]&data[1]); + + if ((CSRw & 0x1)) GSCSRr |= 1; // signal + + if (!(GSIMR & 0x100) ) GSirq(); +} + +static void RegHandlerFINISH(const u32* data) +{ + if ((CSRw & 0x2)) GSCSRr |= 2; // finish + + if (!(GSIMR & 0x200) ) GSirq(); + +} + +static void RegHandlerLABEL(const u32* data) +{ + GSSIGLBLID->LBLID = (GSSIGLBLID->LBLID&~data[1])|(data[0]&data[1]); +} + +typedef void (*GIFRegHandler)(const u32* data); +static GIFRegHandler s_GSHandlers[3] = +{ + RegHandlerSIGNAL, RegHandlerFINISH, RegHandlerLABEL +}; + +__forceinline void GIFPath::PrepRegs() +{ + if( tag.nreg == 0 ) + { + u32 tempreg = tag.regs[0]; + for(u32 i=0; i<16; ++i, tempreg >>= 4) + { + if( i == 8 ) tempreg = tag.regs[1]; + assert( (tempreg&0xf) < 0x64 ); + regs[i] = tempreg & 0xf; + } + } + else + { + u32 tempreg = tag.regs[0]; + for(u32 i=0; i>= 4) + { + assert( (tempreg&0xf) < 0x64 ); + regs[i] = tempreg & 0xf; + } + } +} + +void GIFPath::SetTag(const void* mem) +{ + tag = *((GIFTAG*)mem); + curreg = 0; + + PrepRegs(); +} + +u32 GIFPath::GetReg() +{ + return regs[curreg]; +} + +__forceinline bool GIFPath::StepReg() +{ + if ((++curreg & 0xf) == tag.nreg) + { + curreg = 0; + + if(--tag.nloop == 0) + { + return false; + } + } +} + +__forceinline u32 _gifTransfer( GIF_PATH pathidx, const u8* pMem, u32 size ) +{ GIFPath& path = m_path[pathidx]; + + while(size > 0) + { + if(path.tag.nloop == 0) + { + path.SetTag( pMem ); + + pMem += sizeof(GIFTAG); + --size; + + if(pathidx == 2 && path.tag.eop) + { + Path3transfer = FALSE; + } + + if( pathidx == 0 ) + { + // hack: if too much data for VU1, just ignore. + + // The GIF is evil : if nreg is 0, it's really 16. Otherwise it's the value in nreg. + const int numregs = ((path.tag.nreg-1)&15)+1; + + if((path.tag.nloop * numregs) > (size * ((path.tag.flg == 1) ? 2 : 1))) + { + path.tag.nloop = 0; + return ++size; + } + } + } + else + { + // NOTE: size > 0 => do {} while(size > 0); should be faster than while(size > 0) {} + + switch(path.tag.flg) + { + case GIF_FLG_PACKED: + + do + { + if( path.GetReg() == 0xe ) + { + const int handler = pMem[8]; + if(handler >= 0x60 && handler < 0x63) + s_GSHandlers[handler&0x3]((const u32*)pMem); + } + + size--; + pMem += 16; // 128 bits! //sizeof(GIFPackedReg); + } + while(path.StepReg() && size > 0); + + break; + + case GIF_FLG_REGLIST: + + size *= 2; + + do + { + const int handler = path.GetReg(); + if(handler >= 0x60 && handler < 0x63) + s_GSHandlers[handler&0x3]((const u32*)pMem); + + size--; + pMem += 8; //sizeof(GIFReg); -- 64 bits! + } + while(path.StepReg() && size > 0); + + if(size & 1) pMem += 8; //sizeof(GIFReg); + + size /= 2; + + break; + + case GIF_FLG_IMAGE2: // hmmm + assert(0); + path.tag.nloop = 0; + + break; + + case GIF_FLG_IMAGE: + { + int len = (int)min(size, path.tag.nloop); + + pMem += len * 16; + path.tag.nloop -= len; + size -= len; + } + break; + + jNO_DEFAULT; + + } + } + + if(pathidx == 0) + { + if(path.tag.eop && path.tag.nloop == 0) + { + break; + } + } + } + + if(pathidx == 0) + { + if(size == 0 && path.tag.nloop > 0) + { + path.tag.nloop = 0; + SysPrintf( "path1 hack! \n" ); + + // This means that the giftag data got screwly somewhere + // along the way (often means curreg was in a bad state or something) + } + } + + return size; +} + +// This currently segfaults in the beginning of KH1 if defined. +//#define DO_GIF_TRANSFERS + +void _GSgifTransfer1(u32 *pMem, u32 addr) +{ +#ifdef DO_GIF_TRANSFERS + /* This needs looking at, since I quickly grabbed it from ZeroGS. */ + addr &= 0x3fff; + _gifTransfer( GIF_PATH_1, ((u8*)pMem+(u8)addr), (0x4000-addr)/16); +#endif +} + +void _GSgifTransfer2(u32 *pMem, u32 size) +{ +#ifdef DO_GIF_TRANSFERS + _gifTransfer( GIF_PATH_2, (u8*)pMem, size); +#endif +} + +void _GSgifTransfer3(u32 *pMem, u32 size) +{ +#ifdef DO_GIF_TRANSFERS + _gifTransfer( GIF_PATH_3, (u8*)pMem, size); +#endif +} + diff --git a/plugins/GSnull/GifTransfer.h b/plugins/GSnull/GifTransfer.h new file mode 100644 index 0000000000..0e16a99d62 --- /dev/null +++ b/plugins/GSnull/GifTransfer.h @@ -0,0 +1,98 @@ +/* GSnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + #ifndef __GIF_TRANSFER_H__ + #define __GIF_TRANSFER_H__ + +#include +#include + + struct GSRegSIGBLID +{ + u32 SIGID; + u32 LBLID; +}; + +enum GIF_FLG +{ + GIF_FLG_PACKED = 0, + GIF_FLG_REGLIST = 1, + GIF_FLG_IMAGE = 2, + GIF_FLG_IMAGE2 = 3 +}; + +enum GIF_PATH +{ + GIF_PATH_1 = 0, + GIF_PATH_2, + GIF_PATH_3, +}; + +enum GIF_REG +{ + GIF_REG_PRIM = 0x00, + GIF_REG_RGBA = 0x01, + GIF_REG_STQ = 0x02, + GIF_REG_UV = 0x03, + GIF_REG_XYZF2 = 0x04, + GIF_REG_XYZ2 = 0x05, + GIF_REG_TEX0_1 = 0x06, + GIF_REG_TEX0_2 = 0x07, + GIF_REG_CLAMP_1 = 0x08, + GIF_REG_CLAMP_2 = 0x09, + GIF_REG_FOG = 0x0a, + GIF_REG_XYZF3 = 0x0c, + GIF_REG_XYZ3 = 0x0d, + GIF_REG_A_D = 0x0e, + GIF_REG_NOP = 0x0f, +}; + +struct GIFTAG +{ + u32 nloop : 15; + u32 eop : 1; + u32 dummy0 : 16; + u32 dummy1 : 14; + u32 pre : 1; + u32 prim : 11; + u32 flg : 2; + u32 nreg : 4; + u32 regs[2]; +}; + +struct GIFPath +{ + GIFTAG tag; + u32 curreg; + u32 _pad[3]; + u8 regs[16]; + + __forceinline void PrepRegs(); + void SetTag(const void* mem); + u32 GetReg(); + __forceinline bool StepReg(); +}; + +extern GIFPath m_path[3]; +extern bool Path3transfer; + +extern void _GSgifTransfer1(u32 *pMem, u32 addr); +extern void _GSgifTransfer2(u32 *pMem, u32 size); +extern void _GSgifTransfer3(u32 *pMem, u32 size); + +#endif diff --git a/plugins/GSnull/License.txt b/plugins/GSnull/License.txt new file mode 100644 index 0000000000..7d1f8605f8 --- /dev/null +++ b/plugins/GSnull/License.txt @@ -0,0 +1,342 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + + diff --git a/plugins/GSnull/Linux/Config.cpp b/plugins/GSnull/Linux/Config.cpp new file mode 100644 index 0000000000..d292f5748f --- /dev/null +++ b/plugins/GSnull/Linux/Config.cpp @@ -0,0 +1,171 @@ +/* GSnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#include "GS.h" +#include "Config.h" + + #ifdef __cplusplus +extern "C" +{ +#endif + +#include "support.h" +#include "callbacks.h" +#include "interface.h" + +#ifdef __cplusplus +} +#endif + +GtkWidget *MsgDlg, *About, *Conf; +extern string s_strIniPath; + +void OnMsg_Ok() +{ + gtk_widget_destroy(MsgDlg); + gtk_main_quit(); +} + +void cfgSysMessage(char *fmt, ...) +{ + GtkWidget *Ok,*Txt; + GtkWidget *Box,*Box1; + va_list list; + char msg[512]; + + va_start(list, fmt); + vsprintf(msg, fmt, list); + va_end(list); + + if (msg[strlen(msg) - 1] == '\n') msg[strlen(msg)-1] = 0; + + MsgDlg = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER); + gtk_window_set_title(GTK_WINDOW(MsgDlg), "FireWire Msg"); + gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 5); + + Box = gtk_vbox_new(5, 0); + gtk_container_add(GTK_CONTAINER(MsgDlg), Box); + gtk_widget_show(Box); + + Txt = gtk_label_new(msg); + + gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5); + gtk_widget_show(Txt); + + Box1 = gtk_hbutton_box_new(); + gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0); + gtk_widget_show(Box1); + + Ok = gtk_button_new_with_label("Ok"); + gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsg_Ok), NULL); + gtk_container_add(GTK_CONTAINER(Box1), Ok); + GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT); + gtk_widget_show(Ok); + + gtk_widget_show(MsgDlg); + + gtk_main(); +} + +void OnAbout_Ok(GtkButton *button, gpointer user_data) +{ + gtk_widget_destroy(About); + gtk_main_quit(); +} + +void CFGabout() +{ + About = create_About(); + gtk_widget_show_all(About); + gtk_main(); +} + +void OnConf_Ok(GtkButton *button, gpointer user_data) { + SaveConfig(); + + gtk_widget_destroy(Conf); + gtk_main_quit(); +} + +void OnConf_Cancel(GtkButton *button, gpointer user_data) +{ + gtk_widget_destroy(Conf); + gtk_main_quit(); +} + +void CFGconfigure() +{ + Conf = create_Config(); + + LoadConfig(); + + gtk_widget_show_all(Conf); + gtk_main(); +} + +long CFGmessage(char *msg) { + cfgSysMessage(msg); + + return 0; +} + +void LoadConfig() +{ + FILE *f; + char cfg[255]; + + strcpy(cfg, s_strIniPath.c_str()); + f = fopen(cfg, "r"); + if (f == NULL) + { + printf("failed to open %s\n", s_strIniPath.c_str()); + SaveConfig();//save and return + return; + } + //fscanf(f, "options = %hhx\n", &confOptions); + fclose(f); +} + +void SaveConfig() +{ + FILE *f; + char cfg[255]; + + strcpy(cfg, s_strIniPath.c_str()); + f = fopen(cfg,"w"); + if (f == NULL) + { + printf("failed to open %s\n", s_strIniPath.c_str()); + return; + } + + //fprintf(f, "options = %hhx\n", confOptions); + fclose(f); +} + diff --git a/plugins/GSnull/Linux/Config.h b/plugins/GSnull/Linux/Config.h new file mode 100644 index 0000000000..fca002d5be --- /dev/null +++ b/plugins/GSnull/Linux/Config.h @@ -0,0 +1,25 @@ +/* GSnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +void SaveConf(); +void LoadConf(); + +extern long CFGmessage(char *msg); +extern void CFGconfigure(); +extern void cfgSysMessage(char *fmt, ...); +extern void CFGabout(); diff --git a/plugins/GSnull/Linux/GSLinux.cpp b/plugins/GSnull/Linux/GSLinux.cpp new file mode 100644 index 0000000000..67385d2bc3 --- /dev/null +++ b/plugins/GSnull/Linux/GSLinux.cpp @@ -0,0 +1,108 @@ +/* GSnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "GS.h" +#include "GSLinux.h" + +Display *display; +int screen; + +int GSOpenWindow(void *pDsp, char *Title) +{ + display = XOpenDisplay(0); + screen = DefaultScreen(display); + + if( pDsp != NULL ) + *(Display**)pDsp = display; + else + return -1; + + return 0; +} + +void GSCloseWindow() +{ + XCloseDisplay(display); +} + +void GSProcessMessages() +{ + if ( GSKeyEvent ) + { + int myKeyEvent = GSKeyEvent; + bool myShift = GSShift; + GSKeyEvent = 0; + + switch ( myKeyEvent ) + { + case XK_F5: + OnKeyboardF5(myShift); + break; + case XK_F6: + OnKeyboardF6(myShift); + break; + case XK_F7: + OnKeyboardF7(myShift); + break; + case XK_F9: + OnKeyboardF9(myShift); + break; + } + } +} + + +void HandleKeyEvent(keyEvent *ev) +{ + switch(ev->evt) + { + case KEYPRESS: + switch(ev->key) + { + case XK_F5: + case XK_F6: + case XK_F7: + case XK_F9: + GSKeyEvent = ev->key ; + break; + case XK_Escape: + break; + case XK_Shift_L: + case XK_Shift_R: + GSShift = true; + break; + case XK_Alt_L: + case XK_Alt_R: + GSAlt = true; + break; + } + break; + case KEYRELEASE: + switch(ev->key) + { + case XK_Shift_L: + case XK_Shift_R: + GSShift = false; + break; + case XK_Alt_L: + case XK_Alt_R: + GSAlt = false; + break; + } + } +} diff --git a/plugins/GSnull/Linux/GSLinux.h b/plugins/GSnull/Linux/GSLinux.h new file mode 100644 index 0000000000..d4f1303a9b --- /dev/null +++ b/plugins/GSnull/Linux/GSLinux.h @@ -0,0 +1,33 @@ +/* GSnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __GSLINUX_H__ +#define __GSLINUX_H__ + +#include +#include +#include + +#include "GS.h" + +extern int GSOpenWindow(void *pDsp, char *Title); +extern void GSCloseWindow(); +extern void GSProcessMessages(); +extern void HandleKeyEvent(keyEvent *ev); + +#endif diff --git a/plugins/FWnull/Linux/Linux.cpp b/plugins/GSnull/Linux/Linux.cpp similarity index 94% rename from plugins/FWnull/Linux/Linux.cpp rename to plugins/GSnull/Linux/Linux.cpp index 626584ce52..7bbd963ccf 100644 --- a/plugins/FWnull/Linux/Linux.cpp +++ b/plugins/GSnull/Linux/Linux.cpp @@ -1,4 +1,4 @@ -/* FWnull +/* GSnull * Copyright (C) 2004-2009 PCSX2 Team * * This program is free software; you can redistribute it and/or modify @@ -25,7 +25,7 @@ #include #include -#include "FW.h" +#include "GS.h" #include "Config.h" void SysMessage(char *fmt, ...) @@ -41,12 +41,12 @@ void SysMessage(char *fmt, ...) cfgSysMessage(msg); } -void FWconfigure() +void GSconfigure() { CFGconfigure(); } -void FWabout() +void GSabout() { CFGabout(); } diff --git a/plugins/FWnull/Linux/Linux.h b/plugins/GSnull/Linux/Linux.h similarity index 98% rename from plugins/FWnull/Linux/Linux.h rename to plugins/GSnull/Linux/Linux.h index ed6cd2d1cb..65cf4eac58 100644 --- a/plugins/FWnull/Linux/Linux.h +++ b/plugins/GSnull/Linux/Linux.h @@ -1,4 +1,4 @@ -/* FWnull +/* GSnull * Copyright (C) 2004-2009 PCSX2 Team * * This program is free software; you can redistribute it and/or modify diff --git a/plugins/GSnull/Linux/callbacks.c b/plugins/GSnull/Linux/callbacks.c new file mode 100644 index 0000000000..e87ed8be2d --- /dev/null +++ b/plugins/GSnull/Linux/callbacks.c @@ -0,0 +1,34 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + + +void +OnConf_Ok (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConf_Cancel (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnAbout_Ok (GtkButton *button, + gpointer user_data) +{ + +} + diff --git a/plugins/GSnull/Linux/callbacks.h b/plugins/GSnull/Linux/callbacks.h new file mode 100644 index 0000000000..e606c242f0 --- /dev/null +++ b/plugins/GSnull/Linux/callbacks.h @@ -0,0 +1,14 @@ +#include + + +void +OnConf_Ok (GtkButton *button, + gpointer user_data); + +void +OnConf_Cancel (GtkButton *button, + gpointer user_data); + +void +OnAbout_Ok (GtkButton *button, + gpointer user_data); diff --git a/plugins/GSnull/Linux/gsnull.glade b/plugins/GSnull/Linux/gsnull.glade new file mode 100644 index 0000000000..cef4eab65e --- /dev/null +++ b/plugins/GSnull/Linux/gsnull.glade @@ -0,0 +1,443 @@ + + + + + + + 5 + True + DEV9config + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + 5 + True + False + 5 + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + 5 + True + True + 5 + + + + True + Device: + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + True + False + True + False + + + + True + True + True + True + 0 + + True + * + False + + + + + + True + GTK_SELECTION_BROWSE + + + + True + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + + + + + 0 + False + False + + + + + + + + True + Ethernet + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + 5 + True + True + 5 + + + + True + Device: + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + True + False + True + False + + + + True + True + True + True + 0 + + True + * + False + + + + + + True + GTK_SELECTION_BROWSE + + + + True + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + + + + + 0 + False + False + + + + + + + + True + Hdd + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + True + GTK_BUTTONBOX_DEFAULT_STYLE + 30 + + + + True + True + True + Ok + True + GTK_RELIEF_NORMAL + True + + + + + + + True + True + True + Cancel + True + GTK_RELIEF_NORMAL + True + + + + + + 0 + True + True + + + + + + + + 5 + True + DEV9about + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + 5 + True + False + 5 + + + + True + FireWire Driver + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + Author: linuzappz <linuzappz@hotmail.com> + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + GTK_BUTTONBOX_DEFAULT_STYLE + 30 + + + + True + True + True + Ok + True + GTK_RELIEF_NORMAL + True + + + + + + 0 + True + True + + + + + + + diff --git a/plugins/GSnull/Linux/interface.c b/plugins/GSnull/Linux/interface.c new file mode 100644 index 0000000000..5c23358a21 --- /dev/null +++ b/plugins/GSnull/Linux/interface.c @@ -0,0 +1,240 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ + g_object_set_data (G_OBJECT (component), name, widget) + +GtkWidget* +create_Config (void) +{ + GtkWidget *Config; + GtkWidget *vbox1; + GtkWidget *frame2; + GtkWidget *hbox1; + GtkWidget *label4; + GtkWidget *GtkCombo_Eth; + GList *GtkCombo_Eth_items = NULL; + GtkWidget *combo_entry1; + GtkWidget *label1; + GtkWidget *frame3; + GtkWidget *hbox2; + GtkWidget *label5; + GtkWidget *GtkCombo_Hdd; + GList *GtkCombo_Hdd_items = NULL; + GtkWidget *entry1; + GtkWidget *label15; + GtkWidget *hbuttonbox1; + GtkWidget *button1; + GtkWidget *button2; + + Config = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (Config, "Config"); + gtk_container_set_border_width (GTK_CONTAINER (Config), 5); + gtk_window_set_title (GTK_WINDOW (Config), _("DEV9config")); + + vbox1 = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (vbox1, "vbox1"); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (Config), vbox1); + gtk_container_set_border_width (GTK_CONTAINER (vbox1), 5); + + frame2 = gtk_frame_new (NULL); + gtk_widget_set_name (frame2, "frame2"); + gtk_widget_show (frame2); + gtk_box_pack_start (GTK_BOX (vbox1), frame2, TRUE, TRUE, 0); + + hbox1 = gtk_hbox_new (TRUE, 5); + gtk_widget_set_name (hbox1, "hbox1"); + gtk_widget_show (hbox1); + gtk_container_add (GTK_CONTAINER (frame2), hbox1); + gtk_container_set_border_width (GTK_CONTAINER (hbox1), 5); + + label4 = gtk_label_new (_("Device:")); + gtk_widget_set_name (label4, "label4"); + gtk_widget_show (label4); + gtk_box_pack_start (GTK_BOX (hbox1), label4, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label4), GTK_JUSTIFY_CENTER); + + GtkCombo_Eth = gtk_combo_new (); + g_object_set_data (G_OBJECT (GTK_COMBO (GtkCombo_Eth)->popwin), + "GladeParentKey", GtkCombo_Eth); + gtk_widget_set_name (GtkCombo_Eth, "GtkCombo_Eth"); + gtk_widget_show (GtkCombo_Eth); + gtk_box_pack_start (GTK_BOX (hbox1), GtkCombo_Eth, FALSE, FALSE, 0); + GtkCombo_Eth_items = g_list_append (GtkCombo_Eth_items, (gpointer) ""); + gtk_combo_set_popdown_strings (GTK_COMBO (GtkCombo_Eth), GtkCombo_Eth_items); + g_list_free (GtkCombo_Eth_items); + + combo_entry1 = GTK_COMBO (GtkCombo_Eth)->entry; + gtk_widget_set_name (combo_entry1, "combo_entry1"); + gtk_widget_show (combo_entry1); + + label1 = gtk_label_new (_("Ethernet")); + gtk_widget_set_name (label1, "label1"); + gtk_widget_show (label1); + gtk_frame_set_label_widget (GTK_FRAME (frame2), label1); + + frame3 = gtk_frame_new (NULL); + gtk_widget_set_name (frame3, "frame3"); + gtk_widget_show (frame3); + gtk_box_pack_start (GTK_BOX (vbox1), frame3, TRUE, TRUE, 0); + + hbox2 = gtk_hbox_new (TRUE, 5); + gtk_widget_set_name (hbox2, "hbox2"); + gtk_widget_show (hbox2); + gtk_container_add (GTK_CONTAINER (frame3), hbox2); + gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5); + + label5 = gtk_label_new (_("Device:")); + gtk_widget_set_name (label5, "label5"); + gtk_widget_show (label5); + gtk_box_pack_start (GTK_BOX (hbox2), label5, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label5), GTK_JUSTIFY_CENTER); + + GtkCombo_Hdd = gtk_combo_new (); + g_object_set_data (G_OBJECT (GTK_COMBO (GtkCombo_Hdd)->popwin), + "GladeParentKey", GtkCombo_Hdd); + gtk_widget_set_name (GtkCombo_Hdd, "GtkCombo_Hdd"); + gtk_widget_show (GtkCombo_Hdd); + gtk_box_pack_start (GTK_BOX (hbox2), GtkCombo_Hdd, FALSE, FALSE, 0); + GtkCombo_Hdd_items = g_list_append (GtkCombo_Hdd_items, (gpointer) ""); + gtk_combo_set_popdown_strings (GTK_COMBO (GtkCombo_Hdd), GtkCombo_Hdd_items); + g_list_free (GtkCombo_Hdd_items); + + entry1 = GTK_COMBO (GtkCombo_Hdd)->entry; + gtk_widget_set_name (entry1, "entry1"); + gtk_widget_show (entry1); + + label15 = gtk_label_new (_("Hdd")); + gtk_widget_set_name (label15, "label15"); + gtk_widget_show (label15); + gtk_frame_set_label_widget (GTK_FRAME (frame3), label15); + + hbuttonbox1 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox1, "hbuttonbox1"); + gtk_widget_show (hbuttonbox1); + gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, TRUE, TRUE, 0); + gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 30); + + button1 = gtk_button_new_with_mnemonic (_("Ok")); + gtk_widget_set_name (button1, "button1"); + gtk_widget_show (button1); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), button1); + GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); + + button2 = gtk_button_new_with_mnemonic (_("Cancel")); + gtk_widget_set_name (button2, "button2"); + gtk_widget_show (button2); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), button2); + GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) button1, "clicked", + G_CALLBACK (OnConf_Ok), + NULL); + g_signal_connect ((gpointer) button2, "clicked", + G_CALLBACK (OnConf_Cancel), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (Config, Config, "Config"); + GLADE_HOOKUP_OBJECT (Config, vbox1, "vbox1"); + GLADE_HOOKUP_OBJECT (Config, frame2, "frame2"); + GLADE_HOOKUP_OBJECT (Config, hbox1, "hbox1"); + GLADE_HOOKUP_OBJECT (Config, label4, "label4"); + GLADE_HOOKUP_OBJECT (Config, GtkCombo_Eth, "GtkCombo_Eth"); + GLADE_HOOKUP_OBJECT (Config, combo_entry1, "combo_entry1"); + GLADE_HOOKUP_OBJECT (Config, label1, "label1"); + GLADE_HOOKUP_OBJECT (Config, frame3, "frame3"); + GLADE_HOOKUP_OBJECT (Config, hbox2, "hbox2"); + GLADE_HOOKUP_OBJECT (Config, label5, "label5"); + GLADE_HOOKUP_OBJECT (Config, GtkCombo_Hdd, "GtkCombo_Hdd"); + GLADE_HOOKUP_OBJECT (Config, entry1, "entry1"); + GLADE_HOOKUP_OBJECT (Config, label15, "label15"); + GLADE_HOOKUP_OBJECT (Config, hbuttonbox1, "hbuttonbox1"); + GLADE_HOOKUP_OBJECT (Config, button1, "button1"); + GLADE_HOOKUP_OBJECT (Config, button2, "button2"); + + return Config; +} + +GtkWidget* +create_About (void) +{ + GtkWidget *About; + GtkWidget *vbox2; + GtkWidget *label2; + GtkWidget *label3; + GtkWidget *hbuttonbox2; + GtkWidget *button3; + + About = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (About, "About"); + gtk_container_set_border_width (GTK_CONTAINER (About), 5); + gtk_window_set_title (GTK_WINDOW (About), _("DEV9about")); + + vbox2 = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (vbox2, "vbox2"); + gtk_widget_show (vbox2); + gtk_container_add (GTK_CONTAINER (About), vbox2); + gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5); + + label2 = gtk_label_new (_("FireWire Driver")); + gtk_widget_set_name (label2, "label2"); + gtk_widget_show (label2); + gtk_box_pack_start (GTK_BOX (vbox2), label2, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER); + + label3 = gtk_label_new (_("Author: linuzappz ")); + gtk_widget_set_name (label3, "label3"); + gtk_widget_show (label3); + gtk_box_pack_start (GTK_BOX (vbox2), label3, FALSE, FALSE, 0); + + hbuttonbox2 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox2, "hbuttonbox2"); + gtk_widget_show (hbuttonbox2); + gtk_box_pack_start (GTK_BOX (vbox2), hbuttonbox2, TRUE, TRUE, 0); + gtk_box_set_spacing (GTK_BOX (hbuttonbox2), 30); + + button3 = gtk_button_new_with_mnemonic (_("Ok")); + gtk_widget_set_name (button3, "button3"); + gtk_widget_show (button3); + gtk_container_add (GTK_CONTAINER (hbuttonbox2), button3); + GTK_WIDGET_SET_FLAGS (button3, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) button3, "clicked", + G_CALLBACK (OnAbout_Ok), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (About, About, "About"); + GLADE_HOOKUP_OBJECT (About, vbox2, "vbox2"); + GLADE_HOOKUP_OBJECT (About, label2, "label2"); + GLADE_HOOKUP_OBJECT (About, label3, "label3"); + GLADE_HOOKUP_OBJECT (About, hbuttonbox2, "hbuttonbox2"); + GLADE_HOOKUP_OBJECT (About, button3, "button3"); + + return About; +} + diff --git a/plugins/GSnull/Linux/interface.h b/plugins/GSnull/Linux/interface.h new file mode 100644 index 0000000000..69c303ba3b --- /dev/null +++ b/plugins/GSnull/Linux/interface.h @@ -0,0 +1,6 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +GtkWidget* create_Config (void); +GtkWidget* create_About (void); diff --git a/plugins/GSnull/Linux/support.c b/plugins/GSnull/Linux/support.c new file mode 100644 index 0000000000..00aff29822 --- /dev/null +++ b/plugins/GSnull/Linux/support.c @@ -0,0 +1,144 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include + +#include "support.h" + +GtkWidget* +lookup_widget (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (!parent) + parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + +static GList *pixmaps_directories = NULL; + +/* Use this function to set the directory containing installed pixmaps. */ +void +add_pixmap_directory (const gchar *directory) +{ + pixmaps_directories = g_list_prepend (pixmaps_directories, + g_strdup (directory)); +} + +/* This is an internally used function to find pixmap files. */ +static gchar* +find_pixmap_file (const gchar *filename) +{ + GList *elem; + + /* We step through each of the pixmaps directory to find it. */ + elem = pixmaps_directories; + while (elem) + { + gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data, + G_DIR_SEPARATOR_S, filename); + if (g_file_test (pathname, G_FILE_TEST_EXISTS)) + return pathname; + g_free (pathname); + elem = elem->next; + } + return NULL; +} + +/* This is an internally used function to create pixmaps. */ +GtkWidget* +create_pixmap (GtkWidget *widget, + const gchar *filename) +{ + gchar *pathname = NULL; + GtkWidget *pixmap; + + if (!filename || !filename[0]) + return gtk_image_new (); + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return gtk_image_new (); + } + + pixmap = gtk_image_new_from_file (pathname); + g_free (pathname); + return pixmap; +} + +/* This is an internally used function to create pixmaps. */ +GdkPixbuf* +create_pixbuf (const gchar *filename) +{ + gchar *pathname = NULL; + GdkPixbuf *pixbuf; + GError *error = NULL; + + if (!filename || !filename[0]) + return NULL; + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return NULL; + } + + pixbuf = gdk_pixbuf_new_from_file (pathname, &error); + if (!pixbuf) + { + fprintf (stderr, "Failed to load pixbuf file: %s: %s\n", + pathname, error->message); + g_error_free (error); + } + g_free (pathname); + return pixbuf; +} + +/* This is used to set ATK action descriptions. */ +void +glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description) +{ + gint n_actions, i; + + n_actions = atk_action_get_n_actions (action); + for (i = 0; i < n_actions; i++) + { + if (!strcmp (atk_action_get_name (action, i), action_name)) + atk_action_set_description (action, i, description); + } +} + diff --git a/plugins/GSnull/Linux/support.h b/plugins/GSnull/Linux/support.h new file mode 100644 index 0000000000..a32649e53c --- /dev/null +++ b/plugins/GSnull/Linux/support.h @@ -0,0 +1,69 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* + * Standard gettext macros. + */ +#ifdef ENABLE_NLS +# include +# undef _ +# define _(String) dgettext (PACKAGE, String) +# define Q_(String) g_strip_context ((String), gettext (String)) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define Q_(String) g_strip_context ((String), (String)) +# define N_(String) (String) +#endif + + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* lookup_widget (GtkWidget *widget, + const gchar *widget_name); + + +/* Use this function to set the directory containing installed pixmaps. */ +void add_pixmap_directory (const gchar *directory); + + +/* + * Private Functions. + */ + +/* This is used to create the pixmaps used in the interface. */ +GtkWidget* create_pixmap (GtkWidget *widget, + const gchar *filename); + +/* This is used to create the pixbufs used in the interface. */ +GdkPixbuf* create_pixbuf (const gchar *filename); + +/* This is used to set ATK action descriptions. */ +void glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description); + diff --git a/plugins/GSnull/Makefile.am b/plugins/GSnull/Makefile.am new file mode 100644 index 0000000000..1e86125335 --- /dev/null +++ b/plugins/GSnull/Makefile.am @@ -0,0 +1,35 @@ +# Create a shared library libGSnull +AUTOMAKE_OPTIONS = foreign +noinst_LIBRARIES = libGSnull.a +INCLUDES = -I@srcdir@/../../common/include -I@srcdir@/../../3rdparty -I@srcdir@/Linux -I@srcdir@/null + +libGSnull_a_CXXFLAGS = $(shell pkg-config --cflags gtk+-2.0) +libGSnull_a_CFLAGS = $(shell pkg-config --cflags gtk+-2.0) + +# Create a shared object by faking an exe (thanks to ODE makefiles) +traplibdir=$(prefix) + +if DEBUGBUILD +preext=d +endif + +EXEEXT=$(preext)@so_ext@ + +traplib_PROGRAMS=libGSnull +libGSnull_SOURCES= +libGSnull_DEPENDENCIES = libGSnull.a +libGSnull_LDFLAGS= @SHARED_LDFLAGS@ +libGSnull_LDFLAGS+=-Wl,-soname,@libGSnull_SONAME@ +libGSnull_LDADD=$(libGSnull_a_OBJECTS) + +libGSnull_a_SOURCES = \ +GS.cpp \ +Linux/Config.cpp Linux/Linux.cpp Linux/GSLinux.cpp \ +Linux/GSLinux.h Linux/Config.h Linux/Linux.h \ +GifTransfer.cpp GifTransfer.h \ +null/GSnull.cpp null/GSnull.h + +libGSnull_a_SOURCES += \ +Linux/interface.h Linux/support.c \ +Linux/interface.c Linux/support.h \ +Linux/callbacks.h \ No newline at end of file diff --git a/plugins/GSnull/ReadMe.txt b/plugins/GSnull/ReadMe.txt new file mode 100644 index 0000000000..28bf61f48a --- /dev/null +++ b/plugins/GSnull/ReadMe.txt @@ -0,0 +1,28 @@ +GSnull v0.1 +------------- + + This is an extension to use with play station2 emulators + as PCSX2 (only one right now). + The plugin is free open source code. + + Usage: + ----- + Place the file "GSnull.so.x.x.x" (linux) or "GSnull.dll" (win32) + at the Plugin directory of the Emulator to use it. + + Changes: + ------- + + v0.1: +* First Release +* Tested with Pcsx2 +* Based off of FWnull. +* Currently Linux only. This may change. + + Authors: + ------- +arcum42 + +based off work by: + shadow + linuzappz diff --git a/plugins/GSnull/Windows/Config.cpp b/plugins/GSnull/Windows/Config.cpp new file mode 100644 index 0000000000..593766f613 --- /dev/null +++ b/plugins/GSnull/Windows/Config.cpp @@ -0,0 +1,51 @@ +#include + +#include "../GS.h" + +extern HINSTANCE hInst; +void SaveConfig() +{ + + Config *Conf1 = &conf; + char *szTemp; + char szIniFile[256], szValue[256]; + + GetModuleFileName(GetModuleHandle((LPCSTR)hInst), szIniFile, 256); + szTemp = strrchr(szIniFile, '\\'); + + if(!szTemp) return; + strcpy(szTemp, "\\inis\\gsnull.ini"); + sprintf(szValue,"%u",Conf1->Log); + WritePrivateProfileString("Interface", "Logging",szValue,szIniFile); + +} + +void LoadConfig() { + FILE *fp; + + + Config *Conf1 = &conf; + char *szTemp; + char szIniFile[256], szValue[256]; + + GetModuleFileName(GetModuleHandle((LPCSTR)hInst), szIniFile, 256); + szTemp = strrchr(szIniFile, '\\'); + + if(!szTemp) return ; + strcpy(szTemp, "\\inis\\gsnull.ini"); + fp=fopen("inis\\gsnull.ini","rt");//check if gsnull.ini really exists + if (!fp) + { + CreateDirectory("inis",NULL); + memset(&conf, 0, sizeof(conf)); + conf.Log = 0;//default value + SaveConfig();//save and return + return ; + } + fclose(fp); + GetPrivateProfileString("Interface", "Logging", NULL, szValue, 20, szIniFile); + Conf1->Log = strtoul(szValue, NULL, 10); + return ; + +} + diff --git a/plugins/GSnull/Windows/GS.def b/plugins/GSnull/Windows/GS.def new file mode 100644 index 0000000000..d71a22d69d --- /dev/null +++ b/plugins/GSnull/Windows/GS.def @@ -0,0 +1,41 @@ +; FireWire.def : Declares the module parameters for the DLL. + +LIBRARY "FWnull" + +EXPORTS + ; Explicit exports can go here + PS2EgetLibType @2 + PS2EgetLibName @3 + PS2EgetLibVersion2 @4 + GSinit @5 + GSopen @6 + GSclose @7 + GSshutdown @8 + GSvsync @9 + GSgifTransfer1 @10 + GSgifTransfer2 @11 + GSgifTransfer3 @12 + GSgetLastTag @13 + GSgifSoftReset @14 + GSreadFIFO @15 + GSreadFIFO2 @16 + GSkeyEvent @17 + GSchangeSaveState @18 + GSmakeSnapshot @19 + GSmakeSnapshot2 @20 + GSirqCallback @21 + GSprintf @22 + GSsetBaseMem @23 + GSsetGameCRC @24 + GSsetFrameSkip @25 + GSsetupRecording @26 + GSreset @27 + GSwriteCSR @28 + GSgetDriverInfo @29 + GSsetWindowInfo @30 + GSfreeze @31 + GSconfigure @32 + GSabout @33 + GStest @34 + + diff --git a/plugins/GSnull/Windows/GS.rc b/plugins/GSnull/Windows/GS.rc new file mode 100644 index 0000000000..a505f6108d --- /dev/null +++ b/plugins/GSnull/Windows/GS.rc @@ -0,0 +1,116 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxresmw.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Spanish (Argentina) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESS) +#ifdef _WIN32 +LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_ARGENTINA +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxresmw.h""\r\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_CONFIG DIALOGEX 0, 0, 212, 121 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Firewireconfigure" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "OK",IDOK,48,100,50,14 + PUSHBUTTON "Cancel",IDCANCEL,113,100,50,14 + CONTROL "Enable Logging (for develop use only)",IDC_LOGGING, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,187,13 +END + +IDD_ABOUT DIALOGEX 0, 0, 177, 106 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "FireWire About" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "OK",IDOK,65,85,50,14 + LTEXT "FireWire Driver",IDC_NAME,70,10,48,8 + GROUPBOX "",IDC_STATIC,5,35,170,40 + LTEXT "Author: Shadow and linuzappz",IDC_STATIC,29,19,141,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_CONFIG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 205 + TOPMARGIN, 7 + BOTTOMMARGIN, 114 + END + + IDD_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 170 + TOPMARGIN, 7 + BOTTOMMARGIN, 99 + END +END +#endif // APSTUDIO_INVOKED + +#endif // Spanish (Argentina) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/GSnull/Windows/GSnull_vc2008.sln b/plugins/GSnull/Windows/GSnull_vc2008.sln new file mode 100644 index 0000000000..cbdf517657 --- /dev/null +++ b/plugins/GSnull/Windows/GSnull_vc2008.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GSnull", "GSnull_vc2008.vcproj", "{3D0EB14D-32F3-4D82-9C6D-B806ADBB859C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3D0EB14D-32F3-4D82-9C6D-B806ADBB859C}.Debug|Win32.ActiveCfg = Debug|Win32 + {3D0EB14D-32F3-4D82-9C6D-B806ADBB859C}.Debug|Win32.Build.0 = Debug|Win32 + {3D0EB14D-32F3-4D82-9C6D-B806ADBB859C}.Release|Win32.ActiveCfg = Release|Win32 + {3D0EB14D-32F3-4D82-9C6D-B806ADBB859C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/plugins/GSnull/Windows/GSnull_vc2008.vcproj b/plugins/GSnull/Windows/GSnull_vc2008.vcproj new file mode 100644 index 0000000000..dbf04367b1 --- /dev/null +++ b/plugins/GSnull/Windows/GSnull_vc2008.vcproj @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/GSnull/Windows/GSwin.cpp b/plugins/GSnull/Windows/GSwin.cpp new file mode 100644 index 0000000000..fa3c66a335 --- /dev/null +++ b/plugins/GSnull/Windows/GSwin.cpp @@ -0,0 +1,77 @@ +/* GSnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "GSwin.h" + +HINSTANCE HInst; +HWND GShwnd; + +LRESULT CALLBACK MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_CLOSE: + DestroyWindow(hwnd); + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + default: + return DefWindowProc(hwnd, msg, wParam, lParam); + } + return 0; +} + +int GSOpenWindow(void *pDsp, char *Title) +{ + WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, + GetModuleHandle(NULL), NULL, NULL, NULL, NULL, + "PS2EMU_GSNULL", NULL }; + RegisterClassEx( &wc ); + + GShwnd = CreateWindowEx( WS_EX_CLIENTEDGE, "PS2EMU_GSNULL", Title, + WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, wc.hInstance, NULL); + + if(GShwnd == NULL) + { + GS_LOG("Failed to create window. Exiting..."); + return -1; + } + + if( pDsp != NULL ) *(int*)pDsp = (int)GShwnd; + + return 0; +} + +void GSCloseWindow() +{ +} + +void GSProcessMessages() +{ +} + +// GSkeyEvent gets called when there is a keyEvent from the PAD plugin +void HandleKeyEvent(keyEvent *ev) +{ +} + +EXPORT_C_(s32) GSsetWindowInfo(winInfo *info) +{ + return 0; +} \ No newline at end of file diff --git a/plugins/GSnull/Windows/GSwin.h b/plugins/GSnull/Windows/GSwin.h new file mode 100644 index 0000000000..8e7777fe87 --- /dev/null +++ b/plugins/GSnull/Windows/GSwin.h @@ -0,0 +1,36 @@ +/* GSnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include "../GS.h" + +#ifdef __cplusplus +extern "C" +{ +#endif +#define GSdefs +#include "PS2Edefs.h" +#ifdef __cplusplus +} +#endif + +int GSOpenWindow(void *pDsp, char *Title); +void GSCloseWindow(); +void GSProcessMessages(); +void HandleKeyEvent(keyEvent *ev); \ No newline at end of file diff --git a/plugins/GSnull/Windows/Makefile b/plugins/GSnull/Windows/Makefile new file mode 100644 index 0000000000..afa9da3337 --- /dev/null +++ b/plugins/GSnull/Windows/Makefile @@ -0,0 +1,29 @@ + +RC = windres +STRIP = strip + +PLUGIN = FWnull.dll +CFLAGS = -Wall -O2 -fomit-frame-pointer -I.. -D__WIN32__ -D__MINGW32__ +LIBS = -lcomctl32 -lwsock32 -lwinmm -lgdi32 -lcomdlg32 +RESOBJ = FireWireNull.o +OBJS = ../FW.o Config.o Win32.o ${RESOBJ} + +DEPS:= $(OBJS:.o=.d) + +all: plugin + +plugin: ${OBJS} + dllwrap --def plugin.def -o ${PLUGIN} ${OBJS} ${LIBS} +# ${CC} -shared -Wl,--kill-at,--output-def,plugin.def ${CFLAGS} ${OBJS} -o ${PLUGIN} ${LIBS} + ${STRIP} ${PLUGIN} + +.PHONY: clear plugin + +clean: + rm -f ${OBJS} ${DEPS} ${PLUGIN} + +${RESOBJ}: FireWireNull.rc + ${RC} -D__MINGW32__ -I rc -O coff -o $@ -i $< + +-include ${DEPS} + diff --git a/plugins/GSnull/Windows/ProjectRootDir.vsprops b/plugins/GSnull/Windows/ProjectRootDir.vsprops new file mode 100644 index 0000000000..b8400f4c9c --- /dev/null +++ b/plugins/GSnull/Windows/ProjectRootDir.vsprops @@ -0,0 +1,11 @@ + + + + diff --git a/plugins/GSnull/Windows/Win32.cpp b/plugins/GSnull/Windows/Win32.cpp new file mode 100644 index 0000000000..0071924a65 --- /dev/null +++ b/plugins/GSnull/Windows/Win32.cpp @@ -0,0 +1,81 @@ +#include +#include +#include + + +#include "resource.h" +#include "../GS.h" + +HINSTANCE hInst; + +void SysMessage(char *fmt, ...) { + va_list list; + char tmp[512]; + + va_start(list,fmt); + vsprintf(tmp,fmt,list); + va_end(list); + MessageBox(0, tmp, "GS Plugin Msg", 0); +} + +BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { + + switch(uMsg) { + case WM_INITDIALOG: + LoadConfig(); + if (conf.Log) CheckDlgButton(hW, IDC_LOGGING, TRUE); + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDCANCEL: + EndDialog(hW, TRUE); + return TRUE; + case IDOK: + if (IsDlgButtonChecked(hW, IDC_LOGGING)) + conf.Log = 1; + else conf.Log = 0; + SaveConfig(); + EndDialog(hW, FALSE); + return TRUE; + } + } + return FALSE; +} + +BOOL CALLBACK AboutDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { + switch(uMsg) { + case WM_INITDIALOG: + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDOK: + EndDialog(hW, FALSE); + return TRUE; + } + } + return FALSE; +} + +EXPORT_C_(void) GSconfigure() { + DialogBox(hInst, + MAKEINTRESOURCE(IDD_CONFIG), + GetActiveWindow(), + (DLGPROC)ConfigureDlgProc); +} + +EXPORT_C_(void) GSabout() { + DialogBox(hInst, + MAKEINTRESOURCE(IDD_ABOUT), + GetActiveWindow(), + (DLGPROC)AboutDlgProc); +} + +BOOL APIENTRY DllMain(HANDLE hModule, // DLL INIT + DWORD dwReason, + LPVOID lpReserved) { + hInst = (HINSTANCE)hModule; + return TRUE; // very quick :) +} + diff --git a/plugins/GSnull/Windows/resource.h b/plugins/GSnull/Windows/resource.h new file mode 100644 index 0000000000..6ea8fead11 --- /dev/null +++ b/plugins/GSnull/Windows/resource.h @@ -0,0 +1,21 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by FireWireNull.rc +// +#define IDD_CONFDLG 101 +#define IDD_CONFIG 101 +#define IDD_ABOUT 103 +#define IDC_NAME 1000 +#define IDC_CHECK1 1007 +#define IDC_LOGGING 1007 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 105 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1008 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/GSnull/build.sh b/plugins/GSnull/build.sh new file mode 100644 index 0000000000..e4118a87d9 --- /dev/null +++ b/plugins/GSnull/build.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +echo --------------- +echo Building GSnull +echo --------------- + +curdir=`pwd` + + +if test "${GSnullOPTIONS+set}" != set ; then +export GSnullOPTIONS="" +fi + +if [ $# -gt 0 ] && [ $1 = "all" ] +then + +aclocal +automake -a +autoconf + +./configure ${GSnullOPTIONS} --prefix=${PCSX2PLUGINS} +make clean +make install + +else +make $@ +fi + +if [ $? -ne 0 ] +then +exit 1 +fi \ No newline at end of file diff --git a/plugins/GSnull/configure.ac b/plugins/GSnull/configure.ac new file mode 100644 index 0000000000..bf15cfa1c2 --- /dev/null +++ b/plugins/GSnull/configure.ac @@ -0,0 +1,83 @@ +AC_INIT(GSnull, 0.1,arcum42@gmail.com) + +AM_INIT_AUTOMAKE(GSnull,0.1) + +AC_PROG_CC([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) +AC_PROG_CXX([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) +AC_PROG_CPP([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) + +AC_PROG_INSTALL +AC_PROG_RANLIB + +dnl necessary for compiling assembly +AM_PROG_AS + +AC_SUBST(GSnull_CURRENT, 0) +AC_SUBST(GSnull_REVISION, 1) +AC_SUBST(GSnull_AGE, 0) +AC_SUBST(GSnull_RELEASE,[$GSnull_CURRENT].[$GSnull_REVISION].[$GSnull_AGE]) +AC_SUBST(GSnull_SONAME,libGSnull.so.[$GSnull_CURRENT].[$GSnull_REVISION].[$GSnull_AGE]) + +CFLAGS= +CPPFLAGS= +CXXFLAGS= +CCASFLAGS= + +dnl Check for debug build +AC_MSG_CHECKING(debug build) +AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [debug build]), +debug=$enableval,debug=no) +if test "x$debug" == xyes +then + AC_DEFINE(PCSX2_DEBUG,1,[PCSX2_DEBUG]) + CFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CPPFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CXXFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CCASFLAGS+=" -m32 " +else + AC_DEFINE(NDEBUG,1,[NDEBUG]) + CFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CPPFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CXXFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CCASFLAGS+=" -m32 " +fi +AM_CONDITIONAL(DEBUGBUILD, test x$debug = xyes) +AC_MSG_RESULT($debug) + +AC_DEFINE(__LINUX__,1,[__LINUX__]) + +dnl Check for dev build +AC_MSG_CHECKING(for development build...) +AC_ARG_ENABLE(devbuild, AC_HELP_STRING([--enable-devbuild], [Special Build for developers that simplifies testing and adds extra checks]), + devbuild=$enableval,devbuild=no) +if test "x$devbuild" == xyes +then + AC_DEFINE(GSnull_DEVBUILD,1,[GSnull_DEVBUILD]) +fi +AC_MSG_RESULT($devbuild) +AM_CONDITIONAL(RELEASE_TO_PUBLIC, test x$devbuild = xno) + +AC_CHECK_FUNCS([ _aligned_malloc _aligned_free ], AC_DEFINE(HAVE_ALIGNED_MALLOC)) + +dnl gtk +AC_MSG_CHECKING(gtk2+) +AC_CHECK_PROG(GTK_CONFIG, pkg-config, pkg-config) +LIBS+=$(pkg-config --libs gtk+-2.0) + +dnl bindir = pcsx2exe + +dnl assuming linux environment +so_ext=".so.$GSnull_RELEASE" +SHARED_LDFLAGS="-shared" +AC_SUBST(so_ext) +AC_SUBST(SHARED_LDFLAGS) + +AC_CHECK_LIB(stdc++,main,[LIBS="$LIBS -lstdc++"]) + +AC_OUTPUT([ + Makefile + ]) + +echo "Configuration:" +echo " Debug build? $debug" +echo " Dev build? $devbuild" \ No newline at end of file diff --git a/plugins/GSnull/missing b/plugins/GSnull/missing new file mode 120000 index 0000000000..1f0fe88e65 --- /dev/null +++ b/plugins/GSnull/missing @@ -0,0 +1 @@ +/usr/share/automake-1.10/missing \ No newline at end of file diff --git a/plugins/GSnull/null/GSnull.cpp b/plugins/GSnull/null/GSnull.cpp new file mode 100644 index 0000000000..c7a22b64bf --- /dev/null +++ b/plugins/GSnull/null/GSnull.cpp @@ -0,0 +1,39 @@ + /* GSnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + #include "../GS.h" + +void OnKeyboardF5(int myShift) +{ + SysPrintf("F5 pressed!\n"); +} + +void OnKeyboardF6(int myShift) +{ + SysPrintf("F6 pressed!\n"); +} + +void OnKeyboardF7(int myShift) +{ + SysPrintf("F7 pressed!\n"); +} + +void OnKeyboardF9(int myShift) +{ + SysPrintf("F9 pressed!\n"); +} \ No newline at end of file diff --git a/plugins/GSnull/null/GSnull.h b/plugins/GSnull/null/GSnull.h new file mode 100644 index 0000000000..53c25d1398 --- /dev/null +++ b/plugins/GSnull/null/GSnull.h @@ -0,0 +1,22 @@ + /* GSnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +extern void OnKeyboardF5(int myShift); +extern void OnKeyboardF6(int myShift); +extern void OnKeyboardF7(int myShift); +extern void OnKeyboardF9(int myShift); \ No newline at end of file diff --git a/plugins/LilyPad/LilyPad.cpp b/plugins/LilyPad/LilyPad.cpp index 6f90966ac7..c878eed07d 100644 --- a/plugins/LilyPad/LilyPad.cpp +++ b/plugins/LilyPad/LilyPad.cpp @@ -18,7 +18,7 @@ #include "svnrev.h" #include "resource.h" -#ifdef _DEBUG +#ifdef PCSX2_DEBUG #include "crtdbg.h" #endif @@ -577,7 +577,7 @@ u32 CALLBACK PS2EgetLibVersion2(u32 type) { // Used in about and config screens. void GetNameAndVersionString(wchar_t *out) { -#ifdef _DEBUG +#ifdef PCSX2_DEBUG wsprintfW(out, L"LilyPad Debug %i.%i.%i (r%i)", (VERSION>>8)&0xFF, VERSION&0xFF, (VERSION>>24)&0xFF, SVN_REV); #elif (_MSC_VER != 1400) wsprintfW(out, L"LilyPad svn %i.%i.%i (r%i)", (VERSION>>8)&0xFF, VERSION&0xFF, (VERSION>>24)&0xFF, SVN_REV); @@ -587,7 +587,7 @@ void GetNameAndVersionString(wchar_t *out) { } char* CALLBACK PSEgetLibName() { -#ifdef _DEBUG +#ifdef PCSX2_DEBUG static char version[50]; sprintf(version, "LilyPad Debug (r%i)", SVN_REV); return version; @@ -680,7 +680,7 @@ s32 CALLBACK PADinit(u32 flags) { return PADinit(2); } - #ifdef _DEBUG + #ifdef PCSX2_DEBUG int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); tmpFlag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag( tmpFlag ); diff --git a/plugins/LilyPad/LilyPad_VC2008.vcproj b/plugins/LilyPad/LilyPad_VC2008.vcproj index 4c97c07f5e..8e7255761f 100644 --- a/plugins/LilyPad/LilyPad_VC2008.vcproj +++ b/plugins/LilyPad/LilyPad_VC2008.vcproj @@ -21,7 +21,7 @@ @@ -49,14 +49,7 @@ diff --git a/plugins/PadNull/License.txt b/plugins/PadNull/License.txt new file mode 100644 index 0000000000..7d1f8605f8 --- /dev/null +++ b/plugins/PadNull/License.txt @@ -0,0 +1,342 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + + diff --git a/plugins/PadNull/Linux/Config.cpp b/plugins/PadNull/Linux/Config.cpp new file mode 100644 index 0000000000..05f91b2528 --- /dev/null +++ b/plugins/PadNull/Linux/Config.cpp @@ -0,0 +1,168 @@ +/* FWnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#include "Pad.h" +#include "Config.h" + + #ifdef __cplusplus +extern "C" +{ +#endif + +#include "support.h" +#include "callbacks.h" +#include "interface.h" + +#ifdef __cplusplus +} +#endif + +GtkWidget *MsgDlg, *About, *Conf; +extern string s_strIniPath; + +void OnMsg_Ok() +{ + gtk_widget_destroy(MsgDlg); + gtk_main_quit(); +} + +void SysMessage(char *fmt, ...) +{ + GtkWidget *Ok,*Txt; + GtkWidget *Box,*Box1; + va_list list; + char msg[512]; + + va_start(list, fmt); + vsprintf(msg, fmt, list); + va_end(list); + + if (msg[strlen(msg) - 1] == '\n') msg[strlen(msg)-1] = 0; + + MsgDlg = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER); + gtk_window_set_title(GTK_WINDOW(MsgDlg), "FireWire Msg"); + gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 5); + + Box = gtk_vbox_new(5, 0); + gtk_container_add(GTK_CONTAINER(MsgDlg), Box); + gtk_widget_show(Box); + + Txt = gtk_label_new(msg); + + gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5); + gtk_widget_show(Txt); + + Box1 = gtk_hbutton_box_new(); + gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0); + gtk_widget_show(Box1); + + Ok = gtk_button_new_with_label("Ok"); + gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsg_Ok), NULL); + gtk_container_add(GTK_CONTAINER(Box1), Ok); + GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT); + gtk_widget_show(Ok); + + gtk_widget_show(MsgDlg); + + gtk_main(); +} + +void OnAbout_Ok(GtkButton *button, gpointer user_data) +{ + gtk_widget_destroy(About); + gtk_main_quit(); +} + +EXPORT_C_(void) PADabout() +{ + About = create_About(); + gtk_widget_show_all(About); + gtk_main(); +} + +void OnConf_Ok(GtkButton *button, gpointer user_data) +{ + conf.Log = is_checked(Conf, "check_logging"); + SaveConfig(); + + gtk_widget_destroy(Conf); + gtk_main_quit(); +} + +void OnConf_Cancel(GtkButton *button, gpointer user_data) +{ + gtk_widget_destroy(Conf); + gtk_main_quit(); +} + +EXPORT_C_(void) PADconfigure() +{ + LoadConfig(); + Conf = create_Config(); + + set_checked(Conf, "check_logging", conf.Log); + gtk_widget_show_all(Conf); + gtk_main(); +} + +void LoadConfig() +{ + FILE *f; + char cfg[255]; + + strcpy(cfg, s_strIniPath.c_str()); + f = fopen(cfg, "r"); + if (f == NULL) + { + printf("failed to open %s\n", s_strIniPath.c_str()); + SaveConfig();//save and return + return; + } + fscanf(f, "logging = %hhx\n", &conf.Log); + //fscanf(f, "options = %hhx\n", &confOptions); + fclose(f); +} + +void SaveConfig() +{ + FILE *f; + char cfg[255]; + + strcpy(cfg, s_strIniPath.c_str()); + f = fopen(cfg,"w"); + if (f == NULL) + { + printf("failed to open '%s'\n", s_strIniPath.c_str()); + return; + } + fprintf(f, "logging = %hhx\n", conf.Log); + //fprintf(f, "options = %hhx\n", confOptions); + fclose(f); +} + diff --git a/plugins/PadNull/Linux/Config.h b/plugins/PadNull/Linux/Config.h new file mode 100644 index 0000000000..7251ed01eb --- /dev/null +++ b/plugins/PadNull/Linux/Config.h @@ -0,0 +1,24 @@ +/* FWnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +void SaveConf(); +void LoadConf(); +void SysMessage(char *fmt, ...); + +#define is_checked(main_widget, widget_name) (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)))) +#define set_checked(main_widget,widget_name, state) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)), state) diff --git a/plugins/PadNull/Linux/PadLinux.cpp b/plugins/PadNull/Linux/PadLinux.cpp new file mode 100644 index 0000000000..2337ea5d79 --- /dev/null +++ b/plugins/PadNull/Linux/PadLinux.cpp @@ -0,0 +1,75 @@ +/* PadNull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "PadLinux.h" + +Display *GSdsp; +int autoRepeatMode; + +void _PadUpdate(int pad) +{ + XEvent evt; + KeySym key; + + // keyboard input + while (XPending(GSdsp) > 0) + { + XNextEvent(GSdsp, &evt); + switch (evt.type) + { + case KeyPress: + key = XLookupKeysym((XKeyEvent *) &evt, 0); + + // Add code to check if it's one of the keys we configured here on a real pda plugin.. + + event.evt = KEYPRESS; + event.key = key; + break; + + case KeyRelease: + key = XLookupKeysym((XKeyEvent *) &evt, 0); + + // Add code to check if it's one of the keys we configured here on a real pda plugin.. + + event.evt = KEYRELEASE; + event.key = key; + break; + + case FocusIn: + XAutoRepeatOff(GSdsp); + break; + + case FocusOut: + XAutoRepeatOn(GSdsp); + break; + } + } +} + +s32 _PADOpen(void *pDsp) +{ + GSdsp = *(Display**)pDsp; + XAutoRepeatOff(GSdsp); + + return 0; +} + +void _PADClose() +{ + XAutoRepeatOn(GSdsp); +} diff --git a/plugins/PadNull/Linux/PadLinux.h b/plugins/PadNull/Linux/PadLinux.h new file mode 100644 index 0000000000..6b61c90aee --- /dev/null +++ b/plugins/PadNull/Linux/PadLinux.h @@ -0,0 +1,30 @@ +/* PadNull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __PADLINUX_H__ +#define __PADLINUX_H__ + +#include "Pad.h" +#include +#include + +void _PadUpdate(int pad); +s32 _PADOpen(void *pDsp); +void _PADClose(); + +#endif \ No newline at end of file diff --git a/plugins/PadNull/Linux/callbacks.c b/plugins/PadNull/Linux/callbacks.c new file mode 100644 index 0000000000..e87ed8be2d --- /dev/null +++ b/plugins/PadNull/Linux/callbacks.c @@ -0,0 +1,34 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + + +void +OnConf_Ok (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConf_Cancel (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnAbout_Ok (GtkButton *button, + gpointer user_data) +{ + +} + diff --git a/plugins/PadNull/Linux/callbacks.h b/plugins/PadNull/Linux/callbacks.h new file mode 100644 index 0000000000..e606c242f0 --- /dev/null +++ b/plugins/PadNull/Linux/callbacks.h @@ -0,0 +1,14 @@ +#include + + +void +OnConf_Ok (GtkButton *button, + gpointer user_data); + +void +OnConf_Cancel (GtkButton *button, + gpointer user_data); + +void +OnAbout_Ok (GtkButton *button, + gpointer user_data); diff --git a/plugins/PadNull/Linux/interface.c b/plugins/PadNull/Linux/interface.c new file mode 100644 index 0000000000..18efe01d59 --- /dev/null +++ b/plugins/PadNull/Linux/interface.c @@ -0,0 +1,173 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ + g_object_set_data (G_OBJECT (component), name, widget) + +GtkWidget* +create_Config (void) +{ + GtkWidget *Config; + GtkWidget *vbox1; + GtkWidget *frame3; + GtkWidget *alignment1; + GtkWidget *check_logging; + GtkWidget *label15; + GtkWidget *hbuttonbox1; + GtkWidget *button1; + GtkWidget *button2; + + Config = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (Config, "Config"); + gtk_container_set_border_width (GTK_CONTAINER (Config), 5); + gtk_window_set_title (GTK_WINDOW (Config), _("Padconfig")); + + vbox1 = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (vbox1, "vbox1"); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (Config), vbox1); + gtk_container_set_border_width (GTK_CONTAINER (vbox1), 5); + + frame3 = gtk_frame_new (NULL); + gtk_widget_set_name (frame3, "frame3"); + gtk_widget_show (frame3); + gtk_box_pack_start (GTK_BOX (vbox1), frame3, TRUE, TRUE, 0); + gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_NONE); + + alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_set_name (alignment1, "alignment1"); + gtk_widget_show (alignment1); + gtk_container_add (GTK_CONTAINER (frame3), alignment1); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment1), 0, 0, 12, 0); + + check_logging = gtk_check_button_new_with_mnemonic (_("Enable Logging")); + gtk_widget_set_name (check_logging, "check_logging"); + gtk_widget_show (check_logging); + gtk_container_add (GTK_CONTAINER (alignment1), check_logging); + + label15 = gtk_label_new (_("Logging")); + gtk_widget_set_name (label15, "label15"); + gtk_widget_show (label15); + gtk_frame_set_label_widget (GTK_FRAME (frame3), label15); + gtk_label_set_use_markup (GTK_LABEL (label15), TRUE); + + hbuttonbox1 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox1, "hbuttonbox1"); + gtk_widget_show (hbuttonbox1); + gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, TRUE, TRUE, 0); + gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 30); + + button1 = gtk_button_new_with_mnemonic (_("Ok")); + gtk_widget_set_name (button1, "button1"); + gtk_widget_show (button1); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), button1); + GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); + + button2 = gtk_button_new_with_mnemonic (_("Cancel")); + gtk_widget_set_name (button2, "button2"); + gtk_widget_show (button2); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), button2); + GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) button1, "clicked", + G_CALLBACK (OnConf_Ok), + NULL); + g_signal_connect ((gpointer) button2, "clicked", + G_CALLBACK (OnConf_Cancel), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (Config, Config, "Config"); + GLADE_HOOKUP_OBJECT (Config, vbox1, "vbox1"); + GLADE_HOOKUP_OBJECT (Config, frame3, "frame3"); + GLADE_HOOKUP_OBJECT (Config, alignment1, "alignment1"); + GLADE_HOOKUP_OBJECT (Config, check_logging, "check_logging"); + GLADE_HOOKUP_OBJECT (Config, label15, "label15"); + GLADE_HOOKUP_OBJECT (Config, hbuttonbox1, "hbuttonbox1"); + GLADE_HOOKUP_OBJECT (Config, button1, "button1"); + GLADE_HOOKUP_OBJECT (Config, button2, "button2"); + + return Config; +} + +GtkWidget* +create_About (void) +{ + GtkWidget *About; + GtkWidget *vbox2; + GtkWidget *label2; + GtkWidget *label3; + GtkWidget *hbuttonbox2; + GtkWidget *button3; + + About = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (About, "About"); + gtk_container_set_border_width (GTK_CONTAINER (About), 5); + gtk_window_set_title (GTK_WINDOW (About), _("FWabout")); + + vbox2 = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (vbox2, "vbox2"); + gtk_widget_show (vbox2); + gtk_container_add (GTK_CONTAINER (About), vbox2); + gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5); + + label2 = gtk_label_new (_("PadNull Driver")); + gtk_widget_set_name (label2, "label2"); + gtk_widget_show (label2); + gtk_box_pack_start (GTK_BOX (vbox2), label2, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER); + + label3 = gtk_label_new (_("Original Author: arcum42@gmail.com")); + gtk_widget_set_name (label3, "label3"); + gtk_widget_show (label3); + gtk_box_pack_start (GTK_BOX (vbox2), label3, FALSE, FALSE, 0); + + hbuttonbox2 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox2, "hbuttonbox2"); + gtk_widget_show (hbuttonbox2); + gtk_box_pack_start (GTK_BOX (vbox2), hbuttonbox2, TRUE, TRUE, 0); + gtk_box_set_spacing (GTK_BOX (hbuttonbox2), 30); + + button3 = gtk_button_new_with_mnemonic (_("Ok")); + gtk_widget_set_name (button3, "button3"); + gtk_widget_show (button3); + gtk_container_add (GTK_CONTAINER (hbuttonbox2), button3); + GTK_WIDGET_SET_FLAGS (button3, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) button3, "clicked", + G_CALLBACK (OnAbout_Ok), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (About, About, "About"); + GLADE_HOOKUP_OBJECT (About, vbox2, "vbox2"); + GLADE_HOOKUP_OBJECT (About, label2, "label2"); + GLADE_HOOKUP_OBJECT (About, label3, "label3"); + GLADE_HOOKUP_OBJECT (About, hbuttonbox2, "hbuttonbox2"); + GLADE_HOOKUP_OBJECT (About, button3, "button3"); + + return About; +} + diff --git a/plugins/PadNull/Linux/interface.h b/plugins/PadNull/Linux/interface.h new file mode 100644 index 0000000000..69c303ba3b --- /dev/null +++ b/plugins/PadNull/Linux/interface.h @@ -0,0 +1,6 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +GtkWidget* create_Config (void); +GtkWidget* create_About (void); diff --git a/plugins/PadNull/Linux/pad.glade b/plugins/PadNull/Linux/pad.glade new file mode 100644 index 0000000000..8a407e0fb7 --- /dev/null +++ b/plugins/PadNull/Linux/pad.glade @@ -0,0 +1,240 @@ + + + + + + + 5 + True + Padconfig + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + 5 + True + False + 5 + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + True + Enable Logging + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + + + + + True + <b>Logging</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + True + GTK_BUTTONBOX_DEFAULT_STYLE + 30 + + + + True + True + True + Ok + True + GTK_RELIEF_NORMAL + True + + + + + + + True + True + True + Cancel + True + GTK_RELIEF_NORMAL + True + + + + + + 0 + True + True + + + + + + + + 5 + True + FWabout + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + 5 + True + False + 5 + + + + True + PadNull Driver + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + Original Author: arcum42@gmail.com + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + GTK_BUTTONBOX_DEFAULT_STYLE + 30 + + + + True + True + True + Ok + True + GTK_RELIEF_NORMAL + True + + + + + + 0 + True + True + + + + + + + diff --git a/plugins/PadNull/Linux/support.c b/plugins/PadNull/Linux/support.c new file mode 100644 index 0000000000..00aff29822 --- /dev/null +++ b/plugins/PadNull/Linux/support.c @@ -0,0 +1,144 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include + +#include "support.h" + +GtkWidget* +lookup_widget (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (!parent) + parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + +static GList *pixmaps_directories = NULL; + +/* Use this function to set the directory containing installed pixmaps. */ +void +add_pixmap_directory (const gchar *directory) +{ + pixmaps_directories = g_list_prepend (pixmaps_directories, + g_strdup (directory)); +} + +/* This is an internally used function to find pixmap files. */ +static gchar* +find_pixmap_file (const gchar *filename) +{ + GList *elem; + + /* We step through each of the pixmaps directory to find it. */ + elem = pixmaps_directories; + while (elem) + { + gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data, + G_DIR_SEPARATOR_S, filename); + if (g_file_test (pathname, G_FILE_TEST_EXISTS)) + return pathname; + g_free (pathname); + elem = elem->next; + } + return NULL; +} + +/* This is an internally used function to create pixmaps. */ +GtkWidget* +create_pixmap (GtkWidget *widget, + const gchar *filename) +{ + gchar *pathname = NULL; + GtkWidget *pixmap; + + if (!filename || !filename[0]) + return gtk_image_new (); + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return gtk_image_new (); + } + + pixmap = gtk_image_new_from_file (pathname); + g_free (pathname); + return pixmap; +} + +/* This is an internally used function to create pixmaps. */ +GdkPixbuf* +create_pixbuf (const gchar *filename) +{ + gchar *pathname = NULL; + GdkPixbuf *pixbuf; + GError *error = NULL; + + if (!filename || !filename[0]) + return NULL; + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return NULL; + } + + pixbuf = gdk_pixbuf_new_from_file (pathname, &error); + if (!pixbuf) + { + fprintf (stderr, "Failed to load pixbuf file: %s: %s\n", + pathname, error->message); + g_error_free (error); + } + g_free (pathname); + return pixbuf; +} + +/* This is used to set ATK action descriptions. */ +void +glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description) +{ + gint n_actions, i; + + n_actions = atk_action_get_n_actions (action); + for (i = 0; i < n_actions; i++) + { + if (!strcmp (atk_action_get_name (action, i), action_name)) + atk_action_set_description (action, i, description); + } +} + diff --git a/plugins/PadNull/Linux/support.h b/plugins/PadNull/Linux/support.h new file mode 100644 index 0000000000..a32649e53c --- /dev/null +++ b/plugins/PadNull/Linux/support.h @@ -0,0 +1,69 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* + * Standard gettext macros. + */ +#ifdef ENABLE_NLS +# include +# undef _ +# define _(String) dgettext (PACKAGE, String) +# define Q_(String) g_strip_context ((String), gettext (String)) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define Q_(String) g_strip_context ((String), (String)) +# define N_(String) (String) +#endif + + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* lookup_widget (GtkWidget *widget, + const gchar *widget_name); + + +/* Use this function to set the directory containing installed pixmaps. */ +void add_pixmap_directory (const gchar *directory); + + +/* + * Private Functions. + */ + +/* This is used to create the pixmaps used in the interface. */ +GtkWidget* create_pixmap (GtkWidget *widget, + const gchar *filename); + +/* This is used to create the pixbufs used in the interface. */ +GdkPixbuf* create_pixbuf (const gchar *filename); + +/* This is used to set ATK action descriptions. */ +void glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description); + diff --git a/plugins/PadNull/Makefile.am b/plugins/PadNull/Makefile.am new file mode 100644 index 0000000000..6263b08c0a --- /dev/null +++ b/plugins/PadNull/Makefile.am @@ -0,0 +1,31 @@ +# Create a shared library libPadnull +AUTOMAKE_OPTIONS = foreign +noinst_LIBRARIES = libPadnull.a +INCLUDES = -I@srcdir@/../../common/include -I@srcdir@/../../3rdparty -I@srcdir@/Linux + +libPadnull_a_CXXFLAGS = $(shell pkg-config --cflags gtk+-2.0) +libPadnull_a_CFLAGS = $(shell pkg-config --cflags gtk+-2.0) + +# Create a shared object by faking an exe (thanks to ODE makefiles) +traplibdir=$(prefix) + +if DEBUGBUILD +preext=d +endif + +EXEEXT=$(preext)@so_ext@ + +traplib_PROGRAMS=libPadnull +libPadnull_SOURCES= +libPadnull_DEPENDENCIES = libPadnull.a +libPadnull_LDFLAGS= @SHARED_LDFLAGS@ +libPadnull_LDFLAGS+=-Wl,-soname,@libPadnull_SONAME@ +libPadnull_LDADD=$(libPadnull_a_OBJECTS) + +libPadnull_a_SOURCES = Pad.cpp Pad.h Linux/Config.cpp Linux/Config.h \ +Linux/PadLinux.cpp Linux/PadLinux.h + +libPadnull_a_SOURCES += \ +Linux/interface.h Linux/support.c \ +Linux/interface.c Linux/support.h \ +Linux/callbacks.h \ No newline at end of file diff --git a/plugins/PadNull/Pad.cpp b/plugins/PadNull/Pad.cpp new file mode 100644 index 0000000000..ca4985d9f1 --- /dev/null +++ b/plugins/PadNull/Pad.cpp @@ -0,0 +1,168 @@ +/* FWnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +using namespace std; + +#include "Pad.h" + +const u8 version = PS2E_PAD_VERSION; +const u8 revision = 0; +const u8 build = 1; // increase that with each version + +static char *libraryName = "Padnull Driver"; +string s_strIniPath="inis/Padnull.ini"; + +FILE *padLog; +Config conf; +keyEvent event; +static keyEvent s_event; + +EXPORT_C_(u32) PS2EgetLibType() +{ + return PS2E_LT_PAD; +} + +EXPORT_C_(char*) PS2EgetLibName() +{ + return libraryName; +} + +EXPORT_C_(u32) PS2EgetLibVersion2(u32 type) +{ + return (version<<16) | (revision<<8) | build; +} + +void __Log(const char *fmt, ...) +{ + va_list list; + + if (padLog == NULL) return; + va_start(list, fmt); + vfprintf(padLog, fmt, list); + va_end(list); +} + +void __LogToConsole(const char *fmt, ...) +{ + va_list list; + + va_start(list, fmt); + + if (padLog != NULL) vfprintf(padLog, fmt, list); + + printf("PadNull: "); + vprintf(fmt, list); + va_end(list); +} + +EXPORT_C_(s32) PADinit(u32 flags) +{ + LoadConfig(); + +#ifdef PAD_LOG + if (padLog == NULL) + { + padLog = fopen("logs/padLog.txt", "w"); + if (padLog) setvbuf(padLog, NULL, _IONBF, 0); + } + PAD_LOG("PADinit\n"); +#endif + + return 0; +} + +EXPORT_C_(void) PADshutdown() +{ +#ifdef PAD_LOG + if (padLog != NULL) + { + fclose(padLog); + padLog = NULL; + } +#endif +} + +EXPORT_C_(s32) PADopen(void *pDsp) +{ + memset(&event, 0, sizeof(event)); + + return _PADOpen(pDsp); +} + +EXPORT_C_(void) PADclose() +{ + _PADClose(); +} + +// PADkeyEvent is called every vsync (return NULL if no event) +EXPORT_C_(keyEvent*) PADkeyEvent() +{ + + s_event = event; + event.evt = 0; + + return &s_event; +} + +EXPORT_C_(u8) PADstartPoll(int pad) +{ + return 0; +} + +EXPORT_C_(u8) PADpoll(u8 value) +{ + return 0; +} + +// call to give a hint to the PAD plugin to query for the keyboard state. A +// good plugin will query the OS for keyboard state ONLY in this function. +// This function is necessary when multithreading because otherwise +// the PAD plugin can get into deadlocks with the thread that really owns +// the window (and input). Note that PADupdate can be called from a different +// thread than the other functions, so mutex or other multithreading primitives +// have to be added to maintain data integrity. +EXPORT_C_(u32) PADquery() +// returns: 1 if supported pad1 +// 2 if supported pad2 +// 3 if both are supported +{ + return 3; +} + +EXPORT_C_(void) PADupdate(int pad) +{ + _PadUpdate(pad); +} + +EXPORT_C_(void) PADgsDriverInfo(GSdriverInfo *info) +{ +} + +EXPORT_C_(s32) PADfreeze(int mode, freezeData *data) +{ + return 0; +} + +EXPORT_C_(s32) PADtest() +{ + return 0; +} diff --git a/plugins/PadNull/Pad.h b/plugins/PadNull/Pad.h new file mode 100644 index 0000000000..fb24ff72ca --- /dev/null +++ b/plugins/PadNull/Pad.h @@ -0,0 +1,61 @@ +/* FWnull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __PAD_H__ +#define __PAD_H__ + +#include + +#define PADdefs +#include "PS2Edefs.h" + +#ifdef _WIN32 +#include "PadWin.h" +#else +#include "PadLinux.h" +#endif + +/*#ifdef _MSC_VER +#define EXPORT_C_(type) extern "C" __declspec(dllexport) type CALLBACK +#else +#define EXPORT_C_(type) extern "C" type +#endif*/ + +#ifdef _MSC_VER +#define EXPORT_C_(type) extern "C" type CALLBACK +#else +#define EXPORT_C_(type) extern "C" type +#endif + +#define PAD_LOG __Log + +typedef struct +{ + s32 Log; +} Config; + +extern Config conf; +extern FILE *padLog; +extern keyEvent event; + +extern void __Log(char *fmt, ...); +extern void SysMessage(char *fmt, ...); +extern void SaveConfig(); +extern void LoadConfig(); + +#endif diff --git a/plugins/PadNull/ReadMe.txt b/plugins/PadNull/ReadMe.txt new file mode 100644 index 0000000000..75019a2573 --- /dev/null +++ b/plugins/PadNull/ReadMe.txt @@ -0,0 +1,23 @@ +PadNull v0.1 +------------- + + This is an extension to use with play station2 emulators + as PCSX2 (only one right now). + The plugin is free open source code. + +Usage: +----- + Place the file "libPadNull.so.0.1.0" (linux) or "PadNull.dll" (win32) + at the Plugin directory of the Emulator to use it. + +Changes: +------- + v0.1: + * First Release + * Tested with Pcsx2 + +Authors: +------- +arcum42@gmail.com + + diff --git a/plugins/PadNull/Windows/Config.cpp b/plugins/PadNull/Windows/Config.cpp new file mode 100644 index 0000000000..43621bedd7 --- /dev/null +++ b/plugins/PadNull/Windows/Config.cpp @@ -0,0 +1,69 @@ +/* PadNull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include "../Pad.h" + +extern HINSTANCE hInst; +void SaveConfig() +{ + + Config *Conf1 = &conf; + char *szTemp; + char szIniFile[256], szValue[256]; + + GetModuleFileName(GetModuleHandle((LPCSTR)hInst), szIniFile, 256); + szTemp = strrchr(szIniFile, '\\'); + + if(!szTemp) return; + strcpy(szTemp, "\\inis\\fwnull.ini"); + sprintf(szValue,"%u",Conf1->Log); + WritePrivateProfileString("Interface", "Logging",szValue,szIniFile); + +} + +void LoadConfig() { + FILE *fp; + + + Config *Conf1 = &conf; + char *szTemp; + char szIniFile[256], szValue[256]; + + GetModuleFileName(GetModuleHandle((LPCSTR)hInst), szIniFile, 256); + szTemp = strrchr(szIniFile, '\\'); + + if(!szTemp) return ; + strcpy(szTemp, "\\inis\\fwnull.ini"); + fp=fopen("inis\\fwnull.ini","rt");//check if firewirenull.ini really exists + if (!fp) + { + CreateDirectory("inis",NULL); + memset(&conf, 0, sizeof(conf)); + conf.Log = 0;//default value + SaveConfig();//save and return + return ; + } + fclose(fp); + GetPrivateProfileString("Interface", "Logging", NULL, szValue, 20, szIniFile); + Conf1->Log = strtoul(szValue, NULL, 10); + return ; + +} + diff --git a/plugins/PadNull/Windows/PadNull.def b/plugins/PadNull/Windows/PadNull.def new file mode 100644 index 0000000000..b9d8488af1 --- /dev/null +++ b/plugins/PadNull/Windows/PadNull.def @@ -0,0 +1,23 @@ +; FireWire.def : Declares the module parameters for the DLL. + +LIBRARY "PadNull" + +EXPORTS + ; Explicit exports can go here + PS2EgetLibType @2 + PS2EgetLibName @3 + PS2EgetLibVersion2 @4 + PADinit @5 + PADshutdown @6 + PADopen @7 + PADclose @8 + PADkeyEvent @9 + PADstartPoll @10 + PADpoll @11 + PADquery @12 + PADupdate @13 + PADgsDriverInfo @14 + PADfreeze @15 + PADconfigure @16 + PADtest @17 + PADabout @18 \ No newline at end of file diff --git a/plugins/PadNull/Windows/PadNull.rc b/plugins/PadNull/Windows/PadNull.rc new file mode 100644 index 0000000000..a505f6108d --- /dev/null +++ b/plugins/PadNull/Windows/PadNull.rc @@ -0,0 +1,116 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxresmw.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Spanish (Argentina) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESS) +#ifdef _WIN32 +LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_ARGENTINA +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxresmw.h""\r\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_CONFIG DIALOGEX 0, 0, 212, 121 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Firewireconfigure" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "OK",IDOK,48,100,50,14 + PUSHBUTTON "Cancel",IDCANCEL,113,100,50,14 + CONTROL "Enable Logging (for develop use only)",IDC_LOGGING, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,187,13 +END + +IDD_ABOUT DIALOGEX 0, 0, 177, 106 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "FireWire About" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "OK",IDOK,65,85,50,14 + LTEXT "FireWire Driver",IDC_NAME,70,10,48,8 + GROUPBOX "",IDC_STATIC,5,35,170,40 + LTEXT "Author: Shadow and linuzappz",IDC_STATIC,29,19,141,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_CONFIG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 205 + TOPMARGIN, 7 + BOTTOMMARGIN, 114 + END + + IDD_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 170 + TOPMARGIN, 7 + BOTTOMMARGIN, 99 + END +END +#endif // APSTUDIO_INVOKED + +#endif // Spanish (Argentina) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/PadNull/Windows/PadNull_vc2008.cbp b/plugins/PadNull/Windows/PadNull_vc2008.cbp new file mode 100644 index 0000000000..a0815f31d6 --- /dev/null +++ b/plugins/PadNull/Windows/PadNull_vc2008.cbp @@ -0,0 +1,44 @@ + + + + + + diff --git a/plugins/PadNull/Windows/PadNull_vc2008.layout b/plugins/PadNull/Windows/PadNull_vc2008.layout new file mode 100644 index 0000000000..d55539c58b --- /dev/null +++ b/plugins/PadNull/Windows/PadNull_vc2008.layout @@ -0,0 +1,4 @@ + + + + diff --git a/plugins/PadNull/Windows/PadNull_vc2008.vcproj b/plugins/PadNull/Windows/PadNull_vc2008.vcproj new file mode 100644 index 0000000000..5d19f70dfb --- /dev/null +++ b/plugins/PadNull/Windows/PadNull_vc2008.vcproj @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/PadNull/Windows/PadWin.cpp b/plugins/PadNull/Windows/PadWin.cpp new file mode 100644 index 0000000000..48e3e580a2 --- /dev/null +++ b/plugins/PadNull/Windows/PadWin.cpp @@ -0,0 +1,81 @@ +/* PadNull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "PadWin.h" + +LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +WNDPROC GSwndProc = NULL; +HWND GShwnd = NULL; + +LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_KEYDOWN: + if (lParam & 0x40000000)return TRUE; + + event.evt = KEYPRESS; + event.key = wParam; + break; + + case WM_KEYUP: + event.evt = KEYRELEASE; + event.key = wParam; + break; + + case WM_DESTROY: + case WM_QUIT: + event.evt = KEYPRESS; + event.key = VK_ESCAPE; + return GSwndProc(hWnd, msg, wParam, lParam); + + default: + return GSwndProc(hWnd, msg, wParam, lParam); + }; + + return TRUE; +} + +void _PadUpdate(int pad) +{ +} + +s32 _PADOpen(void *pDsp) +{ + GShwnd = (HWND)*(long*)pDsp; + + if (GShwnd != NULL && GSwndProc != NULL) + { + // revert + SetWindowLongPtr(GShwnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)(GSwndProc)); + } + + GSwndProc = (WNDPROC)GetWindowLongPtr(GShwnd, GWLP_WNDPROC); + GSwndProc = ((WNDPROC)SetWindowLongPtr(GShwnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)(PADwndProc))); + return 0; +} + +void _PADClose() +{ + if (GShwnd != NULL && GSwndProc != NULL) + { + SetWindowLongPtr(GShwnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)(GSwndProc)); + GSwndProc = NULL; + GShwnd = NULL; + } +} \ No newline at end of file diff --git a/plugins/PadNull/Windows/PadWin.h b/plugins/PadNull/Windows/PadWin.h new file mode 100644 index 0000000000..5bd2bd73e1 --- /dev/null +++ b/plugins/PadNull/Windows/PadWin.h @@ -0,0 +1,30 @@ +/* PadNull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __PADLINUX_H__ +#define __PADLINUX_H__ + +#include "../Pad.h" +#include +#include + +void _PadUpdate(int pad); +s32 _PADOpen(void *pDsp); +void _PADClose(); + +#endif \ No newline at end of file diff --git a/plugins/PadNull/Windows/ProjectRootDir.vsprops b/plugins/PadNull/Windows/ProjectRootDir.vsprops new file mode 100644 index 0000000000..b8400f4c9c --- /dev/null +++ b/plugins/PadNull/Windows/ProjectRootDir.vsprops @@ -0,0 +1,11 @@ + + + + diff --git a/plugins/PadNull/Windows/Win32.cpp b/plugins/PadNull/Windows/Win32.cpp new file mode 100644 index 0000000000..3720d897f7 --- /dev/null +++ b/plugins/PadNull/Windows/Win32.cpp @@ -0,0 +1,100 @@ +/* PadNull + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + + +#include "resource.h" +#include "../Pad.h" + +HINSTANCE hInst; + +void SysMessage(char *fmt, ...) { + va_list list; + char tmp[512]; + + va_start(list,fmt); + vsprintf(tmp,fmt,list); + va_end(list); + MessageBox(0, tmp, "Pad Plugin Msg", 0); +} + +BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { + + switch(uMsg) { + case WM_INITDIALOG: + LoadConfig(); + if (conf.Log) CheckDlgButton(hW, IDC_LOGGING, TRUE); + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDCANCEL: + EndDialog(hW, TRUE); + return TRUE; + case IDOK: + if (IsDlgButtonChecked(hW, IDC_LOGGING)) + conf.Log = 1; + else + conf.Log = 0; + SaveConfig(); + EndDialog(hW, FALSE); + return TRUE; + } + } + return FALSE; +} + +BOOL CALLBACK AboutDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { + switch(uMsg) { + case WM_INITDIALOG: + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDOK: + EndDialog(hW, FALSE); + return TRUE; + } + } + return FALSE; +} + +EXPORT_C_(void) PADconfigure() { + DialogBox(hInst, + MAKEINTRESOURCE(IDD_CONFIG), + GetActiveWindow(), + (DLGPROC)ConfigureDlgProc); +} + +EXPORT_C_(void) PADabout() { + DialogBox(hInst, + MAKEINTRESOURCE(IDD_ABOUT), + GetActiveWindow(), + (DLGPROC)AboutDlgProc); +} + +BOOL APIENTRY DllMain(HANDLE hModule, // DLL INIT + DWORD dwReason, + LPVOID lpReserved) { + hInst = (HINSTANCE)hModule; + return TRUE; // very quick :) +} + diff --git a/plugins/PadNull/Windows/resource.h b/plugins/PadNull/Windows/resource.h new file mode 100644 index 0000000000..6ea8fead11 --- /dev/null +++ b/plugins/PadNull/Windows/resource.h @@ -0,0 +1,21 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by FireWireNull.rc +// +#define IDD_CONFDLG 101 +#define IDD_CONFIG 101 +#define IDD_ABOUT 103 +#define IDC_NAME 1000 +#define IDC_CHECK1 1007 +#define IDC_LOGGING 1007 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 105 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1008 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/PadNull/build.sh b/plugins/PadNull/build.sh new file mode 100644 index 0000000000..86f311f53f --- /dev/null +++ b/plugins/PadNull/build.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +echo --------------- +echo Building Padnull +echo --------------- + +curdir=`pwd` + + +if test "${PadnullOPTIONS+set}" != set ; then +export PadnullOPTIONS="" +fi + +if [ $# -gt 0 ] && [ $1 = "all" ] +then + +aclocal +automake -a +autoconf + +./configure ${PadnullOPTIONS} --prefix=${PCSX2PLUGINS} +make clean +make install + +else +make $@ +fi + +if [ $? -ne 0 ] +then +exit 1 +fi \ No newline at end of file diff --git a/plugins/PadNull/configure.ac b/plugins/PadNull/configure.ac new file mode 100644 index 0000000000..1fe5f6375c --- /dev/null +++ b/plugins/PadNull/configure.ac @@ -0,0 +1,83 @@ +AC_INIT(Padnull, 0.1,arcum42@gmail.com) + +AM_INIT_AUTOMAKE(Padnull,0.1) + +AC_PROG_CC([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) +AC_PROG_CXX([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) +AC_PROG_CPP([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) + +AC_PROG_INSTALL +AC_PROG_RANLIB + +dnl necessary for compiling assembly +AM_PROG_AS + +AC_SUBST(Padnull_CURRENT, 0) +AC_SUBST(Padnull_REVISION, 1) +AC_SUBST(Padnull_AGE, 0) +AC_SUBST(Padnull_RELEASE,[$Padnull_CURRENT].[$Padnull_REVISION].[$Padnull_AGE]) +AC_SUBST(Padnull_SONAME,libPadnull.so.[$Padnull_CURRENT].[$Padnull_REVISION].[$Padnull_AGE]) + +CFLAGS= +CPPFLAGS= +CXXFLAGS= +CCASFLAGS= + +dnl Check for debug build +AC_MSG_CHECKING(debug build) +AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [debug build]), +debug=$enableval,debug=no) +if test "x$debug" == xyes +then + AC_DEFINE(PCSX2_DEBUG,1,[PCSX2_DEBUG]) + CFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CPPFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CXXFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CCASFLAGS+=" -m32 " +else + AC_DEFINE(NDEBUG,1,[NDEBUG]) + CFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CPPFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CXXFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CCASFLAGS+=" -m32 " +fi +AM_CONDITIONAL(DEBUGBUILD, test x$debug = xyes) +AC_MSG_RESULT($debug) + +AC_DEFINE(__LINUX__,1,[__LINUX__]) + +dnl Check for dev build +AC_MSG_CHECKING(for development build...) +AC_ARG_ENABLE(devbuild, AC_HELP_STRING([--enable-devbuild], [Special Build for developers that simplifies testing and adds extra checks]), + devbuild=$enableval,devbuild=no) +if test "x$devbuild" == xyes +then + AC_DEFINE(Padnull_DEVBUILD,1,[Padnull_DEVBUILD]) +fi +AC_MSG_RESULT($devbuild) +AM_CONDITIONAL(RELEASE_TO_PUBLIC, test x$devbuild = xno) + +AC_CHECK_FUNCS([ _aligned_malloc _aligned_free ], AC_DEFINE(HAVE_ALIGNED_MALLOC)) + +dnl gtk +AC_MSG_CHECKING(gtk2+) +AC_CHECK_PROG(GTK_CONFIG, pkg-config, pkg-config) +LIBS+=$(pkg-config --libs gtk+-2.0) + +dnl bindir = pcsx2exe + +dnl assuming linux environment +so_ext=".so.$Padnull_RELEASE" +SHARED_LDFLAGS="-shared" +AC_SUBST(so_ext) +AC_SUBST(SHARED_LDFLAGS) + +AC_CHECK_LIB(stdc++,main,[LIBS="$LIBS -lstdc++"]) + +AC_OUTPUT([ + Makefile + ]) + +echo "Configuration:" +echo " Debug build? $debug" +echo " Dev build? $devbuild" \ No newline at end of file diff --git a/plugins/PeopsSPU2/Makefile b/plugins/PeopsSPU2/Makefile index 685c267710..e53dcd2c0e 100644 --- a/plugins/PeopsSPU2/Makefile +++ b/plugins/PeopsSPU2/Makefile @@ -16,9 +16,9 @@ NOTHREADLIB = FALSE ############################################################################## CC = gcc -CCFLAGS1 = -fPIC -c -Wall -O3 -CCFLAGS2 = -fPIC -c -Wall -O2 -ffast-math -CCFLAGS3 = -fPIC -c -Wall -O3 -ffast-math -fomit-frame-pointer +CCFLAGS1 = -fPIC -c -Wall -O3 -m32 +CCFLAGS2 = -fPIC -c -Wall -O2 -ffast-math -m32 +CCFLAGS3 = -fPIC -c -Wall -O3 -ffast-math -fomit-frame-pointer -m32 INCLUDE = LINK = gcc @@ -28,11 +28,11 @@ LIB = -lc -lm ifeq ($(USEALSA), TRUE) OBJ+= alsa.o LIB+= -lasound - LINKFLAGS = -shared -Wl,-soname,libspu2PeopsALSA.so -o libspu2PeopsALSA.so.1.0.3 + LINKFLAGS = -m32 -shared -Wl,-soname,libspu2PeopsALSA.so -o libspu2PeopsALSA.so.1.0.3 CCFLAGS3+= -DUSEALSA else OBJ+= oss.o - LINKFLAGS = -shared -Wl,-soname,libspu2PeopsOSS.so.1.6 -fPIC -fomit-frame-pointer -o libspu2PeopsOSS.so.1.6 + LINKFLAGS = -m32 -shared -Wl,-soname,libspu2PeopsOSS.so.1.6 -fPIC -fomit-frame-pointer -o libspu2PeopsOSS.so.1.6 endif ifeq ($(NOTHREADLIB), TRUE) diff --git a/plugins/SPU2null/Linux/Config.cpp b/plugins/SPU2null/Linux/Config.cpp index a42fc933a1..2e6e4aed6d 100644 --- a/plugins/SPU2null/Linux/Config.cpp +++ b/plugins/SPU2null/Linux/Config.cpp @@ -16,12 +16,25 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "Config.h" #include "SPU2.h" -#include -#include + #ifdef __cplusplus +extern "C" +{ +#endif -GtkWidget *MsgDlg; +#include "support.h" +#include "callbacks.h" +#include "interface.h" + +#ifdef __cplusplus +} +#endif + +using namespace std; + +GtkWidget *MsgDlg, *About, *Conf; void OnMsg_Ok() { @@ -71,16 +84,81 @@ void SysMessage(char *fmt, ...) gtk_main(); } +void OnAbout_Ok(GtkButton *button, gpointer user_data) +{ + gtk_widget_destroy(About); + gtk_main_quit(); +} + +void OnConf_Ok(GtkButton *button, gpointer user_data) +{ + conf.Log = is_checked(Conf, "check_logging"); + SaveConfig(); + + gtk_widget_destroy(Conf); + gtk_main_quit(); +} + +void OnConf_Cancel(GtkButton *button, gpointer user_data) +{ + gtk_widget_destroy(Conf); + gtk_main_quit(); +} + EXPORT_C_(void) SPU2configure() { - SysMessage("Nothing to Configure"); + //SysMessage("Nothing to Configure"); + + Conf = create_Config(); + + LoadConfig(); + + set_checked(Conf, "check_logging", conf.Log); + gtk_widget_show_all(Conf); + gtk_main(); } EXPORT_C_(void) SPU2about() { - SysMessage("%s %d.%d", libraryName, version, build); + //SysMessage("%s %d.%d", libraryName, version, build); + + About = create_About(); + gtk_widget_show_all(About); + gtk_main(); } -void LoadConfig() +void LoadConfig() { + FILE *f; + char cfg[255]; + + strcpy(cfg, s_strIniPath.c_str()); + f = fopen(cfg, "r"); + if (f == NULL) + { + printf("failed to open %s\n", s_strIniPath.c_str()); + SaveConfig();//save and return + return; + } + fscanf(f, "logging = %hhx\n", &conf.Log); + //fscanf(f, "options = %hhx\n", &confOptions); + fclose(f); } + +void SaveConfig() +{ + FILE *f; + char cfg[255]; + + strcpy(cfg, s_strIniPath.c_str()); + f = fopen(cfg,"w"); + if (f == NULL) + { + printf("failed to open %s\n", s_strIniPath.c_str()); + return; + } + + fprintf(f, "logging = %hhx\n", conf.Log); + //fprintf(f, "options = %hhx\n", confOptions); + fclose(f); +} \ No newline at end of file diff --git a/plugins/SPU2null/Linux/Config.h b/plugins/SPU2null/Linux/Config.h new file mode 100644 index 0000000000..ea196262a9 --- /dev/null +++ b/plugins/SPU2null/Linux/Config.h @@ -0,0 +1,30 @@ +/* SPU2null + * Copyright (C) 2002-2005 SPU2null Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +using namespace std; + +void SaveConf(); +void LoadConf(); +extern string s_strIniPath; + +#define is_checked(main_widget, widget_name) (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)))) +#define set_checked(main_widget,widget_name, state) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)), state) diff --git a/plugins/SPU2null/Linux/callbacks.c b/plugins/SPU2null/Linux/callbacks.c new file mode 100644 index 0000000000..e87ed8be2d --- /dev/null +++ b/plugins/SPU2null/Linux/callbacks.c @@ -0,0 +1,34 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + + +void +OnConf_Ok (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConf_Cancel (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnAbout_Ok (GtkButton *button, + gpointer user_data) +{ + +} + diff --git a/plugins/SPU2null/Linux/callbacks.h b/plugins/SPU2null/Linux/callbacks.h new file mode 100644 index 0000000000..e606c242f0 --- /dev/null +++ b/plugins/SPU2null/Linux/callbacks.h @@ -0,0 +1,14 @@ +#include + + +void +OnConf_Ok (GtkButton *button, + gpointer user_data); + +void +OnConf_Cancel (GtkButton *button, + gpointer user_data); + +void +OnAbout_Ok (GtkButton *button, + gpointer user_data); diff --git a/plugins/SPU2null/Linux/interface.c b/plugins/SPU2null/Linux/interface.c new file mode 100644 index 0000000000..1efa3adbbd --- /dev/null +++ b/plugins/SPU2null/Linux/interface.c @@ -0,0 +1,173 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ + g_object_set_data (G_OBJECT (component), name, widget) + +GtkWidget* +create_Config (void) +{ + GtkWidget *Config; + GtkWidget *vbox1; + GtkWidget *frame3; + GtkWidget *alignment1; + GtkWidget *check_logging; + GtkWidget *label15; + GtkWidget *hbuttonbox1; + GtkWidget *button1; + GtkWidget *button2; + + Config = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (Config, "Config"); + gtk_container_set_border_width (GTK_CONTAINER (Config), 5); + gtk_window_set_title (GTK_WINDOW (Config), _("SPU2config")); + + vbox1 = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (vbox1, "vbox1"); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (Config), vbox1); + gtk_container_set_border_width (GTK_CONTAINER (vbox1), 5); + + frame3 = gtk_frame_new (NULL); + gtk_widget_set_name (frame3, "frame3"); + gtk_widget_show (frame3); + gtk_box_pack_start (GTK_BOX (vbox1), frame3, TRUE, TRUE, 0); + gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_NONE); + + alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_set_name (alignment1, "alignment1"); + gtk_widget_show (alignment1); + gtk_container_add (GTK_CONTAINER (frame3), alignment1); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment1), 0, 0, 12, 0); + + check_logging = gtk_check_button_new_with_mnemonic (_("Enable Logging")); + gtk_widget_set_name (check_logging, "check_logging"); + gtk_widget_show (check_logging); + gtk_container_add (GTK_CONTAINER (alignment1), check_logging); + + label15 = gtk_label_new (_("Logging")); + gtk_widget_set_name (label15, "label15"); + gtk_widget_show (label15); + gtk_frame_set_label_widget (GTK_FRAME (frame3), label15); + gtk_label_set_use_markup (GTK_LABEL (label15), TRUE); + + hbuttonbox1 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox1, "hbuttonbox1"); + gtk_widget_show (hbuttonbox1); + gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, TRUE, TRUE, 0); + gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 30); + + button1 = gtk_button_new_with_mnemonic (_("Ok")); + gtk_widget_set_name (button1, "button1"); + gtk_widget_show (button1); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), button1); + GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); + + button2 = gtk_button_new_with_mnemonic (_("Cancel")); + gtk_widget_set_name (button2, "button2"); + gtk_widget_show (button2); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), button2); + GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) button1, "clicked", + G_CALLBACK (OnConf_Ok), + NULL); + g_signal_connect ((gpointer) button2, "clicked", + G_CALLBACK (OnConf_Cancel), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (Config, Config, "Config"); + GLADE_HOOKUP_OBJECT (Config, vbox1, "vbox1"); + GLADE_HOOKUP_OBJECT (Config, frame3, "frame3"); + GLADE_HOOKUP_OBJECT (Config, alignment1, "alignment1"); + GLADE_HOOKUP_OBJECT (Config, check_logging, "check_logging"); + GLADE_HOOKUP_OBJECT (Config, label15, "label15"); + GLADE_HOOKUP_OBJECT (Config, hbuttonbox1, "hbuttonbox1"); + GLADE_HOOKUP_OBJECT (Config, button1, "button1"); + GLADE_HOOKUP_OBJECT (Config, button2, "button2"); + + return Config; +} + +GtkWidget* +create_About (void) +{ + GtkWidget *About; + GtkWidget *vbox2; + GtkWidget *label2; + GtkWidget *label3; + GtkWidget *hbuttonbox2; + GtkWidget *button3; + + About = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (About, "About"); + gtk_container_set_border_width (GTK_CONTAINER (About), 5); + gtk_window_set_title (GTK_WINDOW (About), _("SPU2about")); + + vbox2 = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (vbox2, "vbox2"); + gtk_widget_show (vbox2); + gtk_container_add (GTK_CONTAINER (About), vbox2); + gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5); + + label2 = gtk_label_new (_("SPU2 Null Driver")); + gtk_widget_set_name (label2, "label2"); + gtk_widget_show (label2); + gtk_box_pack_start (GTK_BOX (vbox2), label2, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER); + + label3 = gtk_label_new (_("Original Author: ? (zerofrog? linuz?)\nRevised by arcum42@gmail.com")); + gtk_widget_set_name (label3, "label3"); + gtk_widget_show (label3); + gtk_box_pack_start (GTK_BOX (vbox2), label3, FALSE, FALSE, 0); + + hbuttonbox2 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox2, "hbuttonbox2"); + gtk_widget_show (hbuttonbox2); + gtk_box_pack_start (GTK_BOX (vbox2), hbuttonbox2, TRUE, TRUE, 0); + gtk_box_set_spacing (GTK_BOX (hbuttonbox2), 30); + + button3 = gtk_button_new_with_mnemonic (_("Ok")); + gtk_widget_set_name (button3, "button3"); + gtk_widget_show (button3); + gtk_container_add (GTK_CONTAINER (hbuttonbox2), button3); + GTK_WIDGET_SET_FLAGS (button3, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) button3, "clicked", + G_CALLBACK (OnAbout_Ok), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (About, About, "About"); + GLADE_HOOKUP_OBJECT (About, vbox2, "vbox2"); + GLADE_HOOKUP_OBJECT (About, label2, "label2"); + GLADE_HOOKUP_OBJECT (About, label3, "label3"); + GLADE_HOOKUP_OBJECT (About, hbuttonbox2, "hbuttonbox2"); + GLADE_HOOKUP_OBJECT (About, button3, "button3"); + + return About; +} + diff --git a/plugins/SPU2null/Linux/interface.h b/plugins/SPU2null/Linux/interface.h new file mode 100644 index 0000000000..69c303ba3b --- /dev/null +++ b/plugins/SPU2null/Linux/interface.h @@ -0,0 +1,6 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +GtkWidget* create_Config (void); +GtkWidget* create_About (void); diff --git a/plugins/SPU2null/Linux/spu2.glade b/plugins/SPU2null/Linux/spu2.glade new file mode 100644 index 0000000000..75ce9f6b74 --- /dev/null +++ b/plugins/SPU2null/Linux/spu2.glade @@ -0,0 +1,241 @@ + + + + + + + 5 + True + SPU2config + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + 5 + True + False + 5 + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + True + Enable Logging + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + + + + + True + <b>Logging</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + True + GTK_BUTTONBOX_DEFAULT_STYLE + 30 + + + + True + True + True + Ok + True + GTK_RELIEF_NORMAL + True + + + + + + + True + True + True + Cancel + True + GTK_RELIEF_NORMAL + True + + + + + + 0 + True + True + + + + + + + + 5 + True + SPU2about + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + 5 + True + False + 5 + + + + True + SPU2 Null Driver + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + Original Author: ? (zerofrog? linuz?) +Revised by arcum42@gmail.com + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + GTK_BUTTONBOX_DEFAULT_STYLE + 30 + + + + True + True + True + Ok + True + GTK_RELIEF_NORMAL + True + + + + + + 0 + True + True + + + + + + + diff --git a/plugins/SPU2null/Linux/support.c b/plugins/SPU2null/Linux/support.c new file mode 100644 index 0000000000..00aff29822 --- /dev/null +++ b/plugins/SPU2null/Linux/support.c @@ -0,0 +1,144 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include + +#include "support.h" + +GtkWidget* +lookup_widget (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (!parent) + parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + +static GList *pixmaps_directories = NULL; + +/* Use this function to set the directory containing installed pixmaps. */ +void +add_pixmap_directory (const gchar *directory) +{ + pixmaps_directories = g_list_prepend (pixmaps_directories, + g_strdup (directory)); +} + +/* This is an internally used function to find pixmap files. */ +static gchar* +find_pixmap_file (const gchar *filename) +{ + GList *elem; + + /* We step through each of the pixmaps directory to find it. */ + elem = pixmaps_directories; + while (elem) + { + gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data, + G_DIR_SEPARATOR_S, filename); + if (g_file_test (pathname, G_FILE_TEST_EXISTS)) + return pathname; + g_free (pathname); + elem = elem->next; + } + return NULL; +} + +/* This is an internally used function to create pixmaps. */ +GtkWidget* +create_pixmap (GtkWidget *widget, + const gchar *filename) +{ + gchar *pathname = NULL; + GtkWidget *pixmap; + + if (!filename || !filename[0]) + return gtk_image_new (); + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return gtk_image_new (); + } + + pixmap = gtk_image_new_from_file (pathname); + g_free (pathname); + return pixmap; +} + +/* This is an internally used function to create pixmaps. */ +GdkPixbuf* +create_pixbuf (const gchar *filename) +{ + gchar *pathname = NULL; + GdkPixbuf *pixbuf; + GError *error = NULL; + + if (!filename || !filename[0]) + return NULL; + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return NULL; + } + + pixbuf = gdk_pixbuf_new_from_file (pathname, &error); + if (!pixbuf) + { + fprintf (stderr, "Failed to load pixbuf file: %s: %s\n", + pathname, error->message); + g_error_free (error); + } + g_free (pathname); + return pixbuf; +} + +/* This is used to set ATK action descriptions. */ +void +glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description) +{ + gint n_actions, i; + + n_actions = atk_action_get_n_actions (action); + for (i = 0; i < n_actions; i++) + { + if (!strcmp (atk_action_get_name (action, i), action_name)) + atk_action_set_description (action, i, description); + } +} + diff --git a/plugins/SPU2null/Linux/support.h b/plugins/SPU2null/Linux/support.h new file mode 100644 index 0000000000..a32649e53c --- /dev/null +++ b/plugins/SPU2null/Linux/support.h @@ -0,0 +1,69 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* + * Standard gettext macros. + */ +#ifdef ENABLE_NLS +# include +# undef _ +# define _(String) dgettext (PACKAGE, String) +# define Q_(String) g_strip_context ((String), gettext (String)) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define Q_(String) g_strip_context ((String), (String)) +# define N_(String) (String) +#endif + + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* lookup_widget (GtkWidget *widget, + const gchar *widget_name); + + +/* Use this function to set the directory containing installed pixmaps. */ +void add_pixmap_directory (const gchar *directory); + + +/* + * Private Functions. + */ + +/* This is used to create the pixmaps used in the interface. */ +GtkWidget* create_pixmap (GtkWidget *widget, + const gchar *filename); + +/* This is used to create the pixbufs used in the interface. */ +GdkPixbuf* create_pixbuf (const gchar *filename); + +/* This is used to set ATK action descriptions. */ +void glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description); + diff --git a/plugins/SPU2null/Makefile.am b/plugins/SPU2null/Makefile.am index 394dba22a3..768683e86f 100644 --- a/plugins/SPU2null/Makefile.am +++ b/plugins/SPU2null/Makefile.am @@ -22,6 +22,11 @@ libSPU2null_LDFLAGS= @SHARED_LDFLAGS@ libSPU2null_LDFLAGS+=-Wl,-soname,@libSPU2null_SONAME@ libSPU2null_LDADD=$(libSPU2null_a_OBJECTS) -libSPU2null_a_SOURCES = SPU2.cpp SPU2.h Linux/Config.cpp +libSPU2null_a_SOURCES = SPU2.cpp SPU2.h Linux/Config.cpp + +libSPU2null_a_SOURCES += \ +Linux/interface.h Linux/support.c \ +Linux/interface.c Linux/support.h \ +Linux/callbacks.h #SUBDIRS = Linux \ No newline at end of file diff --git a/plugins/SPU2null/SPU2.cpp b/plugins/SPU2null/SPU2.cpp index e8a8e23697..5b2033ca7c 100644 --- a/plugins/SPU2null/SPU2.cpp +++ b/plugins/SPU2null/SPU2.cpp @@ -20,11 +20,13 @@ #include #include - -const unsigned char version = PS2E_SPU2_VERSION; -const unsigned char revision = 0; -const unsigned char build = 7; // increase that with each version -const unsigned int minor = 1; // increase that with each version +#include +using namespace std; + +const u8 version = PS2E_SPU2_VERSION; +const u8 revision = 0; +const u8 build = 8; // increase that with each version +const u32 minor = 0; // increase that with each version // ADSR constants #define ATTACK_MS 494L @@ -33,11 +35,12 @@ const unsigned int minor = 1; // increase that with each version #define SUSTAIN_MS 441L #define RELEASE_MS 437L -#ifdef _DEBUG +#ifdef PCSX2_DEBUG char *libraryName = "SPU2null (Debug)"; #else char *libraryName = "SPU2null "; #endif +string s_strIniPath="inis/SPU2null.ini"; FILE *spu2Log; Config conf; @@ -47,16 +50,16 @@ ADMA Adma7; u32 MemAddr[2]; u32 g_nSpuInit = 0; -unsigned short interrupt = 0; +u16 interrupt = 0; s8 *spu2regs = NULL; u16* spu2mem = NULL; u16* pSpuIrq[2] = {NULL}; u32 dwEndChannel2[2] = {0}; // keeps track of what channels have ended -unsigned long dwNoiseVal = 1; // global noise generator +u32 dwNoiseVal = 1; // global noise generator -int SPUCycles = 0, SPUWorkerCycles = 0; -int SPUStartCycle[2]; -int SPUTargetCycle[2]; +s32 SPUCycles = 0, SPUWorkerCycles = 0; +s32 SPUStartCycle[2]; +s32 SPUTargetCycle[2]; int ADMAS4Write(); int ADMAS7Write(); @@ -67,7 +70,7 @@ void (*irqCallbackSPU2)(); // func of main emu, called on spu i void (*irqCallbackDMA4)() = 0; // func of main emu, called on spu irq void (*irqCallbackDMA7)() = 0; // func of main emu, called on spu irq -const int f[5][2] = { +const s32 f[5][2] = { { 0, 0 }, { 60, 0 }, { 115, -52 }, @@ -218,9 +221,9 @@ EXPORT_C_(void) SPU2async(u32 cycle) void InitADSR() // INIT ADSR { - unsigned long r, rs, rd; - int i; - memset(RateTable, 0, sizeof(unsigned long)*160); // build the rate table according to Neill's rules (see at bottom of file) + u32 r, rs, rd; + s32 i; + memset(RateTable, 0, sizeof(u32)*160); // build the rate table according to Neill's rules (see at bottom of file) r = 3; rs = 1; @@ -675,9 +678,9 @@ int ADMAS4Write() spuaddr = C0_SPUADDR; // SPU2 Deinterleaves the Left and Right Channels - memcpy((short*)(spu2mem + spuaddr + 0x2000), (short*)Adma4.MemAddr, 512); + memcpy((s16*)(spu2mem + spuaddr + 0x2000), (s16*)Adma4.MemAddr, 512); Adma4.MemAddr += 256; - memcpy((short*)(spu2mem + spuaddr + 0x2200), (short*)Adma4.MemAddr, 512); + memcpy((s16*)(spu2mem + spuaddr + 0x2200), (s16*)Adma4.MemAddr, 512); Adma4.MemAddr += 256; spuaddr = (spuaddr + 256) & 511; C0_SPUADDR_SET(spuaddr); @@ -701,9 +704,9 @@ int ADMAS7Write() spuaddr = C1_SPUADDR; // SPU2 Deinterleaves the Left and Right Channels - memcpy((short*)(spu2mem + spuaddr + 0x2400), (short*)Adma7.MemAddr, 512); + memcpy((s16*)(spu2mem + spuaddr + 0x2400), (s16*)Adma7.MemAddr, 512); Adma7.MemAddr += 256; - memcpy((short*)(spu2mem + spuaddr + 0x2600), (short*)Adma7.MemAddr, 512); + memcpy((s16*)(spu2mem + spuaddr + 0x2600), (s16*)Adma7.MemAddr, 512); Adma7.MemAddr += 256; spuaddr = (spuaddr + 256) & 511; C1_SPUADDR_SET(spuaddr); @@ -737,7 +740,7 @@ EXPORT_C_(void) SPU2writeDMA4Mem(u16* pMem, int size) } spuaddr = C0_SPUADDR; - memcpy((unsigned char*)(spu2mem + spuaddr), (unsigned char*)pMem, size << 1); + memcpy((u8*)(spu2mem + spuaddr), (u8*)pMem, size << 1); spuaddr += size; C0_SPUADDR_SET(spuaddr); @@ -776,7 +779,7 @@ EXPORT_C_(void) SPU2writeDMA7Mem(u16* pMem, int size) } spuaddr = C1_SPUADDR; - memcpy((unsigned char*)(spu2mem + spuaddr), (unsigned char*)pMem, size << 1); + memcpy((u8*)(spu2mem + spuaddr), (u8*)pMem, size << 1); spuaddr += size; C1_SPUADDR_SET(spuaddr); @@ -817,9 +820,9 @@ EXPORT_C_(void) SPU2interruptDMA7() } // turn channels on -void SoundOn(int start, int end, unsigned short val) // SOUND ON PSX COMAND +void SoundOn(s32 start, s32 end, u16 val) // SOUND ON PSX COMAND { - for (int ch = start;ch < end;ch++, val >>= 1) // loop channels + for (s32 ch = start;ch < end;ch++, val >>= 1) // loop channels { if ((val&1) && voices[ch].pStart) // mmm... start has to be set before key on !?! { @@ -830,16 +833,16 @@ void SoundOn(int start, int end, unsigned short val) // SOUND ON PSX COMAND } // turn channels off -void SoundOff(int start, int end, unsigned short val) // SOUND OFF PSX COMMAND +void SoundOff(s32 start, s32 end, u16 val) // SOUND OFF PSX COMMAND { - for (int ch = start;ch < end;ch++, val >>= 1) // loop channels + for (s32 ch = start;ch < end;ch++, val >>= 1) // loop channels { if (val&1) // && s_chan[i].bOn) mmm... voices[ch].bStop = true; } } -void FModOn(int start, int end, unsigned short val) // FMOD ON PSX COMMAND +void FModOn(s32 start, s32 end, u16 val) // FMOD ON PSX COMMAND { int ch; @@ -888,8 +891,10 @@ EXPORT_C_(void) SPU2write(u32 mem, u16 value) case 4: { int NP; - if (value > 0x3fff) NP = 0x3fff; // get pitch val - else NP = value; + if (value > 0x3fff) + NP = 0x3fff; // get pitch val + else + NP = value; pvoice->pvoice->pitch = NP; @@ -921,8 +926,8 @@ EXPORT_C_(void) SPU2write(u32 mem, u16 value) // more channel info if ((r >= 0x01c0 && r <= 0x02E0) || (r >= 0x05c0 && r <= 0x06E0)) { - int ch = 0; - unsigned long rx = r; + s32 ch = 0; + u32 rx = r; if (rx >= 0x400) { ch = 24; @@ -936,7 +941,7 @@ EXPORT_C_(void) SPU2write(u32 mem, u16 value) switch (rx) { case 0x1C0: - pvoice->iStartAddr = (((unsigned long)value & 0x3f) << 16) | (pvoice->iStartAddr & 0xFFFF); + pvoice->iStartAddr = (((u32)value & 0x3f) << 16) | (pvoice->iStartAddr & 0xFFFF); pvoice->pStart = (u8*)(spu2mem + pvoice->iStartAddr); break; case 0x1C2: @@ -944,7 +949,7 @@ EXPORT_C_(void) SPU2write(u32 mem, u16 value) pvoice->pStart = (u8*)(spu2mem + pvoice->iStartAddr); break; case 0x1C4: - pvoice->iLoopAddr = (((unsigned long)value & 0x3f) << 16) | (pvoice->iLoopAddr & 0xFFFF); + pvoice->iLoopAddr = (((u32)value & 0x3f) << 16) | (pvoice->iLoopAddr & 0xFFFF); pvoice->pLoop = (u8*)(spu2mem + pvoice->iLoopAddr); pvoice->bIgnoreLoop = pvoice->iLoopAddr > 0; break; @@ -955,7 +960,7 @@ EXPORT_C_(void) SPU2write(u32 mem, u16 value) break; case 0x1C8: // unused... check if it gets written as well - pvoice->iNextAddr = (((unsigned long)value & 0x3f) << 16) | (pvoice->iNextAddr & 0xFFFF); + pvoice->iNextAddr = (((u32)value & 0x3f) << 16) | (pvoice->iNextAddr & 0xFFFF); break; case 0x1CA: // unused... check if it gets written as well @@ -979,8 +984,8 @@ EXPORT_C_(void) SPU2write(u32 mem, u16 value) IRQINFO |= 4; irqCallbackSPU2(); } - if (spuaddr > 0xFFFFE) - spuaddr = 0x2800; + if (spuaddr > 0xFFFFE) spuaddr = 0x2800; + C0_SPUADDR_SET(spuaddr); spu2Ru16(REG_C0_SPUSTAT) &= ~0x80; spu2Ru16(REG_C0_CTRL) &= ~0x30; @@ -995,8 +1000,8 @@ EXPORT_C_(void) SPU2write(u32 mem, u16 value) IRQINFO |= 8; irqCallbackSPU2(); } - if (spuaddr > 0xFFFFE) - spuaddr = 0x2800; + if (spuaddr > 0xFFFFE) spuaddr = 0x2800; + C1_SPUADDR_SET(spuaddr); spu2Ru16(REG_C1_SPUSTAT) &= ~0x80; spu2Ru16(REG_C1_CTRL) &= ~0x30; @@ -1079,23 +1084,27 @@ EXPORT_C_(u16) SPU2read(u32 mem) if ((r >= 0x0000 && r <= 0x0180) || (r >= 0x0400 && r <= 0x0580)) // some channel info? { - int ch = 0; - if (r >= 0x400) ch = ((r - 0x400) >> 4) + 24; - else ch = (r >> 4); + s32 ch = 0; + + if (r >= 0x400) + ch = ((r - 0x400) >> 4) + 24; + else + ch = (r >> 4); VOICE_PROCESSED* pvoice = &voices[ch]; switch (r&0x0f) { case 10: - return (unsigned short)(pvoice->ADSRX.EnvelopeVol >> 16); + return (u16)(pvoice->ADSRX.EnvelopeVol >> 16); } } if ((r > 0x01c0 && r <= 0x02E0) || (r > 0x05c0 && r <= 0x06E0)) // some channel info? { - int ch = 0; - unsigned long rx = r; + s32 ch = 0; + u32 rx = r; + if (rx >= 0x400) { ch = 24; @@ -1129,16 +1138,15 @@ EXPORT_C_(u16) SPU2read(u32 mem) spuaddr = C0_SPUADDR; ret = spu2mem[spuaddr]; spuaddr++; - if (spuaddr > 0xfffff) - spuaddr = 0; + if (spuaddr > 0xfffff) spuaddr = 0; C0_SPUADDR_SET(spuaddr); break; + case REG_C1_SPUDATA: spuaddr = C1_SPUADDR; ret = spu2mem[spuaddr]; spuaddr++; - if (spuaddr > 0xfffff) - spuaddr = 0; + if (spuaddr > 0xfffff) spuaddr = 0; C1_SPUADDR_SET(spuaddr); break; @@ -1193,7 +1201,7 @@ void VOICE_PROCESSED::SetVolume(int iProcessRight) if (vol&0x8000) // sweep not working { - short sInc = 1; // -> sweep up? + s16 sInc = 1; // -> sweep up? if (vol&0x2000) sInc = -1; // -> or down? if (vol&0x1000) vol ^= 0xffff; // -> mmm... phase inverted? have to investigate this vol = ((vol & 0x7f) + 1) / 2; // -> sweep: 0..127 -> 0..64 @@ -1267,7 +1275,10 @@ EXPORT_C_(s32) SPU2freeze(int mode, freezeData *data) { memcpy(spu2regs, spud->spu2regs, 0x10000); } - else printf("SPU2null wrong format\n"); + else + { + printf("SPU2null wrong format\n"); + } } else if (mode == FREEZE_SAVE) diff --git a/plugins/SPU2null/SPU2.h b/plugins/SPU2null/SPU2.h index 842ff27b85..eb65db59ef 100644 --- a/plugins/SPU2null/SPU2.h +++ b/plugins/SPU2null/SPU2.h @@ -15,7 +15,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + #ifndef __SPU2_H__ #define __SPU2_H__ @@ -46,15 +46,15 @@ extern "C" extern FILE *spu2Log; #define SPU2_LOG __Log //debug mode -extern const unsigned char version; -extern const unsigned char revision; -extern const unsigned char build; -extern const unsigned int minor; +extern const u8 version; +extern const u8 revision; +extern const u8 build; +extern const u32 minor; extern char *libraryName; typedef struct { - int Log; + s32 Log; } Config; extern Config conf; @@ -218,18 +218,18 @@ struct _SPU_VOICE // ADSR INFOS PER CHANNEL struct ADSRInfoEx { - int State; - int AttackModeExp; - int AttackRate; - int DecayRate; - int SustainLevel; - int SustainModeExp; - int SustainIncrease; - int SustainRate; - int ReleaseModeExp; - int ReleaseRate; - int EnvelopeVol; - long lVolume; + s32 State; + s32 AttackModeExp; + s32 AttackRate; + s32 DecayRate; + s32 SustainLevel; + s32 SustainModeExp; + s32 SustainIncrease; + s32 SustainRate; + s32 ReleaseModeExp; + s32 ReleaseRate; + s32 EnvelopeVol; + s32 lVolume; }; #define NSSIZE 48 // ~ 1 ms of data @@ -257,18 +257,18 @@ struct VOICE_PROCESSED // start save state - int iSBPos; // mixing stuff - int spos; - int sinc; + s32 iSBPos; // mixing stuff + s32 spos; + s32 sinc; - int iActFreq; // current psx pitch - int iUsedFreq; // current pc pitch + s32 iActFreq; // current psx pitch + s32 iUsedFreq; // current pc pitch - int iStartAddr, iLoopAddr, iNextAddr; + s32 iStartAddr, iLoopAddr, iNextAddr; ADSRInfoEx ADSRX; // next ADSR settings (will be moved to active on sample start) bool bIgnoreLoop, bNew, bNoise, bReverb, bOn, bStop, bVolChanged; - int memoffset; // if first core, 0, if second, 0x400 + s32 memoffset; // if first core, 0, if second, 0x400 // end save state @@ -283,11 +283,11 @@ struct VOICE_PROCESSED struct ADMA { - unsigned short * MemAddr; - long IntPointer; - int Index; - int AmountLeft; - int Enabled; + u16 * MemAddr; + s32 IntPointer; + s32 Index; + s32 AmountLeft; + s32 Enabled; }; #endif /* __SPU2_H__ */ diff --git a/plugins/SPU2null/configure.ac b/plugins/SPU2null/configure.ac index 59ffe18988..67a5de0468 100644 --- a/plugins/SPU2null/configure.ac +++ b/plugins/SPU2null/configure.ac @@ -1,6 +1,6 @@ -AC_INIT(SPU2null, 0.5,arcum42@gmail.com) +AC_INIT(SPU2null, 0.71,arcum42@gmail.com) -AM_INIT_AUTOMAKE(SPU2null,0.8) +AM_INIT_AUTOMAKE(SPU2null,0.71) AC_PROG_CC([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) AC_PROG_CXX([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) @@ -13,14 +13,15 @@ dnl necessary for compiling assembly AM_PROG_AS AC_SUBST(SPU2null_CURRENT, 0) -AC_SUBST(SPU2null_REVISION, 8) -AC_SUBST(SPU2null_AGE, 0) +AC_SUBST(SPU2null_REVISION, 7) +AC_SUBST(SPU2null_AGE, 1) AC_SUBST(SPU2null_RELEASE,[$SPU2null_CURRENT].[$SPU2null_REVISION].[$SPU2null_AGE]) AC_SUBST(SPU2null_SONAME,libSPU2null.so.[$SPU2null_CURRENT].[$SPU2null_REVISION].[$SPU2null_AGE]) CFLAGS= CPPFLAGS= CXXFLAGS= +CCASFLAGS= dnl Check for debug build AC_MSG_CHECKING(debug build) @@ -28,15 +29,17 @@ AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [debug build]), debug=$enableval,debug=no) if test "x$debug" == xyes then - AC_DEFINE(_DEBUG,1,[_DEBUG]) - CFLAGS+="-g -fPIC -Wall -Wno-unused-value " - CPPFLAGS+="-g -fPIC -Wall -Wno-unused-value " - CXXFLAGS+="-g -fPIC -Wall -Wno-unused-value " + AC_DEFINE(PCSX2_DEBUG,1,[PCSX2_DEBUG]) + CFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CPPFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CXXFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CCASFLAGS+=" -m32 " else AC_DEFINE(NDEBUG,1,[NDEBUG]) - CFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value " - CPPFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value " - CXXFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value " + CFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CPPFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CXXFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CCASFLAGS+=" -m32 " fi AM_CONDITIONAL(DEBUGBUILD, test x$debug = xyes) AC_MSG_RESULT($debug) diff --git a/plugins/USBnull/Linux/Config.cpp b/plugins/USBnull/Linux/Config.cpp index 1456f2e2d6..a931f6cfde 100644 --- a/plugins/USBnull/Linux/Config.cpp +++ b/plugins/USBnull/Linux/Config.cpp @@ -26,14 +26,21 @@ #include using namespace std; +#include "USB.h" +#include "Config.h" + + #ifdef __cplusplus extern "C" { -#include "interface.h" -#include "support.h" -//#include "callbacks.h" -} +#endif -#include "USB.h" +#include "support.h" +#include "callbacks.h" +#include "interface.h" + +#ifdef __cplusplus +} +#endif GtkWidget *MsgDlg, *About, *Conf; extern string s_strIniPath; @@ -44,7 +51,7 @@ void OnMsg_Ok() gtk_main_quit(); } -void cfgSysMessage(char *fmt, ...) +void SysMessage(char *fmt, ...) { GtkWidget *Ok, *Txt; GtkWidget *Box, *Box1; @@ -92,7 +99,7 @@ void OnAbout_Ok(GtkButton *button, gpointer user_data) gtk_main_quit(); } -void CFGabout() +EXPORT_C_(void) USBabout() { About = create_About(); gtk_widget_show_all(About); @@ -101,6 +108,9 @@ void CFGabout() void OnConf_Ok(GtkButton *button, gpointer user_data) { + conf.Log = is_checked(Conf, "check_logging"); + SaveConfig(); + gtk_widget_destroy(Conf); gtk_main_quit(); } @@ -111,21 +121,16 @@ void OnConf_Cancel(GtkButton *button, gpointer user_data) gtk_main_quit(); } -void CFGconfigure() +EXPORT_C_(void) USBconfigure() { + LoadConfig(); Conf = create_Config(); + set_checked(Conf, "check_logging", conf.Log); gtk_widget_show_all(Conf); gtk_main(); } -long CFGmessage(char *msg) -{ - cfgSysMessage(msg); - - return 0; -} - void LoadConfig() { FILE *f; @@ -135,10 +140,11 @@ void LoadConfig() f = fopen(cfg, "r"); if (f == NULL) { - printf("failed to open %s\n", s_strIniPath.c_str()); + printf("failed to open '%s'\n", s_strIniPath.c_str()); SaveConfig();//save and return return; } + fscanf(f, "logging = %hhx\n", &conf.Log); //fscanf(f, "options = %hhx\n", &confOptions); fclose(f); } @@ -152,10 +158,11 @@ void SaveConfig() f = fopen(cfg,"w"); if (f == NULL) { - printf("failed to open %s\n", s_strIniPath.c_str()); + printf("failed to open '%s'\n", s_strIniPath.c_str()); return; } + fprintf(f, "logging = %hhx\n", conf.Log); //fprintf(f, "options = %hhx\n", confOptions); fclose(f); } diff --git a/plugins/USBnull/Linux/Config.h b/plugins/USBnull/Linux/Config.h index c4036d30ed..54fddc414f 100644 --- a/plugins/USBnull/Linux/Config.h +++ b/plugins/USBnull/Linux/Config.h @@ -18,7 +18,7 @@ void SaveConfig(); void LoadConfig(); -void cfgSysMessage(char *fmt, ...); -void CFGabout(); -void CFGconfigure(); -long CFGmessage(char *msg); +void SysMessage(char *fmt, ...); + +#define is_checked(main_widget, widget_name) (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)))) +#define set_checked(main_widget,widget_name, state) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)), state) diff --git a/plugins/USBnull/Linux/Linux.cpp b/plugins/USBnull/Linux/Linux.cpp index 739a7a8162..8ab4944954 100644 --- a/plugins/USBnull/Linux/Linux.cpp +++ b/plugins/USBnull/Linux/Linux.cpp @@ -28,7 +28,7 @@ #include "USB.h" #include "Config.h" -void SysMessage(char *fmt, ...) +/*void SysMessage(char *fmt, ...) { va_list list; char msg[512]; @@ -39,9 +39,9 @@ void SysMessage(char *fmt, ...) va_end(list); cfgSysMessage(msg); -} +}*/ -void USBconfigure() +/*void USBconfigure() { CFGconfigure(); } @@ -49,5 +49,5 @@ void USBconfigure() void USBabout() { CFGabout(); -} +}*/ diff --git a/plugins/USBnull/Linux/interface.c b/plugins/USBnull/Linux/interface.c index 5c23358a21..0e304b63fe 100644 --- a/plugins/USBnull/Linux/interface.c +++ b/plugins/USBnull/Linux/interface.c @@ -31,28 +31,18 @@ create_Config (void) { GtkWidget *Config; GtkWidget *vbox1; - GtkWidget *frame2; - GtkWidget *hbox1; - GtkWidget *label4; - GtkWidget *GtkCombo_Eth; - GList *GtkCombo_Eth_items = NULL; - GtkWidget *combo_entry1; - GtkWidget *label1; GtkWidget *frame3; - GtkWidget *hbox2; - GtkWidget *label5; - GtkWidget *GtkCombo_Hdd; - GList *GtkCombo_Hdd_items = NULL; - GtkWidget *entry1; + GtkWidget *alignment1; + GtkWidget *check_logging; GtkWidget *label15; - GtkWidget *hbuttonbox1; - GtkWidget *button1; - GtkWidget *button2; + GtkWidget *hbuttonbox3; + GtkWidget *button4; + GtkWidget *button5; Config = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_name (Config, "Config"); gtk_container_set_border_width (GTK_CONTAINER (Config), 5); - gtk_window_set_title (GTK_WINDOW (Config), _("DEV9config")); + gtk_window_set_title (GTK_WINDOW (Config), _("USBconfig")); vbox1 = gtk_vbox_new (FALSE, 5); gtk_widget_set_name (vbox1, "vbox1"); @@ -60,121 +50,63 @@ create_Config (void) gtk_container_add (GTK_CONTAINER (Config), vbox1); gtk_container_set_border_width (GTK_CONTAINER (vbox1), 5); - frame2 = gtk_frame_new (NULL); - gtk_widget_set_name (frame2, "frame2"); - gtk_widget_show (frame2); - gtk_box_pack_start (GTK_BOX (vbox1), frame2, TRUE, TRUE, 0); - - hbox1 = gtk_hbox_new (TRUE, 5); - gtk_widget_set_name (hbox1, "hbox1"); - gtk_widget_show (hbox1); - gtk_container_add (GTK_CONTAINER (frame2), hbox1); - gtk_container_set_border_width (GTK_CONTAINER (hbox1), 5); - - label4 = gtk_label_new (_("Device:")); - gtk_widget_set_name (label4, "label4"); - gtk_widget_show (label4); - gtk_box_pack_start (GTK_BOX (hbox1), label4, FALSE, FALSE, 0); - gtk_label_set_justify (GTK_LABEL (label4), GTK_JUSTIFY_CENTER); - - GtkCombo_Eth = gtk_combo_new (); - g_object_set_data (G_OBJECT (GTK_COMBO (GtkCombo_Eth)->popwin), - "GladeParentKey", GtkCombo_Eth); - gtk_widget_set_name (GtkCombo_Eth, "GtkCombo_Eth"); - gtk_widget_show (GtkCombo_Eth); - gtk_box_pack_start (GTK_BOX (hbox1), GtkCombo_Eth, FALSE, FALSE, 0); - GtkCombo_Eth_items = g_list_append (GtkCombo_Eth_items, (gpointer) ""); - gtk_combo_set_popdown_strings (GTK_COMBO (GtkCombo_Eth), GtkCombo_Eth_items); - g_list_free (GtkCombo_Eth_items); - - combo_entry1 = GTK_COMBO (GtkCombo_Eth)->entry; - gtk_widget_set_name (combo_entry1, "combo_entry1"); - gtk_widget_show (combo_entry1); - - label1 = gtk_label_new (_("Ethernet")); - gtk_widget_set_name (label1, "label1"); - gtk_widget_show (label1); - gtk_frame_set_label_widget (GTK_FRAME (frame2), label1); - frame3 = gtk_frame_new (NULL); gtk_widget_set_name (frame3, "frame3"); gtk_widget_show (frame3); gtk_box_pack_start (GTK_BOX (vbox1), frame3, TRUE, TRUE, 0); - hbox2 = gtk_hbox_new (TRUE, 5); - gtk_widget_set_name (hbox2, "hbox2"); - gtk_widget_show (hbox2); - gtk_container_add (GTK_CONTAINER (frame3), hbox2); - gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5); + alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_set_name (alignment1, "alignment1"); + gtk_widget_show (alignment1); + gtk_container_add (GTK_CONTAINER (frame3), alignment1); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment1), 0, 0, 12, 0); - label5 = gtk_label_new (_("Device:")); - gtk_widget_set_name (label5, "label5"); - gtk_widget_show (label5); - gtk_box_pack_start (GTK_BOX (hbox2), label5, FALSE, FALSE, 0); - gtk_label_set_justify (GTK_LABEL (label5), GTK_JUSTIFY_CENTER); + check_logging = gtk_check_button_new_with_mnemonic (_("Enable Logging")); + gtk_widget_set_name (check_logging, "check_logging"); + gtk_widget_show (check_logging); + gtk_container_add (GTK_CONTAINER (alignment1), check_logging); - GtkCombo_Hdd = gtk_combo_new (); - g_object_set_data (G_OBJECT (GTK_COMBO (GtkCombo_Hdd)->popwin), - "GladeParentKey", GtkCombo_Hdd); - gtk_widget_set_name (GtkCombo_Hdd, "GtkCombo_Hdd"); - gtk_widget_show (GtkCombo_Hdd); - gtk_box_pack_start (GTK_BOX (hbox2), GtkCombo_Hdd, FALSE, FALSE, 0); - GtkCombo_Hdd_items = g_list_append (GtkCombo_Hdd_items, (gpointer) ""); - gtk_combo_set_popdown_strings (GTK_COMBO (GtkCombo_Hdd), GtkCombo_Hdd_items); - g_list_free (GtkCombo_Hdd_items); - - entry1 = GTK_COMBO (GtkCombo_Hdd)->entry; - gtk_widget_set_name (entry1, "entry1"); - gtk_widget_show (entry1); - - label15 = gtk_label_new (_("Hdd")); + label15 = gtk_label_new (_("Logging")); gtk_widget_set_name (label15, "label15"); gtk_widget_show (label15); gtk_frame_set_label_widget (GTK_FRAME (frame3), label15); + gtk_label_set_use_markup (GTK_LABEL (label15), TRUE); - hbuttonbox1 = gtk_hbutton_box_new (); - gtk_widget_set_name (hbuttonbox1, "hbuttonbox1"); - gtk_widget_show (hbuttonbox1); - gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, TRUE, TRUE, 0); - gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 30); + hbuttonbox3 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox3, "hbuttonbox3"); + gtk_widget_show (hbuttonbox3); + gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox3, TRUE, TRUE, 0); + gtk_box_set_spacing (GTK_BOX (hbuttonbox3), 30); - button1 = gtk_button_new_with_mnemonic (_("Ok")); - gtk_widget_set_name (button1, "button1"); - gtk_widget_show (button1); - gtk_container_add (GTK_CONTAINER (hbuttonbox1), button1); - GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); + button4 = gtk_button_new_with_mnemonic (_("Ok")); + gtk_widget_set_name (button4, "button4"); + gtk_widget_show (button4); + gtk_container_add (GTK_CONTAINER (hbuttonbox3), button4); + GTK_WIDGET_SET_FLAGS (button4, GTK_CAN_DEFAULT); - button2 = gtk_button_new_with_mnemonic (_("Cancel")); - gtk_widget_set_name (button2, "button2"); - gtk_widget_show (button2); - gtk_container_add (GTK_CONTAINER (hbuttonbox1), button2); - GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); + button5 = gtk_button_new_with_mnemonic (_("Cancel")); + gtk_widget_set_name (button5, "button5"); + gtk_widget_show (button5); + gtk_container_add (GTK_CONTAINER (hbuttonbox3), button5); + GTK_WIDGET_SET_FLAGS (button5, GTK_CAN_DEFAULT); - g_signal_connect ((gpointer) button1, "clicked", + g_signal_connect ((gpointer) button4, "clicked", G_CALLBACK (OnConf_Ok), NULL); - g_signal_connect ((gpointer) button2, "clicked", + g_signal_connect ((gpointer) button5, "clicked", G_CALLBACK (OnConf_Cancel), NULL); /* Store pointers to all widgets, for use by lookup_widget(). */ GLADE_HOOKUP_OBJECT_NO_REF (Config, Config, "Config"); GLADE_HOOKUP_OBJECT (Config, vbox1, "vbox1"); - GLADE_HOOKUP_OBJECT (Config, frame2, "frame2"); - GLADE_HOOKUP_OBJECT (Config, hbox1, "hbox1"); - GLADE_HOOKUP_OBJECT (Config, label4, "label4"); - GLADE_HOOKUP_OBJECT (Config, GtkCombo_Eth, "GtkCombo_Eth"); - GLADE_HOOKUP_OBJECT (Config, combo_entry1, "combo_entry1"); - GLADE_HOOKUP_OBJECT (Config, label1, "label1"); GLADE_HOOKUP_OBJECT (Config, frame3, "frame3"); - GLADE_HOOKUP_OBJECT (Config, hbox2, "hbox2"); - GLADE_HOOKUP_OBJECT (Config, label5, "label5"); - GLADE_HOOKUP_OBJECT (Config, GtkCombo_Hdd, "GtkCombo_Hdd"); - GLADE_HOOKUP_OBJECT (Config, entry1, "entry1"); + GLADE_HOOKUP_OBJECT (Config, alignment1, "alignment1"); + GLADE_HOOKUP_OBJECT (Config, check_logging, "check_logging"); GLADE_HOOKUP_OBJECT (Config, label15, "label15"); - GLADE_HOOKUP_OBJECT (Config, hbuttonbox1, "hbuttonbox1"); - GLADE_HOOKUP_OBJECT (Config, button1, "button1"); - GLADE_HOOKUP_OBJECT (Config, button2, "button2"); + GLADE_HOOKUP_OBJECT (Config, hbuttonbox3, "hbuttonbox3"); + GLADE_HOOKUP_OBJECT (Config, button4, "button4"); + GLADE_HOOKUP_OBJECT (Config, button5, "button5"); return Config; } @@ -200,13 +132,13 @@ create_About (void) gtk_container_add (GTK_CONTAINER (About), vbox2); gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5); - label2 = gtk_label_new (_("FireWire Driver")); + label2 = gtk_label_new (_("USB Null Driver")); gtk_widget_set_name (label2, "label2"); gtk_widget_show (label2); gtk_box_pack_start (GTK_BOX (vbox2), label2, FALSE, FALSE, 0); gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER); - label3 = gtk_label_new (_("Author: linuzappz ")); + label3 = gtk_label_new (_("Original Author: linuzappz \nRevised by arcum42@gmail.com.")); gtk_widget_set_name (label3, "label3"); gtk_widget_show (label3); gtk_box_pack_start (GTK_BOX (vbox2), label3, FALSE, FALSE, 0); diff --git a/plugins/USBnull/Linux/usbnull.glade b/plugins/USBnull/Linux/usbnull.glade index cef4eab65e..03afe746ac 100644 --- a/plugins/USBnull/Linux/usbnull.glade +++ b/plugins/USBnull/Linux/usbnull.glade @@ -6,7 +6,7 @@ 5 True - DEV9config + USBconfig GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False @@ -27,140 +27,6 @@ False 5 - - - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - 5 - True - True - 5 - - - - True - Device: - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - False - True - False - True - False - - - - True - True - True - True - 0 - - True - * - False - - - - - - True - GTK_SELECTION_BROWSE - - - - True - - - - True - - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - - - - - - - 0 - False - False - - - - - - - - True - Ethernet - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - True @@ -169,98 +35,29 @@ GTK_SHADOW_ETCHED_IN - - 5 + True - True - 5 + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 - + True - Device: - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 + True + Enable Logging + True + GTK_RELIEF_NORMAL + True + False + False + True - - 0 - False - False - - - - - - True - False - True - False - True - False - - - - True - True - True - True - 0 - - True - * - False - - - - - - True - GTK_SELECTION_BROWSE - - - - True - - - - True - - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - - - - - - - 0 - False - False - @@ -268,9 +65,9 @@ True - Hdd + <b>Logging</b> False - False + True GTK_JUSTIFY_LEFT False False @@ -296,13 +93,13 @@ - + True GTK_BUTTONBOX_DEFAULT_STYLE 30 - + True True True @@ -315,7 +112,7 @@ - + True True True @@ -364,7 +161,7 @@ True - FireWire Driver + USB Null Driver False False GTK_JUSTIFY_CENTER @@ -389,7 +186,8 @@ True - Author: linuzappz <linuzappz@hotmail.com> + Original Author: linuzappz <linuzappz@hotmail.com> +Revised by arcum42@gmail.com. False False GTK_JUSTIFY_LEFT diff --git a/plugins/USBnull/Makefile.am b/plugins/USBnull/Makefile.am index d4241d3ad0..b341b28e91 100644 --- a/plugins/USBnull/Makefile.am +++ b/plugins/USBnull/Makefile.am @@ -28,6 +28,6 @@ USB.h Linux/Config.h Linux/Linux.h libUSBnull_a_SOURCES += \ Linux/interface.h Linux/support.c \ Linux/interface.c Linux/support.h \ -Linux/callbacks.c Linux/callbacks.h +Linux/callbacks.h #SUBDIRS = Linux \ No newline at end of file diff --git a/plugins/USBnull/USB.cpp b/plugins/USBnull/USB.cpp index 6aa6bab4bc..3afa17d50f 100644 --- a/plugins/USBnull/USB.cpp +++ b/plugins/USBnull/USB.cpp @@ -23,13 +23,13 @@ using namespace std; #include "USB.h" -string s_strIniPath; const unsigned char version = PS2E_USB_VERSION; const unsigned char revision = 0; const unsigned char build = 6; // increase that with each version static char *libraryName = "USBnull Driver"; +string s_strIniPath="inis/USBnull.ini"; //void (*USBirq)(); USBcallback USBirq; Config conf; @@ -95,35 +95,35 @@ EXPORT_C_(void) USBclose() EXPORT_C_(u8 ) USBread8(u32 addr) { - USB_LOG("*UnKnown 8bit read at address %lx ", addr); + USB_LOG("*Unknown 8bit read at address %lx ", addr); return 0; } EXPORT_C_(u16) USBread16(u32 addr) { - USB_LOG("*UnKnown 16bit read at address %lx", addr); + USB_LOG("*Unknown 16bit read at address %lx", addr); return 0; } EXPORT_C_(u32) USBread32(u32 addr) { - USB_LOG("*UnKnown 32bit read at address %lx", addr); + USB_LOG("*Unknown 32bit read at address %lx", addr); return 0; } EXPORT_C_(void) USBwrite8(u32 addr, u8 value) { - USB_LOG("*UnKnown 8bit write at address %lx value %x\n", addr, value); + USB_LOG("*Unknown 8bit write at address %lx value %x\n", addr, value); } EXPORT_C_(void) USBwrite16(u32 addr, u16 value) { - USB_LOG("*UnKnown 16bit write at address %lx value %x\n", addr, value); + USB_LOG("*Unknown 16bit write at address %lx value %x\n", addr, value); } EXPORT_C_(void) USBwrite32(u32 addr, u32 value) { - USB_LOG("*UnKnown 32bit write at address %lx value %lx\n", addr, value); + USB_LOG("*Unknown 32bit write at address %lx value %lx\n", addr, value); } EXPORT_C_(void) USBirqCallback(USBcallback callback) @@ -143,6 +143,7 @@ EXPORT_C_(USBhandler) USBirqHandler(void) EXPORT_C_(void) USBsetRAM(void *mem) { + USB_LOG("*Setting ram.\n"); } // extended funcs diff --git a/plugins/USBnull/USB.h b/plugins/USBnull/USB.h index b10424e5d1..382753ba3a 100644 --- a/plugins/USBnull/USB.h +++ b/plugins/USBnull/USB.h @@ -1,5 +1,5 @@ -/* USBlinuz - * Copyright (C) 2002-2004 USBlinuz Team +/* USBnull + * Copyright (C) 2002-2009 pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,17 +16,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef __USB_H__ #define __USB_H__ #include -extern "C" -{ #define USBdefs #include "PS2Edefs.h" -} #ifdef _WIN32 diff --git a/plugins/USBnull/Windows/USBnull_vc2008.vcproj b/plugins/USBnull/Windows/USBnull_vc2008.vcproj index 6aa6dc011d..fd6980a38b 100644 --- a/plugins/USBnull/Windows/USBnull_vc2008.vcproj +++ b/plugins/USBnull/Windows/USBnull_vc2008.vcproj @@ -39,9 +39,6 @@ /> @@ -105,10 +102,6 @@ /> -#include -#include +#include #include -#include "PS2Etypes.h" +#include +#include +using namespace std; + #include "DEV9.h" const unsigned char version = PS2E_DEV9_VERSION; @@ -28,9 +29,11 @@ const unsigned char revision = 0; const unsigned char build = 4; // increase that with each version const char *libraryName = "DEV9null Driver"; +string s_strIniPath="inis/DEV9null.ini"; -void (*DEV9irq)(); +void (*DEV9irq)(int); FILE *dev9Log; +Config conf; EXPORT_C_(u32) PS2EgetLibType() { @@ -47,10 +50,12 @@ EXPORT_C_(u32) PS2EgetLibVersion2(u32 type) return (version<<16) | (revision<<8) | build; } -void __Log(char *fmt, ...) +void __Log(char *fmt, ...) { va_list list; + if (!conf.Log || dev9Log == NULL) return; + va_start(list, fmt); vfprintf(dev9Log, fmt, list); va_end(list); @@ -58,11 +63,25 @@ void __Log(char *fmt, ...) EXPORT_C_(s32) DEV9init() { +#ifdef __LINUX__ // for until we get a win32 version sorted out / implemented... + LoadConfig(); +#endif + +#ifdef DEV9_LOG + dev9Log = fopen("logs/dev9Log.txt", "w"); + if (dev9Log) setvbuf(dev9Log, NULL, _IONBF, 0); + DEV9_LOG("dev9null plugin version %d,%d\n", revision, build); + DEV9_LOG("DEV9init\n"); +#endif + return 0; } EXPORT_C_(void) DEV9shutdown() { +#ifdef DEV9_LOG + if (dev9Log) fclose(dev9Log); +#endif } EXPORT_C_(s32) DEV9open(void *pDsp) @@ -77,42 +96,50 @@ EXPORT_C_(void) DEV9close() EXPORT_C_(u8) DEV9read8(u32 addr) { + DEV9_LOG("*Unknown 8bit read at address %lx ", addr); return 0; } EXPORT_C_(u16 ) DEV9read16(u32 addr) { + DEV9_LOG("*Unknown 16bit read at address %lx ", addr); return 0; } EXPORT_C_(u32 ) DEV9read32(u32 addr) { + DEV9_LOG("*Unknown 32bit read at address %lx ", addr); return 0; } EXPORT_C_(void) DEV9write8(u32 addr, u8 value) { + DEV9_LOG("*Unknown 8bit write at address %lx value %x\n", addr, value); } EXPORT_C_(void) DEV9write16(u32 addr, u16 value) { + DEV9_LOG("*Unknown 16bit write at address %lx value %x\n", addr, value); } EXPORT_C_(void) DEV9write32(u32 addr, u32 value) { + DEV9_LOG("*Unknown 32bit write at address %lx value %x\n", addr, value); } EXPORT_C_(void) DEV9readDMA8Mem(u32 *pMem, int size) { + DEV9_LOG("Reading DMA8 Mem."); } EXPORT_C_(void) DEV9writeDMA8Mem(u32* pMem, int size) { + DEV9_LOG("Writing DMA8 Mem."); } EXPORT_C_(void) DEV9irqCallback(DEV9callback callback) { - + DEV9irq = callback; } EXPORT_C_(DEV9handler) DEV9irqHandler(void) @@ -127,6 +154,7 @@ EXPORT_C_(s32) DEV9test() return 0; } +#ifdef _WIN32 EXPORT_C_(void) DEV9configure() { SysMessage("Nothing to Configure"); @@ -136,8 +164,6 @@ EXPORT_C_(void) DEV9about() { } -#ifdef _WIN32 - HINSTANCE hInst; void SysMessage(const char *fmt, ...) diff --git a/plugins/dev9null/DEV9.h b/plugins/dev9null/DEV9.h index a827a0e019..4a8da1fdcb 100644 --- a/plugins/dev9null/DEV9.h +++ b/plugins/dev9null/DEV9.h @@ -1,3 +1,21 @@ +/* dev9null + * Copyright (C) 2002-2009 pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + #ifndef __DEV9_H__ #define __DEV9_H__ @@ -11,11 +29,15 @@ #include #endif -extern "C" -{ #define DEV9defs #include "PS2Edefs.h" -} + +typedef struct { + int Log; +} Config; + +extern Config conf; +#define DEV9_LOG __Log /*#ifdef _MSC_VER #define EXPORT_C_(type) extern "C" __declspec(dllexport) type CALLBACK @@ -35,7 +57,10 @@ extern const unsigned char build; extern const unsigned int minor; extern const char *libraryName; -extern void (*DEV9irq)(); +void SaveConfig(); +void LoadConfig(); + +extern void (*DEV9irq)(int); extern void SysMessage(const char *fmt, ...); extern FILE *dev9Log; diff --git a/plugins/dev9null/Linux/Config.cpp b/plugins/dev9null/Linux/Config.cpp index 89b686d779..fb99c4381d 100644 --- a/plugins/dev9null/Linux/Config.cpp +++ b/plugins/dev9null/Linux/Config.cpp @@ -16,15 +16,35 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#include "Config.h" #include "DEV9.h" + #ifdef __cplusplus + +extern "C" +{ +#endif -#include -#include -#include -#include +#include "support.h" +#include "callbacks.h" +#include "interface.h" -GtkWidget *MsgDlg; +#ifdef __cplusplus +} +#endif + +GtkWidget *MsgDlg, *About, *Conf; +extern string s_strIniPath; void OnMsg_Ok() { @@ -74,6 +94,76 @@ void SysMessage(const char *fmt, ...) gtk_main(); } -void LoadConfig() +void OnAbout_Ok(GtkButton *button, gpointer user_data) { + gtk_widget_destroy(About); + gtk_main_quit(); } + +EXPORT_C_(void) DEV9about() +{ + About = create_About(); + gtk_widget_show_all(About); + gtk_main(); +} + +void OnConf_Ok(GtkButton *button, gpointer user_data) +{ + conf.Log = is_checked(Conf, "check_logging"); + SaveConfig(); + + gtk_widget_destroy(Conf); + gtk_main_quit(); +} + +void OnConf_Cancel(GtkButton *button, gpointer user_data) +{ + gtk_widget_destroy(Conf); + gtk_main_quit(); +} + +EXPORT_C_(void) DEV9configure() +{ + LoadConfig(); + Conf = create_Config(); + + set_checked(Conf, "check_logging", conf.Log); + gtk_widget_show_all(Conf); + gtk_main(); +} + +void LoadConfig() +{ + FILE *f; + char cfg[255]; + + strcpy(cfg, s_strIniPath.c_str()); + f = fopen(cfg, "r"); + if (f == NULL) + { + printf("failed to open %s\n", s_strIniPath.c_str()); + SaveConfig();//save and return + return; + } + fscanf(f, "logging = %hhx\n", &conf.Log); + //fscanf(f, "options = %hhx\n", &confOptions); + fclose(f); +} + +void SaveConfig() +{ + FILE *f; + char cfg[255]; + + strcpy(cfg, s_strIniPath.c_str()); + f = fopen(cfg,"w"); + if (f == NULL) + { + printf("failed to open '%s'\n", s_strIniPath.c_str()); + return; + } + fprintf(f, "logging = %hhx\n", conf.Log); + //fprintf(f, "options = %hhx\n", confOptions); + fclose(f); +} + diff --git a/plugins/dev9null/Linux/Config.h b/plugins/dev9null/Linux/Config.h new file mode 100644 index 0000000000..a5de746902 --- /dev/null +++ b/plugins/dev9null/Linux/Config.h @@ -0,0 +1,24 @@ +/* dev9null + * Copyright (C) 2004-2009 PCSX2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +void SaveConfig(); +void LoadConfig(); +void SysMessage(char *fmt, ...); + +#define is_checked(main_widget, widget_name) (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)))) +#define set_checked(main_widget,widget_name, state) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)), state) diff --git a/plugins/dev9null/Linux/callbacks.c b/plugins/dev9null/Linux/callbacks.c new file mode 100644 index 0000000000..e87ed8be2d --- /dev/null +++ b/plugins/dev9null/Linux/callbacks.c @@ -0,0 +1,34 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + + +void +OnConf_Ok (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConf_Cancel (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnAbout_Ok (GtkButton *button, + gpointer user_data) +{ + +} + diff --git a/plugins/dev9null/Linux/callbacks.h b/plugins/dev9null/Linux/callbacks.h new file mode 100644 index 0000000000..e606c242f0 --- /dev/null +++ b/plugins/dev9null/Linux/callbacks.h @@ -0,0 +1,14 @@ +#include + + +void +OnConf_Ok (GtkButton *button, + gpointer user_data); + +void +OnConf_Cancel (GtkButton *button, + gpointer user_data); + +void +OnAbout_Ok (GtkButton *button, + gpointer user_data); diff --git a/plugins/dev9null/Linux/dev9.glade b/plugins/dev9null/Linux/dev9.glade new file mode 100644 index 0000000000..204ecc3db2 --- /dev/null +++ b/plugins/dev9null/Linux/dev9.glade @@ -0,0 +1,509 @@ + + + + + + + 5 + True + DEV9config + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + 5 + True + False + 5 + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + 5 + True + True + 5 + + + + True + Device: + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + True + False + True + False + + + + True + True + True + True + 0 + + True + * + False + + + + + + True + GTK_SELECTION_BROWSE + + + + True + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + + + + + 0 + False + False + + + + + + + + True + Ethernet + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + 5 + True + True + 5 + + + + True + Device: + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + True + False + True + False + + + + True + True + True + True + 0 + + True + * + False + + + + + + True + GTK_SELECTION_BROWSE + + + + True + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + + + + + 0 + False + False + + + + + + + + True + Hdd + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + True + Enable Logging + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + + + + + True + <b>Logging</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + True + GTK_BUTTONBOX_DEFAULT_STYLE + 30 + + + + True + True + True + Ok + True + GTK_RELIEF_NORMAL + True + + + + + + + True + True + True + Cancel + True + GTK_RELIEF_NORMAL + True + + + + + + 0 + True + True + + + + + + + + 5 + True + DEV9about + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + 5 + True + False + 5 + + + + True + Dev9 null Driver + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + Original Author: linuzappz <linuzappz@hotmail.com> +Revised by arcum42@gmail.com + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + GTK_BUTTONBOX_DEFAULT_STYLE + 30 + + + + True + True + True + Ok + True + GTK_RELIEF_NORMAL + True + + + + + + 0 + True + True + + + + + + + diff --git a/plugins/dev9null/Linux/interface.c b/plugins/dev9null/Linux/interface.c new file mode 100644 index 0000000000..9625f99b79 --- /dev/null +++ b/plugins/dev9null/Linux/interface.c @@ -0,0 +1,271 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ + g_object_set_data (G_OBJECT (component), name, widget) + +GtkWidget* +create_Config (void) +{ + GtkWidget *Config; + GtkWidget *vbox1; + GtkWidget *frame2; + GtkWidget *hbox1; + GtkWidget *label4; + GtkWidget *GtkCombo_Eth; + GList *GtkCombo_Eth_items = NULL; + GtkWidget *combo_entry1; + GtkWidget *label1; + GtkWidget *frame3; + GtkWidget *hbox2; + GtkWidget *label5; + GtkWidget *GtkCombo_Hdd; + GList *GtkCombo_Hdd_items = NULL; + GtkWidget *entry1; + GtkWidget *label15; + GtkWidget *frame4; + GtkWidget *alignment1; + GtkWidget *check_logging; + GtkWidget *label16; + GtkWidget *hbuttonbox1; + GtkWidget *button1; + GtkWidget *button2; + + Config = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (Config, "Config"); + gtk_container_set_border_width (GTK_CONTAINER (Config), 5); + gtk_window_set_title (GTK_WINDOW (Config), _("DEV9config")); + + vbox1 = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (vbox1, "vbox1"); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (Config), vbox1); + gtk_container_set_border_width (GTK_CONTAINER (vbox1), 5); + + frame2 = gtk_frame_new (NULL); + gtk_widget_set_name (frame2, "frame2"); + gtk_widget_show (frame2); + gtk_box_pack_start (GTK_BOX (vbox1), frame2, TRUE, TRUE, 0); + + hbox1 = gtk_hbox_new (TRUE, 5); + gtk_widget_set_name (hbox1, "hbox1"); + gtk_widget_show (hbox1); + gtk_container_add (GTK_CONTAINER (frame2), hbox1); + gtk_container_set_border_width (GTK_CONTAINER (hbox1), 5); + + label4 = gtk_label_new (_("Device:")); + gtk_widget_set_name (label4, "label4"); + gtk_widget_show (label4); + gtk_box_pack_start (GTK_BOX (hbox1), label4, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label4), GTK_JUSTIFY_CENTER); + + GtkCombo_Eth = gtk_combo_new (); + g_object_set_data (G_OBJECT (GTK_COMBO (GtkCombo_Eth)->popwin), + "GladeParentKey", GtkCombo_Eth); + gtk_widget_set_name (GtkCombo_Eth, "GtkCombo_Eth"); + gtk_widget_show (GtkCombo_Eth); + gtk_box_pack_start (GTK_BOX (hbox1), GtkCombo_Eth, FALSE, FALSE, 0); + GtkCombo_Eth_items = g_list_append (GtkCombo_Eth_items, (gpointer) ""); + gtk_combo_set_popdown_strings (GTK_COMBO (GtkCombo_Eth), GtkCombo_Eth_items); + g_list_free (GtkCombo_Eth_items); + + combo_entry1 = GTK_COMBO (GtkCombo_Eth)->entry; + gtk_widget_set_name (combo_entry1, "combo_entry1"); + gtk_widget_show (combo_entry1); + + label1 = gtk_label_new (_("Ethernet")); + gtk_widget_set_name (label1, "label1"); + gtk_widget_show (label1); + gtk_frame_set_label_widget (GTK_FRAME (frame2), label1); + + frame3 = gtk_frame_new (NULL); + gtk_widget_set_name (frame3, "frame3"); + gtk_widget_show (frame3); + gtk_box_pack_start (GTK_BOX (vbox1), frame3, TRUE, TRUE, 0); + + hbox2 = gtk_hbox_new (TRUE, 5); + gtk_widget_set_name (hbox2, "hbox2"); + gtk_widget_show (hbox2); + gtk_container_add (GTK_CONTAINER (frame3), hbox2); + gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5); + + label5 = gtk_label_new (_("Device:")); + gtk_widget_set_name (label5, "label5"); + gtk_widget_show (label5); + gtk_box_pack_start (GTK_BOX (hbox2), label5, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label5), GTK_JUSTIFY_CENTER); + + GtkCombo_Hdd = gtk_combo_new (); + g_object_set_data (G_OBJECT (GTK_COMBO (GtkCombo_Hdd)->popwin), + "GladeParentKey", GtkCombo_Hdd); + gtk_widget_set_name (GtkCombo_Hdd, "GtkCombo_Hdd"); + gtk_widget_show (GtkCombo_Hdd); + gtk_box_pack_start (GTK_BOX (hbox2), GtkCombo_Hdd, FALSE, FALSE, 0); + GtkCombo_Hdd_items = g_list_append (GtkCombo_Hdd_items, (gpointer) ""); + gtk_combo_set_popdown_strings (GTK_COMBO (GtkCombo_Hdd), GtkCombo_Hdd_items); + g_list_free (GtkCombo_Hdd_items); + + entry1 = GTK_COMBO (GtkCombo_Hdd)->entry; + gtk_widget_set_name (entry1, "entry1"); + gtk_widget_show (entry1); + + label15 = gtk_label_new (_("Hdd")); + gtk_widget_set_name (label15, "label15"); + gtk_widget_show (label15); + gtk_frame_set_label_widget (GTK_FRAME (frame3), label15); + + frame4 = gtk_frame_new (NULL); + gtk_widget_set_name (frame4, "frame4"); + gtk_widget_show (frame4); + gtk_box_pack_start (GTK_BOX (vbox1), frame4, TRUE, TRUE, 0); + gtk_frame_set_shadow_type (GTK_FRAME (frame4), GTK_SHADOW_NONE); + + alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_set_name (alignment1, "alignment1"); + gtk_widget_show (alignment1); + gtk_container_add (GTK_CONTAINER (frame4), alignment1); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment1), 0, 0, 12, 0); + + check_logging = gtk_check_button_new_with_mnemonic (_("Enable Logging")); + gtk_widget_set_name (check_logging, "check_logging"); + gtk_widget_show (check_logging); + gtk_container_add (GTK_CONTAINER (alignment1), check_logging); + + label16 = gtk_label_new (_("Logging")); + gtk_widget_set_name (label16, "label16"); + gtk_widget_show (label16); + gtk_frame_set_label_widget (GTK_FRAME (frame4), label16); + gtk_label_set_use_markup (GTK_LABEL (label16), TRUE); + + hbuttonbox1 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox1, "hbuttonbox1"); + gtk_widget_show (hbuttonbox1); + gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, TRUE, TRUE, 0); + gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 30); + + button1 = gtk_button_new_with_mnemonic (_("Ok")); + gtk_widget_set_name (button1, "button1"); + gtk_widget_show (button1); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), button1); + GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); + + button2 = gtk_button_new_with_mnemonic (_("Cancel")); + gtk_widget_set_name (button2, "button2"); + gtk_widget_show (button2); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), button2); + GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) button1, "clicked", + G_CALLBACK (OnConf_Ok), + NULL); + g_signal_connect ((gpointer) button2, "clicked", + G_CALLBACK (OnConf_Cancel), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (Config, Config, "Config"); + GLADE_HOOKUP_OBJECT (Config, vbox1, "vbox1"); + GLADE_HOOKUP_OBJECT (Config, frame2, "frame2"); + GLADE_HOOKUP_OBJECT (Config, hbox1, "hbox1"); + GLADE_HOOKUP_OBJECT (Config, label4, "label4"); + GLADE_HOOKUP_OBJECT (Config, GtkCombo_Eth, "GtkCombo_Eth"); + GLADE_HOOKUP_OBJECT (Config, combo_entry1, "combo_entry1"); + GLADE_HOOKUP_OBJECT (Config, label1, "label1"); + GLADE_HOOKUP_OBJECT (Config, frame3, "frame3"); + GLADE_HOOKUP_OBJECT (Config, hbox2, "hbox2"); + GLADE_HOOKUP_OBJECT (Config, label5, "label5"); + GLADE_HOOKUP_OBJECT (Config, GtkCombo_Hdd, "GtkCombo_Hdd"); + GLADE_HOOKUP_OBJECT (Config, entry1, "entry1"); + GLADE_HOOKUP_OBJECT (Config, label15, "label15"); + GLADE_HOOKUP_OBJECT (Config, frame4, "frame4"); + GLADE_HOOKUP_OBJECT (Config, alignment1, "alignment1"); + GLADE_HOOKUP_OBJECT (Config, check_logging, "check_logging"); + GLADE_HOOKUP_OBJECT (Config, label16, "label16"); + GLADE_HOOKUP_OBJECT (Config, hbuttonbox1, "hbuttonbox1"); + GLADE_HOOKUP_OBJECT (Config, button1, "button1"); + GLADE_HOOKUP_OBJECT (Config, button2, "button2"); + + return Config; +} + +GtkWidget* +create_About (void) +{ + GtkWidget *About; + GtkWidget *vbox2; + GtkWidget *label2; + GtkWidget *label3; + GtkWidget *hbuttonbox2; + GtkWidget *button3; + + About = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (About, "About"); + gtk_container_set_border_width (GTK_CONTAINER (About), 5); + gtk_window_set_title (GTK_WINDOW (About), _("DEV9about")); + + vbox2 = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (vbox2, "vbox2"); + gtk_widget_show (vbox2); + gtk_container_add (GTK_CONTAINER (About), vbox2); + gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5); + + label2 = gtk_label_new (_("Dev9 null Driver")); + gtk_widget_set_name (label2, "label2"); + gtk_widget_show (label2); + gtk_box_pack_start (GTK_BOX (vbox2), label2, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER); + + label3 = gtk_label_new (_("Original Author: linuzappz \nRevised by arcum42@gmail.com")); + gtk_widget_set_name (label3, "label3"); + gtk_widget_show (label3); + gtk_box_pack_start (GTK_BOX (vbox2), label3, FALSE, FALSE, 0); + + hbuttonbox2 = gtk_hbutton_box_new (); + gtk_widget_set_name (hbuttonbox2, "hbuttonbox2"); + gtk_widget_show (hbuttonbox2); + gtk_box_pack_start (GTK_BOX (vbox2), hbuttonbox2, TRUE, TRUE, 0); + gtk_box_set_spacing (GTK_BOX (hbuttonbox2), 30); + + button3 = gtk_button_new_with_mnemonic (_("Ok")); + gtk_widget_set_name (button3, "button3"); + gtk_widget_show (button3); + gtk_container_add (GTK_CONTAINER (hbuttonbox2), button3); + GTK_WIDGET_SET_FLAGS (button3, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) button3, "clicked", + G_CALLBACK (OnAbout_Ok), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (About, About, "About"); + GLADE_HOOKUP_OBJECT (About, vbox2, "vbox2"); + GLADE_HOOKUP_OBJECT (About, label2, "label2"); + GLADE_HOOKUP_OBJECT (About, label3, "label3"); + GLADE_HOOKUP_OBJECT (About, hbuttonbox2, "hbuttonbox2"); + GLADE_HOOKUP_OBJECT (About, button3, "button3"); + + return About; +} + diff --git a/plugins/dev9null/Linux/interface.h b/plugins/dev9null/Linux/interface.h new file mode 100644 index 0000000000..69c303ba3b --- /dev/null +++ b/plugins/dev9null/Linux/interface.h @@ -0,0 +1,6 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +GtkWidget* create_Config (void); +GtkWidget* create_About (void); diff --git a/plugins/dev9null/Linux/support.c b/plugins/dev9null/Linux/support.c new file mode 100644 index 0000000000..00aff29822 --- /dev/null +++ b/plugins/dev9null/Linux/support.c @@ -0,0 +1,144 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include + +#include "support.h" + +GtkWidget* +lookup_widget (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (!parent) + parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + +static GList *pixmaps_directories = NULL; + +/* Use this function to set the directory containing installed pixmaps. */ +void +add_pixmap_directory (const gchar *directory) +{ + pixmaps_directories = g_list_prepend (pixmaps_directories, + g_strdup (directory)); +} + +/* This is an internally used function to find pixmap files. */ +static gchar* +find_pixmap_file (const gchar *filename) +{ + GList *elem; + + /* We step through each of the pixmaps directory to find it. */ + elem = pixmaps_directories; + while (elem) + { + gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data, + G_DIR_SEPARATOR_S, filename); + if (g_file_test (pathname, G_FILE_TEST_EXISTS)) + return pathname; + g_free (pathname); + elem = elem->next; + } + return NULL; +} + +/* This is an internally used function to create pixmaps. */ +GtkWidget* +create_pixmap (GtkWidget *widget, + const gchar *filename) +{ + gchar *pathname = NULL; + GtkWidget *pixmap; + + if (!filename || !filename[0]) + return gtk_image_new (); + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return gtk_image_new (); + } + + pixmap = gtk_image_new_from_file (pathname); + g_free (pathname); + return pixmap; +} + +/* This is an internally used function to create pixmaps. */ +GdkPixbuf* +create_pixbuf (const gchar *filename) +{ + gchar *pathname = NULL; + GdkPixbuf *pixbuf; + GError *error = NULL; + + if (!filename || !filename[0]) + return NULL; + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return NULL; + } + + pixbuf = gdk_pixbuf_new_from_file (pathname, &error); + if (!pixbuf) + { + fprintf (stderr, "Failed to load pixbuf file: %s: %s\n", + pathname, error->message); + g_error_free (error); + } + g_free (pathname); + return pixbuf; +} + +/* This is used to set ATK action descriptions. */ +void +glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description) +{ + gint n_actions, i; + + n_actions = atk_action_get_n_actions (action); + for (i = 0; i < n_actions; i++) + { + if (!strcmp (atk_action_get_name (action, i), action_name)) + atk_action_set_description (action, i, description); + } +} + diff --git a/plugins/dev9null/Linux/support.h b/plugins/dev9null/Linux/support.h new file mode 100644 index 0000000000..a32649e53c --- /dev/null +++ b/plugins/dev9null/Linux/support.h @@ -0,0 +1,69 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* + * Standard gettext macros. + */ +#ifdef ENABLE_NLS +# include +# undef _ +# define _(String) dgettext (PACKAGE, String) +# define Q_(String) g_strip_context ((String), gettext (String)) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define Q_(String) g_strip_context ((String), (String)) +# define N_(String) (String) +#endif + + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* lookup_widget (GtkWidget *widget, + const gchar *widget_name); + + +/* Use this function to set the directory containing installed pixmaps. */ +void add_pixmap_directory (const gchar *directory); + + +/* + * Private Functions. + */ + +/* This is used to create the pixmaps used in the interface. */ +GtkWidget* create_pixmap (GtkWidget *widget, + const gchar *filename); + +/* This is used to create the pixbufs used in the interface. */ +GdkPixbuf* create_pixbuf (const gchar *filename); + +/* This is used to set ATK action descriptions. */ +void glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description); + diff --git a/plugins/dev9null/Makefile.am b/plugins/dev9null/Makefile.am index 708b882df6..d8137623c7 100644 --- a/plugins/dev9null/Makefile.am +++ b/plugins/dev9null/Makefile.am @@ -22,6 +22,10 @@ libDEV9null_LDFLAGS= @SHARED_LDFLAGS@ libDEV9null_LDFLAGS+=-Wl,-soname,@libDEV9null_SONAME@ libDEV9null_LDADD=$(libDEV9null_a_OBJECTS) -libDEV9null_a_SOURCES = DEV9.cpp DEV9.h Linux/Config.cpp +libDEV9null_a_SOURCES = DEV9.cpp DEV9.h Linux/Config.cpp Linux/Config.h +libDEV9null_a_SOURCES += \ +Linux/interface.h Linux/support.c \ +Linux/interface.c Linux/support.h \ +Linux/callbacks.h #SUBDIRS = Linux \ No newline at end of file diff --git a/plugins/dev9null/Windows/DEV9null_vc2008.vcproj b/plugins/dev9null/Windows/DEV9null_vc2008.vcproj index 84c15bd706..d572808963 100644 --- a/plugins/dev9null/Windows/DEV9null_vc2008.vcproj +++ b/plugins/dev9null/Windows/DEV9null_vc2008.vcproj @@ -86,7 +86,7 @@ @@ -107,10 +107,6 @@ /> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/plugins/spu2-x/LGPL.txt b/plugins/spu2-x/LGPL.txt index ebb7aa9340..a5043111dc 100644 --- a/plugins/spu2-x/LGPL.txt +++ b/plugins/spu2-x/LGPL.txt @@ -1,503 +1,164 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the Library. diff --git a/plugins/spu2-x/License.txt b/plugins/spu2-x/License.txt index 4f562f9be8..fc02b8d6df 100644 --- a/plugins/spu2-x/License.txt +++ b/plugins/spu2-x/License.txt @@ -1,6 +1,7 @@ [This file contains the template for the SPU2-X code rights license. For the full - rant-like preamble of the LGP, see LGPL.TXT.] + rant-like preamble of the LGPL, see GPL.txt and LGPL.txt -- both lisences apply, + with the LGPL as a subset extension of the GPL.] /* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 @@ -8,18 +9,14 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ \ No newline at end of file diff --git a/plugins/spu2-x/src/ADSR.cpp b/plugins/spu2-x/src/ADSR.cpp index 39fb3549f3..e11925b2d0 100644 --- a/plugins/spu2-x/src/ADSR.cpp +++ b/plugins/spu2-x/src/ADSR.cpp @@ -1,23 +1,19 @@ /* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 -* Developed and maintained by the Pcsx2 Development Team. -* -* Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] -* -* This library is free software; you can redistribute it and/or modify it under -* the terms of the GNU Lesser General Public License as published by the Free -* Software Foundation; either version 2.1 of the the License, or (at your -* option) any later version. -* -* This library is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License -* for more details. -* -* You should have received a copy of the GNU Lesser General Public License along -* with this library; if not, write to the Free Software Foundation, Inc., 59 -* Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -*/ + * Developed and maintained by the Pcsx2 Development Team. + * + * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] + * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ #include "Spu2.h" diff --git a/plugins/spu2-x/src/BaseTypes.h b/plugins/spu2-x/src/BaseTypes.h index 99a7ffc8cc..0ff1667d34 100644 --- a/plugins/spu2-x/src/BaseTypes.h +++ b/plugins/spu2-x/src/BaseTypes.h @@ -61,29 +61,17 @@ extern void SysMessage(const char *fmt, ...); // Abbreviated macros for dev/debug only consoles and msgboxes. #ifdef SPU2X_DEVBUILD - # define DevCon Console # define DevMsg MsgBox - static const bool IsDevBuild = true; - #else - # define DevCon 0&&Console # define DevMsg - static const bool IsDevBuild = false; - #endif -#ifdef _DEBUG - +#ifdef PCSX2_DEBUG # define DbgCon Console - static const bool IsDebugBuild = true; - #else - # define DbgCon 0&&Console -static const bool IsDebugBuild = false; - #endif struct StereoOut16; diff --git a/plugins/spu2-x/src/Debug.cpp b/plugins/spu2-x/src/Debug.cpp index dbf6293c91..404db45524 100644 --- a/plugins/spu2-x/src/Debug.cpp +++ b/plugins/spu2-x/src/Debug.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Spu2.h" diff --git a/plugins/spu2-x/src/DllInterface.cpp b/plugins/spu2-x/src/DllInterface.cpp index 6e55ec3101..e6d39bb691 100644 --- a/plugins/spu2-x/src/DllInterface.cpp +++ b/plugins/spu2-x/src/DllInterface.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Spu2.h" @@ -68,9 +64,9 @@ static void InitLibraryName() // subversion revision tags: strcpy( libraryName, "SPU2-X" - #ifdef _DEBUG_FAST + #ifdef DEBUG_FAST "-Debug" - #elif defined( DEBUG ) + #elif defined( PCSX2_DEBUG ) "-Debug/Strict" // strict debugging is slow! #else "-Dev" @@ -83,9 +79,9 @@ static void InitLibraryName() // to label the specific revision: sprintf_s( libraryName, "SPU2-X r%d%s" - #ifdef _DEBUG_FAST + #ifdef DEBUG_FAST "-Debug" - #elif defined( _DEBUG ) + #elif defined( PCSX2_DEBUG ) "-Debug/Strict" // strict debugging is slow! #else "-Dev" @@ -307,8 +303,7 @@ EXPORT_C_(void) SPU2shutdown() EXPORT_C_(void) SPU2setClockPtr(u32 *ptr) { - cPtr=ptr; - hasPtr=(cPtr!=NULL); + cyclePtr = ptr; } bool numpad_plus = false, numpad_plus_old = false; @@ -341,14 +336,14 @@ EXPORT_C_(void) SPU2async(u32 cycles) numpad_plus_old = numpad_plus;*/ } - if(hasPtr) + if(cyclePtr != NULL) { - TimeUpdate(*cPtr); + TimeUpdate( *cyclePtr ); } else { - pClocks+=cycles; - TimeUpdate(pClocks); + pClocks += cycles; + TimeUpdate( pClocks ); } } @@ -373,7 +368,8 @@ EXPORT_C_(u16) SPU2read(u32 rmem) } else { - TimeUpdate( *cPtr ); + if( cyclePtr != NULL ) + TimeUpdate( *cyclePtr ); if (rmem>>16 == 0x1f80) { @@ -430,7 +426,9 @@ EXPORT_C_(void) SPU2write(u32 rmem, u16 value) // If the SPU2 isn't in in sync with the IOP, samples can end up playing at rather // incorrect pitches and loop lengths. - TimeUpdate( *cPtr ); + if( cyclePtr != NULL ) + TimeUpdate( *cyclePtr ); + if (rmem>>16 == 0x1f80) SPU_ps1_write(rmem,value); else diff --git a/plugins/spu2-x/src/Dma.cpp b/plugins/spu2-x/src/Dma.cpp index b38bcb7149..8b2d4b102c 100644 --- a/plugins/spu2-x/src/Dma.cpp +++ b/plugins/spu2-x/src/Dma.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Spu2.h" @@ -313,7 +309,7 @@ void DoDMAWrite(int core,u16 *pMem,u32 size) void SPU2readDMA(int core, u16* pMem, u32 size) { - if(hasPtr) TimeUpdate(*cPtr); + if( cyclePtr != NULL ) TimeUpdate( *cyclePtr ); Cores[core].TSA &= 0xffff8; @@ -394,7 +390,7 @@ void SPU2readDMA(int core, u16* pMem, u32 size) void SPU2writeDMA(int core, u16* pMem, u32 size) { - if(hasPtr) TimeUpdate(*cPtr); + if(cyclePtr != NULL) TimeUpdate(*cyclePtr); Cores[core].DMAPtr=pMem; diff --git a/plugins/spu2-x/src/Linux/Alsa.cpp b/plugins/spu2-x/src/Linux/Alsa.cpp index 97df382e53..8f6cfa0484 100644 --- a/plugins/spu2-x/src/Linux/Alsa.cpp +++ b/plugins/spu2-x/src/Linux/Alsa.cpp @@ -1,48 +1,45 @@ -/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 - * Developed and maintained by the Pcsx2 Development Team. - * - * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] - * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - // Adapted from ZeroSPU2 code by Zerofrog. Heavily modified by Arcum42. - -#include - -#define ALSA_MEM_DEF -#include "Alsa.h" -#include "SndOut.h" - +/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 + * Developed and maintained by the Pcsx2 Development Team. + * + * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] + * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ + + // Adapted from ZeroSPU2 code by Zerofrog. Heavily modified by Arcum42. + +#include + +#define ALSA_MEM_DEF +#include "Alsa.h" +#include "SndOut.h" + class AlsaMod: public SndOutModule { protected: static const int PacketsPerBuffer = 1; // increase this if ALSA can't keep up with 512-sample packets static const int MAX_BUFFER_COUNT = 4; - static const int NumBuffers = 4; // TODO: this should be configurable someday -- lower values reduce latency. + static const int NumBuffers = 4; // TODO: this should be configurable someday -- lower values reduce latency. unsigned int pspeed; - - snd_pcm_t *handle; - snd_pcm_uframes_t buffer_size; + + snd_pcm_t *handle; + snd_pcm_uframes_t buffer_size; snd_async_handler_t *pcm_callback; - - uint period_time; - uint buffer_time; - -protected: - // Invoked by the static ExternalCallback method below. + + uint period_time; + uint buffer_time; + +protected: + // Invoked by the static ExternalCallback method below. void _InternalCallback() { snd_pcm_sframes_t avail; @@ -61,148 +58,148 @@ protected: avail = snd_pcm_avail_update(handle); } } - - // Preps and invokes the _InternalCallback above. This provides a cdecl-compliant - // entry point for our C++ified object state. :) - static void ExternalCallback( snd_async_handler_t *pcm_callback ) - { + + // Preps and invokes the _InternalCallback above. This provides a cdecl-compliant + // entry point for our C++ified object state. :) + static void ExternalCallback( snd_async_handler_t *pcm_callback ) + { AlsaMod *data = (AlsaMod*)snd_async_handler_get_callback_private( pcm_callback ); - - jASSUME( data != NULL ); - jASSUME( data->handle == snd_async_handler_get_pcm(pcm_callback) ); - - // Not sure if we just need an assert, or something like this: - //if( data->handle != snd_async_handler_get_pcm(pcm_callback) ) return; - - data->_InternalCallback(); - } - -public: - - s32 Init() - { - snd_pcm_hw_params_t *hwparams; - snd_pcm_sw_params_t *swparams; - snd_pcm_status_t *status; - int pchannels = 2; - snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE; - - handle = NULL; - pcm_callback = NULL; - pspeed = SAMPLE_RATE; - - // buffer time and period time are in microseconds... - // (don't simplify the equation below -- it'll just cause integer rounding errors. - period_time = (SndOutPacketSize*1000) / (SampleRate / 1000); - buffer_time = period_time * NumBuffers; - - int err; - - err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); - if(err < 0) - { - ERROR_LOG("Audio open error: %s\n", snd_strerror(err)); - return -1; - } - - err = snd_pcm_nonblock(handle, 0); - if(err < 0) - { - ERROR_LOG("Can't set blocking mode: %s\n", snd_strerror(err)); - return -1; - } - - snd_pcm_hw_params_alloca(&hwparams); - snd_pcm_sw_params_alloca(&swparams); - - err = snd_pcm_hw_params_any(handle, hwparams); - if (err < 0) - { - ERROR_LOG("Broken configuration for this PCM: %s\n", snd_strerror(err)); - return -1; - } - - err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); - if (err < 0) - { - ERROR_LOG("Access type not available: %s\n", snd_strerror(err)); - return -1; - } - - err = snd_pcm_hw_params_set_format(handle, hwparams, format); - if (err < 0) - { - ERROR_LOG("Sample format not available: %s\n", snd_strerror(err)); - return -1; - } - - err = snd_pcm_hw_params_set_channels(handle, hwparams, pchannels); - if (err < 0) - { - ERROR_LOG("Channels count not available: %s\n", snd_strerror(err)); - return -1; - } - err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &pspeed, 0); - if (err < 0) - { - ERROR_LOG("Rate not available: %s\n", snd_strerror(err)); - return -1; - } - - err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0); - if(err < 0) { - ERROR_LOG("Buffer time error: %s\n", snd_strerror(err)); - return -1; - } - - err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0); - if (err < 0) - { - ERROR_LOG("Period time error: %s\n", snd_strerror(err)); - return -1; - } - - err = snd_pcm_hw_params(handle, hwparams); - if (err < 0) - { - ERROR_LOG("Unable to install hw params: %s\n", snd_strerror(err)); - return -1; - } - - snd_pcm_status_alloca(&status); - err = snd_pcm_status(handle, status); - if(err < 0) - { - ERROR_LOG("Unable to get status: %s\n", snd_strerror(err)); - return -1; - } - + + jASSUME( data != NULL ); + jASSUME( data->handle == snd_async_handler_get_pcm(pcm_callback) ); + + // Not sure if we just need an assert, or something like this: + //if( data->handle != snd_async_handler_get_pcm(pcm_callback) ) return; + + data->_InternalCallback(); + } + +public: + + s32 Init() + { + snd_pcm_hw_params_t *hwparams; + snd_pcm_sw_params_t *swparams; + snd_pcm_status_t *status; + int pchannels = 2; + snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE; + + handle = NULL; + pcm_callback = NULL; + pspeed = SAMPLE_RATE; + + // buffer time and period time are in microseconds... + // (don't simplify the equation below -- it'll just cause integer rounding errors. + period_time = (SndOutPacketSize*1000) / (SampleRate / 1000); + buffer_time = period_time * NumBuffers; + + int err; + + err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); + if(err < 0) + { + ERROR_LOG("Audio open error: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_nonblock(handle, 0); + if(err < 0) + { + ERROR_LOG("Can't set blocking mode: %s\n", snd_strerror(err)); + return -1; + } + + snd_pcm_hw_params_alloca(&hwparams); + snd_pcm_sw_params_alloca(&swparams); + + err = snd_pcm_hw_params_any(handle, hwparams); + if (err < 0) + { + ERROR_LOG("Broken configuration for this PCM: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); + if (err < 0) + { + ERROR_LOG("Access type not available: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_hw_params_set_format(handle, hwparams, format); + if (err < 0) + { + ERROR_LOG("Sample format not available: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_hw_params_set_channels(handle, hwparams, pchannels); + if (err < 0) + { + ERROR_LOG("Channels count not available: %s\n", snd_strerror(err)); + return -1; + } + err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &pspeed, 0); + if (err < 0) + { + ERROR_LOG("Rate not available: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0); + if(err < 0) { + ERROR_LOG("Buffer time error: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0); + if (err < 0) + { + ERROR_LOG("Period time error: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_hw_params(handle, hwparams); + if (err < 0) + { + ERROR_LOG("Unable to install hw params: %s\n", snd_strerror(err)); + return -1; + } + + snd_pcm_status_alloca(&status); + err = snd_pcm_status(handle, status); + if(err < 0) + { + ERROR_LOG("Unable to get status: %s\n", snd_strerror(err)); + return -1; + } + // Bind our asynchronous callback magic: snd_async_add_pcm_handler( &pcm_callback, handle, ExternalCallback, this ); - - snd_pcm_start( handle ); - // Diagnostic code: - //buffer_size = snd_pcm_status_get_avail(status); - - return 0; - } - - void Close() - { - if(handle == NULL) return; - - snd_pcm_drop(handle); - snd_pcm_close(handle); - handle = NULL; - } - + + snd_pcm_start( handle ); + // Diagnostic code: + //buffer_size = snd_pcm_status_get_avail(status); + + return 0; + } + + void Close() + { + if(handle == NULL) return; + + snd_pcm_drop(handle); + snd_pcm_close(handle); + handle = NULL; + } + virtual void Configure(uptr parent) { } - virtual bool Is51Out() const { return false; } - + virtual bool Is51Out() const { return false; } + s32 Test() const { return 0; @@ -210,12 +207,12 @@ public: int GetEmptySampleCount() const { - if(handle == NULL) return 0; - - // Returns the amount of free buffer space, in samples. - uint l = snd_pcm_avail_update(handle); - if( l < 0 ) return 0; - return (l / 1000) * (SampleRate / 1000); + if(handle == NULL) return 0; + + // Returns the amount of free buffer space, in samples. + uint l = snd_pcm_avail_update(handle); + if( l < 0 ) return 0; + return (l / 1000) * (SampleRate / 1000); } const wchar_t* GetIdent() const diff --git a/plugins/spu2-x/src/Linux/Config.cpp b/plugins/spu2-x/src/Linux/Config.cpp index 1be745c561..8853b4346f 100644 --- a/plugins/spu2-x/src/Linux/Config.cpp +++ b/plugins/spu2-x/src/Linux/Config.cpp @@ -3,21 +3,17 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ #include "Spu2.h" #include "Dialogs.h" diff --git a/plugins/spu2-x/src/Linux/Config.h b/plugins/spu2-x/src/Linux/Config.h index ae3a159d8e..c7c6afe6a0 100644 --- a/plugins/spu2-x/src/Linux/Config.h +++ b/plugins/spu2-x/src/Linux/Config.h @@ -3,21 +3,17 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ #ifndef CONFIG_H_INCLUDED #define CONFIG_H_INCLUDED diff --git a/plugins/spu2-x/src/Linux/Dialogs.cpp b/plugins/spu2-x/src/Linux/Dialogs.cpp index 5746dbd0d2..dfe8ea4b08 100644 --- a/plugins/spu2-x/src/Linux/Dialogs.cpp +++ b/plugins/spu2-x/src/Linux/Dialogs.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ // To be continued... \ No newline at end of file diff --git a/plugins/spu2-x/src/Linux/Dialogs.h b/plugins/spu2-x/src/Linux/Dialogs.h index 13348bd283..d8266ff3bd 100644 --- a/plugins/spu2-x/src/Linux/Dialogs.h +++ b/plugins/spu2-x/src/Linux/Dialogs.h @@ -3,21 +3,17 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ #ifndef DIALOG_H_INCLUDED #define DIALOG_H_INCLUDED diff --git a/plugins/spu2-x/src/Linux/Linux.cpp b/plugins/spu2-x/src/Linux/Linux.cpp index c926b448cb..443917f845 100644 --- a/plugins/spu2-x/src/Linux/Linux.cpp +++ b/plugins/spu2-x/src/Linux/Linux.cpp @@ -3,21 +3,17 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ #include "Linux.h" diff --git a/plugins/spu2-x/src/Linux/Linux.h b/plugins/spu2-x/src/Linux/Linux.h index ac3438fb51..0ba3c0c0cb 100644 --- a/plugins/spu2-x/src/Linux/Linux.h +++ b/plugins/spu2-x/src/Linux/Linux.h @@ -3,21 +3,17 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ #ifndef __LINUX_H__ #define __LINUX_H__ diff --git a/plugins/spu2-x/src/Lowpass.cpp b/plugins/spu2-x/src/Lowpass.cpp index f862f32da5..c6d6e84fb0 100644 --- a/plugins/spu2-x/src/Lowpass.cpp +++ b/plugins/spu2-x/src/Lowpass.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Lowpass.h" diff --git a/plugins/spu2-x/src/Lowpass.h b/plugins/spu2-x/src/Lowpass.h index 13f0d742ce..23dc5f8380 100644 --- a/plugins/spu2-x/src/Lowpass.h +++ b/plugins/spu2-x/src/Lowpass.h @@ -1,24 +1,21 @@ -//GiGaHeRz's SPU2 Driver -//Copyright (c) 2003-2008, David Quintana -// -//This library is free software; you can redistribute it and/or -//modify it under the terms of the GNU Lesser General Public -//License as published by the Free Software Foundation; either -//version 2.1 of the License, or (at your option) any later version. -// -//This library is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -//Lesser General Public License for more details. -// -//You should have received a copy of the GNU Lesser General Public -//License along with this library; if not, write to the Free Software -//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -#pragma once +/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 +* Developed and maintained by the Pcsx2 Development Team. +* +* Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] +* +* SPU2-X is free software: you can redistribute it and/or modify it under the terms +* of the GNU Lesser General Public License as published by the Free Software Found- +* ation, either version 3 of the License, or (at your option) any later version. +* +* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with SPU2-X. If not, see . +*/ -#ifndef _LOWPASS_H_ -#define _LOWPASS_H_ +#pragma once #include "BaseTypes.h" @@ -31,4 +28,3 @@ struct LPF_data double sample( double inval ); }; -#endif diff --git a/plugins/spu2-x/src/Makefile.am b/plugins/spu2-x/src/Makefile.am index 41449973a1..ffd70c5832 100644 --- a/plugins/spu2-x/src/Makefile.am +++ b/plugins/spu2-x/src/Makefile.am @@ -6,11 +6,6 @@ INCLUDES = -I@srcdir@/../../../common/include -I@srcdir@/3rdparty -I@srcdir@/.. libSPU2X_a_CXXFLAGS = $(shell pkg-config --cflags gtk+-2.0) -liconv libSPU2X_a_CFLAGS = $(shell pkg-config --cflags gtk+-2.0) -liconv -if X86_64 -libSPU2X_a_CXXFLAGS += -fPIC -libSPU2X_a_CFLAGS += -fPIC -endif - # Create a shared object by faking an exe (thanks to ODE makefiles) traplibdir=$(prefix) diff --git a/plugins/spu2-x/src/Mixer.cpp b/plugins/spu2-x/src/Mixer.cpp index 61598816c3..066444f7e4 100644 --- a/plugins/spu2-x/src/Mixer.cpp +++ b/plugins/spu2-x/src/Mixer.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Spu2.h" @@ -503,7 +499,7 @@ static __forceinline StereoOut32 ReadInputPV( uint core ) static __forceinline void spu2M_WriteFast( u32 addr, s16 value ) { // throw an assertion if the memory range is invalid: -#ifndef _DEBUG_FAST +#ifndef DEBUG_FAST jASSUME( addr < SPU2_DYN_MEMLINE ); #endif *GetMemPtr( addr ) = value; diff --git a/plugins/spu2-x/src/ReadInput.cpp b/plugins/spu2-x/src/ReadInput.cpp index eaa50d1f50..b6ab222c86 100644 --- a/plugins/spu2-x/src/ReadInput.cpp +++ b/plugins/spu2-x/src/ReadInput.cpp @@ -1,23 +1,19 @@ /* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 -* Developed and maintained by the Pcsx2 Development Team. -* -* Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] -* -* This library is free software; you can redistribute it and/or modify it under -* the terms of the GNU Lesser General Public License as published by the Free -* Software Foundation; either version 2.1 of the the License, or (at your -* option) any later version. -* -* This library is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License -* for more details. -* -* You should have received a copy of the GNU Lesser General Public License along -* with this library; if not, write to the Free Software Foundation, Inc., 59 -* Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -*/ + * Developed and maintained by the Pcsx2 Development Team. + * + * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] + * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ #include "Spu2.h" diff --git a/plugins/spu2-x/src/RegLog.cpp b/plugins/spu2-x/src/RegLog.cpp index c240141270..7c8d58808e 100644 --- a/plugins/spu2-x/src/RegLog.cpp +++ b/plugins/spu2-x/src/RegLog.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Spu2.h" diff --git a/plugins/spu2-x/src/RegTable.cpp b/plugins/spu2-x/src/RegTable.cpp index 9ecf2e7f82..423a9cdad8 100644 --- a/plugins/spu2-x/src/RegTable.cpp +++ b/plugins/spu2-x/src/RegTable.cpp @@ -1,20 +1,20 @@ -//GiGaHeRz's SPU2 Driver -//Copyright (c) 2003-2008, David Quintana -// -//This library is free software; you can redistribute it and/or -//modify it under the terms of the GNU Lesser General Public -//License as published by the Free Software Foundation; either -//version 2.1 of the License, or (at your option) any later version. -// -//This library is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -//Lesser General Public License for more details. -// -//You should have received a copy of the GNU Lesser General Public -//License along with this library; if not, write to the Free Software -//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// +/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 + * Developed and maintained by the Pcsx2 Development Team. + * + * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] + * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ + #include "Spu2.h" #include "RegTable.h" diff --git a/plugins/spu2-x/src/Reverb.cpp b/plugins/spu2-x/src/Reverb.cpp index 7f70c3d7a8..a2d91e2727 100644 --- a/plugins/spu2-x/src/Reverb.cpp +++ b/plugins/spu2-x/src/Reverb.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Spu2.h" diff --git a/plugins/spu2-x/src/SaveStateSPU.cpp b/plugins/spu2-x/src/SaveStateSPU.cpp index d8ea6b31a1..5b19f5b59b 100644 --- a/plugins/spu2-x/src/SaveStateSPU.cpp +++ b/plugins/spu2-x/src/SaveStateSPU.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Spu2.h" @@ -219,4 +215,7 @@ EXPORT_C_(s32) SPU2freeze(int mode, freezeData *data) jNO_DEFAULT; } + + // technically unreachable, but kills a warning: + return 0; } diff --git a/plugins/spu2-x/src/SndOut.cpp b/plugins/spu2-x/src/SndOut.cpp index 55f035e692..0fcb169080 100644 --- a/plugins/spu2-x/src/SndOut.cpp +++ b/plugins/spu2-x/src/SndOut.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Spu2.h" diff --git a/plugins/spu2-x/src/Spu2.cpp b/plugins/spu2-x/src/Spu2.cpp index cccd18f8ce..7928a8f0f2 100644 --- a/plugins/spu2-x/src/Spu2.cpp +++ b/plugins/spu2-x/src/Spu2.cpp @@ -3,23 +3,18 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ - #include "Spu2.h" #include "RegTable.h" @@ -53,10 +48,8 @@ s16 OutPos; s16 InputPos; u32 Cycles; -u32* cPtr=NULL; -u32 lClocks=0; - -bool hasPtr=false; +u32* cyclePtr = NULL; +u32 lClocks = 0; int PlayMode; @@ -93,7 +86,7 @@ extern void SysMessage(const char *fmt, ...); __forceinline s16 * __fastcall GetMemPtr(u32 addr) { -#ifndef _DEBUG_FAST +#ifndef DEBUG_FAST // In case you're wondering, this assert is the reason SPU2-X // runs so incrediously slow in Debug mode. :P jASSUME( addr < 0x100000 ); @@ -932,10 +925,13 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value ) if( ((value>>15)&1) && (!thiscore.CoreEnabled) && (thiscore.InitDelay==0) ) // on init/reset { - if(hasPtr) + // When we have exact cycle update info from the Pcsx2 IOP unit, then use + // the more accurate delayed initialization system. + + if(cyclePtr != NULL) { - thiscore.InitDelay=1; - thiscore.Regs.STATX=0; + thiscore.InitDelay = 1; + thiscore.Regs.STATX = 0; } else { diff --git a/plugins/spu2-x/src/Spu2.h b/plugins/spu2-x/src/Spu2.h index 9d3bcaf70c..a96a589136 100644 --- a/plugins/spu2-x/src/Spu2.h +++ b/plugins/spu2-x/src/Spu2.h @@ -1,29 +1,24 @@ /* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 * Developed and maintained by the Pcsx2 Development Team. * - * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ -#ifndef SPU2_H_INCLUDED -#define SPU2_H_INCLUDED +#pragma once #include "BaseTypes.h" -#include "PS2Edefs.h" +#include "Pcsx2Defs.h" + +#include "Utilities/Exceptions.h" #ifdef __LINUX__ #include @@ -174,13 +169,12 @@ extern int PlayMode; extern int recording; extern u32 lClocks; -extern u32* cPtr; -extern bool hasPtr; +extern u32* cyclePtr; extern void SPU2writeLog( const char* action, u32 rmem, u16 value ); extern void TimeUpdate(u32 cClocks); -extern u16 SPU_ps1_read(u32 mem); +extern u16 SPU_ps1_read(u32 mem); extern void SPU_ps1_write(u32 mem, u16 value); extern void SPU2_FastWrite( u32 rmem, u16 value ); @@ -216,5 +210,3 @@ extern StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input ); extern s32 MulShr32( s32 srcval, s32 mulval ); //#define PCM24_S1_INTERLEAVE - -#endif // SPU2_H_INCLUDED // diff --git a/plugins/spu2-x/src/Spu2replay.h b/plugins/spu2-x/src/Spu2replay.h index 46efa0abe3..747a8adce0 100644 --- a/plugins/spu2-x/src/Spu2replay.h +++ b/plugins/spu2-x/src/Spu2replay.h @@ -16,8 +16,7 @@ //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#ifndef SPU2REPLAY_H_INCLUDED -#define SPU2REPLAY_H_INCLUDED +#pragma once // s2r dumping int s2r_open(char *filename); @@ -35,5 +34,3 @@ EXPORT_C_(void) s2r_replay(HWND hwnd, HINSTANCE hinst, LPSTR filename, int nCmdS #endif extern bool replay_mode; - -#endif//SPU2REPLAY_H_INCLUDED \ No newline at end of file diff --git a/plugins/spu2-x/src/Timestretcher.cpp b/plugins/spu2-x/src/Timestretcher.cpp index 08ab039337..d347bbe350 100644 --- a/plugins/spu2-x/src/Timestretcher.cpp +++ b/plugins/spu2-x/src/Timestretcher.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * -* This library is free software; you can redistribute it and/or modify it under -* the terms of the GNU Lesser General Public License as published by the Free -* Software Foundation; either version 2.1 of the the License, or (at your -* option) any later version. -* -* This library is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License -* for more details. -* -* You should have received a copy of the GNU Lesser General Public License along -* with this library; if not, write to the Free Software Foundation, Inc., 59 -* Temple Place, Suite 330, Boston, MA 02111-1307 USA -* +* SPU2-X is free software: you can redistribute it and/or modify it under the terms +* of the GNU Lesser General Public License as published by the Free Software Found- +* ation, either version 3 of the License, or (at your option) any later version. +* +* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with SPU2-X. If not, see . */ #include "Spu2.h" diff --git a/plugins/spu2-x/src/Wavedump_wav.cpp b/plugins/spu2-x/src/Wavedump_wav.cpp index cfddf7cabb..bc09a67b51 100644 --- a/plugins/spu2-x/src/Wavedump_wav.cpp +++ b/plugins/spu2-x/src/Wavedump_wav.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include diff --git a/plugins/spu2-x/src/Windows/AboutBox.cpp b/plugins/spu2-x/src/Windows/AboutBox.cpp index a485862f9c..3049172f1b 100644 --- a/plugins/spu2-x/src/Windows/AboutBox.cpp +++ b/plugins/spu2-x/src/Windows/AboutBox.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Dialogs.h" diff --git a/plugins/spu2-x/src/Windows/CfgHelpers.cpp b/plugins/spu2-x/src/Windows/CfgHelpers.cpp index 8b5a4f5194..b0b48b7a91 100644 --- a/plugins/spu2-x/src/Windows/CfgHelpers.cpp +++ b/plugins/spu2-x/src/Windows/CfgHelpers.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Dialogs.h" @@ -110,7 +106,7 @@ void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSi } } -void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring Data, int DataSize, const TCHAR* Default) +void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring& Data, int DataSize, const TCHAR* Default) { wchar_t workspace[512]; GetPrivateProfileString(Section,Name,L"",workspace,DataSize,CfgFile); diff --git a/plugins/spu2-x/src/Windows/Config.cpp b/plugins/spu2-x/src/Windows/Config.cpp index b400380b9c..5c3e6d6f9a 100644 --- a/plugins/spu2-x/src/Windows/Config.cpp +++ b/plugins/spu2-x/src/Windows/Config.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Dialogs.h" diff --git a/plugins/spu2-x/src/Windows/Config.h b/plugins/spu2-x/src/Windows/Config.h index bd1ff56079..24ae24c2ba 100644 --- a/plugins/spu2-x/src/Windows/Config.h +++ b/plugins/spu2-x/src/Windows/Config.h @@ -3,24 +3,19 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ -#ifndef CONFIG_H_INCLUDED -#define CONFIG_H_INCLUDED +#pragma once #include @@ -150,5 +145,3 @@ void ReadSettings(); void WriteSettings(); void configure(); void AboutBox(); - -#endif // CONFIG_H_INCLUDED diff --git a/plugins/spu2-x/src/Windows/ConfigDebug.cpp b/plugins/spu2-x/src/Windows/ConfigDebug.cpp index e724bd7f25..0373c225c4 100644 --- a/plugins/spu2-x/src/Windows/ConfigDebug.cpp +++ b/plugins/spu2-x/src/Windows/ConfigDebug.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Dialogs.h" diff --git a/plugins/spu2-x/src/Windows/ConfigSoundtouch.cpp b/plugins/spu2-x/src/Windows/ConfigSoundtouch.cpp index 1e2c9d6fa0..781ef22002 100644 --- a/plugins/spu2-x/src/Windows/ConfigSoundtouch.cpp +++ b/plugins/spu2-x/src/Windows/ConfigSoundtouch.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Dialogs.h" diff --git a/plugins/spu2-x/src/Windows/Dialogs.h b/plugins/spu2-x/src/Windows/Dialogs.h index fca47d9e99..72065d4d03 100644 --- a/plugins/spu2-x/src/Windows/Dialogs.h +++ b/plugins/spu2-x/src/Windows/Dialogs.h @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #pragma once @@ -69,7 +65,7 @@ void CfgWriteInt(const TCHAR* Section, const TCHAR* Name, int Value); void CfgWriteStr(const TCHAR* Section, const TCHAR* Name, const wstring& Data); bool CfgReadBool(const TCHAR *Section,const TCHAR* Name, bool Default); -void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring Data, int DataSize, const TCHAR* Default); +void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring& Data, int DataSize, const TCHAR* Default); void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSize, const TCHAR* Default); int CfgReadInt(const TCHAR* Section, const TCHAR* Name,int Default); diff --git a/plugins/spu2-x/src/Windows/RealtimeDebugger.cpp b/plugins/spu2-x/src/Windows/RealtimeDebugger.cpp index 0aa82ffd83..5c4e0da69a 100644 --- a/plugins/spu2-x/src/Windows/RealtimeDebugger.cpp +++ b/plugins/spu2-x/src/Windows/RealtimeDebugger.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ diff --git a/plugins/spu2-x/src/Windows/SndOut_DSound.cpp b/plugins/spu2-x/src/Windows/SndOut_DSound.cpp index f30b6fb0a0..9d89a78aa0 100644 --- a/plugins/spu2-x/src/Windows/SndOut_DSound.cpp +++ b/plugins/spu2-x/src/Windows/SndOut_DSound.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #define _WIN32_DCOM @@ -194,10 +190,6 @@ public: for(uint i=0;i. */ #define _WIN32_DCOM diff --git a/plugins/spu2-x/src/Windows/SndOut_waveOut.cpp b/plugins/spu2-x/src/Windows/SndOut_waveOut.cpp index ed93c09520..6ef8272f68 100644 --- a/plugins/spu2-x/src/Windows/SndOut_waveOut.cpp +++ b/plugins/spu2-x/src/Windows/SndOut_waveOut.cpp @@ -3,20 +3,16 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ #include "Dialogs.h" diff --git a/plugins/spu2-x/src/Windows/Spu2-X.def b/plugins/spu2-x/src/Windows/Spu2-X.def index e2a13e4a3c..73f00f60f2 100644 --- a/plugins/spu2-x/src/Windows/Spu2-X.def +++ b/plugins/spu2-x/src/Windows/Spu2-X.def @@ -3,19 +3,16 @@ ; * ; * Originally based on SPU2ghz v1.9 beta, by David Quintana. ; * -; * This library is free software; you can redistribute it and/or modify it under -; * the terms of the GNU Lesser General Public License as published by the Free -; * Software Foundation; either version 2.1 of the the License, or (at your -; * option) any later version. -; * -; * This library is distributed in the hope that it will be useful, but WITHOUT -; * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -; * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License -; * for more details. -; * -; * You should have received a copy of the GNU Lesser General Public License along -; * with this library; if not, write to the Free Software Foundation, Inc., 59 -; * Temple Place, Suite 330, Boston, MA 02111-1307 USA +; * SPU2-X is free software: you can redistribute it and/or modify it under the terms +; * of the GNU Lesser General Public License as published by the Free Software Found- +; * ation, either version 3 of the License, or (at your option) any later version. +; * +; * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +; * PURPOSE. See the GNU Lesser General Public License for more details. +; * +; * You should have received a copy of the GNU Lesser General Public License +; * along with SPU2-X. If not, see . ; SPU2-X.def : Declares the module parameters for the DLL. diff --git a/plugins/spu2-x/src/Windows/Spu2-X.rc b/plugins/spu2-x/src/Windows/Spu2-X.rc index 94c31330d7..1fca43b0df 100644 --- a/plugins/spu2-x/src/Windows/Spu2-X.rc +++ b/plugins/spu2-x/src/Windows/Spu2-X.rc @@ -7,7 +7,8 @@ // // Generated from the TEXTINCLUDE 2 resource. // -#include "afxresmw.h" +#include "afxresmw.h" + ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -270,11 +271,6 @@ VS_VERSION_INFO VERSIONINFO FILEVERSION 1,1,1,0 PRODUCTVERSION 1,1,1,0 FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif FILEOS 0x4L FILETYPE 0x2L FILESUBTYPE 0x0L diff --git a/plugins/spu2-x/src/Windows/Spu2-X_vs2008.vcproj b/plugins/spu2-x/src/Windows/Spu2-X_vs2008.vcproj index 7555d04ad8..205a90fb38 100644 --- a/plugins/spu2-x/src/Windows/Spu2-X_vs2008.vcproj +++ b/plugins/spu2-x/src/Windows/Spu2-X_vs2008.vcproj @@ -18,7 +18,7 @@ @@ -160,7 +148,7 @@ /> . + */ + #include "Dialogs.h" int SendDialogMsg( HWND hwnd, int dlgId, UINT code, WPARAM wParam, LPARAM lParam) diff --git a/plugins/spu2-x/src/Windows/dsp.h b/plugins/spu2-x/src/Windows/dsp.h index ca1d187484..e3d3c2ce4a 100644 --- a/plugins/spu2-x/src/Windows/dsp.h +++ b/plugins/spu2-x/src/Windows/dsp.h @@ -25,6 +25,8 @@ // Configuration data should be stored in \plugin.ini // (look at the vis plugin for configuration code) +#pragma once + typedef struct winampDSPModule { char *description; // description HWND hwndParent; // parent window (filled in by calling app) diff --git a/plugins/spu2-x/src/configure.ac b/plugins/spu2-x/src/configure.ac index eb2596fcef..edb2e34e3a 100644 --- a/plugins/spu2-x/src/configure.ac +++ b/plugins/spu2-x/src/configure.ac @@ -21,6 +21,7 @@ AC_SUBST(SPU2X_SONAME,libSPU2X.so.[$SPU2X_CURRENT].[$SPU2X_REVISION].[$SPU2X_AGE CFLAGS= CPPFLAGS= CXXFLAGS= +CCASFLAGS= dnl Check for debug build AC_MSG_CHECKING(debug build) @@ -28,15 +29,17 @@ AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [debug build]), debug=$enableval,debug=no) if test "x$debug" == xyes then - AC_DEFINE(_DEBUG,1,[_DEBUG]) - CFLAGS+="-g -fPIC -Wall -Wno-unused-value " - CPPFLAGS+="-g -fPIC -Wall -Wno-unused-value " - CXXFLAGS+="-g -fPIC -Wall -Wno-unused-value " + AC_DEFINE(PCSX2_DEBUG,1,[PCSX2_DEBUG]) + CFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CPPFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CXXFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CCASFLAGS+=" -m32 " else AC_DEFINE(NDEBUG,1,[NDEBUG]) - CFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value " - CPPFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value " - CXXFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value " + CFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CPPFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CXXFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CCASFLAGS+=" -m32 " fi AM_CONDITIONAL(DEBUGBUILD, test x$debug = xyes) AC_MSG_RESULT($debug) @@ -60,32 +63,6 @@ dnl gtk AC_MSG_CHECKING(gtk2+) AC_CHECK_PROG(GTK_CONFIG, pkg-config, pkg-config) LIBS+=$(pkg-config --libs gtk+-2.0) -dnl Check for 64bit CPU -AC_MSG_CHECKING(for a x86-64 CPU) -dnl if test "$build_os" == "target_os" -dnl then -AC_TRY_RUN([ -int main() -{ -int a = 0; -int*pa = &a; -asm(".intel_syntax\n" - "mov %%rax, %0\n" - "mov %%eax, [%%rax]\n" - ".att_syntax\n" - : : "r"(pa) : "%rax"); -return 0; -} -],cpu64=yes,cpu64=no,) -dnl else -dnl cpu64=no -dnl fi -if test "x$cpu64" == xyes -then -AC_DEFINE(__x86_64__,1,[__x86_64__]) -fi -AC_MSG_RESULT($cpu64) -AM_CONDITIONAL(X86_64, test x$cpu64 = xyes) dnl bindir = pcsx2exe diff --git a/plugins/spu2-x/src/defs.h b/plugins/spu2-x/src/defs.h index aaabe1683f..fdbbc8eaf5 100644 --- a/plugins/spu2-x/src/defs.h +++ b/plugins/spu2-x/src/defs.h @@ -3,24 +3,19 @@ * * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the the License, or (at your - * option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . */ -#ifndef DEFS_H_INCLUDED -#define DEFS_H_INCLUDED +#pragma once struct V_VolumeLR { @@ -441,5 +436,3 @@ static __forceinline u32 timeGetTime() return (u32)(t.time*1000+t.millitm); } #endif - -#endif // DEFS_H_INCLUDED // diff --git a/plugins/spu2-x/src/regs.h b/plugins/spu2-x/src/regs.h index 2effce816a..10a789118f 100644 --- a/plugins/spu2-x/src/regs.h +++ b/plugins/spu2-x/src/regs.h @@ -1,22 +1,21 @@ -//GiGaHeRz's SPU2 Driver -//Copyright (c) 2003-2008, David Quintana -// -//This library is free software; you can redistribute it and/or -//modify it under the terms of the GNU Lesser General Public -//License as published by the Free Software Foundation; either -//version 2.1 of the License, or (at your option) any later version. -// -//This library is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -//Lesser General Public License for more details. -// -//You should have received a copy of the GNU Lesser General Public -//License along with this library; if not, write to the Free Software -//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -#ifndef REGS_H_INCLUDED -#define REGS_H_INCLUDED +/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 + * Developed and maintained by the Pcsx2 Development Team. + * + * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] + * + * SPU2-X is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ + +#pragma once #define SPU2_CORE0 0x00000000 #define SPU2_CORE1 0x00000400 @@ -181,4 +180,3 @@ Core attributes (SD_C) #define VOICE_ADDR_LSAX 0x4 // Loop point address #define VOICE_ADDR_NAX 0x8 // Waveform data that should be read next -#endif // REGS_H_INCLUDED // \ No newline at end of file diff --git a/plugins/spu2-x/src/spdif.h b/plugins/spu2-x/src/spdif.h index 16cca3ef5f..52391706aa 100644 --- a/plugins/spu2-x/src/spdif.h +++ b/plugins/spu2-x/src/spdif.h @@ -15,8 +15,8 @@ //License along with this library; if not, write to the Free Software //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#ifndef SPDIF_H_INCLUDED -#define SPDIF_H_INCLUDED + +#pragma once #ifndef u32 typedef unsigned int u32; @@ -109,4 +109,3 @@ typedef struct _chstatus u8 reservd2[22]; } chstatus: -#endif//SPDIF_H_INCLUDED \ No newline at end of file diff --git a/plugins/xpad/stdafx.h b/plugins/xpad/stdafx.h index 7d782ced5f..326e8d0bc1 100644 --- a/plugins/xpad/stdafx.h +++ b/plugins/xpad/stdafx.h @@ -4,58 +4,93 @@ #pragma once -#pragma warning(disable: 4996) +#pragma warning(disable: 4996 4995 4324 4100 4101 4201) -#ifndef VC_EXTRALEAN -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers -#endif +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. // Modify the following defines if you have to target a platform prior to the ones specified below. // Refer to MSDN for the latest info on corresponding values for different platforms. -#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. -#define WINVER 0x0510 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. + +#ifndef WINVER // Specifies that the minimum required platform is Windows Vista. +#define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows. #endif -#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. -#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 2000 or later. -#endif +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif -#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98. #define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. #endif -#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. -#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later. +#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0. +#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE. #endif -#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#include // MFC core and standard components -//#include // MFC extensions -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT -//#include +#include +#include +#include +#include #include -#include -#include -#include #include -#define countof(a) (sizeof(a)/sizeof(a[0])) +// stdc + +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace std; +using namespace stdext; + +extern string format(const char* fmt, ...); + +// syntactic sugar + +// put these into vc9/common7/ide/usertype.dat to have them highlighted + +typedef unsigned char uint8; +typedef signed char int8; +typedef unsigned short uint16; +typedef signed short int16; +typedef unsigned int uint32; +typedef signed int int32; +typedef unsigned long long uint64; +typedef signed long long int64; + +#define countof(a) (sizeof(a) / sizeof(a[0])) #define EXPORT_C extern "C" __declspec(dllexport) void __stdcall #define EXPORT_C_(type) extern "C" __declspec(dllexport) type __stdcall +#define ALIGN_STACK(n) __declspec(align(n)) int __dummy; + #ifndef RESTRICT #ifdef __INTEL_COMPILER #define RESTRICT restrict - #elif _MSC_VER >= 1400 + #elif _MSC_VER >= 1400 // TODO: gcc #define RESTRICT __restrict #else #define RESTRICT #endif #endif -#pragma warning(disable : 4995 4324 4100) +#if defined(_DEBUG) && defined(_MSC_VER) + #define ASSERT assert +#else + #define ASSERT(exp) ((void)0) +#endif + + diff --git a/plugins/xpad/vsprops/debug.vsprops b/plugins/xpad/vsprops/debug.vsprops index 9d5c60bf96..b7506beeec 100644 --- a/plugins/xpad/vsprops/debug.vsprops +++ b/plugins/xpad/vsprops/debug.vsprops @@ -10,7 +10,7 @@ PreprocessorDefinitions="_DEBUG" MinimalRebuild="true" BasicRuntimeChecks="1" - RuntimeLibrary="1" + RuntimeLibrary="3" /> m_pads; + vector m_pads; XPad* m_pad; int m_index; bool m_cfgreaddata; @@ -531,7 +499,7 @@ static class XPadPlugin BYTE UnknownCommand(int index, BYTE value) { - TRACE(_T("Unknown command %02x (%d, %02x)\n"), m_cmd, index, value); + // printf("Unknown command %02x (%d, %02x)\n", m_cmd, index, value); return 0; } @@ -544,8 +512,8 @@ public: , m_cfgreaddata(false) , m_handler(NULL) { - m_pads.Add(new XPad(0)); - m_pads.Add(new XPad(1)); + m_pads.push_back(new XPad(0)); + m_pads.push_back(new XPad(1)); for(int i = 0; i < countof(m_handlers); i++) { @@ -565,6 +533,16 @@ public: m_handlers['O'] = &XPadPlugin::SetDS2NativeMode; } + virtual ~XPadPlugin() + { + for(vector::iterator i = m_pads.begin(); i != m_pads.end(); i++) + { + delete *i; + } + + m_pads.clear(); + } + void StartPoll(int pad) { m_pad = m_pads[pad & 1]; @@ -602,7 +580,7 @@ static int s_nRefs = 0; static HWND s_hWnd = NULL; static WNDPROC s_GSWndProc = NULL; -static class CKeyEventList : protected CAtlList, protected CCritSec +static class CKeyEventList : protected list, protected CCritSec { public: void Push(UINT32 event, UINT32 key) @@ -614,16 +592,18 @@ public: e.event = event; e.key = key; - AddTail(e); + push_back(e); } bool Pop(KeyEvent& e) { CAutoLock cAutoLock(this); - if(IsEmpty()) return false; - - e = RemoveHead(); + if(empty()) return false; + + e = front(); + + pop_front(); return true; } @@ -647,7 +627,7 @@ LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) break; } - return s_GSWndProc(hWnd, msg, wParam, lParam); + return CallWindowProc(s_GSWndProc, hWnd, msg, wParam, lParam); } // diff --git a/plugins/xpad/xpad.h b/plugins/xpad/xpad.h index 9afa410498..1c4f48e165 100644 --- a/plugins/xpad/xpad.h +++ b/plugins/xpad/xpad.h @@ -21,21 +21,6 @@ #pragma once -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -class xpadApp : public CWinApp -{ -public: - xpadApp(); - -public: - virtual BOOL InitInstance(); - - DECLARE_MESSAGE_MAP() -}; - // ps1 #define PSE_LT_PAD 8 diff --git a/plugins/xpad/xpad_vs2008.vcproj b/plugins/xpad/xpad_vs2008.vcproj index d44d4c5f32..105b923bb4 100644 --- a/plugins/xpad/xpad_vs2008.vcproj +++ b/plugins/xpad/xpad_vs2008.vcproj @@ -23,7 +23,7 @@ Name="Debug|Win32" ConfigurationType="2" InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\ProjectRootDir.vsprops;..\..\common\vsprops\BaseProperties.vsprops;.\vsprops\debug.vsprops" - UseOfMFC="1" + UseOfMFC="0" CharacterSet="2" > @@ -281,7 +281,7 @@ Name="Debug SSE2|Win32" ConfigurationType="2" InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\ProjectRootDir.vsprops;..\..\common\vsprops\BaseProperties.vsprops;.\vsprops\debug.vsprops;.\vsprops\sse2.vsprops" - UseOfMFC="1" + UseOfMFC="0" CharacterSet="2" > @@ -536,7 +536,7 @@ Name="Release SSSE3|Win32" ConfigurationType="2" InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\ProjectRootDir.vsprops;..\..\common\vsprops\BaseProperties.vsprops;.\vsprops\release.vsprops;.\vsprops\sse2.vsprops;.\vsprops\ssse3.vsprops" - UseOfMFC="1" + UseOfMFC="0" CharacterSet="2" WholeProgramOptimization="1" > @@ -664,7 +664,7 @@ Name="Debug SSSE3|Win32" ConfigurationType="2" InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\ProjectRootDir.vsprops;..\..\common\vsprops\BaseProperties.vsprops;.\vsprops\debug.vsprops;.\vsprops\sse2.vsprops;.\vsprops\ssse3.vsprops" - UseOfMFC="1" + UseOfMFC="0" CharacterSet="2" > diff --git a/plugins/zerogs/dx/GS.h b/plugins/zerogs/dx/GS.h index 871f6ff0de..87837c4fc2 100644 --- a/plugins/zerogs/dx/GS.h +++ b/plugins/zerogs/dx/GS.h @@ -22,11 +22,8 @@ #include #include -// need C definitions -extern "C" { #define GSdefs #include "PS2Edefs.h" -} #ifdef _WIN32 diff --git a/plugins/zerogs/dx/GSmain.cpp b/plugins/zerogs/dx/GSmain.cpp index 0ee9b5ce74..8ccb6c057c 100644 --- a/plugins/zerogs/dx/GSmain.cpp +++ b/plugins/zerogs/dx/GSmain.cpp @@ -46,7 +46,7 @@ using namespace std; #pragma warning(disable:4244) #endif -#ifdef _DEBUG +#ifdef PCSX2_DEBUG HANDLE g_hCurrentThread = NULL; #endif @@ -73,7 +73,7 @@ unsigned char revision = 0; // revision and build gives plugin version unsigned char build = VER; unsigned char minor = 1; -#ifdef _DEBUG +#ifdef PCSX2_DEBUG char *libraryName = "ZeroGS (Debug) "; #elif defined(RELEASE_TO_PUBLIC) @@ -354,7 +354,7 @@ s32 CALLBACK GSopen(void *pDsp, char *Title, int multithread) { GS_LOG("GSopen\n"); -#ifdef _DEBUG +#ifdef PCSX2_DEBUG g_hCurrentThread = GetCurrentThread(); #endif @@ -760,7 +760,7 @@ void CALLBACK GSgetLastTag(u64* ptag) void _GSgifTransfer(pathInfo *path, u32 *pMem, u32 size) { -#ifdef _DEBUG +#ifdef PCSX2_DEBUG assert( g_hCurrentThread == GetCurrentThread() ); #endif @@ -964,7 +964,7 @@ void CALLBACK GSgifTransfer1(u32 *pMem, u32 addr) addr &= 0x3fff; -#ifdef _DEBUG +#ifdef PCSX2_DEBUG PRIM_LOG("count: %d\n", count); count++; #endif diff --git a/plugins/zerogs/dx/Regs.cpp b/plugins/zerogs/dx/Regs.cpp index 7f4673a5e6..5d094feba1 100644 --- a/plugins/zerogs/dx/Regs.cpp +++ b/plugins/zerogs/dx/Regs.cpp @@ -77,7 +77,7 @@ u32 s_uTex1Data[2][2] = {0}, s_uClampData[2] = {0}; void __fastcall GIFPackedRegHandlerNull(u32* data) { -#ifdef _DEBUG +#ifdef PCSX2_DEBUG DEBUG_LOG("Unexpected packed reg handler %8.8lx_%8.8lx %x\n", data[0], data[1], data[2]); #endif } @@ -367,7 +367,7 @@ __forceinline void clampWrite(int i, u32 *data) void __fastcall GIFRegHandlerNull(u32* data) { -#ifdef _DEBUG +#ifdef PCSX2_DEBUG if( (((uptr)&data[2])&0xffff) == 0 ) return; diff --git a/plugins/zerogs/dx/Windows/zerogs_2008.vcproj b/plugins/zerogs/dx/Windows/zerogs_2008.vcproj index 06357c714d..da22f2bdc5 100644 --- a/plugins/zerogs/dx/Windows/zerogs_2008.vcproj +++ b/plugins/zerogs/dx/Windows/zerogs_2008.vcproj @@ -18,7 +18,7 @@ #endif -extern "C" { - #include "PS2Etypes.h" +extern "C" { + #if defined(_MSC_VER) && !defined(__x86_64__) void * memcpy_amd(void *dest, const void *src, size_t n) diff --git a/plugins/zerogs/dx/targets.cpp b/plugins/zerogs/dx/targets.cpp index 84b867cda0..5ab52c8b70 100644 --- a/plugins/zerogs/dx/targets.cpp +++ b/plugins/zerogs/dx/targets.cpp @@ -268,7 +268,7 @@ void ZeroGS::CRenderTarget::Resolve() D3DLOCKED_RECT locksrc; pd3dDevice->GetRenderTargetData(psurf, psys); -#if !defined(RELEASE_TO_PUBLIC) && defined(_DEBUG) +#if !defined(RELEASE_TO_PUBLIC) && defined(PCSX2_DEBUG) if( g_bSaveResolved ) { D3DXSaveSurfaceToFile("resolved.tga", D3DXIFF_TGA, psys, NULL, NULL); g_bSaveResolved = 0; @@ -293,7 +293,7 @@ void ZeroGS::CRenderTarget::Resolve(int startrange, int endrange) if( vb[0].prndr == this || vb[0].pdepth == this ) Flush(0); if( vb[1].prndr == this || vb[1].pdepth == this ) Flush(1); -#if !defined(RELEASE_TO_PUBLIC) && defined(_DEBUG) +#if !defined(RELEASE_TO_PUBLIC) && defined(PCSX2_DEBUG) if( g_bSaveResolved ) { D3DXSaveSurfaceToFile("resolved.tga", D3DXIFF_TGA, psys, NULL, NULL); g_bSaveResolved = 0; @@ -589,7 +589,7 @@ void ZeroGS::CRenderTarget::ConvertTo32() pd3dDevice->SetPixelShader(ppsConvert16to32); pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); -#ifdef _DEBUG +#ifdef PCSX2_DEBUG //g_bSaveZUpdate = 1; //D3DXSaveSurfaceToFile("tex3.tga", D3DXIFF_TGA, psurfConv, NULL, NULL); if( g_bSaveZUpdate ) { @@ -801,7 +801,7 @@ void ZeroGS::CRenderTarget::ConvertTo16() pd3dDevice->SetPixelShader(ppsConvert32to16); pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); -#ifdef _DEBUG +#ifdef PCSX2_DEBUG //g_bSaveZUpdate = 1; if( g_bSaveZUpdate ) { pd3dDevice->GetRenderTargetData(psurf, psys); @@ -1186,7 +1186,7 @@ void ZeroGS::CDepthTarget::Update(int context, ZeroGS::CRenderTarget* prndr) if( conf.options & GSOPTION_WIREFRAME ) SETRS(D3DRS_FILLMODE, D3DFILL_WIREFRAME); SETRS(D3DRS_SCISSORTESTENABLE, TRUE); -#ifdef _DEBUG +#ifdef PCSX2_DEBUG if( g_bSaveZUpdate ) { if( pusetarg != NULL ) D3DXSaveTextureToFile("tex.tga", D3DXIFF_TGA, pusetarg->ptex, NULL); @@ -1268,7 +1268,7 @@ CRenderTarget* ZeroGS::CRenderTargetMngr::GetTarg(const frameInfo& frame, DWORD // can be both 16bit and 32bit if( (frame.psm&2) != (it->second->psm&2) ) { // a lot of games do this actually... -#ifdef _DEBUG +#ifdef PCSX2_DEBUG WARN_LOG("Really bad formats! %d %d\n", frame.psm, it->second->psm); #endif if( !(opts&TO_StrictHeight) ) { @@ -1949,7 +1949,7 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info ++it; } -#ifdef _DEBUG +#ifdef PCSX2_DEBUG PRIM_LOG("memtarget: tbp: %x tbw: %x th: %x psm: %x\n", tex0.tbp0, tex0.tbw, tex0.th, tex0.psm); #endif @@ -2383,7 +2383,7 @@ void ZeroGS::CRangeManager::Insert(int start, int end) { int imin = 0, imax = (int)ranges.size(), imid; -#ifdef _DEBUG +#ifdef PCSX2_DEBUG // sanity check for(int i = 0; i < (int)ranges.size()-1; ++i) assert( ranges[i].end < ranges[i+1].start ); #endif @@ -2433,7 +2433,7 @@ void ZeroGS::CRangeManager::Insert(int start, int end) if( startindex == 0 && end < ranges.front().start ) { ranges.insert(ranges.begin(), RANGE(start, end)); -#ifdef _DEBUG +#ifdef PCSX2_DEBUG // sanity check for(int i = 0; i < (int)ranges.size()-1; ++i) assert( ranges[i].end < ranges[i+1].start ); #endif @@ -2462,7 +2462,7 @@ void ZeroGS::CRangeManager::Insert(int start, int end) // create a new range ranges.insert(ranges.begin()+startindex, RANGE(start, end)); -#ifdef _DEBUG +#ifdef PCSX2_DEBUG // sanity check for(int i = 0; i < (int)ranges.size()-1; ++i) assert( ranges[i].end < ranges[i+1].start ); #endif @@ -2480,7 +2480,7 @@ void ZeroGS::CRangeManager::Insert(int start, int end) if( lastend > ranges.back().end ) ranges.back().end = lastend; if( end > ranges.back().end ) ranges.back().end = end; -#ifdef _DEBUG +#ifdef PCSX2_DEBUG // sanity check for(int i = 0; i < (int)ranges.size()-1; ++i) assert( ranges[i].end < ranges[i+1].start ); #endif @@ -2493,7 +2493,7 @@ void ZeroGS::CRangeManager::Insert(int start, int end) if( start < ranges.front().start ) ranges.front().start = start; if( end > ranges.front().end ) ranges.front().end = end; -#ifdef _DEBUG +#ifdef PCSX2_DEBUG // sanity check for(int i = 0; i < (int)ranges.size()-1; ++i) assert( ranges[i].end < ranges[i+1].start ); #endif @@ -2509,7 +2509,7 @@ void ZeroGS::CRangeManager::Insert(int start, int end) if( start < ranges[startindex].start ) ranges[startindex].start = start; if( end > ranges[startindex].end ) ranges[startindex].end = end; -#ifdef _DEBUG +#ifdef PCSX2_DEBUG // sanity check for(int i = 0; i < (int)ranges.size()-1; ++i) assert( ranges[i].end < ranges[i+1].start ); #endif @@ -2569,7 +2569,7 @@ void FlushTransferRanges(const tex0Info* ptex) // Flush(0); // Flush(1); // -//#ifdef _DEBUG +//#ifdef PCSX2_DEBUG // // make sure targets are still the same // list::iterator it; // FORIT(it, listTransmissionUpdateTargs) { @@ -2811,7 +2811,7 @@ void TransferHostLocal(const void* pbyMem, u32 nQWordSize) } else s_vTransferCache.resize(0); -#if !defined(RELEASE_TO_PUBLIC) && defined(_DEBUG) +#if !defined(RELEASE_TO_PUBLIC) && defined(PCSX2_DEBUG) if( g_bSaveTrans ) { tex0Info t; t.tbp0 = gs.dstbuf.bp; @@ -3244,7 +3244,7 @@ void TransferLocalLocal() g_MemTargs.ClearRange(dststart, dstend); -#if !defined(RELEASE_TO_PUBLIC) && defined(_DEBUG) +#if !defined(RELEASE_TO_PUBLIC) && defined(PCSX2_DEBUG) if( g_bSaveTrans ) { tex0Info t; t.tbp0 = gs.dstbuf.bp; diff --git a/plugins/zerogs/dx/zerogs.cpp b/plugins/zerogs/dx/zerogs.cpp index af7ffadfa6..989bff2caf 100644 --- a/plugins/zerogs/dx/zerogs.cpp +++ b/plugins/zerogs/dx/zerogs.cpp @@ -598,7 +598,7 @@ void ZeroGS::VB::CheckFrame(int tbp) //u32 key = zbuf.zbp|(frame.fbw<<16); //CRenderTargetMngr::MAPTARGETS::iterator it = s_RTs.mapTargets.find(key); // if( it != s_RTs.mapTargets.end() ) { -//#ifdef _DEBUG +//#ifdef PCSX2_DEBUG // DEBUG_LOG("zbuf resolve\n"); //#endif // if( it->second->status & CRenderTarget::TS_Resolved ) @@ -856,7 +856,7 @@ HRESULT ZeroGS::Create(LONG _width, LONG _height) UINT adapter = D3DADAPTER_DEFAULT; D3DDEVTYPE devtype = !DEBUG_PS2 ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF; -#ifndef _DEBUG +#ifndef PCSX2_DEBUG DWORD hwoptions = D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE; #else DWORD hwoptions = D3DCREATE_HARDWARE_VERTEXPROCESSING; @@ -1906,7 +1906,7 @@ void ZeroGS::Flush(int context) return; } -#if defined(PRIM_LOG) && defined(_DEBUG) +#if defined(PRIM_LOG) && defined(PCSX2_DEBUG) static const char* patst[8] = { "NEVER", "ALWAYS", "LESS", "LEQUAL", "EQUAL", "GEQUAL", "GREATER", "NOTEQUAL"}; static const char* pztst[4] = { "NEVER", "ALWAYS", "GEQUAL", "GREATER" }; static const char* pafail[4] = { "KEEP", "FB_ONLY", "ZB_ONLY", "RGB_ONLY" }; @@ -2067,7 +2067,7 @@ void ZeroGS::Flush(int context) else ptextarg = NULL; } -#ifdef _DEBUG +#ifdef PCSX2_DEBUG if( g_bSaveFlushedFrame & 0x80000000 ) { char str[255]; sprintf(str, "rndr.tga", g_SaveFrameNum); @@ -2393,7 +2393,7 @@ void ZeroGS::Flush(int context) } else { // save the texture -#ifdef _DEBUG +#ifdef PCSX2_DEBUG // CMemoryTarget* pmemtarg = g_MemTargs.GetMemoryTarget(curvb.tex0, 0); // assert( curvb.pmemtarg == pmemtarg ); // if( PSMT_ISCLUT(curvb.tex0.psm) ) @@ -2546,7 +2546,7 @@ void ZeroGS::Flush(int context) } } -#ifdef _DEBUG +#ifdef PCSX2_DEBUG if( bDestAlphaColor == 1 ) { WARN_LOG("dest alpha blending! manipulate alpha here\n"); } @@ -2719,7 +2719,7 @@ void ZeroGS::Flush(int context) //WARN_LOG("Need to reset dest alpha color\n"); } -#ifdef _DEBUG +#ifdef PCSX2_DEBUG if( g_bSaveFlushedFrame & 0xf ) { char str[255]; sprintf(str, "frames\\frame%.4d.jpg", g_SaveFrameNum++); diff --git a/plugins/zerogs/opengl/GSmain.cpp b/plugins/zerogs/opengl/GSmain.cpp index abdcf05c0a..be3a6c309e 100644 --- a/plugins/zerogs/opengl/GSmain.cpp +++ b/plugins/zerogs/opengl/GSmain.cpp @@ -470,8 +470,7 @@ s32 CALLBACK GSopen(void *pDsp, char *Title, int multithread) { return -1; } - if( pDsp != NULL ) - *(HWND*)pDsp = GShwnd; + if( pDsp != NULL ) *(HWND*)pDsp = GShwnd; ERROR_LOG("creating zerogs\n"); //if (conf.record) recOpen(); @@ -827,299 +826,6 @@ void CALLBACK GSvsync(int interlace) GL_REPORT_ERRORD(); } -void GIFtag(pathInfo *path, u32 *data) { - - path->tag.nloop = data[0] & 0x7fff; - path->tag.eop = (data[0] >> 15) & 0x1; - u32 tagpre = (data[1] >> 14) & 0x1; - u32 tagprim = (data[1] >> 15) & 0x7ff; - u32 tagflg = (data[1] >> 26) & 0x3; - path->tag.nreg = (data[1] >> 28)<<2; - - if (path->tag.nreg == 0) path->tag.nreg = 64; - - gs.q = 1; - -// GS_LOG("GIFtag: %8.8lx_%8.8lx_%8.8lx_%8.8lx: EOP=%d, NLOOP=%x, FLG=%x, NREG=%d, PRE=%d\n", -// data[3], data[2], data[1], data[0], -// path->tag.eop, path->tag.nloop, tagflg, path->tag.nreg, tagpre); - - path->mode = tagflg+1; - - switch (tagflg) { - case 0x0: - path->regs = *(u64 *)(data+2); - path->regn = 0; - if (tagpre) - GIFRegHandlerPRIM((u32*)&tagprim); - - break; - - case 0x1: - path->regs = *(u64 *)(data+2); - path->regn = 0; - break; - } -} - -void _GSgifPacket(pathInfo *path, u32 *pMem) { // 128bit - - int reg = (int)((path->regs >> path->regn) & 0xf); - g_GIFPackedRegHandlers[reg](pMem); - - path->regn += 4; - if (path->tag.nreg == path->regn) { - path->regn = 0; - path->tag.nloop--; - } -} - -void _GSgifRegList(pathInfo *path, u32 *pMem) { // 64bit - int reg; - - reg = (int)((path->regs >> path->regn) & 0xf); - - g_GIFRegHandlers[reg](pMem); - path->regn += 4; - if (path->tag.nreg == path->regn) { - path->regn = 0; - path->tag.nloop--; - } -} - -static int nPath3Hack = 0; - -void CALLBACK GSgetLastTag(u64* ptag) -{ - *(u32*)ptag = nPath3Hack; - nPath3Hack = 0; -} - -void _GSgifTransfer(pathInfo *path, u32 *pMem, u32 size) -{ -#ifdef _WIN32 - assert( g_hCurrentThread == GetCurrentThread() ); -#endif - -#ifdef _DEBUG - if( conf.log & 0x20 ) { - static int nSaveIndex=0; - GS_LOG("%d: p:%d %x\n", nSaveIndex++, (path==&gs.path3)?3:(path==&gs.path2?2:1), size); - int vals[4] = {0}; - for(int i = 0; i < size; i++) { - for(int j = 0; j < 4; ++j ) - vals[j] ^= pMem[4*i+j]; - } - GS_LOG("%x %x %x %x\n", vals[0], vals[1], vals[2], vals[3]); - } -#endif - - while(size > 0) - { - //LOG(_T("Transfer(%08x, %d) START\n"), pMem, size); - if (path->tag.nloop == 0) - { - GIFtag(path, pMem); - pMem+= 4; - size--; - - if ((g_GameSettings & GAME_PATH3HACK) && path == &gs.path3 && gs.path3.tag.eop) - nPath3Hack = 1; - - if (path == &gs.path1) - { - // if too much data, just ignore - if (path->tag.nloop * (path->tag.nreg / 4) > (int)size * (path->mode==2?2:1)) - { - static int lasttime = 0; - if( timeGetTime() - lasttime > 5000 ) - { - ERROR_LOG("VU1 too much data, ignore if gfx are fine\n"); - lasttime = timeGetTime(); - } - path->tag.nloop = 0; - return; - } - - if (path->mode == 1) - { - // check if 0xb is in any reg, if yes, exit (kh2) - for(int i = 0; i < path->tag.nreg; i += 4) - { - if (((path->regs >> i)&0xf) == 11) - { - static int lasttime = 0; - if( timeGetTime() - lasttime > 5000 ) - { - ERROR_LOG("Invalid unpack type\n"); - lasttime = timeGetTime(); - } - path->tag.nloop = 0; - return; - } - } - } - } - - if(path->tag.nloop == 0 ) - { - if( path == &gs.path1 ) - { - // ffx hack - /*if( g_GameSettings & GAME_FFXHACK ) - {*/ - if( path->tag.eop ) - return; - continue; - /*}*/ - - return; - } - - if( !path->tag.eop ) - { - //DEBUG_LOG("continuing from eop\n"); - continue; - } - - continue; - } - } - - switch(path->mode) { - case 1: // PACKED - { - assert( path->tag.nloop > 0 ); - for(; size > 0; size--, pMem += 4) - { - int reg = (int)((path->regs >> path->regn) & 0xf); - - g_GIFPackedRegHandlers[reg](pMem); - - path->regn += 4; - if (path->tag.nreg == path->regn) - { - path->regn = 0; - if( path->tag.nloop-- <= 1 ) - { - size--; - pMem += 4; - break; - } - } - } - break; - } - case 2: // REGLIST - { - //GS_LOG("%8.8x%8.8x %d L\n", ((u32*)&gs.regs)[1], *(u32*)&gs.regs, path->tag.nreg/4); - assert( path->tag.nloop > 0 ); - size *= 2; - for(; size > 0; pMem+= 2, size--) - { - int reg = (int)((path->regs >> path->regn) & 0xf); - g_GIFRegHandlers[reg](pMem); - path->regn += 4; - if (path->tag.nreg == path->regn) - { - path->regn = 0; - if( path->tag.nloop-- <= 1 ) - { - size--; - pMem += 2; - break; - } - } - } - - if( size & 1 ) pMem += 2; - size /= 2; - break; - } - case 3: // GIF_IMAGE (FROM_VFRAM) - case 4: // Used in the DirectX version, so we'll use it here too. - { - if(gs.imageTransfer >= 0 && gs.imageTransfer <= 1) - { - int process = min((int)size, path->tag.nloop); - - if( process > 0 ) - { - if ( gs.imageTransfer ) - ZeroGS::TransferLocalHost(pMem, process); - else - ZeroGS::TransferHostLocal(pMem, process*4); - - path->tag.nloop -= process; - pMem += process*4; size -= process; - - assert( size == 0 || path->tag.nloop == 0 ); - } - break; - } - else - { - // simulate - int process = min((int)size, path->tag.nloop); - path->tag.nloop -= process; - pMem += process*4; size -= process; - } - - break; - } - default: // GIF_IMAGE - GS_LOG("*** WARNING **** Unexpected GIFTag flag\n"); - assert(0); - path->tag.nloop = 0; - break; - } - - if( path == &gs.path1 && path->tag.eop ) - return; - } -} - -void CALLBACK GSgifTransfer2(u32 *pMem, u32 size) -{ - //GS_LOG("GSgifTransfer2 size = %lx (mode %d, gs.path2.tag.nloop = %d)\n", size, gs.path2.mode, gs.path2.tag.nloop); - - _GSgifTransfer(&gs.path2, pMem, size); -} - -void CALLBACK GSgifTransfer3(u32 *pMem, u32 size) -{ - //GS_LOG("GSgifTransfer3 size = %lx (mode %d, gs.path3.tag.nloop = %d)\n", size, gs.path3.mode, gs.path3.tag.nloop); - - nPath3Hack = 0; - _GSgifTransfer(&gs.path3, pMem, size); -} - -static int count = 0; -void CALLBACK GSgifTransfer1(u32 *pMem, u32 addr) -{ - pathInfo *path = &gs.path1; - - //GS_LOG("GSgifTransfer1 0x%x (mode %d)\n", addr, path->mode); - - addr &= 0x3fff; - -#ifdef _DEBUG - PRIM_LOG("count: %d\n", count); - count++; -#endif - - gs.path1.tag.nloop = 0; - gs.path1.tag.eop = 0; - _GSgifTransfer(&gs.path1, (u32*)((u8*)pMem+addr), (0x4000-addr)/16); - - if( !gs.path1.tag.eop && gs.path1.tag.nloop > 0 ) { - assert( (addr&0xf) == 0 ); //BUG - gs.path1.tag.nloop = 0; - ERROR_LOG("Transfer1 - 2\n"); - return; - } -} - void CALLBACK GSreadFIFO(u64 *pMem) { //GS_LOG("GSreadFIFO\n"); diff --git a/plugins/zerogs/opengl/GifTransfer.cpp b/plugins/zerogs/opengl/GifTransfer.cpp new file mode 100644 index 0000000000..bfed0dac67 --- /dev/null +++ b/plugins/zerogs/opengl/GifTransfer.cpp @@ -0,0 +1,312 @@ +/* ZeroGS KOSMOS + * Copyright (C) 2005-2006 zerofrog@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + #include "GifTransfer.h" + + void GIFtag(pathInfo *path, u32 *data) { + + path->tag.nloop = data[0] & 0x7fff; + path->tag.eop = (data[0] >> 15) & 0x1; + u32 tagpre = (data[1] >> 14) & 0x1; + u32 tagprim = (data[1] >> 15) & 0x7ff; + u32 tagflg = (data[1] >> 26) & 0x3; + path->tag.nreg = (data[1] >> 28)<<2; + + if (path->tag.nreg == 0) path->tag.nreg = 64; + + gs.q = 1; + +// GS_LOG("GIFtag: %8.8lx_%8.8lx_%8.8lx_%8.8lx: EOP=%d, NLOOP=%x, FLG=%x, NREG=%d, PRE=%d\n", +// data[3], data[2], data[1], data[0], +// path->tag.eop, path->tag.nloop, tagflg, path->tag.nreg, tagpre); + + path->mode = tagflg+1; + + switch (tagflg) { + case 0x0: + path->regs = *(u64 *)(data+2); + path->regn = 0; + if (tagpre) + GIFRegHandlerPRIM((u32*)&tagprim); + + break; + + case 0x1: + path->regs = *(u64 *)(data+2); + path->regn = 0; + break; + } +} + +void _GSgifPacket(pathInfo *path, u32 *pMem) { // 128bit + + int reg = (int)((path->regs >> path->regn) & 0xf); + g_GIFPackedRegHandlers[reg](pMem); + + path->regn += 4; + if (path->tag.nreg == path->regn) { + path->regn = 0; + path->tag.nloop--; + } +} + +void _GSgifRegList(pathInfo *path, u32 *pMem) { // 64bit + int reg; + + reg = (int)((path->regs >> path->regn) & 0xf); + + g_GIFRegHandlers[reg](pMem); + path->regn += 4; + if (path->tag.nreg == path->regn) { + path->regn = 0; + path->tag.nloop--; + } +} + +static int nPath3Hack = 0; + +void CALLBACK GSgetLastTag(u64* ptag) +{ + *(u32*)ptag = nPath3Hack; + nPath3Hack = 0; +} + +void _GSgifTransfer(pathInfo *path, u32 *pMem, u32 size) +{ +#ifdef _WIN32 + assert( g_hCurrentThread == GetCurrentThread() ); +#endif + +#ifdef _DEBUG + if( conf.log & 0x20 ) { + static int nSaveIndex=0; + GS_LOG("%d: p:%d %x\n", nSaveIndex++, (path==&gs.path3)?3:(path==&gs.path2?2:1), size); + int vals[4] = {0}; + for(int i = 0; i < size; i++) { + for(int j = 0; j < 4; ++j ) + vals[j] ^= pMem[4*i+j]; + } + GS_LOG("%x %x %x %x\n", vals[0], vals[1], vals[2], vals[3]); + } +#endif + + while(size > 0) + { + //LOG(_T("Transfer(%08x, %d) START\n"), pMem, size); + if (path->tag.nloop == 0) + { + GIFtag(path, pMem); + pMem+= 4; + size--; + + if ((g_GameSettings & GAME_PATH3HACK) && path == &gs.path3 && gs.path3.tag.eop) + nPath3Hack = 1; + + if (path == &gs.path1) + { + // if too much data, just ignore + if (path->tag.nloop * (path->tag.nreg / 4) > (int)size * (path->mode==2?2:1)) + { + static int lasttime = 0; + if( timeGetTime() - lasttime > 5000 ) + { + ERROR_LOG("VU1 too much data, ignore if gfx are fine\n"); + lasttime = timeGetTime(); + } + path->tag.nloop = 0; + return; + } + + if (path->mode == 1) + { + // check if 0xb is in any reg, if yes, exit (kh2) + for(int i = 0; i < path->tag.nreg; i += 4) + { + if (((path->regs >> i)&0xf) == 11) + { + static int lasttime = 0; + if( timeGetTime() - lasttime > 5000 ) + { + ERROR_LOG("Invalid unpack type\n"); + lasttime = timeGetTime(); + } + path->tag.nloop = 0; + return; + } + } + } + } + + if(path->tag.nloop == 0 ) + { + if( path == &gs.path1 ) + { + // ffx hack + /*if( g_GameSettings & GAME_FFXHACK ) + {*/ + if( path->tag.eop ) + return; + continue; + /*}*/ + + return; + } + + if( !path->tag.eop ) + { + //DEBUG_LOG("continuing from eop\n"); + continue; + } + + continue; + } + } + + switch(path->mode) { + case 1: // PACKED + { + assert( path->tag.nloop > 0 ); + for(; size > 0; size--, pMem += 4) + { + int reg = (int)((path->regs >> path->regn) & 0xf); + + g_GIFPackedRegHandlers[reg](pMem); + + path->regn += 4; + if (path->tag.nreg == path->regn) + { + path->regn = 0; + if( path->tag.nloop-- <= 1 ) + { + size--; + pMem += 4; + break; + } + } + } + break; + } + case 2: // REGLIST + { + //GS_LOG("%8.8x%8.8x %d L\n", ((u32*)&gs.regs)[1], *(u32*)&gs.regs, path->tag.nreg/4); + assert( path->tag.nloop > 0 ); + size *= 2; + for(; size > 0; pMem+= 2, size--) + { + int reg = (int)((path->regs >> path->regn) & 0xf); + g_GIFRegHandlers[reg](pMem); + path->regn += 4; + if (path->tag.nreg == path->regn) + { + path->regn = 0; + if( path->tag.nloop-- <= 1 ) + { + size--; + pMem += 2; + break; + } + } + } + + if( size & 1 ) pMem += 2; + size /= 2; + break; + } + case 3: // GIF_IMAGE (FROM_VFRAM) + case 4: // Used in the DirectX version, so we'll use it here too. + { + if(gs.imageTransfer >= 0 && gs.imageTransfer <= 1) + { + int process = min((int)size, path->tag.nloop); + + if( process > 0 ) + { + if ( gs.imageTransfer ) + ZeroGS::TransferLocalHost(pMem, process); + else + ZeroGS::TransferHostLocal(pMem, process*4); + + path->tag.nloop -= process; + pMem += process*4; size -= process; + + assert( size == 0 || path->tag.nloop == 0 ); + } + break; + } + else + { + // simulate + int process = min((int)size, path->tag.nloop); + path->tag.nloop -= process; + pMem += process*4; size -= process; + } + + break; + } + default: // GIF_IMAGE + GS_LOG("*** WARNING **** Unexpected GIFTag flag\n"); + assert(0); + path->tag.nloop = 0; + break; + } + + if( path == &gs.path1 && path->tag.eop ) + return; + } +} + +void CALLBACK GSgifTransfer2(u32 *pMem, u32 size) +{ + //GS_LOG("GSgifTransfer2 size = %lx (mode %d, gs.path2.tag.nloop = %d)\n", size, gs.path2.mode, gs.path2.tag.nloop); + + _GSgifTransfer(&gs.path2, pMem, size); +} + +void CALLBACK GSgifTransfer3(u32 *pMem, u32 size) +{ + //GS_LOG("GSgifTransfer3 size = %lx (mode %d, gs.path3.tag.nloop = %d)\n", size, gs.path3.mode, gs.path3.tag.nloop); + + nPath3Hack = 0; + _GSgifTransfer(&gs.path3, pMem, size); +} + +static int count = 0; +void CALLBACK GSgifTransfer1(u32 *pMem, u32 addr) +{ + pathInfo *path = &gs.path1; + + //GS_LOG("GSgifTransfer1 0x%x (mode %d)\n", addr, path->mode); + + addr &= 0x3fff; + +#ifdef _DEBUG + PRIM_LOG("count: %d\n", count); + count++; +#endif + + gs.path1.tag.nloop = 0; + gs.path1.tag.eop = 0; + _GSgifTransfer(&gs.path1, (u32*)((u8*)pMem+addr), (0x4000-addr)/16); + + if( !gs.path1.tag.eop && gs.path1.tag.nloop > 0 ) { + assert( (addr&0xf) == 0 ); //BUG + gs.path1.tag.nloop = 0; + ERROR_LOG("Transfer1 - 2\n"); + return; + } +} diff --git a/plugins/zerogs/opengl/GifTransfer.h b/plugins/zerogs/opengl/GifTransfer.h new file mode 100644 index 0000000000..28b43a79d0 --- /dev/null +++ b/plugins/zerogs/opengl/GifTransfer.h @@ -0,0 +1,31 @@ +/* ZeroGS KOSMOS + * Copyright (C) 2005-2006 zerofrog@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "GS.h" +#include "Mem.h" +#include "Regs.h" +#include "zerogs.h" + +void GIFtag(pathInfo *path, u32 *data); +void _GSgifPacket(pathInfo *path, u32 *pMem); +void _GSgifRegList(pathInfo *path, u32 *pMem); +void _GSgifTransfer(pathInfo *path, u32 *pMem, u32 size); + +extern GIFRegHandler g_GIFPackedRegHandlers[]; +extern GIFRegHandler g_GIFRegHandlers[]; \ No newline at end of file diff --git a/plugins/zerogs/opengl/Linux/Makefile.am b/plugins/zerogs/opengl/Linux/Makefile.am index aa98f152c5..e1631ec3ac 100644 --- a/plugins/zerogs/opengl/Linux/Makefile.am +++ b/plugins/zerogs/opengl/Linux/Makefile.am @@ -1,10 +1,4 @@ noinst_LIBRARIES = libZeroGSLinux.a -if X86_64 -libZeroGSLinux_a_CPPFLAGS = -fPIC -libZeroGSLinux_a_CXXFLAGS = -fPIC -libZeroGSLinux_a_CFLAGS = -fPIC -endif - INCLUDES = $(shell pkg-config --cflags gtk+-2.0) -I@srcdir@/../ -I@srcdir@/../common libZeroGSLinux_a_SOURCES = callbacks.c Conf.cpp interface.c Linux.cpp support.c diff --git a/plugins/zerogs/opengl/Makefile.am b/plugins/zerogs/opengl/Makefile.am index c66a43a85b..3523948ac0 100644 --- a/plugins/zerogs/opengl/Makefile.am +++ b/plugins/zerogs/opengl/Makefile.am @@ -6,16 +6,9 @@ INCLUDES = -I@srcdir@/../../../common/include -I@srcdir@/../../../3rdparty libZeroGSogl_a_CPPFLAGS = $(shell pkg-config --cflags gtk+-2.0) libZeroGSogl_a_CXXFLAGS = $(shell pkg-config --cflags gtk+-2.0) -if X86_64 -libZeroGSogl_a_CPPFLAGS += -fPIC -libZeroGSogl_a_CXXFLAGS += -fPIC -CCASFLAGS += -fPIC -endif - # Create a shared object by faking an exe (thanks to ODE makefiles) traplibdir=$(prefix) - if RELEASE_TO_PUBLIC preext=r endif @@ -31,13 +24,9 @@ libZeroGSogl_LDADD=$(libZeroGSogl_a_OBJECTS) libZeroGSogl_a_SOURCES = \ GSmain.cpp memcpy_amd.cpp Regs.cpp x86.cpp zpipe.cpp \ -Mem.cpp rasterfont.cpp targets.cpp zerogs.cpp +Mem.cpp rasterfont.cpp targets.cpp zerogs.cpp GifTransfer.cpp -if X86_64 -libZeroGSogl_a_SOURCES += x86-64.S -else libZeroGSogl_a_SOURCES += x86-32.S -endif if SSE2 CCASFLAGS+= -DZEROGS_SSE2 diff --git a/plugins/zerogs/opengl/Win32/zerogsogl_2008.vcproj b/plugins/zerogs/opengl/Win32/zerogsogl_2008.vcproj index 19a3b591a8..09d5998433 100644 --- a/plugins/zerogs/opengl/Win32/zerogsogl_2008.vcproj +++ b/plugins/zerogs/opengl/Win32/zerogsogl_2008.vcproj @@ -17,8 +17,8 @@ + + + @@ -278,6 +287,14 @@ RelativePath=".\Conf.cpp" > + + + + diff --git a/plugins/zerogs/opengl/configure b/plugins/zerogs/opengl/configure deleted file mode 100644 index 8650685df9..0000000000 --- a/plugins/zerogs/opengl/configure +++ /dev/null @@ -1,7282 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.63 for ZeroGSogl 0.96.2. -# -# Report bugs to . -# -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - -if test "x$CONFIG_SHELL" = x; then - if (eval ":") 2>/dev/null; then - as_have_required=yes -else - as_have_required=no -fi - - if test $as_have_required = yes && (eval ": -(as_func_return () { - (exit \$1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = \"\$1\" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test \$exitcode = 0) || { (exit 1); exit 1; } - -( - as_lineno_1=\$LINENO - as_lineno_2=\$LINENO - test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && - test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } -") 2> /dev/null; then - : -else - as_candidate_shells= - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - case $as_dir in - /*) - for as_base in sh bash ksh sh5; do - as_candidate_shells="$as_candidate_shells $as_dir/$as_base" - done;; - esac -done -IFS=$as_save_IFS - - - for as_shell in $as_candidate_shells $SHELL; do - # Try only shells that exist, to save several forks. - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { ("$as_shell") 2> /dev/null <<\_ASEOF -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - -: -_ASEOF -}; then - CONFIG_SHELL=$as_shell - as_have_required=yes - if { "$as_shell" 2> /dev/null <<\_ASEOF -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - -: -(as_func_return () { - (exit $1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = "$1" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test $exitcode = 0) || { (exit 1); exit 1; } - -( - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } - -_ASEOF -}; then - break -fi - -fi - - done - - if test "x$CONFIG_SHELL" != x; then - for as_var in BASH_ENV ENV - do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - done - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} -fi - - - if test $as_have_required = no; then - echo This script requires a shell more modern than all the - echo shells that I found on your system. Please install a - echo modern shell, or manually run the script under such a - echo shell if you do have one. - { (exit 1); exit 1; } -fi - - -fi - -fi - - - -(eval "as_func_return () { - (exit \$1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = \"\$1\" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test \$exitcode = 0") || { - echo No shell found that supports shell functions. - echo Please tell bug-autoconf@gnu.org about your system, - echo including any error possibly output before this message. - echo This can help us improve future autoconf versions. - echo Configuration will now proceed without shell functions. -} - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -p' - fi -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - - -exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Identity of this package. -PACKAGE_NAME='ZeroGSogl' -PACKAGE_TARNAME='zerogsogl' -PACKAGE_VERSION='0.96.2' -PACKAGE_STRING='ZeroGSogl 0.96.2' -PACKAGE_BUGREPORT='zerofrog@gmail.com' - -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='LTLIBOBJS -LIBOBJS -EGREP -GREP -SHARED_LDFLAGS -so_ext -GTK_CONFIG -X86_64_FALSE -X86_64_TRUE -SSE2_FALSE -SSE2_TRUE -RELEASE_TO_PUBLIC_FALSE -RELEASE_TO_PUBLIC_TRUE -ZEROGS_SONAME -ZEROGS_RELEASE -ZEROGS_AGE -ZEROGS_REVISION -ZEROGS_CURRENT -am__fastdepCCAS_FALSE -am__fastdepCCAS_TRUE -CCASDEPMODE -CCASFLAGS -CCAS -RANLIB -CPP -am__fastdepCXX_FALSE -am__fastdepCXX_TRUE -CXXDEPMODE -ac_ct_CXX -CXXFLAGS -CXX -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__quote -am__include -DEPDIR -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_dependency_tracking -enable_debug -enable_devbuild -enable_sse2 -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CXX -CXXFLAGS -CCC -CPP -CCAS -CCASFLAGS' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 - { (exit 1); exit 1; }; } - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 - { (exit 1); exit 1; }; } - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 - { (exit 1); exit 1; }; } - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 - { (exit 1); exit 1; }; } - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) { $as_echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { $as_echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 - { (exit 1); exit 1; }; } ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; } -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - { $as_echo "$as_me: error: working directory cannot be determined" >&2 - { (exit 1); exit 1; }; } -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 - { (exit 1); exit 1; }; } - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 - { (exit 1); exit 1; }; } - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures ZeroGSogl 0.96.2 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/zerogsogl] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of ZeroGSogl 0.96.2:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors - --enable-debug debug build - --enable-devbuild Special Build for developers that simplifies testing - and adds extra checks - --enable-sse2 Enable sse2 instructions - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CXX C++ compiler command - CXXFLAGS C++ compiler flags - CPP C preprocessor - CCAS assembler compiler command (defaults to CC) - CCASFLAGS assembler compiler flags (defaults to CFLAGS) - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to . -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -ZeroGSogl configure 0.96.2 -generated by GNU Autoconf 2.63 - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by ZeroGSogl $as_me 0.96.2, which was -generated by GNU Autoconf 2.63. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" -done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; - 2) - ac_configure_args1="$ac_configure_args1 '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - ac_configure_args="$ac_configure_args '$ac_arg'" - ;; - esac - done -done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) $as_unset $ac_var ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - cat <<\_ASBOX -## ----------------- ## -## Output variables. ## -## ----------------- ## -_ASBOX - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------------- ## -## File substitutions. ## -## ------------------- ## -_ASBOX - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - ac_site_file1=$CONFIG_SITE -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test -r "$ac_site_file"; then - { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -fi - - - - - - - - - - - - - - - - - - - - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -am__api_version='1.10' - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 -$as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} - { (exit 1); exit 1; }; } -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in - ./ | .// | /cC/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - -done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:$LINENO: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - { { $as_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken -alias in your environment" >&5 -$as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken -alias in your environment" >&2;} - { (exit 1); exit 1; }; } - fi - - test "$2" = conftest.file - ) -then - # Ok. - : -else - { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files! -Check your system clock" >&5 -$as_echo "$as_me: error: newly created file is older than distributed files! -Check your system clock" >&2;} - { (exit 1); exit 1; }; } -fi -{ $as_echo "$as_me:$LINENO: result: yes" >&5 -$as_echo "yes" >&6; } -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` - -test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} -fi - -{ $as_echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if test "${ac_cv_path_mkdir+set}" = set; then - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done -done -IFS=$as_save_IFS - -fi - - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - test -d ./--version && rmdir ./--version - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -mkdir_p="$MKDIR_P" -case $mkdir_p in - [\\/$]* | ?:[\\/]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AWK+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:$LINENO: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:$LINENO: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - { { $as_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 -$as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} - { (exit 1); exit 1; }; } - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE=ZeroGSogl - VERSION=0.96.2 - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} - -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_STRIP+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:$LINENO: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -# Always define AMTAR for backward compatibility. - -AMTAR=${AMTAR-"${am_missing_run}tar"} - -am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - for ac_prog in gcc g++ cl KCC CC cxx cc++ xlC aCC c++ - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:$LINENO: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in gcc g++ cl KCC CC cxx cc++ xlC aCC c++ -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - - -test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; }; } - -# Provide some information about the compiler. -$as_echo "$as_me:$LINENO: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -{ (ac_try="$ac_compiler --version >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compiler --version >&5") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -v >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compiler -v >&5") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -V >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compiler -V >&5") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { (ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi - -{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -if test -z "$ac_file"; then - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; }; } -fi - -ac_exeext=$ac_cv_exeext - -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; }; } - fi - fi -fi -{ $as_echo "$as_me:$LINENO: result: yes" >&5 -$as_echo "yes" >&6; } - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; }; } -fi - -rm -f conftest$ac_cv_exeext -{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if test "${ac_cv_objext+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_compiler_gnu=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_compiler_gnu=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cc_g=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CFLAGS="" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - : -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cc_g=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cc_c89=$ac_arg -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:$LINENO: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:$LINENO: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo done -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# We grep out `Entering directory' and `Leaving directory' -# messages which can occur if `w' ends up in MAKEFLAGS. -# In particular we don't look at `^make:' because GNU make might -# be invoked under some other name (usually "gmake"), in which -# case it prints its new name instead of `make'. -if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then - am__include=include - am__quote= - _am_result=GNU -fi -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then - am__include=.include - am__quote="\"" - _am_result=BSD - fi -fi - - -{ $as_echo "$as_me:$LINENO: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test -z "$CXX"; then - if test -n "$CCC"; then - CXX=$CCC - else - if test -n "$ac_tool_prefix"; then - for ac_prog in gcc g++ cl KCC CC cxx cc++ xlC aCC c++ - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CXX+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - { $as_echo "$as_me:$LINENO: result: $CXX" >&5 -$as_echo "$CXX" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in gcc g++ cl KCC CC cxx cc++ xlC aCC c++ -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CXX="$ac_prog" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 -$as_echo "$ac_ct_CXX" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CXX" && break -done - - if test "x$ac_ct_CXX" = x; then - CXX="g++" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CXX=$ac_ct_CXX - fi -fi - - fi -fi -# Provide some information about the compiler. -$as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -{ (ac_try="$ac_compiler --version >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compiler --version >&5") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -v >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compiler -v >&5") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -V >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compiler -V >&5") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 -$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if test "${ac_cv_cxx_compiler_gnu+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_compiler_gnu=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_compiler_gnu=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 -$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GXX=yes -else - GXX= -fi -ac_test_CXXFLAGS=${CXXFLAGS+set} -ac_save_CXXFLAGS=$CXXFLAGS -{ $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 -$as_echo_n "checking whether $CXX accepts -g... " >&6; } -if test "${ac_cv_prog_cxx_g+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_save_cxx_werror_flag=$ac_cxx_werror_flag - ac_cxx_werror_flag=yes - ac_cv_prog_cxx_g=no - CXXFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cxx_g=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CXXFLAGS="" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - : -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cxx_g=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cxx_werror_flag=$ac_save_cxx_werror_flag -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 -$as_echo "$ac_cv_prog_cxx_g" >&6; } -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -depcc="$CXX" am_compiler_list= - -{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CXX_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CXX_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CXX_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } -CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then - am__fastdepCXX_TRUE= - am__fastdepCXX_FALSE='#' -else - am__fastdepCXX_TRUE='#' - am__fastdepCXX_FALSE= -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - : -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - # Broken: success on invalid input. -continue -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:$LINENO: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - : -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - # Broken: success on invalid input. -continue -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -if test "x$CC" != xcc; then - { $as_echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5 -$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } -else - { $as_echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5 -$as_echo_n "checking whether cc understands -c and -o together... " >&6; } -fi -set dummy $CC; ac_cc=`$as_echo "$2" | - sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -# Make sure it works both with $CC and with simple cc. -# We do the test twice because some compilers refuse to overwrite an -# existing .o file with -o, though they will create one. -ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' -rm -f conftest2.* -if { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - test -f conftest2.$ac_objext && { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; -then - eval ac_cv_prog_cc_${ac_cc}_c_o=yes - if test "x$CC" != xcc; then - # Test first that cc exists at all. - if { ac_try='cc -c conftest.$ac_ext >&5' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' - rm -f conftest2.* - if { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - test -f conftest2.$ac_objext && { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; - then - # cc works too. - : - else - # cc exists but doesn't like -o. - eval ac_cv_prog_cc_${ac_cc}_c_o=no - fi - fi - fi -else - eval ac_cv_prog_cc_${ac_cc}_c_o=no -fi -rm -f core conftest* - -fi -if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then - { $as_echo "$as_me:$LINENO: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } - -cat >>confdefs.h <<\_ACEOF -#define NO_MINUS_C_MINUS_O 1 -_ACEOF - -fi - -# FIXME: we rely on the cache variable name because -# there is no other way. -set dummy $CC -am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o -if test "$am_t" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi - - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in - ./ | .// | /cC/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - -done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_RANLIB+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:$LINENO: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - - -# By default we simply use the C compiler to build assembly code. - -test "${CCAS+set}" = set || CCAS=$CC -test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS - - - -depcc="$CCAS" am_compiler_list= - -{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if test "${am_cv_CCAS_dependencies_compiler_type+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CCAS_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CCAS_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CCAS_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:$LINENO: result: $am_cv_CCAS_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CCAS_dependencies_compiler_type" >&6; } -CCASDEPMODE=depmode=$am_cv_CCAS_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CCAS_dependencies_compiler_type" = gcc3; then - am__fastdepCCAS_TRUE= - am__fastdepCCAS_FALSE='#' -else - am__fastdepCCAS_TRUE='#' - am__fastdepCCAS_FALSE= -fi - - - -ZEROGS_CURRENT=0 - -ZEROGS_REVISION=96 - -ZEROGS_AGE=2 - -ZEROGS_RELEASE=$ZEROGS_CURRENT.$ZEROGS_REVISION.$ZEROGS_AGE - -ZEROGS_SONAME=libZeroGSogl.so.$ZEROGS_CURRENT.$ZEROGS_REVISION.$ZEROGS_AGE - - -CFLAGS=" -I/opt/cg/include -L/opt/cg/lib " -CPPFLAGS=" -I/opt/cg/include -L/opt/cg/lib " -CXXFLAGS=" -I/opt/cg/include -L/opt/cg/lib " - -{ $as_echo "$as_me:$LINENO: checking debug build" >&5 -$as_echo_n "checking debug build... " >&6; } -# Check whether --enable-debug was given. -if test "${enable_debug+set}" = set; then - enableval=$enable_debug; debug=$enableval -else - debug=no -fi - -if test "x$debug" == xyes -then - -cat >>confdefs.h <<\_ACEOF -#define _DEBUG 1 -_ACEOF - - CFLAGS+="-g " - CPPFLAGS+="-g " - CXXFLAGS+="-g -fpermissive " -else - -cat >>confdefs.h <<\_ACEOF -#define NDEBUG 1 -_ACEOF - - CFLAGS+="-O3 -fomit-frame-pointer " - CPPFLAGS+="-O3 -fomit-frame-pointer " - CXXFLAGS+="-O3 -fomit-frame-pointer -fpermissive " -fi -{ $as_echo "$as_me:$LINENO: result: $debug" >&5 -$as_echo "$debug" >&6; } - - - - -for ac_func in _aligned_malloc _aligned_free -do -as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 -$as_echo_n "checking for $ac_func... " >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - eval "$as_ac_var=yes" -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -as_val=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - cat >>confdefs.h <<\_ACEOF -#define HAVE_ALIGNED_MALLOC 1 -_ACEOF - -fi -done - - -{ $as_echo "$as_me:$LINENO: checking for development build..." >&5 -$as_echo_n "checking for development build...... " >&6; } -# Check whether --enable-devbuild was given. -if test "${enable_devbuild+set}" = set; then - enableval=$enable_devbuild; devbuild=$enableval -else - devbuild=no -fi - -if test "x$devbuild" == xyes -then - -cat >>confdefs.h <<\_ACEOF -#define ZEROGS_DEVBUILD 1 -_ACEOF - -fi -{ $as_echo "$as_me:$LINENO: result: $devbuild" >&5 -$as_echo "$devbuild" >&6; } - if test x$devbuild = xno; then - RELEASE_TO_PUBLIC_TRUE= - RELEASE_TO_PUBLIC_FALSE='#' -else - RELEASE_TO_PUBLIC_TRUE='#' - RELEASE_TO_PUBLIC_FALSE= -fi - - -{ $as_echo "$as_me:$LINENO: checking check for sse2..." >&5 -$as_echo_n "checking check for sse2...... " >&6; } -# Check whether --enable-sse2 was given. -if test "${enable_sse2+set}" = set; then - enableval=$enable_sse2; sse2=$enableval -else - sse2=no -fi - -if test "x$sse2" == xyes -then - -cat >>confdefs.h <<\_ACEOF -#define ZEROGS_SSE2 1 -_ACEOF - -fi -{ $as_echo "$as_me:$LINENO: result: $sse2" >&5 -$as_echo "$sse2" >&6; } - if test x$sse2 = xyes; then - SSE2_TRUE= - SSE2_FALSE='#' -else - SSE2_TRUE='#' - SSE2_FALSE= -fi - - -{ $as_echo "$as_me:$LINENO: checking for a x86-64 CPU" >&5 -$as_echo_n "checking for a x86-64 CPU... " >&6; } -if test "$cross_compiling" = yes; then - { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: cannot run test program while cross compiling -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: cannot run test program while cross compiling -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; }; } -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int main() -{ -int a = 0; -int*pa = &a; -asm(".intel_syntax\n" - "mov %%rax, %0\n" - "mov %%eax, [%%rax]\n" - ".att_syntax\n" - : : "r"(pa) : "%rax"); -return 0; -} - -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cpu64=yes -else - $as_echo "$as_me: program exited with status $ac_status" >&5 -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -cpu64=no -fi -rm -rf conftest.dSYM -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -if test "x$cpu64" == xyes -then - -cat >>confdefs.h <<\_ACEOF -#define __x86_64__ 1 -_ACEOF - -fi -{ $as_echo "$as_me:$LINENO: result: $cpu64" >&5 -$as_echo "$cpu64" >&6; } - if test x$cpu64 = xyes; then - X86_64_TRUE= - X86_64_FALSE='#' -else - X86_64_TRUE='#' - X86_64_FALSE= -fi - - -{ $as_echo "$as_me:$LINENO: checking gtk2+" >&5 -$as_echo_n "checking gtk2+... " >&6; } -# Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_GTK_CONFIG+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$GTK_CONFIG"; then - ac_cv_prog_GTK_CONFIG="$GTK_CONFIG" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_GTK_CONFIG="pkg-config" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -GTK_CONFIG=$ac_cv_prog_GTK_CONFIG -if test -n "$GTK_CONFIG"; then - { $as_echo "$as_me:$LINENO: result: $GTK_CONFIG" >&5 -$as_echo "$GTK_CONFIG" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - -LIBS+=$(pkg-config --libs gtk+-2.0) - - -so_ext=".so.$ZEROGS_RELEASE" -SHARED_LDFLAGS="-shared" - - - -{ $as_echo "$as_me:$LINENO: checking OpenGL" >&5 -$as_echo_n "checking OpenGL... " >&6; } - - - -for ac_header in GL/gl.h GL/glu.h GL/glext.h -do -as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 -$as_echo_n "checking for $ac_header... " >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#if HAVE_GL_GL_H - #include - #endif - #if HAVE_GL_GLU_H - #include - #endif - - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - eval "$as_ac_Header=yes" -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_Header=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -ac_res=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -as_val=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -{ $as_echo "$as_me:$LINENO: checking for main in -lGL" >&5 -$as_echo_n "checking for main in -lGL... " >&6; } -if test "${ac_cv_lib_GL_main+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lGL $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_GL_main=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_GL_main=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_GL_main" >&5 -$as_echo "$ac_cv_lib_GL_main" >&6; } -if test "x$ac_cv_lib_GL_main" = x""yes; then - LIBS="$LIBS -lGL" -fi - -{ $as_echo "$as_me:$LINENO: checking for main in -lGLU" >&5 -$as_echo_n "checking for main in -lGLU... " >&6; } -if test "${ac_cv_lib_GLU_main+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lGLU $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_GLU_main=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_GLU_main=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_GLU_main" >&5 -$as_echo "$ac_cv_lib_GLU_main" >&6; } -if test "x$ac_cv_lib_GLU_main" = x""yes; then - LIBS="$LIBS -lGLU" -fi - -{ $as_echo "$as_me:$LINENO: checking for main in -lGLEW" >&5 -$as_echo_n "checking for main in -lGLEW... " >&6; } -if test "${ac_cv_lib_GLEW_main+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lGLEW $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_GLEW_main=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_GLEW_main=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_GLEW_main" >&5 -$as_echo "$ac_cv_lib_GLEW_main" >&6; } -if test "x$ac_cv_lib_GLEW_main" = x""yes; then - LIBS="$LIBS -lGLEW" -fi - -{ $as_echo "$as_me:$LINENO: checking Cg" >&5 -$as_echo_n "checking Cg... " >&6; } -#AC_CHECK_HEADERS([Cg/cg.h Cg/cgGL.h]) - -{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if test "${ac_cv_path_GREP+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done -done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:$LINENO: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done -done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_header_stdc=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_stdc=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - $as_echo "$as_me: program exited with status $ac_status" >&5 -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -rf conftest.dSYM -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do -as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 -$as_echo_n "checking for $ac_header... " >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - eval "$as_ac_Header=yes" -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_Header=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -ac_res=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -as_val=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - -for ac_header in jpeglib.h -do -as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 -$as_echo_n "checking for $ac_header... " >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -fi -ac_res=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 -$as_echo_n "checking $ac_header usability... " >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 -$as_echo_n "checking $ac_header presence... " >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## --------------------------------- ## -## Report this to zerofrog@gmail.com ## -## --------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 -$as_echo_n "checking for $ac_header... " >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - -fi -as_val=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -else - { { $as_echo "$as_me:$LINENO: error: Install libjpeg-dev" >&5 -$as_echo "$as_me: error: Install libjpeg-dev" >&2;} - { (exit 1); exit 1; }; } -fi - -done - - -{ $as_echo "$as_me:$LINENO: checking for main in -ljpeg" >&5 -$as_echo_n "checking for main in -ljpeg... " >&6; } -if test "${ac_cv_lib_jpeg_main+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ljpeg $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_jpeg_main=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_jpeg_main=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_jpeg_main" >&5 -$as_echo "$ac_cv_lib_jpeg_main" >&6; } -if test "x$ac_cv_lib_jpeg_main" = x""yes; then - LIBS="$LIBS -ljpeg" -fi - -{ $as_echo "$as_me:$LINENO: checking for main in -lpthread" >&5 -$as_echo_n "checking for main in -lpthread... " >&6; } -if test "${ac_cv_lib_pthread_main+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_pthread_main=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_pthread_main=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_main" >&5 -$as_echo "$ac_cv_lib_pthread_main" >&6; } -if test "x$ac_cv_lib_pthread_main" = x""yes; then - LIBS="$LIBS -lpthread" -fi - -{ $as_echo "$as_me:$LINENO: checking for main in -lstdc++" >&5 -$as_echo_n "checking for main in -lstdc++... " >&6; } -if test "${ac_cv_lib_stdcpp_main+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lstdc++ $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_stdcpp_main=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_stdcpp_main=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_stdcpp_main" >&5 -$as_echo "$ac_cv_lib_stdcpp_main" >&6; } -if test "x$ac_cv_lib_stdcpp_main" = x""yes; then - LIBS="$LIBS -lstdc++" -fi - -{ $as_echo "$as_me:$LINENO: checking for main in -lz" >&5 -$as_echo_n "checking for main in -lz... " >&6; } -if test "${ac_cv_lib_z_main+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_z_main=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_z_main=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_z_main" >&5 -$as_echo "$ac_cv_lib_z_main" >&6; } -if test "x$ac_cv_lib_z_main" = x""yes; then - LIBS="$LIBS -lz" -fi - -{ $as_echo "$as_me:$LINENO: checking for main in -ldl" >&5 -$as_echo_n "checking for main in -ldl... " >&6; } -if test "${ac_cv_lib_dl_main+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_dl_main=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_dl_main=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_main" >&5 -$as_echo "$ac_cv_lib_dl_main" >&6; } -if test "x$ac_cv_lib_dl_main" = x""yes; then - LIBS="$LIBS -ldl" -fi - -{ $as_echo "$as_me:$LINENO: checking for main in -lXxf86vm" >&5 -$as_echo_n "checking for main in -lXxf86vm... " >&6; } -if test "${ac_cv_lib_Xxf86vm_main+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lXxf86vm $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_Xxf86vm_main=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_Xxf86vm_main=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_Xxf86vm_main" >&5 -$as_echo "$ac_cv_lib_Xxf86vm_main" >&6; } -if test "x$ac_cv_lib_Xxf86vm_main" = x""yes; then - LIBS="$LIBS -lXxf86vm" -else - echo "Error! You need to have libXxf86vm-dev." ; exit -1 -fi - - - -LIBS+=" -lCg -lCgGL" - -ac_config_files="$ac_config_files Makefile Linux/Makefile" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) $as_unset $ac_var ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && - { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file - else - { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -ac_script=' -:mline -/\\$/{ - N - s,\\\n,, - b mline -} -t clear -:clear -s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g -t quote -s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g -t quote -b any -:quote -s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g -s/\[/\\&/g -s/\]/\\&/g -s/\$/$$/g -H -:any -${ - g - s/^\n// - s/\n/ /g - p -} -' -DEFS=`sed -n "$ac_script" confdefs.h` - - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - { { $as_echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -$as_echo "$as_me: error: conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -$as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then - { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -$as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then - { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCCAS\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -$as_echo "$as_me: error: conditional \"am__fastdepCCAS\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${RELEASE_TO_PUBLIC_TRUE}" && test -z "${RELEASE_TO_PUBLIC_FALSE}"; then - { { $as_echo "$as_me:$LINENO: error: conditional \"RELEASE_TO_PUBLIC\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -$as_echo "$as_me: error: conditional \"RELEASE_TO_PUBLIC\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${SSE2_TRUE}" && test -z "${SSE2_FALSE}"; then - { { $as_echo "$as_me:$LINENO: error: conditional \"SSE2\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -$as_echo "$as_me: error: conditional \"SSE2\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${X86_64_TRUE}" && test -z "${X86_64_FALSE}"; then - { { $as_echo "$as_me:$LINENO: error: conditional \"X86_64\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -$as_echo "$as_me: error: conditional \"X86_64\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi - -: ${CONFIG_STATUS=./config.status} -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -p' - fi -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 - -# Save the log message, to keep $[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by ZeroGSogl $as_me 0.96.2, which was -generated by GNU Autoconf 2.63. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTION]... [FILE]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - -Configuration files: -$config_files - -Configuration commands: -$config_commands - -Report bugs to ." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_version="\\ -ZeroGSogl config.status 0.96.2 -configured by $0, generated by GNU Autoconf 2.63, - with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" - -Copyright (C) 2008 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" - ac_need_defaults=false;; - --he | --h | --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { $as_echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "Linux/Makefile") CONFIG_FILES="$CONFIG_FILES Linux/Makefile" ;; - - *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= - trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status -' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || -{ - $as_echo "$as_me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=' ' -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } -ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\).*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\).*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ - || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 -$as_echo "$as_me: error: could not setup config files machinery" >&2;} - { (exit 1); exit 1; }; } -_ACEOF - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/ -s/:*\${srcdir}:*/:/ -s/:*@srcdir@:*/:/ -s/^\([^=]*=[ ]*\):*/\1/ -s/:*$// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - - -eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 -$as_echo "$as_me: error: invalid tag $ac_tag" >&2;} - { (exit 1); exit 1; }; };; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 -$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} - { (exit 1); exit 1; }; };; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - ac_file_inputs="$ac_file_inputs '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin" \ - || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 -$as_echo "$as_me: error: could not create $ac_file" >&2;} - { (exit 1); exit 1; }; } ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - { as_dir="$ac_dir" - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} - { (exit 1); exit 1; }; }; } - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= - -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p -' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 -$as_echo "$as_me: error: could not create $ac_file" >&2;} - { (exit 1); exit 1; }; } - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&2;} - - rm -f "$tmp/stdin" - case $ac_file in - -) cat "$tmp/out" && rm -f "$tmp/out";; - *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; - esac \ - || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 -$as_echo "$as_me: error: could not create $ac_file" >&2;} - { (exit 1); exit 1; }; } - ;; - - - :C) { $as_echo "$as_me:$LINENO: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || # Autoconf 2.62 quotes --file arguments for eval, but not when files -# are listed without --file. Let's play safe and only enable the eval -# if we detect the quoting. -case $CONFIG_FILES in -*\'*) eval set x "$CONFIG_FILES" ;; -*) set x $CONFIG_FILES ;; -esac -shift -for mf -do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - { as_dir=$dirpart/$fdir - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} - { (exit 1); exit 1; }; }; } - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done -done - ;; - - esac -done # for ac_tag - - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - - -echo "Configuration:" -echo " Target system type: $target" -echo " x86-64 build? $cpu64" -echo " SSE2 enabled? $sse2" -echo " Debug build? $debug" -echo " Dev build? $devbuild" diff --git a/plugins/zerogs/opengl/configure.ac b/plugins/zerogs/opengl/configure.ac index b602230a08..c097cedbec 100644 --- a/plugins/zerogs/opengl/configure.ac +++ b/plugins/zerogs/opengl/configure.ac @@ -22,6 +22,7 @@ AC_SUBST(ZEROGS_SONAME, libZeroGSogl.so.[$ZEROGS_CURRENT].[$ZEROGS_REVISION].[$Z CFLAGS=" -I/opt/cg/include -L/opt/cg/lib " CPPFLAGS=" -I/opt/cg/include -L/opt/cg/lib " CXXFLAGS=" -I/opt/cg/include -L/opt/cg/lib " +CCASFLAGS= dnl Check for debug build AC_MSG_CHECKING(debug build) @@ -30,14 +31,16 @@ AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [debug build]), if test "x$debug" == xyes then AC_DEFINE(_DEBUG,1,[_DEBUG]) - CFLAGS+="-g " - CPPFLAGS+="-g " - CXXFLAGS+="-g -fpermissive " + CFLAGS+="-g -m32 " + CPPFLAGS+="-g -m32 " + CXXFLAGS+="-g -fpermissive -m32 " + CCASFLAGS+=" -m32 " else AC_DEFINE(NDEBUG,1,[NDEBUG]) - CFLAGS+="-O3 -fomit-frame-pointer " - CPPFLAGS+="-O3 -fomit-frame-pointer " - CXXFLAGS+="-O3 -fomit-frame-pointer -fpermissive " + CFLAGS+="-O3 -fomit-frame-pointer -m32 " + CPPFLAGS+="-O3 -fomit-frame-pointer -m32 " + CXXFLAGS+="-O3 -fomit-frame-pointer -fpermissive -m32 " + CCASFLAGS+=" -m32 " fi AC_MSG_RESULT($debug) @@ -65,33 +68,6 @@ fi AC_MSG_RESULT($sse2) AM_CONDITIONAL(SSE2, test x$sse2 = xyes) -dnl Check for 64bit CPU -AC_MSG_CHECKING(for a x86-64 CPU) -dnl if test "$build_os" == "target_os" -dnl then -AC_TRY_RUN([ -int main() -{ -int a = 0; -int*pa = &a; -asm(".intel_syntax\n" - "mov %%rax, %0\n" - "mov %%eax, [%%rax]\n" - ".att_syntax\n" - : : "r"(pa) : "%rax"); -return 0; -} -],cpu64=yes,cpu64=no,) -dnl else -dnl cpu64=no -dnl fi -if test "x$cpu64" == xyes -then -AC_DEFINE(__x86_64__,1,[__x86_64__]) -fi -AC_MSG_RESULT($cpu64) -AM_CONDITIONAL(X86_64, test x$cpu64 = xyes) - dnl gtk AC_MSG_CHECKING(gtk2+) AC_CHECK_PROG(GTK_CONFIG, pkg-config, pkg-config) diff --git a/plugins/zeropad/Linux/callbacks.c b/plugins/zeropad/Linux/callbacks.c new file mode 100644 index 0000000000..81945c91cb --- /dev/null +++ b/plugins/zeropad/Linux/callbacks.c @@ -0,0 +1,123 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + + +void +OnAbout_Ok (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + +} + + +void +OnConf_Pad1 (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConf_Pad2 (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConf_Pad3 (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConf_Pad4 (GtkButton *button, + gpointer user_data) +{ + +} + + +void +on_joydevicescombo_changed (GtkComboBox *combobox, + gpointer user_data) +{ + +} + + +void +OnConf_Key (GtkButton *button, + gpointer user_data) +{ + +} + + +void +on_checkbutton_reversery_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + +} + + +void +on_checkbutton_reverserx_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + +} + + +void +on_forcefeedback_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + +} + + +void +on_checkbutton_reverselx_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + +} + + +void +on_checkbutton_reversely_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + +} + + +void +OnConf_Ok (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConf_Cancel (GtkButton *button, + gpointer user_data) +{ + +} + diff --git a/plugins/zeropad/Linux/callbacks.h b/plugins/zeropad/Linux/callbacks.h index cb64e16292..ff61cd234e 100644 --- a/plugins/zeropad/Linux/callbacks.h +++ b/plugins/zeropad/Linux/callbacks.h @@ -1,6 +1,11 @@ #include +void +OnAbout_Ok (GtkDialog *dialog, + gint response_id, + gpointer user_data); + void OnConf_Pad1 (GtkButton *button, gpointer user_data); @@ -10,21 +15,33 @@ OnConf_Pad2 (GtkButton *button, gpointer user_data); void -OnConf_Key (GtkButton *button, +OnConf_Pad3 (GtkButton *button, gpointer user_data); void -OnConf_Cancel (GtkButton *button, - gpointer user_data); - -void -OnConf_Ok (GtkButton *button, +OnConf_Pad4 (GtkButton *button, gpointer user_data); void on_joydevicescombo_changed (GtkComboBox *combobox, gpointer user_data); +void +OnConf_Key (GtkButton *button, + gpointer user_data); + +void +on_checkbutton_reversery_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_checkbutton_reverserx_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_forcefeedback_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + void on_checkbutton_reverselx_toggled (GtkToggleButton *togglebutton, gpointer user_data); @@ -34,13 +51,9 @@ on_checkbutton_reversely_toggled (GtkToggleButton *togglebutton, gpointer user_data); void -on_checkbutton_reverserx_toggled (GtkToggleButton *togglebutton, +OnConf_Ok (GtkButton *button, gpointer user_data); void -on_checkbutton_reversery_toggled (GtkToggleButton *togglebutton, - gpointer user_data); - -void -on_forcefeedback_toggled (GtkToggleButton *togglebutton, +OnConf_Cancel (GtkButton *button, gpointer user_data); diff --git a/plugins/zeropad/Linux/gui.cpp b/plugins/zeropad/Linux/gui.cpp new file mode 100644 index 0000000000..b7b6bccfb2 --- /dev/null +++ b/plugins/zeropad/Linux/gui.cpp @@ -0,0 +1,287 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + #include +#include +#include + +#include "joystick.h" + +#include "zeropad.h" +#include "linux.h" + +extern "C" +{ +#include "interface.h" +#include "support.h" +#include "callbacks.h" +} + +extern string s_strIniPath; +GtkWidget *Conf = NULL, *About = NULL; +GtkWidget *s_devicecombo = NULL; +extern void UpdateConf(int pad); + +void SaveConfig() +{ + int i, j; + FILE *f; + char cfg[255]; + + strcpy(cfg, s_strIniPath.c_str()); + f = fopen(cfg, "w"); + if (f == NULL) + { + printf("ZeroPAD: failed to save ini %s\n", s_strIniPath.c_str()); + return; + } + + for (j = 0; j < 2 * PADSUBKEYS; j++) + { + for (i = 0; i < PADKEYS; i++) + { + fprintf(f, "[%d][%d] = 0x%lx\n", j, i, conf.keys[j][i]); + } + } + fprintf(f, "log = %d\n", conf.log); + fprintf(f, "options = %d\n", conf.options); + fclose(f); +} + +void LoadConfig() +{ + FILE *f; + char str[256]; + char cfg[255]; + int i, j; + + memset(&conf, 0, sizeof(conf)); + conf.keys[0][0] = XK_a; // L2 + conf.keys[0][1] = XK_semicolon; // R2 + conf.keys[0][2] = XK_w; // L1 + conf.keys[0][3] = XK_p; // R1 + conf.keys[0][4] = XK_i; // TRIANGLE + conf.keys[0][5] = XK_l; // CIRCLE + conf.keys[0][6] = XK_k; // CROSS + conf.keys[0][7] = XK_j; // SQUARE + conf.keys[0][8] = XK_v; // SELECT + conf.keys[0][11] = XK_n; // START + conf.keys[0][12] = XK_e; // UP + conf.keys[0][13] = XK_f; // RIGHT + conf.keys[0][14] = XK_d; // DOWN + conf.keys[0][15] = XK_s; // LEFT + conf.log = 0; + + strcpy(cfg, s_strIniPath.c_str()); + f = fopen(cfg, "r"); + if (f == NULL) + { + printf("ZeroPAD: failed to load ini %s\n", s_strIniPath.c_str()); + SaveConfig(); //save and return + return; + } + + for (j = 0; j < 2 * PADSUBKEYS; j++) + { + for (i = 0; i < PADKEYS; i++) + { + sprintf(str, "[%d][%d] = 0x%%x\n", j, i); + if (fscanf(f, str, &conf.keys[j][i]) == 0) conf.keys[j][i] = 0; + } + } + fscanf(f, "log = %d\n", &conf.log); + fscanf(f, "options = %d\n", &conf.options); + fclose(f); +} + +GtkWidget *MsgDlg; + +void OnMsg_Ok() +{ + gtk_widget_destroy(MsgDlg); + gtk_main_quit(); +} + +// GUI event handlers +void on_joydevicescombo_changed(GtkComboBox *combobox, gpointer user_data) +{ + int joyid = gtk_combo_box_get_active(combobox); + + // unassign every joystick with this pad + for (int i = 0; i < (int)s_vjoysticks.size(); ++i) + { + if (s_vjoysticks[i]->GetPAD() == s_selectedpad) s_vjoysticks[i]->Assign(-1); + } + + if (joyid >= 0 && joyid < (int)s_vjoysticks.size()) s_vjoysticks[joyid]->Assign(s_selectedpad); +} + +void on_checkbutton_reverselx_toggled(GtkToggleButton *togglebutton, gpointer user_data) +{ + int mask = PADOPTION_REVERTLX << (16 * s_selectedpad); + + if (gtk_toggle_button_get_active(togglebutton)) + conf.options |= mask; + else + conf.options &= ~mask; +} + +void on_checkbutton_reversely_toggled(GtkToggleButton *togglebutton, gpointer user_data) +{ + int mask = PADOPTION_REVERTLY << (16 * s_selectedpad); + + if (gtk_toggle_button_get_active(togglebutton)) + conf.options |= mask; + else + conf.options &= ~mask; +} + +void on_checkbutton_reverserx_toggled(GtkToggleButton *togglebutton, gpointer user_data) +{ + int mask = PADOPTION_REVERTRX << (16 * s_selectedpad); + if (gtk_toggle_button_get_active(togglebutton)) + conf.options |= mask; + else + conf.options &= ~mask; +} + +void on_checkbutton_reversery_toggled(GtkToggleButton *togglebutton, gpointer user_data) +{ + int mask = PADOPTION_REVERTRY << (16 * s_selectedpad); + + if (gtk_toggle_button_get_active(togglebutton)) + conf.options |= mask; + else + conf.options &= ~mask; +} + +void on_forcefeedback_toggled(GtkToggleButton *togglebutton, gpointer user_data) +{ + int mask = PADOPTION_REVERTLX << (16 * s_selectedpad); + + if (gtk_toggle_button_get_active(togglebutton)) + { + conf.options |= mask; + + int joyid = gtk_combo_box_get_active(GTK_COMBO_BOX(s_devicecombo)); + + if (joyid >= 0 && joyid < (int)s_vjoysticks.size()) s_vjoysticks[joyid]->TestForce(); + } + else + { + conf.options &= ~mask; + } +} + +void SysMessage(char *fmt, ...) +{ + GtkWidget *Ok, *Txt; + GtkWidget *Box, *Box1; + va_list list; + char msg[512]; + + va_start(list, fmt); + vsprintf(msg, fmt, list); + va_end(list); + + if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0; + + MsgDlg = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER); + gtk_window_set_title(GTK_WINDOW(MsgDlg), "ZeroPad"); + gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 5); + + Box = gtk_vbox_new(5, 0); + gtk_container_add(GTK_CONTAINER(MsgDlg), Box); + gtk_widget_show(Box); + + Txt = gtk_label_new(msg); + + gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5); + gtk_widget_show(Txt); + + Box1 = gtk_hbutton_box_new(); + gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0); + gtk_widget_show(Box1); + + Ok = gtk_button_new_with_label("Ok"); + gtk_signal_connect(GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsg_Ok), NULL); + gtk_container_add(GTK_CONTAINER(Box1), Ok); + GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT); + gtk_widget_show(Ok); + + gtk_widget_show(MsgDlg); + + gtk_main(); +} + +void OnConf_Pad1(GtkButton *button, gpointer user_data) +{ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) UpdateConf(0); +} + +void OnConf_Pad2(GtkButton *button, gpointer user_data) +{ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) UpdateConf(1); +} + +void OnConf_Pad3(GtkButton *button, gpointer user_data) +{ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) UpdateConf(2); +} + +void OnConf_Pad4(GtkButton *button, gpointer user_data) +{ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) UpdateConf(3); +} + +void OnConf_Ok(GtkButton *button, gpointer user_data) +{ +// conf.analog = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Analog)); + SaveConfig(); + + gtk_widget_destroy(Conf); + gtk_main_quit(); +} + +void OnConf_Cancel(GtkButton *button, gpointer user_data) +{ + gtk_widget_destroy(Conf); + gtk_main_quit(); + LoadConfig(); // load previous config +} + +void OnAbout_Ok(GtkDialog *About, gint response_id, gpointer user_data) +{ + gtk_widget_destroy(GTK_WIDGET(About)); + gtk_main_quit(); +} + +void CALLBACK PADabout() +{ + + About = create_About(); + + gtk_widget_show_all(About); + gtk_main(); +} + +s32 CALLBACK PADtest() +{ + return 0; +} \ No newline at end of file diff --git a/plugins/zeropad/Linux/interface.c b/plugins/zeropad/Linux/interface.c index ffd4261e65..dd5158b82c 100644 --- a/plugins/zeropad/Linux/interface.c +++ b/plugins/zeropad/Linux/interface.c @@ -42,11 +42,18 @@ create_About (void) gchar *translators = _("translator-credits"); About = gtk_about_dialog_new (); + gtk_widget_set_name (About, "About"); + gtk_container_set_border_width (GTK_CONTAINER (About), 5); + gtk_window_set_destroy_with_parent (GTK_WINDOW (About), TRUE); gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (About), VERSION); gtk_about_dialog_set_name (GTK_ABOUT_DIALOG (About), _("ZeroPAD")); gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG (About), authors); gtk_about_dialog_set_translator_credits (GTK_ABOUT_DIALOG (About), translators); + g_signal_connect ((gpointer) About, "response", + G_CALLBACK (OnAbout_Ok), + NULL); + /* Store pointers to all widgets, for use by lookup_widget(). */ GLADE_HOOKUP_OBJECT_NO_REF (About, About, "About"); @@ -65,6 +72,8 @@ create_Conf (void) GtkWidget *PAD1; GSList *PAD1_group = NULL; GtkWidget *PAD2; + GtkWidget *PAD3; + GtkWidget *PAD4; GtkWidget *label2; GtkWidget *vbox2; GtkWidget *label5; @@ -91,62 +100,86 @@ create_Conf (void) GtkWidget *eLx; GtkWidget *eRy; GtkWidget *eLy; - GtkWidget *Select; - GtkWidget *L1; - GtkWidget *Left; - GtkWidget *Down; - GtkWidget *Analog; - GtkWidget *R2; - GtkWidget *Start; - GtkWidget *R1; - GtkWidget *Cross; - GtkWidget *Triangle; - GtkWidget *Circle; - GtkWidget *Square; - GtkWidget *L3; - GtkWidget *Up; - GtkWidget *L2; - GtkWidget *Lx; - GtkWidget *Ly; - GtkWidget *Rx; - GtkWidget *Ry; - GtkWidget *Right; - GtkWidget *label3; + GtkWidget *eL_Up; + GtkWidget *eL_Left; + GtkWidget *eL_Right; + GtkWidget *eL_Down; + GtkWidget *eR_Up; + GtkWidget *eR_Left; + GtkWidget *eR_Right; + GtkWidget *eR_Down; GtkWidget *R3; + GtkWidget *Select; + GtkWidget *Start; + GtkWidget *Square; + GtkWidget *Circle; + GtkWidget *L2; + GtkWidget *L1; + GtkWidget *Down; + GtkWidget *Up; + GtkWidget *Left; + GtkWidget *Right; + GtkWidget *R1; + GtkWidget *R2; + GtkWidget *Triangle; + GtkWidget *Cross; + GtkWidget *L3; + GtkWidget *checkbutton_reversery; + GtkWidget *checkbutton_reverserx; + GtkWidget *R_Down; + GtkWidget *Ry; + GtkWidget *Rx; + GtkWidget *R_Up; + GtkWidget *R_Right; + GtkWidget *R_Left; + GtkWidget *forcefeedback; GtkWidget *checkbutton_reverselx; GtkWidget *checkbutton_reversely; - GtkWidget *checkbutton_reverserx; - GtkWidget *checkbutton_reversery; - GtkWidget *forcefeedback; + GtkWidget *L_Down; + GtkWidget *Ly; + GtkWidget *Lx; + GtkWidget *L_Up; + GtkWidget *L_Left; + GtkWidget *L_Right; + GtkWidget *label3; + GtkWidget *Analog; + GtkWidget *label6; GtkWidget *dialog_action_area1; - GtkWidget *cancelbutton1; GtkWidget *okbutton1; + GtkWidget *cancelbutton1; Conf = gtk_dialog_new (); + gtk_widget_set_name (Conf, "Conf"); gtk_window_set_title (GTK_WINDOW (Conf), _("ZeroPAD Configuration Dialog")); gtk_window_set_type_hint (GTK_WINDOW (Conf), GDK_WINDOW_TYPE_HINT_DIALOG); dialog_vbox1 = GTK_DIALOG (Conf)->vbox; + gtk_widget_set_name (dialog_vbox1, "dialog_vbox1"); gtk_widget_show (dialog_vbox1); vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (vbox1, "vbox1"); gtk_widget_show (vbox1); gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, TRUE, TRUE, 0); frame1 = gtk_frame_new (NULL); + gtk_widget_set_name (frame1, "frame1"); gtk_widget_show (frame1); gtk_box_pack_start (GTK_BOX (vbox1), frame1, FALSE, FALSE, 0); alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_set_name (alignment1, "alignment1"); gtk_widget_show (alignment1); gtk_container_add (GTK_CONTAINER (frame1), alignment1); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment1), 0, 0, 12, 0); hbox1 = gtk_hbox_new (FALSE, 0); + gtk_widget_set_name (hbox1, "hbox1"); gtk_widget_show (hbox1); gtk_container_add (GTK_CONTAINER (alignment1), hbox1); PAD1 = gtk_radio_button_new_with_mnemonic (NULL, _("PAD1")); + gtk_widget_set_name (PAD1, "PAD1"); gtk_widget_show (PAD1); gtk_box_pack_start (GTK_BOX (hbox1), PAD1, FALSE, FALSE, 0); gtk_radio_button_set_group (GTK_RADIO_BUTTON (PAD1), PAD1_group); @@ -154,420 +187,626 @@ create_Conf (void) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (PAD1), TRUE); PAD2 = gtk_radio_button_new_with_mnemonic (NULL, _("PAD2")); + gtk_widget_set_name (PAD2, "PAD2"); gtk_widget_show (PAD2); gtk_box_pack_start (GTK_BOX (hbox1), PAD2, FALSE, FALSE, 0); gtk_radio_button_set_group (GTK_RADIO_BUTTON (PAD2), PAD1_group); PAD1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (PAD2)); + PAD3 = gtk_radio_button_new_with_mnemonic (NULL, _("PAD1 alt.")); + gtk_widget_set_name (PAD3, "PAD3"); + gtk_widget_show (PAD3); + gtk_box_pack_start (GTK_BOX (hbox1), PAD3, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (PAD3), PAD1_group); + PAD1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (PAD3)); + + PAD4 = gtk_radio_button_new_with_mnemonic (NULL, _("PAD2 alt.")); + gtk_widget_set_name (PAD4, "PAD4"); + gtk_widget_show (PAD4); + gtk_box_pack_start (GTK_BOX (hbox1), PAD4, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (PAD4), PAD1_group); + PAD1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (PAD4)); + label2 = gtk_label_new (_("Choose PAD to modify")); + gtk_widget_set_name (label2, "label2"); gtk_widget_show (label2); gtk_frame_set_label_widget (GTK_FRAME (frame1), label2); gtk_label_set_use_markup (GTK_LABEL (label2), TRUE); vbox2 = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (vbox2, "vbox2"); gtk_widget_show (vbox2); - gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, TRUE, 0); label5 = gtk_label_new (_("Joystick to use for this PAD")); + gtk_widget_set_name (label5, "label5"); gtk_widget_show (label5); gtk_box_pack_start (GTK_BOX (vbox2), label5, FALSE, FALSE, 0); joydevicescombo = gtk_combo_box_entry_new_text (); + gtk_widget_set_name (joydevicescombo, "joydevicescombo"); gtk_widget_show (joydevicescombo); - gtk_box_pack_start (GTK_BOX (vbox2), joydevicescombo, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox2), joydevicescombo, FALSE, TRUE, 0); fixed1 = gtk_fixed_new (); + gtk_widget_set_name (fixed1, "fixed1"); gtk_widget_show (fixed1); gtk_box_pack_start (GTK_BOX (vbox1), fixed1, TRUE, TRUE, 0); eL2 = gtk_entry_new (); + gtk_widget_set_name (eL2, "eL2"); gtk_widget_show (eL2); - gtk_fixed_put (GTK_FIXED (fixed1), eL2, 64, 40); + gtk_fixed_put (GTK_FIXED (fixed1), eL2, 64, 32); gtk_widget_set_size_request (eL2, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eL2), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eL2), 8226); eL1 = gtk_entry_new (); + gtk_widget_set_name (eL1, "eL1"); gtk_widget_show (eL1); - gtk_fixed_put (GTK_FIXED (fixed1), eL1, 64, 104); + gtk_fixed_put (GTK_FIXED (fixed1), eL1, 64, 80); gtk_widget_set_size_request (eL1, 64, 24); gtk_entry_set_invisible_char (GTK_ENTRY (eL1), 8226); eSelect = gtk_entry_new (); + gtk_widget_set_name (eSelect, "eSelect"); gtk_widget_show (eSelect); - gtk_fixed_put (GTK_FIXED (fixed1), eSelect, 168, 64); + gtk_fixed_put (GTK_FIXED (fixed1), eSelect, 200, 184); gtk_widget_set_size_request (eSelect, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eSelect), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eSelect), 8226); eStart = gtk_entry_new (); + gtk_widget_set_name (eStart, "eStart"); gtk_widget_show (eStart); - gtk_fixed_put (GTK_FIXED (fixed1), eStart, 280, 64); + gtk_fixed_put (GTK_FIXED (fixed1), eStart, 272, 184); gtk_widget_set_size_request (eStart, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eStart), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eStart), 8226); eUp = gtk_entry_new (); + gtk_widget_set_name (eUp, "eUp"); gtk_widget_show (eUp); - gtk_fixed_put (GTK_FIXED (fixed1), eUp, 64, 168); + gtk_fixed_put (GTK_FIXED (fixed1), eUp, 64, 136); gtk_widget_set_size_request (eUp, 64, 24); gtk_entry_set_invisible_char (GTK_ENTRY (eUp), 8226); eRight = gtk_entry_new (); + gtk_widget_set_name (eRight, "eRight"); gtk_widget_show (eRight); - gtk_fixed_put (GTK_FIXED (fixed1), eRight, 128, 208); + gtk_fixed_put (GTK_FIXED (fixed1), eRight, 128, 184); gtk_widget_set_size_request (eRight, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eRight), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eRight), 8226); eLeft = gtk_entry_new (); + gtk_widget_set_name (eLeft, "eLeft"); gtk_widget_show (eLeft); - gtk_fixed_put (GTK_FIXED (fixed1), eLeft, 0, 208); + gtk_fixed_put (GTK_FIXED (fixed1), eLeft, 0, 184); gtk_widget_set_size_request (eLeft, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eLeft), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eLeft), 8226); eDown = gtk_entry_new (); + gtk_widget_set_name (eDown, "eDown"); gtk_widget_show (eDown); - gtk_fixed_put (GTK_FIXED (fixed1), eDown, 64, 256); + gtk_fixed_put (GTK_FIXED (fixed1), eDown, 64, 232); gtk_widget_set_size_request (eDown, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eDown), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eDown), 8226); eR2 = gtk_entry_new (); + gtk_widget_set_name (eR2, "eR2"); gtk_widget_show (eR2); - gtk_fixed_put (GTK_FIXED (fixed1), eR2, 368, 32); + gtk_fixed_put (GTK_FIXED (fixed1), eR2, 408, 32); gtk_widget_set_size_request (eR2, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eR2), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eR2), 8226); eR1 = gtk_entry_new (); + gtk_widget_set_name (eR1, "eR1"); gtk_widget_show (eR1); - gtk_fixed_put (GTK_FIXED (fixed1), eR1, 368, 104); + gtk_fixed_put (GTK_FIXED (fixed1), eR1, 408, 80); gtk_widget_set_size_request (eR1, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eR1), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eR1), 8226); eAnalog = gtk_entry_new (); + gtk_widget_set_name (eAnalog, "eAnalog"); gtk_widget_show (eAnalog); - gtk_fixed_put (GTK_FIXED (fixed1), eAnalog, 224, 128); + gtk_fixed_put (GTK_FIXED (fixed1), eAnalog, 240, 232); gtk_widget_set_size_request (eAnalog, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eAnalog), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eAnalog), 8226); eSquare = gtk_entry_new (); + gtk_widget_set_name (eSquare, "eSquare"); gtk_widget_show (eSquare); - gtk_fixed_put (GTK_FIXED (fixed1), eSquare, 304, 208); + gtk_fixed_put (GTK_FIXED (fixed1), eSquare, 344, 184); gtk_widget_set_size_request (eSquare, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eSquare), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eSquare), 8226); eTriangle = gtk_entry_new (); + gtk_widget_set_name (eTriangle, "eTriangle"); gtk_widget_show (eTriangle); - gtk_fixed_put (GTK_FIXED (fixed1), eTriangle, 368, 168); + gtk_fixed_put (GTK_FIXED (fixed1), eTriangle, 408, 136); gtk_widget_set_size_request (eTriangle, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eTriangle), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eTriangle), 8226); eCircle = gtk_entry_new (); + gtk_widget_set_name (eCircle, "eCircle"); gtk_widget_show (eCircle); - gtk_fixed_put (GTK_FIXED (fixed1), eCircle, 432, 208); + gtk_fixed_put (GTK_FIXED (fixed1), eCircle, 472, 184); gtk_widget_set_size_request (eCircle, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eCircle), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eCircle), 8226); eCross = gtk_entry_new (); + gtk_widget_set_name (eCross, "eCross"); gtk_widget_show (eCross); - gtk_fixed_put (GTK_FIXED (fixed1), eCross, 368, 256); + gtk_fixed_put (GTK_FIXED (fixed1), eCross, 408, 232); gtk_widget_set_size_request (eCross, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eCross), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eCross), 8226); eR3 = gtk_entry_new (); + gtk_widget_set_name (eR3, "eR3"); gtk_widget_show (eR3); - gtk_fixed_put (GTK_FIXED (fixed1), eR3, 272, 272); + gtk_fixed_put (GTK_FIXED (fixed1), eR3, 272, 56); gtk_widget_set_size_request (eR3, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eR3), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eR3), 8226); eL3 = gtk_entry_new (); + gtk_widget_set_name (eL3, "eL3"); gtk_widget_show (eL3); - gtk_fixed_put (GTK_FIXED (fixed1), eL3, 176, 272); + gtk_fixed_put (GTK_FIXED (fixed1), eL3, 200, 56); gtk_widget_set_size_request (eL3, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eL3), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eL3), 8226); eRx = gtk_entry_new (); + gtk_widget_set_name (eRx, "eRx"); gtk_widget_show (eRx); - gtk_fixed_put (GTK_FIXED (fixed1), eRx, 272, 352); - gtk_widget_set_size_request (eRx, 80, 24); + gtk_fixed_put (GTK_FIXED (fixed1), eRx, 408, 384); + gtk_widget_set_size_request (eRx, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eRx), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eRx), 8226); eLx = gtk_entry_new (); + gtk_widget_set_name (eLx, "eLx"); gtk_widget_show (eLx); - gtk_fixed_put (GTK_FIXED (fixed1), eLx, 160, 352); - gtk_widget_set_size_request (eLx, 80, 24); + gtk_fixed_put (GTK_FIXED (fixed1), eLx, 64, 384); + gtk_widget_set_size_request (eLx, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eLx), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eLx), 8226); eRy = gtk_entry_new (); + gtk_widget_set_name (eRy, "eRy"); gtk_widget_show (eRy); - gtk_fixed_put (GTK_FIXED (fixed1), eRy, 272, 416); - gtk_widget_set_size_request (eRy, 80, 24); + gtk_fixed_put (GTK_FIXED (fixed1), eRy, 408, 432); + gtk_widget_set_size_request (eRy, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eRy), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eRy), 8226); eLy = gtk_entry_new (); + gtk_widget_set_name (eLy, "eLy"); gtk_widget_show (eLy); - gtk_fixed_put (GTK_FIXED (fixed1), eLy, 160, 416); - gtk_widget_set_size_request (eLy, 80, 24); + gtk_fixed_put (GTK_FIXED (fixed1), eLy, 64, 432); + gtk_widget_set_size_request (eLy, 64, 24); gtk_editable_set_editable (GTK_EDITABLE (eLy), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (eLy), 8226); - Select = gtk_button_new_with_mnemonic (_("Select")); - gtk_widget_show (Select); - gtk_fixed_put (GTK_FIXED (fixed1), Select, 168, 32); - gtk_widget_set_size_request (Select, 64, 32); + eL_Up = gtk_entry_new (); + gtk_widget_set_name (eL_Up, "eL_Up"); + gtk_widget_show (eL_Up); + gtk_fixed_put (GTK_FIXED (fixed1), eL_Up, 64, 336); + gtk_widget_set_size_request (eL_Up, 64, 24); - L1 = gtk_button_new_with_mnemonic (_("L1")); - gtk_widget_show (L1); - gtk_fixed_put (GTK_FIXED (fixed1), L1, 64, 72); - gtk_widget_set_size_request (L1, 64, 32); + eL_Left = gtk_entry_new (); + gtk_widget_set_name (eL_Left, "eL_Left"); + gtk_widget_show (eL_Left); + gtk_fixed_put (GTK_FIXED (fixed1), eL_Left, 0, 408); + gtk_widget_set_size_request (eL_Left, 64, 24); - Left = gtk_button_new_with_mnemonic (_("Left")); - gtk_widget_show (Left); - gtk_fixed_put (GTK_FIXED (fixed1), Left, 0, 176); - gtk_widget_set_size_request (Left, 64, 32); + eL_Right = gtk_entry_new (); + gtk_widget_set_name (eL_Right, "eL_Right"); + gtk_widget_show (eL_Right); + gtk_fixed_put (GTK_FIXED (fixed1), eL_Right, 128, 408); + gtk_widget_set_size_request (eL_Right, 64, 24); - Down = gtk_button_new_with_mnemonic (_("Down")); - gtk_widget_show (Down); - gtk_fixed_put (GTK_FIXED (fixed1), Down, 64, 224); - gtk_widget_set_size_request (Down, 64, 32); + eL_Down = gtk_entry_new (); + gtk_widget_set_name (eL_Down, "eL_Down"); + gtk_widget_show (eL_Down); + gtk_fixed_put (GTK_FIXED (fixed1), eL_Down, 64, 480); + gtk_widget_set_size_request (eL_Down, 64, 24); - Analog = gtk_button_new_with_mnemonic (_("Analog")); - gtk_widget_show (Analog); - gtk_fixed_put (GTK_FIXED (fixed1), Analog, 224, 96); - gtk_widget_set_size_request (Analog, 64, 32); + eR_Up = gtk_entry_new (); + gtk_widget_set_name (eR_Up, "eR_Up"); + gtk_widget_show (eR_Up); + gtk_fixed_put (GTK_FIXED (fixed1), eR_Up, 408, 336); + gtk_widget_set_size_request (eR_Up, 64, 24); - R2 = gtk_button_new_with_mnemonic (_("R2")); - gtk_widget_show (R2); - gtk_fixed_put (GTK_FIXED (fixed1), R2, 368, 0); - gtk_widget_set_size_request (R2, 64, 32); + eR_Left = gtk_entry_new (); + gtk_widget_set_name (eR_Left, "eR_Left"); + gtk_widget_show (eR_Left); + gtk_fixed_put (GTK_FIXED (fixed1), eR_Left, 344, 408); + gtk_widget_set_size_request (eR_Left, 64, 24); - Start = gtk_button_new_with_mnemonic (_("Start")); - gtk_widget_show (Start); - gtk_fixed_put (GTK_FIXED (fixed1), Start, 280, 32); - gtk_widget_set_size_request (Start, 64, 32); + eR_Right = gtk_entry_new (); + gtk_widget_set_name (eR_Right, "eR_Right"); + gtk_widget_show (eR_Right); + gtk_fixed_put (GTK_FIXED (fixed1), eR_Right, 472, 408); + gtk_widget_set_size_request (eR_Right, 64, 24); - R1 = gtk_button_new_with_mnemonic (_("R1")); - gtk_widget_show (R1); - gtk_fixed_put (GTK_FIXED (fixed1), R1, 368, 72); - gtk_widget_set_size_request (R1, 64, 32); - - Cross = gtk_button_new_with_mnemonic (_("Cross")); - gtk_widget_show (Cross); - gtk_fixed_put (GTK_FIXED (fixed1), Cross, 368, 224); - gtk_widget_set_size_request (Cross, 64, 32); - - Triangle = gtk_button_new_with_mnemonic (_("Triangle")); - gtk_widget_show (Triangle); - gtk_fixed_put (GTK_FIXED (fixed1), Triangle, 368, 136); - gtk_widget_set_size_request (Triangle, 64, 32); - - Circle = gtk_button_new_with_mnemonic (_("Circle")); - gtk_widget_show (Circle); - gtk_fixed_put (GTK_FIXED (fixed1), Circle, 432, 176); - gtk_widget_set_size_request (Circle, 64, 32); - - Square = gtk_button_new_with_mnemonic (_("Square")); - gtk_widget_show (Square); - gtk_fixed_put (GTK_FIXED (fixed1), Square, 304, 176); - gtk_widget_set_size_request (Square, 64, 32); - - L3 = gtk_button_new_with_mnemonic (_("L3")); - gtk_widget_show (L3); - gtk_fixed_put (GTK_FIXED (fixed1), L3, 176, 240); - gtk_widget_set_size_request (L3, 64, 32); - - Up = gtk_button_new_with_mnemonic (_("Up")); - gtk_widget_show (Up); - gtk_fixed_put (GTK_FIXED (fixed1), Up, 64, 136); - gtk_widget_set_size_request (Up, 64, 32); - - L2 = gtk_button_new_with_mnemonic (_("L2")); - gtk_widget_show (L2); - gtk_fixed_put (GTK_FIXED (fixed1), L2, 64, 8); - gtk_widget_set_size_request (L2, 64, 32); - - Lx = gtk_button_new_with_mnemonic (_("Lx")); - gtk_widget_show (Lx); - gtk_fixed_put (GTK_FIXED (fixed1), Lx, 160, 320); - gtk_widget_set_size_request (Lx, 80, 32); - - Ly = gtk_button_new_with_mnemonic (_("Ly")); - gtk_widget_show (Ly); - gtk_fixed_put (GTK_FIXED (fixed1), Ly, 160, 384); - gtk_widget_set_size_request (Ly, 80, 32); - - Rx = gtk_button_new_with_mnemonic (_("Rx")); - gtk_widget_show (Rx); - gtk_fixed_put (GTK_FIXED (fixed1), Rx, 272, 320); - gtk_widget_set_size_request (Rx, 80, 32); - - Ry = gtk_button_new_with_mnemonic (_("Ry")); - gtk_widget_show (Ry); - gtk_fixed_put (GTK_FIXED (fixed1), Ry, 272, 384); - gtk_widget_set_size_request (Ry, 80, 32); - - Right = gtk_button_new_with_mnemonic (_("Right")); - gtk_widget_show (Right); - gtk_fixed_put (GTK_FIXED (fixed1), Right, 128, 176); - gtk_widget_set_size_request (Right, 64, 32); - - label3 = gtk_label_new (_("Analog Controls (move mouse or analog joystick to select)")); - gtk_widget_show (label3); - gtk_fixed_put (GTK_FIXED (fixed1), label3, 48, 296); - gtk_widget_set_size_request (label3, 408, 16); - gtk_label_set_single_line_mode (GTK_LABEL (label3), TRUE); + eR_Down = gtk_entry_new (); + gtk_widget_set_name (eR_Down, "eR_Down"); + gtk_widget_show (eR_Down); + gtk_fixed_put (GTK_FIXED (fixed1), eR_Down, 408, 480); + gtk_widget_set_size_request (eR_Down, 64, 24); R3 = gtk_button_new_with_mnemonic (_("R3")); + gtk_widget_set_name (R3, "R3"); gtk_widget_show (R3); - gtk_fixed_put (GTK_FIXED (fixed1), R3, 272, 240); - gtk_widget_set_size_request (R3, 64, 32); + gtk_fixed_put (GTK_FIXED (fixed1), R3, 272, 32); + gtk_widget_set_size_request (R3, 64, 24); + + Select = gtk_button_new_with_mnemonic (_("Select")); + gtk_widget_set_name (Select, "Select"); + gtk_widget_show (Select); + gtk_fixed_put (GTK_FIXED (fixed1), Select, 200, 160); + gtk_widget_set_size_request (Select, 64, 24); + + Start = gtk_button_new_with_mnemonic (_("Start")); + gtk_widget_set_name (Start, "Start"); + gtk_widget_show (Start); + gtk_fixed_put (GTK_FIXED (fixed1), Start, 272, 160); + gtk_widget_set_size_request (Start, 64, 24); + + Square = gtk_button_new_with_mnemonic (_("Square")); + gtk_widget_set_name (Square, "Square"); + gtk_widget_show (Square); + gtk_fixed_put (GTK_FIXED (fixed1), Square, 344, 160); + gtk_widget_set_size_request (Square, 64, 24); + + Circle = gtk_button_new_with_mnemonic (_("Circle")); + gtk_widget_set_name (Circle, "Circle"); + gtk_widget_show (Circle); + gtk_fixed_put (GTK_FIXED (fixed1), Circle, 472, 160); + gtk_widget_set_size_request (Circle, 64, 24); + + L2 = gtk_button_new_with_mnemonic (_("L2")); + gtk_widget_set_name (L2, "L2"); + gtk_widget_show (L2); + gtk_fixed_put (GTK_FIXED (fixed1), L2, 64, 8); + gtk_widget_set_size_request (L2, 64, 24); + + L1 = gtk_button_new_with_mnemonic (_("L1")); + gtk_widget_set_name (L1, "L1"); + gtk_widget_show (L1); + gtk_fixed_put (GTK_FIXED (fixed1), L1, 64, 56); + gtk_widget_set_size_request (L1, 64, 24); + + Down = gtk_button_new_with_mnemonic (_("Down")); + gtk_widget_set_name (Down, "Down"); + gtk_widget_show (Down); + gtk_fixed_put (GTK_FIXED (fixed1), Down, 64, 208); + gtk_widget_set_size_request (Down, 64, 24); + + Up = gtk_button_new_with_mnemonic (_("Up")); + gtk_widget_set_name (Up, "Up"); + gtk_widget_show (Up); + gtk_fixed_put (GTK_FIXED (fixed1), Up, 64, 112); + gtk_widget_set_size_request (Up, 64, 24); + + Left = gtk_button_new_with_mnemonic (_("Left")); + gtk_widget_set_name (Left, "Left"); + gtk_widget_show (Left); + gtk_fixed_put (GTK_FIXED (fixed1), Left, 0, 160); + gtk_widget_set_size_request (Left, 64, 24); + + Right = gtk_button_new_with_mnemonic (_("Right")); + gtk_widget_set_name (Right, "Right"); + gtk_widget_show (Right); + gtk_fixed_put (GTK_FIXED (fixed1), Right, 128, 160); + gtk_widget_set_size_request (Right, 64, 24); + + R1 = gtk_button_new_with_mnemonic (_("R1")); + gtk_widget_set_name (R1, "R1"); + gtk_widget_show (R1); + gtk_fixed_put (GTK_FIXED (fixed1), R1, 408, 56); + gtk_widget_set_size_request (R1, 64, 24); + + R2 = gtk_button_new_with_mnemonic (_("R2")); + gtk_widget_set_name (R2, "R2"); + gtk_widget_show (R2); + gtk_fixed_put (GTK_FIXED (fixed1), R2, 408, 8); + gtk_widget_set_size_request (R2, 64, 24); + + Triangle = gtk_button_new_with_mnemonic (_("Triangle")); + gtk_widget_set_name (Triangle, "Triangle"); + gtk_widget_show (Triangle); + gtk_fixed_put (GTK_FIXED (fixed1), Triangle, 408, 112); + gtk_widget_set_size_request (Triangle, 64, 24); + + Cross = gtk_button_new_with_mnemonic (_("Cross")); + gtk_widget_set_name (Cross, "Cross"); + gtk_widget_show (Cross); + gtk_fixed_put (GTK_FIXED (fixed1), Cross, 408, 208); + gtk_widget_set_size_request (Cross, 64, 24); + + L3 = gtk_button_new_with_mnemonic (_("L3")); + gtk_widget_set_name (L3, "L3"); + gtk_widget_show (L3); + gtk_fixed_put (GTK_FIXED (fixed1), L3, 200, 32); + gtk_widget_set_size_request (L3, 64, 24); + + checkbutton_reversery = gtk_check_button_new_with_mnemonic (_("Reverse RY")); + gtk_widget_set_name (checkbutton_reversery, "checkbutton_reversery"); + gtk_widget_show (checkbutton_reversery); + gtk_fixed_put (GTK_FIXED (fixed1), checkbutton_reversery, 384, 536); + gtk_widget_set_size_request (checkbutton_reversery, 111, 22); + + checkbutton_reverserx = gtk_check_button_new_with_mnemonic (_("Reverse RX")); + gtk_widget_set_name (checkbutton_reverserx, "checkbutton_reverserx"); + gtk_widget_show (checkbutton_reverserx); + gtk_fixed_put (GTK_FIXED (fixed1), checkbutton_reverserx, 384, 512); + gtk_widget_set_size_request (checkbutton_reverserx, 111, 22); + + R_Down = gtk_button_new_with_mnemonic (_("Down")); + gtk_widget_set_name (R_Down, "R_Down"); + gtk_widget_show (R_Down); + gtk_fixed_put (GTK_FIXED (fixed1), R_Down, 408, 456); + gtk_widget_set_size_request (R_Down, 64, 24); + + Ry = gtk_button_new_with_mnemonic (_("Ry")); + gtk_widget_set_name (Ry, "Ry"); + gtk_widget_show (Ry); + gtk_fixed_put (GTK_FIXED (fixed1), Ry, 408, 408); + gtk_widget_set_size_request (Ry, 64, 24); + + Rx = gtk_button_new_with_mnemonic (_("Rx")); + gtk_widget_set_name (Rx, "Rx"); + gtk_widget_show (Rx); + gtk_fixed_put (GTK_FIXED (fixed1), Rx, 408, 360); + gtk_widget_set_size_request (Rx, 64, 24); + + R_Up = gtk_button_new_with_mnemonic (_("Up")); + gtk_widget_set_name (R_Up, "R_Up"); + gtk_widget_show (R_Up); + gtk_fixed_put (GTK_FIXED (fixed1), R_Up, 408, 312); + gtk_widget_set_size_request (R_Up, 64, 24); + + R_Right = gtk_button_new_with_mnemonic (_("Right")); + gtk_widget_set_name (R_Right, "R_Right"); + gtk_widget_show (R_Right); + gtk_fixed_put (GTK_FIXED (fixed1), R_Right, 472, 384); + gtk_widget_set_size_request (R_Right, 64, 24); + + R_Left = gtk_button_new_with_mnemonic (_("Left")); + gtk_widget_set_name (R_Left, "R_Left"); + gtk_widget_show (R_Left); + gtk_fixed_put (GTK_FIXED (fixed1), R_Left, 344, 384); + gtk_widget_set_size_request (R_Left, 64, 24); + + forcefeedback = gtk_check_button_new_with_mnemonic (_("Enable Force\nFeedback")); + gtk_widget_set_name (forcefeedback, "forcefeedback"); + gtk_widget_show (forcefeedback); + gtk_fixed_put (GTK_FIXED (fixed1), forcefeedback, 216, 512); + gtk_widget_set_size_request (forcefeedback, 112, 48); checkbutton_reverselx = gtk_check_button_new_with_mnemonic (_("Reverse LX")); + gtk_widget_set_name (checkbutton_reverselx, "checkbutton_reverselx"); gtk_widget_show (checkbutton_reverselx); - gtk_fixed_put (GTK_FIXED (fixed1), checkbutton_reverselx, 16, 328); + gtk_fixed_put (GTK_FIXED (fixed1), checkbutton_reverselx, 48, 512); gtk_widget_set_size_request (checkbutton_reverselx, 111, 22); checkbutton_reversely = gtk_check_button_new_with_mnemonic (_("Reverse LY")); + gtk_widget_set_name (checkbutton_reversely, "checkbutton_reversely"); gtk_widget_show (checkbutton_reversely); - gtk_fixed_put (GTK_FIXED (fixed1), checkbutton_reversely, 16, 352); + gtk_fixed_put (GTK_FIXED (fixed1), checkbutton_reversely, 48, 536); gtk_widget_set_size_request (checkbutton_reversely, 111, 22); - checkbutton_reverserx = gtk_check_button_new_with_mnemonic (_("Reverse RX")); - gtk_widget_show (checkbutton_reverserx); - gtk_fixed_put (GTK_FIXED (fixed1), checkbutton_reverserx, 16, 376); - gtk_widget_set_size_request (checkbutton_reverserx, 111, 22); + L_Down = gtk_button_new_with_mnemonic (_("Down")); + gtk_widget_set_name (L_Down, "L_Down"); + gtk_widget_show (L_Down); + gtk_fixed_put (GTK_FIXED (fixed1), L_Down, 64, 456); + gtk_widget_set_size_request (L_Down, 64, 24); - checkbutton_reversery = gtk_check_button_new_with_mnemonic (_("Reverse RY")); - gtk_widget_show (checkbutton_reversery); - gtk_fixed_put (GTK_FIXED (fixed1), checkbutton_reversery, 16, 400); - gtk_widget_set_size_request (checkbutton_reversery, 111, 22); + Ly = gtk_button_new_with_mnemonic (_("Ly")); + gtk_widget_set_name (Ly, "Ly"); + gtk_widget_show (Ly); + gtk_fixed_put (GTK_FIXED (fixed1), Ly, 64, 408); + gtk_widget_set_size_request (Ly, 64, 24); - forcefeedback = gtk_check_button_new_with_mnemonic (_("Enable Force\nFeedback")); - gtk_widget_show (forcefeedback); - gtk_fixed_put (GTK_FIXED (fixed1), forcefeedback, 384, 320); - gtk_widget_set_size_request (forcefeedback, 112, 48); + Lx = gtk_button_new_with_mnemonic (_("Lx")); + gtk_widget_set_name (Lx, "Lx"); + gtk_widget_show (Lx); + gtk_fixed_put (GTK_FIXED (fixed1), Lx, 64, 360); + gtk_widget_set_size_request (Lx, 64, 24); + + L_Up = gtk_button_new_with_mnemonic (_("Up")); + gtk_widget_set_name (L_Up, "L_Up"); + gtk_widget_show (L_Up); + gtk_fixed_put (GTK_FIXED (fixed1), L_Up, 64, 312); + gtk_widget_set_size_request (L_Up, 64, 24); + + L_Left = gtk_button_new_with_mnemonic (_("Left")); + gtk_widget_set_name (L_Left, "L_Left"); + gtk_widget_show (L_Left); + gtk_fixed_put (GTK_FIXED (fixed1), L_Left, 0, 384); + gtk_widget_set_size_request (L_Left, 64, 24); + + L_Right = gtk_button_new_with_mnemonic (_("Right")); + gtk_widget_set_name (L_Right, "L_Right"); + gtk_widget_show (L_Right); + gtk_fixed_put (GTK_FIXED (fixed1), L_Right, 128, 384); + gtk_widget_set_size_request (L_Right, 64, 24); + + label3 = gtk_label_new (_("Analog Controls (move mouse or analog joystick to select)")); + gtk_widget_set_name (label3, "label3"); + gtk_widget_show (label3); + gtk_fixed_put (GTK_FIXED (fixed1), label3, 72, 256); + gtk_widget_set_size_request (label3, 400, 24); + gtk_label_set_line_wrap (GTK_LABEL (label3), TRUE); + gtk_label_set_single_line_mode (GTK_LABEL (label3), TRUE); + + Analog = gtk_button_new_with_mnemonic (_("Analog")); + gtk_widget_set_name (Analog, "Analog"); + gtk_widget_show (Analog); + gtk_fixed_put (GTK_FIXED (fixed1), Analog, 240, 208); + gtk_widget_set_size_request (Analog, 64, 24); + + label6 = gtk_label_new (_("(Note: The analog key controls and joystick controls do not work well together currently, and should not be mixed. )")); + gtk_widget_set_name (label6, "label6"); + gtk_widget_show (label6); + gtk_fixed_put (GTK_FIXED (fixed1), label6, 56, 280); + gtk_widget_set_size_request (label6, 448, 32); + gtk_label_set_justify (GTK_LABEL (label6), GTK_JUSTIFY_CENTER); + gtk_label_set_line_wrap (GTK_LABEL (label6), TRUE); dialog_action_area1 = GTK_DIALOG (Conf)->action_area; + gtk_widget_set_name (dialog_action_area1, "dialog_action_area1"); gtk_widget_show (dialog_action_area1); gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END); - cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel"); - gtk_widget_show (cancelbutton1); - gtk_dialog_add_action_widget (GTK_DIALOG (Conf), cancelbutton1, GTK_RESPONSE_CANCEL); - GTK_WIDGET_SET_FLAGS (cancelbutton1, GTK_CAN_DEFAULT); - okbutton1 = gtk_button_new_from_stock ("gtk-ok"); + gtk_widget_set_name (okbutton1, "okbutton1"); gtk_widget_show (okbutton1); gtk_dialog_add_action_widget (GTK_DIALOG (Conf), okbutton1, GTK_RESPONSE_OK); GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT); + cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel"); + gtk_widget_set_name (cancelbutton1, "cancelbutton1"); + gtk_widget_show (cancelbutton1); + gtk_dialog_add_action_widget (GTK_DIALOG (Conf), cancelbutton1, GTK_RESPONSE_CANCEL); + GTK_WIDGET_SET_FLAGS (cancelbutton1, GTK_CAN_DEFAULT); + g_signal_connect ((gpointer) PAD1, "clicked", G_CALLBACK (OnConf_Pad1), NULL); g_signal_connect ((gpointer) PAD2, "clicked", G_CALLBACK (OnConf_Pad2), NULL); + g_signal_connect ((gpointer) PAD3, "clicked", + G_CALLBACK (OnConf_Pad3), + NULL); + g_signal_connect ((gpointer) PAD4, "clicked", + G_CALLBACK (OnConf_Pad4), + NULL); g_signal_connect ((gpointer) joydevicescombo, "changed", G_CALLBACK (on_joydevicescombo_changed), NULL); + g_signal_connect ((gpointer) R3, "clicked", + G_CALLBACK (OnConf_Key), + NULL); g_signal_connect ((gpointer) Select, "clicked", G_CALLBACK (OnConf_Key), NULL); - g_signal_connect ((gpointer) L1, "clicked", - G_CALLBACK (OnConf_Key), - NULL); - g_signal_connect ((gpointer) Left, "clicked", - G_CALLBACK (OnConf_Key), - NULL); - g_signal_connect ((gpointer) Down, "clicked", - G_CALLBACK (OnConf_Key), - NULL); - g_signal_connect ((gpointer) Analog, "clicked", - G_CALLBACK (OnConf_Key), - NULL); - g_signal_connect ((gpointer) R2, "clicked", - G_CALLBACK (OnConf_Key), - NULL); g_signal_connect ((gpointer) Start, "clicked", G_CALLBACK (OnConf_Key), NULL); - g_signal_connect ((gpointer) R1, "clicked", - G_CALLBACK (OnConf_Key), - NULL); - g_signal_connect ((gpointer) Cross, "clicked", - G_CALLBACK (OnConf_Key), - NULL); - g_signal_connect ((gpointer) Triangle, "clicked", + g_signal_connect ((gpointer) Square, "clicked", G_CALLBACK (OnConf_Key), NULL); g_signal_connect ((gpointer) Circle, "clicked", G_CALLBACK (OnConf_Key), NULL); - g_signal_connect ((gpointer) Square, "clicked", + g_signal_connect ((gpointer) L2, "clicked", G_CALLBACK (OnConf_Key), NULL); - g_signal_connect ((gpointer) L3, "clicked", + g_signal_connect ((gpointer) L1, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) Down, "clicked", G_CALLBACK (OnConf_Key), NULL); g_signal_connect ((gpointer) Up, "clicked", G_CALLBACK (OnConf_Key), NULL); - g_signal_connect ((gpointer) L2, "clicked", - G_CALLBACK (OnConf_Key), - NULL); - g_signal_connect ((gpointer) Lx, "clicked", - G_CALLBACK (OnConf_Key), - NULL); - g_signal_connect ((gpointer) Ly, "clicked", - G_CALLBACK (OnConf_Key), - NULL); - g_signal_connect ((gpointer) Rx, "clicked", - G_CALLBACK (OnConf_Key), - NULL); - g_signal_connect ((gpointer) Ry, "clicked", + g_signal_connect ((gpointer) Left, "clicked", G_CALLBACK (OnConf_Key), NULL); g_signal_connect ((gpointer) Right, "clicked", G_CALLBACK (OnConf_Key), NULL); - g_signal_connect ((gpointer) R3, "clicked", + g_signal_connect ((gpointer) R1, "clicked", G_CALLBACK (OnConf_Key), NULL); + g_signal_connect ((gpointer) R2, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) Triangle, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) Cross, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) L3, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) checkbutton_reversery, "toggled", + G_CALLBACK (on_checkbutton_reversery_toggled), + NULL); + g_signal_connect ((gpointer) checkbutton_reverserx, "toggled", + G_CALLBACK (on_checkbutton_reverserx_toggled), + NULL); + g_signal_connect ((gpointer) R_Down, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) Ry, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) Rx, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) R_Up, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) R_Right, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) R_Left, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) forcefeedback, "toggled", + G_CALLBACK (on_forcefeedback_toggled), + NULL); g_signal_connect ((gpointer) checkbutton_reverselx, "toggled", G_CALLBACK (on_checkbutton_reverselx_toggled), NULL); g_signal_connect ((gpointer) checkbutton_reversely, "toggled", G_CALLBACK (on_checkbutton_reversely_toggled), NULL); - g_signal_connect ((gpointer) checkbutton_reverserx, "toggled", - G_CALLBACK (on_checkbutton_reverserx_toggled), + g_signal_connect ((gpointer) L_Down, "clicked", + G_CALLBACK (OnConf_Key), NULL); - g_signal_connect ((gpointer) checkbutton_reversery, "toggled", - G_CALLBACK (on_checkbutton_reversery_toggled), + g_signal_connect ((gpointer) Ly, "clicked", + G_CALLBACK (OnConf_Key), NULL); - g_signal_connect ((gpointer) forcefeedback, "toggled", - G_CALLBACK (on_forcefeedback_toggled), + g_signal_connect ((gpointer) Lx, "clicked", + G_CALLBACK (OnConf_Key), NULL); - g_signal_connect ((gpointer) cancelbutton1, "clicked", - G_CALLBACK (OnConf_Cancel), + g_signal_connect ((gpointer) L_Up, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) L_Left, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) L_Right, "clicked", + G_CALLBACK (OnConf_Key), + NULL); + g_signal_connect ((gpointer) Analog, "clicked", + G_CALLBACK (OnConf_Key), NULL); g_signal_connect ((gpointer) okbutton1, "clicked", G_CALLBACK (OnConf_Ok), NULL); + g_signal_connect ((gpointer) cancelbutton1, "clicked", + G_CALLBACK (OnConf_Cancel), + NULL); /* Store pointers to all widgets, for use by lookup_widget(). */ GLADE_HOOKUP_OBJECT_NO_REF (Conf, Conf, "Conf"); @@ -578,6 +817,8 @@ create_Conf (void) GLADE_HOOKUP_OBJECT (Conf, hbox1, "hbox1"); GLADE_HOOKUP_OBJECT (Conf, PAD1, "PAD1"); GLADE_HOOKUP_OBJECT (Conf, PAD2, "PAD2"); + GLADE_HOOKUP_OBJECT (Conf, PAD3, "PAD3"); + GLADE_HOOKUP_OBJECT (Conf, PAD4, "PAD4"); GLADE_HOOKUP_OBJECT (Conf, label2, "label2"); GLADE_HOOKUP_OBJECT (Conf, vbox2, "vbox2"); GLADE_HOOKUP_OBJECT (Conf, label5, "label5"); @@ -604,36 +845,53 @@ create_Conf (void) GLADE_HOOKUP_OBJECT (Conf, eLx, "eLx"); GLADE_HOOKUP_OBJECT (Conf, eRy, "eRy"); GLADE_HOOKUP_OBJECT (Conf, eLy, "eLy"); - GLADE_HOOKUP_OBJECT (Conf, Select, "Select"); - GLADE_HOOKUP_OBJECT (Conf, L1, "L1"); - GLADE_HOOKUP_OBJECT (Conf, Left, "Left"); - GLADE_HOOKUP_OBJECT (Conf, Down, "Down"); - GLADE_HOOKUP_OBJECT (Conf, Analog, "Analog"); - GLADE_HOOKUP_OBJECT (Conf, R2, "R2"); - GLADE_HOOKUP_OBJECT (Conf, Start, "Start"); - GLADE_HOOKUP_OBJECT (Conf, R1, "R1"); - GLADE_HOOKUP_OBJECT (Conf, Cross, "Cross"); - GLADE_HOOKUP_OBJECT (Conf, Triangle, "Triangle"); - GLADE_HOOKUP_OBJECT (Conf, Circle, "Circle"); - GLADE_HOOKUP_OBJECT (Conf, Square, "Square"); - GLADE_HOOKUP_OBJECT (Conf, L3, "L3"); - GLADE_HOOKUP_OBJECT (Conf, Up, "Up"); - GLADE_HOOKUP_OBJECT (Conf, L2, "L2"); - GLADE_HOOKUP_OBJECT (Conf, Lx, "Lx"); - GLADE_HOOKUP_OBJECT (Conf, Ly, "Ly"); - GLADE_HOOKUP_OBJECT (Conf, Rx, "Rx"); - GLADE_HOOKUP_OBJECT (Conf, Ry, "Ry"); - GLADE_HOOKUP_OBJECT (Conf, Right, "Right"); - GLADE_HOOKUP_OBJECT (Conf, label3, "label3"); + GLADE_HOOKUP_OBJECT (Conf, eL_Up, "eL_Up"); + GLADE_HOOKUP_OBJECT (Conf, eL_Left, "eL_Left"); + GLADE_HOOKUP_OBJECT (Conf, eL_Right, "eL_Right"); + GLADE_HOOKUP_OBJECT (Conf, eL_Down, "eL_Down"); + GLADE_HOOKUP_OBJECT (Conf, eR_Up, "eR_Up"); + GLADE_HOOKUP_OBJECT (Conf, eR_Left, "eR_Left"); + GLADE_HOOKUP_OBJECT (Conf, eR_Right, "eR_Right"); + GLADE_HOOKUP_OBJECT (Conf, eR_Down, "eR_Down"); GLADE_HOOKUP_OBJECT (Conf, R3, "R3"); + GLADE_HOOKUP_OBJECT (Conf, Select, "Select"); + GLADE_HOOKUP_OBJECT (Conf, Start, "Start"); + GLADE_HOOKUP_OBJECT (Conf, Square, "Square"); + GLADE_HOOKUP_OBJECT (Conf, Circle, "Circle"); + GLADE_HOOKUP_OBJECT (Conf, L2, "L2"); + GLADE_HOOKUP_OBJECT (Conf, L1, "L1"); + GLADE_HOOKUP_OBJECT (Conf, Down, "Down"); + GLADE_HOOKUP_OBJECT (Conf, Up, "Up"); + GLADE_HOOKUP_OBJECT (Conf, Left, "Left"); + GLADE_HOOKUP_OBJECT (Conf, Right, "Right"); + GLADE_HOOKUP_OBJECT (Conf, R1, "R1"); + GLADE_HOOKUP_OBJECT (Conf, R2, "R2"); + GLADE_HOOKUP_OBJECT (Conf, Triangle, "Triangle"); + GLADE_HOOKUP_OBJECT (Conf, Cross, "Cross"); + GLADE_HOOKUP_OBJECT (Conf, L3, "L3"); + GLADE_HOOKUP_OBJECT (Conf, checkbutton_reversery, "checkbutton_reversery"); + GLADE_HOOKUP_OBJECT (Conf, checkbutton_reverserx, "checkbutton_reverserx"); + GLADE_HOOKUP_OBJECT (Conf, R_Down, "R_Down"); + GLADE_HOOKUP_OBJECT (Conf, Ry, "Ry"); + GLADE_HOOKUP_OBJECT (Conf, Rx, "Rx"); + GLADE_HOOKUP_OBJECT (Conf, R_Up, "R_Up"); + GLADE_HOOKUP_OBJECT (Conf, R_Right, "R_Right"); + GLADE_HOOKUP_OBJECT (Conf, R_Left, "R_Left"); + GLADE_HOOKUP_OBJECT (Conf, forcefeedback, "forcefeedback"); GLADE_HOOKUP_OBJECT (Conf, checkbutton_reverselx, "checkbutton_reverselx"); GLADE_HOOKUP_OBJECT (Conf, checkbutton_reversely, "checkbutton_reversely"); - GLADE_HOOKUP_OBJECT (Conf, checkbutton_reverserx, "checkbutton_reverserx"); - GLADE_HOOKUP_OBJECT (Conf, checkbutton_reversery, "checkbutton_reversery"); - GLADE_HOOKUP_OBJECT (Conf, forcefeedback, "forcefeedback"); + GLADE_HOOKUP_OBJECT (Conf, L_Down, "L_Down"); + GLADE_HOOKUP_OBJECT (Conf, Ly, "Ly"); + GLADE_HOOKUP_OBJECT (Conf, Lx, "Lx"); + GLADE_HOOKUP_OBJECT (Conf, L_Up, "L_Up"); + GLADE_HOOKUP_OBJECT (Conf, L_Left, "L_Left"); + GLADE_HOOKUP_OBJECT (Conf, L_Right, "L_Right"); + GLADE_HOOKUP_OBJECT (Conf, label3, "label3"); + GLADE_HOOKUP_OBJECT (Conf, Analog, "Analog"); + GLADE_HOOKUP_OBJECT (Conf, label6, "label6"); GLADE_HOOKUP_OBJECT_NO_REF (Conf, dialog_action_area1, "dialog_action_area1"); - GLADE_HOOKUP_OBJECT (Conf, cancelbutton1, "cancelbutton1"); GLADE_HOOKUP_OBJECT (Conf, okbutton1, "okbutton1"); + GLADE_HOOKUP_OBJECT (Conf, cancelbutton1, "cancelbutton1"); return Conf; } diff --git a/plugins/zeropad/Linux/linux.cpp b/plugins/zeropad/Linux/linux.cpp index 410c236344..1cbe3ab0d6 100644 --- a/plugins/zeropad/Linux/linux.cpp +++ b/plugins/zeropad/Linux/linux.cpp @@ -1,5 +1,5 @@ /* ZeroPAD - author: zerofrog(@gmail.com) - * Copyright (C) 2006-2007 + * Copyright (C) 2006-2007 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,589 +16,355 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include - -#define JOYSTICK_SUPPORT -#ifdef JOYSTICK_SUPPORT -#include -#endif - -#include "zeropad.h" - -extern "C" { -#include "interface.h" -#include "support.h" -#include "callbacks.h" -} +#include "linux.h" Display *GSdsp; -static pthread_spinlock_t s_mutexStatus; -static u32 s_keyPress[2], s_keyRelease[2]; // thread safe -static u32 s_bSDLInit = false; -// holds all joystick info -class JoystickInfo -{ -public: - JoystickInfo(); - ~JoystickInfo() { Destroy(); } - - void Destroy(); - // opens handles to all possible joysticks - static void EnumerateJoysticks(vector& vjoysticks); - - bool Init(int id, bool bStartThread=true); // opens a handle and gets information - void Assign(int pad); // assigns a joystick to a pad - - void TestForce(); - - const string& GetName() { return devname; } - int GetNumButtons() { return numbuttons; } - int GetNumAxes() { return numaxes; } - int GetNumPOV() { return numpov; } - int GetId() { return _id; } - int GetPAD() { return pad; } - int GetDeadzone(int axis) { return deadzone; } - - void SaveState(); - int GetButtonState(int i) { return vbutstate[i]; } - int GetAxisState(int i) { return vaxisstate[i]; } - void SetButtonState(int i, int state) { vbutstate[i] = state; } - void SetAxisState(int i, int value) { vaxisstate[i] = value; } -#ifdef JOYSTICK_SUPPORT - SDL_Joystick* GetJoy() { return joy; } -#endif - -private: - - string devname; // pretty device name - int _id; - int numbuttons, numaxes, numpov; - int axisrange, deadzone; - int pad; - - vector vbutstate, vaxisstate; - -#ifdef JOYSTICK_SUPPORT - SDL_Joystick* joy; -#endif +static const char* s_pGuiKeyMap[] = +{ + "L2", "R2", "L1", "R1", + "Triangle", "Circle", "Cross", "Square", + "Select", "L3", "R3", "Start", + "Up", "Right", "Down", "Left", + "Lx", "Rx", "Ly", "Ry", + "L_Up", "L_Right", "L_Down", "L_Left", + "R_Up", "R_Right", "R_Down", "R_Left" }; -static vector s_vjoysticks; - -extern string s_strIniPath; - -void SaveConfig() -{ - int i, j; - FILE *f; - char cfg[255]; - - strcpy(cfg, s_strIniPath.c_str()); - f = fopen(cfg,"w"); - if (f == NULL) { - printf("ZeroPAD: failed to save ini %s\n", s_strIniPath.c_str()); - return; - } - - for (j=0; j<2; j++) { - for (i=0; i::iterator it; - FORIT(it, s_vjoysticks) delete *it; - s_vjoysticks.clear(); -} - -void _PADupdate(int pad) -{ - pthread_spin_lock(&s_mutexStatus); - status[pad] |= s_keyRelease[pad]; - status[pad] &= ~s_keyPress[pad]; - s_keyRelease[pad] = 0; - s_keyPress[pad] = 0; - pthread_spin_unlock(&s_mutexStatus); + vector::iterator it = s_vjoysticks.begin(); + + // Delete everything in the vector vjoysticks. + while (it != s_vjoysticks.end()) + { + delete *it; + it ++; + } + + s_vjoysticks.clear(); } int _GetJoystickIdFromPAD(int pad) { - // select the right joystick id - int joyid = -1; - for(int i = 0; i < PADKEYS; ++i) { - if( IS_JOYSTICK(conf.keys[pad][i]) || IS_JOYBUTTONS(conf.keys[pad][i]) ) { - joyid = PAD_GETJOYID(conf.keys[pad][i]); - break; - } - } - - return joyid; + // select the right joystick id + int joyid = -1; + + for (int p = 0; p < PADSUBKEYS; p++) + { + for (int i = 0; i < PADKEYS; ++i) + { + u32 temp = conf.keys[(PadEnum[pad][p])][i]; + + if (IS_JOYSTICK( temp) || IS_JOYBUTTONS(temp)) + { + joyid = PAD_GETJOYID(temp); + return joyid; + } + } + } + + if (!JoystickIdWithinBounds(joyid)) + { + // get first unused joystick + for (joyid = 0; joyid < s_vjoysticks.size(); ++joyid) + { + if (s_vjoysticks[joyid]->GetPAD() < 0) break; + } + } + + return joyid; } void CALLBACK PADupdate(int pad) { - int i; - XEvent E; - int keyPress=0,keyRelease=0; - KeySym key; + // Poll keyboard. + PollForKeyboardInput(pad); - // keyboard input - while (XPending(GSdsp) > 0) { - XNextEvent(GSdsp, &E); - switch (E.type) { - case KeyPress: - //_KeyPress(pad, XLookupKeysym((XKeyEvent *)&E, 0)); break; - key = XLookupKeysym((XKeyEvent *)&E, 0); - for (i=0; iGetPAD(); + + if (IS_JOYBUTTONS(key)) + { + int value = SDL_JoystickGetButton((pjoy)->GetJoy(), PAD_GETJOYBUTTON(key)); + + if (value) + clear_bit(status[pad], i); // released + else + set_bit(status[pad], i); // pressed + } + else if (IS_JOYSTICK(key)) + { + int value = SDL_JoystickGetAxis((pjoy)->GetJoy(), PAD_GETJOYSTICK_AXIS(key)); + + switch (i) + { + case PAD_LX: + case PAD_LY: + case PAD_RX: + case PAD_RY: + if (abs(value) > (pjoy)->GetDeadzone(value)) + Analog::ConfigurePad(i, pad, value); + else + Analog::ResetPad(i, pad); + break; + } + } + #ifdef EXPERIMENTAL_POV_CODE + else if (IS_HAT(key)) + { + int value = SDL_JoystickGetHat((pjoy)->GetJoy(), PAD_GETJOYSTICK_AXIS(key)); + + //PAD_LOG("Hat = %d for key %d\n", PAD_GETPOVDIR(key), key); + if ((value != SDL_HAT_CENTERED) && (PAD_GETHATDIR(key) == value)) + { + if ((value == SDL_HAT_UP) || (value == SDL_HAT_RIGHT) || (value == SDL_HAT_DOWN) ||(value == SDL_HAT_LEFT)) + { + set_bit(status[pad], i); + PAD_LOG("Registered %s. Set (%d)\n", HatName(value), i); + } + else + { + clear_bit(status[pad], i); + } + } + else + { + clear_bit(status[pad], i); + } + } + #endif + else if (IS_POV(key)) + { + int value = SDL_JoystickGetAxis((pjoy)->GetJoy(), PAD_GETJOYSTICK_AXIS(key)); + + if (PAD_GETPOVSIGN(key) && (value < -2048)) + clear_bit(status[pad], i); + else if (!PAD_GETPOVSIGN(key) && (value > 2048)) + clear_bit(status[pad], i); + else + set_bit(status[pad], i); + } } - } - - // joystick info -#ifdef JOYSTICK_SUPPORT - - SDL_JoystickUpdate(); - for (int i=0; i= 0 && joyid < (int)s_vjoysticks.size()) { - pjoy = s_vjoysticks[joyid]; - if( SDL_JoystickGetButton((pjoy)->GetJoy(), PAD_GETJOYBUTTON(key)) ) { - status[(pjoy)->GetPAD()] &= ~(1<GetPAD()] |= (1<= 0 && joyid < (int)s_vjoysticks.size()) { - - pjoy = s_vjoysticks[joyid]; - int value = SDL_JoystickGetAxis((pjoy)->GetJoy(), PAD_GETJOYSTICK_AXIS(key)); - int pad = (pjoy)->GetPAD(); - switch(i) { - case PAD_LX: - if( abs(value) > (pjoy)->GetDeadzone(value) ) { - g_lanalog[pad].x = value/256; - if( conf.options&PADOPTION_REVERTLX ) - g_lanalog[pad].x = -g_lanalog[pad].x; - g_lanalog[pad].x += 0x80; - } - else g_lanalog[pad].x = 0x80; - break; - case PAD_LY: - if( abs(value) > (pjoy)->GetDeadzone(value) ) { - g_lanalog[pad].y = value/256; - if( conf.options&PADOPTION_REVERTLX ) - g_lanalog[pad].y = -g_lanalog[pad].y; - g_lanalog[pad].y += 0x80; - } - else g_lanalog[pad].y = 0x80; - break; - case PAD_RX: - if( abs(value) > (pjoy)->GetDeadzone(value) ) { - g_ranalog[pad].x = value/256; - if( conf.options&PADOPTION_REVERTLX ) - g_ranalog[pad].x = -g_ranalog[pad].x; - g_ranalog[pad].x += 0x80; - } - else g_ranalog[pad].x = 0x80; - break; - case PAD_RY: - if( abs(value) > (pjoy)->GetDeadzone(value) ) { - g_ranalog[pad].y = value/256; - if( conf.options&PADOPTION_REVERTLX ) - g_ranalog[pad].y = -g_ranalog[pad].y; - g_ranalog[pad].y += 0x80; - } - else g_ranalog[pad].y = 0x80; - break; - } - } - } - else if( IS_POV(key) ) { - int joyid = PAD_GETJOYID(key); - if( joyid >= 0 && joyid < (int)s_vjoysticks.size()) { - - pjoy = s_vjoysticks[joyid]; - - int value = SDL_JoystickGetAxis((pjoy)->GetJoy(), PAD_GETJOYSTICK_AXIS(key)); - int pad = (pjoy)->GetPAD(); - if( PAD_GETPOVSIGN(key) && (value<-2048) ) - status[pad] &= ~(1<2048) ) - status[pad] &= ~(1< 0) { - gtk_entry_set_text(GTK_ENTRY(Btn), tmp.c_str()); - } + if (tmp.size() > 0) + { + gtk_entry_set_text(GTK_ENTRY(Btn), tmp.c_str()); + } else gtk_entry_set_text(GTK_ENTRY(Btn), "Unknown"); - gtk_object_set_user_data(GTK_OBJECT(Btn), (void*)(PADKEYS*pad+i)); + gtk_object_set_user_data(GTK_OBJECT(Btn), (void*)(PADKEYS * pad + i)); } - // check bounds - int joyid = _GetJoystickIdFromPAD(pad); - if( joyid < 0 || joyid >= (int)s_vjoysticks.size() ) { - // get first unused joystick - for(joyid = 0; joyid < s_vjoysticks.size(); ++joyid) { - if( s_vjoysticks[joyid]->GetPAD() < 0 ) - break; - } - } - - if( joyid >= 0 && joyid < (int)s_vjoysticks.size() ) { - // select the combo - gtk_combo_box_set_active(GTK_COMBO_BOX(s_devicecombo), joyid); - } - else gtk_combo_box_set_active(GTK_COMBO_BOX(s_devicecombo), s_vjoysticks.size()); // no gamepad + // check bounds + int joyid = _GetJoystickIdFromPAD(pad); - int padopts = conf.options>>(16*pad); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(Conf, "checkbutton_reverselx")), padopts&PADOPTION_REVERTLX); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(Conf, "checkbutton_reversely")), padopts&PADOPTION_REVERTLY); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(Conf, "checkbutton_reverserx")), padopts&PADOPTION_REVERTRX); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(Conf, "checkbutton_reversery")), padopts&PADOPTION_REVERTRY); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(Conf, "forcefeedback")), padopts&PADOPTION_FORCEFEEDBACK); + if (JoystickIdWithinBounds(joyid)) + gtk_combo_box_set_active(GTK_COMBO_BOX(s_devicecombo), joyid); // select the combo + else + gtk_combo_box_set_active(GTK_COMBO_BOX(s_devicecombo), s_vjoysticks.size()); // no gamepad + + int padopts = conf.options >> (16 * pad); + + set_checked(Conf, "checkbutton_reverselx", padopts & PADOPTION_REVERTLX); + set_checked(Conf, "checkbutton_reversely", padopts & PADOPTION_REVERTLY); + set_checked(Conf, "checkbutton_reverserx", padopts & PADOPTION_REVERTRX); + set_checked(Conf, "checkbutton_reversery", padopts & PADOPTION_REVERTRY); + set_checked(Conf, "forcefeedback", padopts & PADOPTION_FORCEFEEDBACK); +} + +GtkWidget* GetLabelWidget(GtkButton *button) +{ + const char* buttonname = gtk_widget_get_name(GTK_WIDGET(button)); + const char* labelname = GetLabelFromButton(buttonname).c_str(); + return lookup_widget(Conf, labelname); +} + +int GetLabelId(GtkWidget *label) +{ + if (label == NULL) + { + PAD_LOG("couldn't find correct label\n"); + return -1; + } + + return (int)(uptr)gtk_object_get_user_data(GTK_OBJECT(label)); } void OnConf_Key(GtkButton *button, gpointer user_data) { - GdkEvent *ev; - GtkWidget* label = lookup_widget(Conf, GetLabelFromButton(gtk_button_get_label(button)).c_str()); - if( label == NULL ) { - printf("couldn't find correct label\n"); - return; - } - - int id = (int)(uptr)gtk_object_get_user_data(GTK_OBJECT(label)); - int pad = id/PADKEYS; - int key = id%PADKEYS; - unsigned long *pkey = &conf.keys[pad][key]; + GtkWidget* label = GetLabelWidget(button); + bool captured = false; + char str[32]; + int id = GetLabelId(label); + + if (id == -1) return; + + int pad = id / PADKEYS; + int key = id % PADKEYS; - vector::iterator itjoy; - - // save the states -#ifdef JOYSTICK_SUPPORT - SDL_JoystickUpdate(); - FORIT(itjoy, s_vjoysticks) (*itjoy)->SaveState(); -#endif - - for (;;) { - ev = gdk_event_get(); - if (ev != NULL) { - if (ev->type == GDK_KEY_PRESS) { - *pkey = ev->key.keyval; - - char* tmp = XKeysymToString(*pkey); - if (tmp != NULL) - gtk_entry_set_text(GTK_ENTRY(label), tmp); - else - gtk_entry_set_text(GTK_ENTRY(label), "Unknown"); - return; + // save the joystick states + UpdateJoysticks(); + + while (!captured) + { + vector::iterator itjoy; + char *tmp; + + if (PollX11Keyboard(tmp, conf.keys[pad][key])) + { + strcpy(str, tmp); + captured = true; + break; + } + + SDL_JoystickUpdate(); + + itjoy = s_vjoysticks.begin(); + while ((itjoy != s_vjoysticks.end()) && (!captured)) + { + int jbutton, direction; + + if ((*itjoy)->PollButtons(jbutton, conf.keys[pad][key])) + { + + sprintf(str, "JBut %d", jbutton); + captured = true; + break; } - } -#ifdef JOYSTICK_SUPPORT - SDL_JoystickUpdate(); - FORIT(itjoy, s_vjoysticks) { - - // MAKE sure to look for changes in the state!! - - for(int i = 0; i < (*itjoy)->GetNumButtons(); ++i) { - int but = SDL_JoystickGetButton((*itjoy)->GetJoy(), i); - if( but != (*itjoy)->GetButtonState(i) ) { - - if( !but ) { // released, we don't really want this - (*itjoy)->SetButtonState(i, 0); - break; - } - - *pkey = PAD_JOYBUTTON((*itjoy)->GetId(), i); - char str[32]; - sprintf(str, "JBut %d", i); - gtk_entry_set_text(GTK_ENTRY(label), str); - return; - } - } - - for(int i = 0; i < (*itjoy)->GetNumAxes(); ++i) { - int value = SDL_JoystickGetAxis((*itjoy)->GetJoy(), i); - - if( value != (*itjoy)->GetAxisState(i) ) { - - if( abs(value) <= (*itjoy)->GetAxisState(i)) {// we don't want this - // released, we don't really want this - (*itjoy)->SetButtonState(i, value); - break; - } - - - if( abs(value) > 0x3fff ) { - if( key < 16 ) { // POV - *pkey = PAD_POV((*itjoy)->GetId(), value<0, i); - char str[32]; - sprintf(str, "JPOV %d%s", i, value<0?"-":"+"); - gtk_entry_set_text(GTK_ENTRY(label), str); - return; - } - else { // axis - *pkey = PAD_JOYSTICK((*itjoy)->GetId(), i); - char str[32]; - sprintf(str, "JAxis %d", i); - gtk_entry_set_text(GTK_ENTRY(label), str); - return; - } - } - } - } - } + bool negative = false; + bool pov = (!((key == PAD_RY) || (key == PAD_LY) || (key == PAD_RX) || (key == PAD_LX))); + + if ((*itjoy)->PollAxes(pov, jbutton, negative, conf.keys[pad][key])) + { + if (pov) + sprintf(str, "JPOV %d%s", jbutton, (negative) ? "-" : "+"); + else + sprintf(str, "JAxis %d", jbutton); + captured = true; + break; + } + +#ifdef EXPERIMENTAL_POV_CODE + if ((*itjoy)->PollHats(jbutton, direction, conf.keys[pad][key])) + { + switch (direction) + { + case SDL_HAT_UP: sprintf(str, "JPOVU-%d", jbutton); break; + case SDL_HAT_RIGHT: sprintf(str, "JPOVR-%d", jbutton); break; + case SDL_HAT_DOWN: sprintf(str, "JPOVD-%d", jbutton); break; + case SDL_HAT_LEFT: sprintf(str, "JPOVL-%d", jbutton); break; + } + captured = true; + break; + } #endif - } -} - -void OnConf_Pad1(GtkButton *button, gpointer user_data) -{ - if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) ) - UpdateConf(0); -} - -void OnConf_Pad2(GtkButton *button, gpointer user_data) -{ - if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) ) - UpdateConf(1); -} - -void OnConf_Ok(GtkButton *button, gpointer user_data) -{ -// conf.analog = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Analog)); - SaveConfig(); - - gtk_widget_destroy(Conf); - gtk_main_quit(); -} - -void OnConf_Cancel(GtkButton *button, gpointer user_data) -{ - gtk_widget_destroy(Conf); - gtk_main_quit(); - LoadConfig(); // load previous config + itjoy++; + } + } + + gtk_entry_set_text(GTK_ENTRY(label), str); } void CALLBACK PADconfigure() @@ -607,228 +373,33 @@ void CALLBACK PADconfigure() getcwd(strcurdir, 256); s_strIniPath = strcurdir; s_strIniPath += "/inis/zeropad.ini"; - + LoadConfig(); Conf = create_Conf(); - // recreate - JoystickInfo::EnumerateJoysticks(s_vjoysticks); + // recreate + JoystickInfo::EnumerateJoysticks(s_vjoysticks); - s_devicecombo = lookup_widget(Conf, "joydevicescombo"); + s_devicecombo = lookup_widget(Conf, "joydevicescombo"); - // fill the combo - char str[255]; - vector::iterator it; - FORIT(it, s_vjoysticks) { - sprintf(str, "%d: %s - but: %d, axes: %d, pov: %d", (*it)->GetId(), (*it)->GetName().c_str(), - (*it)->GetNumButtons(), (*it)->GetNumAxes(), (*it)->GetNumPOV()); - gtk_combo_box_append_text (GTK_COMBO_BOX (s_devicecombo), str); - } - gtk_combo_box_append_text (GTK_COMBO_BOX (s_devicecombo), "No Gamepad"); + // fill the combo + char str[255]; + vector::iterator it = s_vjoysticks.begin(); + + // Delete everything in the vector vjoysticks. + while (it != s_vjoysticks.end()) + { + sprintf(str, "%d: %s - but: %d, axes: %d, hats: %d", (*it)->GetId(), (*it)->GetName().c_str(), + (*it)->GetNumButtons(), (*it)->GetNumAxes(), (*it)->GetNumHats()); + gtk_combo_box_append_text(GTK_COMBO_BOX(s_devicecombo), str); + it++; + } + + gtk_combo_box_append_text(GTK_COMBO_BOX(s_devicecombo), "No Gamepad"); UpdateConf(0); - gtk_widget_show_all(Conf); + gtk_widget_show_all(Conf); gtk_main(); } - -// GUI event handlers -void on_joydevicescombo_changed(GtkComboBox *combobox, gpointer user_data) -{ - int joyid = gtk_combo_box_get_active(combobox); - - // unassign every joystick with this pad - for(int i = 0; i < (int)s_vjoysticks.size(); ++i) { - if( s_vjoysticks[i]->GetPAD() == s_selectedpad ) - s_vjoysticks[i]->Assign(-1); - } - - if( joyid >= 0 && joyid < (int)s_vjoysticks.size() ) - s_vjoysticks[joyid]->Assign(s_selectedpad); -} - -void on_checkbutton_reverselx_toggled(GtkToggleButton *togglebutton, gpointer user_data) -{ - int mask = PADOPTION_REVERTLX<<(16*s_selectedpad); - if( gtk_toggle_button_get_active(togglebutton) ) conf.options |= mask; - else conf.options &= ~mask; -} - -void on_checkbutton_reversely_toggled(GtkToggleButton *togglebutton, gpointer user_data) -{ - int mask = PADOPTION_REVERTLY<<(16*s_selectedpad); - if( gtk_toggle_button_get_active(togglebutton) ) conf.options |= mask; - else conf.options &= ~mask; -} - -void on_checkbutton_reverserx_toggled(GtkToggleButton *togglebutton, gpointer user_data) -{ - int mask = PADOPTION_REVERTRX<<(16*s_selectedpad); - if( gtk_toggle_button_get_active(togglebutton) ) conf.options |= mask; - else conf.options &= ~mask; -} - -void on_checkbutton_reversery_toggled(GtkToggleButton *togglebutton, gpointer user_data) -{ - int mask = PADOPTION_REVERTRY<<(16*s_selectedpad); - if( gtk_toggle_button_get_active(togglebutton) ) conf.options |= mask; - else conf.options &= ~mask; -} - -void on_forcefeedback_toggled(GtkToggleButton *togglebutton, gpointer user_data) -{ - int mask = PADOPTION_REVERTLX<<(16*s_selectedpad); - if( gtk_toggle_button_get_active(togglebutton) ) { - conf.options |= mask; - - int joyid = gtk_combo_box_get_active(GTK_COMBO_BOX(s_devicecombo)); - if( joyid >= 0 && joyid < (int)s_vjoysticks.size() ) - s_vjoysticks[joyid]->TestForce(); - } - else conf.options &= ~mask; -} - -GtkWidget *About = NULL; - -void OnAbout_Ok(GtkButton *button, gpointer user_data) -{ - gtk_widget_destroy(About); - gtk_main_quit(); -} - -void CALLBACK PADabout() { - - About = create_About(); - - gtk_widget_show_all(About); - gtk_main(); -} - -s32 CALLBACK PADtest() { - return 0; -} - -////////////////////////// -// Joystick definitions // -////////////////////////// - -// opens handles to all possible joysticks -void JoystickInfo::EnumerateJoysticks(vector& vjoysticks) -{ -#ifdef JOYSTICK_SUPPORT - - if( !s_bSDLInit ) { - if( SDL_Init(SDL_INIT_JOYSTICK) < 0 ) - return; - SDL_JoystickEventState(SDL_QUERY); - s_bSDLInit = true; - } - - vector::iterator it; - FORIT(it, vjoysticks) delete *it; - - vjoysticks.resize(SDL_NumJoysticks()); - for(int i = 0; i < (int)vjoysticks.size(); ++i) { - vjoysticks[i] = new JoystickInfo(); - vjoysticks[i]->Init(i, true); - } - - // set the pads - for(int pad = 0; pad < 2; ++pad) { - // select the right joystick id - int joyid = -1; - for(int i = 0; i < PADKEYS; ++i) { - if( IS_JOYSTICK(conf.keys[pad][i]) || IS_JOYBUTTONS(conf.keys[pad][i]) ) { - joyid = PAD_GETJOYID(conf.keys[pad][i]); - break; - } - } - - if( joyid >= 0 && joyid < (int)s_vjoysticks.size() ) - s_vjoysticks[joyid]->Assign(pad); - } - -#endif -} - -JoystickInfo::JoystickInfo() -{ -#ifdef JOYSTICK_SUPPORT - joy = NULL; -#endif - _id = -1; - pad = -1; - axisrange = 0x7fff; - deadzone = 2000; -} - -void JoystickInfo::Destroy() -{ -#ifdef JOYSTICK_SUPPORT - if( joy != NULL ) { - if( SDL_JoystickOpened(_id) ) - SDL_JoystickClose(joy); - joy = NULL; - } -#endif -} - -bool JoystickInfo::Init(int id, bool bStartThread) -{ -#ifdef JOYSTICK_SUPPORT - Destroy(); - _id = id; - - joy = SDL_JoystickOpen(id); - if( joy == NULL ) { - printf("failed to open joystick %d\n", id); - return false; - } - - numaxes = SDL_JoystickNumAxes(joy); - numbuttons = SDL_JoystickNumButtons(joy); - numpov = SDL_JoystickNumHats(joy); - devname = SDL_JoystickName(id); - vbutstate.resize(numbuttons); - vaxisstate.resize(numbuttons); - - return true; -#else - return false; -#endif -} - -// assigns a joystick to a pad -void JoystickInfo::Assign(int newpad) -{ - if( pad == newpad ) - return; - - pad = newpad; - - if( pad >= 0 ) { - for(int i = 0; i < PADKEYS; ++i) { - if( IS_JOYBUTTONS(conf.keys[pad][i]) ) { - conf.keys[pad][i] = PAD_JOYBUTTON(_id, PAD_GETJOYBUTTON(conf.keys[pad][i])); - } - else if( IS_JOYSTICK(conf.keys[pad][i]) ) { - conf.keys[pad][i] = PAD_JOYSTICK(_id, PAD_GETJOYBUTTON(conf.keys[pad][i])); - } - } - } -} - -void JoystickInfo::SaveState() -{ -#ifdef JOYSTICK_SUPPORT - for(int i = 0; i < numbuttons; ++i) - vbutstate[i] = SDL_JoystickGetButton(joy, i); - for(int i = 0; i < numaxes; ++i) - vaxisstate[i] = SDL_JoystickGetAxis(joy, i); -#endif -} - -void JoystickInfo::TestForce() -{ -} diff --git a/plugins/zeropad/Linux/linux.h b/plugins/zeropad/Linux/linux.h new file mode 100644 index 0000000000..26de22f1b6 --- /dev/null +++ b/plugins/zeropad/Linux/linux.h @@ -0,0 +1,41 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "joystick.h" +#include "keyboard.h" +#include "zeropad.h" + +#include +#include +#include +#include + + +extern "C" +{ +#include "interface.h" +#include "support.h" +#include "callbacks.h" +} + +extern GtkWidget *Conf, *s_devicecombo; +extern string s_strIniPath; + + +#define is_checked(main_widget, widget_name) (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)))) +#define set_checked(main_widget,widget_name, state) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)), state) diff --git a/plugins/zeropad/Linux/zeropad.glade b/plugins/zeropad/Linux/zeropad.glade index 08c54d6205..7c33fea000 100644 --- a/plugins/zeropad/Linux/zeropad.glade +++ b/plugins/zeropad/Linux/zeropad.glade @@ -4,8 +4,9 @@ + 5 True - False + True ZeroPAD False Author: zerofrog(@gmail.com) @@ -14,6 +15,7 @@ Thanks to: florin sasu <florinsasu@hotmail.com> and SSSPSXPad, TwinPad authors translator-credits + @@ -44,20 +46,6 @@ and SSSPSXPad, TwinPad authors True GTK_BUTTONBOX_END - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - -6 - - - - True @@ -68,7 +56,21 @@ and SSSPSXPad, TwinPad authors GTK_RELIEF_NORMAL True -5 - + + + + + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + True + -6 + @@ -151,6 +153,48 @@ and SSSPSXPad, TwinPad authors False + + + + True + True + PAD1 alt. + True + GTK_RELIEF_NORMAL + True + False + False + True + PAD1 + + + + 0 + False + False + + + + + + True + True + PAD2 alt. + True + GTK_RELIEF_NORMAL + True + False + False + True + PAD1 + + + + 0 + False + False + + @@ -228,14 +272,14 @@ and SSSPSXPad, TwinPad authors 0 - True + False True 0 - True + False True @@ -260,7 +304,7 @@ and SSSPSXPad, TwinPad authors 64 - 40 + 32 @@ -280,7 +324,7 @@ and SSSPSXPad, TwinPad authors 64 - 104 + 80 @@ -299,8 +343,8 @@ and SSSPSXPad, TwinPad authors False - 168 - 64 + 200 + 184 @@ -319,8 +363,8 @@ and SSSPSXPad, TwinPad authors False - 280 - 64 + 272 + 184 @@ -340,7 +384,7 @@ and SSSPSXPad, TwinPad authors 64 - 168 + 136 @@ -360,7 +404,7 @@ and SSSPSXPad, TwinPad authors 128 - 208 + 184 @@ -380,7 +424,7 @@ and SSSPSXPad, TwinPad authors 0 - 208 + 184 @@ -400,7 +444,7 @@ and SSSPSXPad, TwinPad authors 64 - 256 + 232 @@ -419,7 +463,7 @@ and SSSPSXPad, TwinPad authors False - 368 + 408 32 @@ -439,8 +483,8 @@ and SSSPSXPad, TwinPad authors False - 368 - 104 + 408 + 80 @@ -459,8 +503,8 @@ and SSSPSXPad, TwinPad authors False - 224 - 128 + 240 + 232 @@ -479,8 +523,8 @@ and SSSPSXPad, TwinPad authors False - 304 - 208 + 344 + 184 @@ -499,8 +543,8 @@ and SSSPSXPad, TwinPad authors False - 368 - 168 + 408 + 136 @@ -519,8 +563,8 @@ and SSSPSXPad, TwinPad authors False - 432 - 208 + 472 + 184 @@ -539,8 +583,8 @@ and SSSPSXPad, TwinPad authors False - 368 - 256 + 408 + 232 @@ -560,7 +604,7 @@ and SSSPSXPad, TwinPad authors 272 - 272 + 56 @@ -579,14 +623,14 @@ and SSSPSXPad, TwinPad authors False - 176 - 272 + 200 + 56 - 80 + 64 24 True True @@ -599,14 +643,14 @@ and SSSPSXPad, TwinPad authors False - 272 - 352 + 408 + 384 - 80 + 64 24 True True @@ -619,14 +663,14 @@ and SSSPSXPad, TwinPad authors False - 160 - 352 + 64 + 384 - 80 + 64 24 True True @@ -639,14 +683,14 @@ and SSSPSXPad, TwinPad authors False - 272 - 416 + 408 + 432 - 80 + 64 24 True True @@ -659,15 +703,193 @@ and SSSPSXPad, TwinPad authors False - 160 - 416 + 64 + 432 + + + + + + 64 + 24 + True + True + True + True + 0 + + True + * + False + + + 64 + 336 + + + + + + 64 + 24 + True + True + True + True + 0 + + True + * + False + + + 0 + 408 + + + + + + 64 + 24 + True + True + True + True + 0 + + True + * + False + + + 128 + 408 + + + + + + 64 + 24 + True + True + True + True + 0 + + True + * + False + + + 64 + 480 + + + + + + 64 + 24 + True + True + True + True + 0 + + True + * + False + + + 408 + 336 + + + + + + 64 + 24 + True + True + True + True + 0 + + True + * + False + + + 344 + 408 + + + + + + 64 + 24 + True + True + True + True + 0 + + True + * + False + + + 472 + 408 + + + + + + 64 + 24 + True + True + True + True + 0 + + True + * + False + + + 408 + 480 + + + + + + 64 + 24 + True + True + R3 + True + GTK_RELIEF_NORMAL + True + + + + 272 + 32 64 - 32 + 24 True True Select @@ -677,105 +899,15 @@ and SSSPSXPad, TwinPad authors - 168 - 32 - - - - - - 64 - 32 - True - True - L1 - True - GTK_RELIEF_NORMAL - True - - - - 64 - 72 - - - - - - 64 - 32 - True - True - Left - True - GTK_RELIEF_NORMAL - True - - - - 0 - 176 - - - - - - 64 - 32 - True - True - Down - True - GTK_RELIEF_NORMAL - True - - - - 64 - 224 - - - - - - 64 - 32 - True - True - Analog - True - GTK_RELIEF_NORMAL - True - - - - 224 - 96 - - - - - - 64 - 32 - True - True - R2 - True - GTK_RELIEF_NORMAL - True - - - - 368 - 0 + 200 + 160 64 - 32 + 24 True True Start @@ -785,87 +917,15 @@ and SSSPSXPad, TwinPad authors - 280 - 32 - - - - - - 64 - 32 - True - True - R1 - True - GTK_RELIEF_NORMAL - True - - - - 368 - 72 - - - - - - 64 - 32 - True - True - Cross - True - GTK_RELIEF_NORMAL - True - - - - 368 - 224 - - - - - - 64 - 32 - True - True - Triangle - True - GTK_RELIEF_NORMAL - True - - - - 368 - 136 - - - - - - 64 - 32 - True - True - Circle - True - GTK_RELIEF_NORMAL - True - - - - 432 - 176 + 272 + 160 64 - 32 + 24 True True Square @@ -875,51 +935,33 @@ and SSSPSXPad, TwinPad authors - 304 - 176 + 344 + 160 - + 64 - 32 + 24 True True - L3 + Circle True GTK_RELIEF_NORMAL True - + - 176 - 240 - - - - - - 64 - 32 - True - True - Up - True - GTK_RELIEF_NORMAL - True - - - - 64 - 136 + 472 + 160 64 - 32 + 24 True True L2 @@ -935,81 +977,81 @@ and SSSPSXPad, TwinPad authors - - 80 - 32 + + 64 + 24 True True - Lx + L1 True GTK_RELIEF_NORMAL True - + - 160 - 320 + 64 + 56 - - 80 - 32 + + 64 + 24 True True - Ly + Down True GTK_RELIEF_NORMAL True - + - 160 - 384 + 64 + 208 - - 80 - 32 + + 64 + 24 True True - Rx + Up True GTK_RELIEF_NORMAL True - + - 272 - 320 + 64 + 112 - - 80 - 32 + + 64 + 24 True True - Ry + Left True GTK_RELIEF_NORMAL True - + - 272 - 384 + 0 + 160 64 - 32 + 24 True True Right @@ -1020,114 +1062,97 @@ and SSSPSXPad, TwinPad authors 128 - 176 + 160 - - 408 - 16 - True - Analog Controls (move mouse or analog joystick to select) - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - True - 0 - - - 48 - 296 - - - - - + 64 - 32 + 24 True True - R3 + R1 True GTK_RELIEF_NORMAL True - + - 272 - 240 + 408 + 56 - - 111 - 22 + + 64 + 24 True True - Reverse LX + R2 True GTK_RELIEF_NORMAL True - False - False - True - + - 16 - 328 + 408 + 8 - - 111 - 22 + + 64 + 24 True True - Reverse LY + Triangle True GTK_RELIEF_NORMAL True - False - False - True - + - 16 - 352 + 408 + 112 - - 111 - 22 + + 64 + 24 True True - Reverse RX + Cross True GTK_RELIEF_NORMAL True - False - False - True - + - 16 - 376 + 408 + 208 + + + + + + 64 + 24 + True + True + L3 + True + GTK_RELIEF_NORMAL + True + + + + 200 + 32 @@ -1147,8 +1172,137 @@ and SSSPSXPad, TwinPad authors - 16 - 400 + 384 + 536 + + + + + + 111 + 22 + True + True + Reverse RX + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 384 + 512 + + + + + + 64 + 24 + True + True + Down + True + GTK_RELIEF_NORMAL + True + + + + 408 + 456 + + + + + + 64 + 24 + True + True + Ry + True + GTK_RELIEF_NORMAL + True + + + + 408 + 408 + + + + + + 64 + 24 + True + True + Rx + True + GTK_RELIEF_NORMAL + True + + + + 408 + 360 + + + + + + 64 + 24 + True + True + Up + True + GTK_RELIEF_NORMAL + True + + + + 408 + 312 + + + + + + 64 + 24 + True + True + Right + True + GTK_RELIEF_NORMAL + True + + + + 472 + 384 + + + + + + 64 + 24 + True + True + Left + True + GTK_RELIEF_NORMAL + True + + + + 344 + 384 @@ -1169,8 +1323,228 @@ Feedback - 384 - 320 + 216 + 512 + + + + + + 111 + 22 + True + True + Reverse LX + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 48 + 512 + + + + + + 111 + 22 + True + True + Reverse LY + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 48 + 536 + + + + + + 64 + 24 + True + True + Down + True + GTK_RELIEF_NORMAL + True + + + + 64 + 456 + + + + + + 64 + 24 + True + True + Ly + True + GTK_RELIEF_NORMAL + True + + + + 64 + 408 + + + + + + 64 + 24 + True + True + Lx + True + GTK_RELIEF_NORMAL + True + + + + 64 + 360 + + + + + + 64 + 24 + True + True + Up + True + GTK_RELIEF_NORMAL + True + + + + 64 + 312 + + + + + + 64 + 24 + True + True + Left + True + GTK_RELIEF_NORMAL + True + + + + 0 + 384 + + + + + + 64 + 24 + True + True + Right + True + GTK_RELIEF_NORMAL + True + + + + 128 + 384 + + + + + + 400 + 24 + True + Analog Controls (move mouse or analog joystick to select) + False + False + GTK_JUSTIFY_LEFT + True + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + True + 0 + + + 72 + 256 + + + + + + 64 + 24 + True + True + Analog + True + GTK_RELIEF_NORMAL + True + + + + 240 + 208 + + + + + + 448 + 32 + True + (Note: The analog key controls and joystick controls do not work well together currently, and should not be mixed. ) + False + False + GTK_JUSTIFY_CENTER + True + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 56 + 280 diff --git a/plugins/zeropad/Makefile.am b/plugins/zeropad/Makefile.am index 08047050a6..8d383d794f 100644 --- a/plugins/zeropad/Makefile.am +++ b/plugins/zeropad/Makefile.am @@ -6,11 +6,6 @@ INCLUDES = -I@srcdir@/../../common/include libZeroPAD_a_CXXFLAGS = $(shell pkg-config --cflags gtk+-2.0) libZeroPAD_a_CFLAGS = $(shell pkg-config --cflags gtk+-2.0) -if X86_64 -libZeroPAD_a_CXXFLAGS += -fPIC -libZeroPAD_a_CFLAGS += -fPIC -endif - # Create a shared object by faking an exe (thanks to ODE makefiles) traplibdir=$(prefix) @@ -27,4 +22,5 @@ libZeroPAD_LDFLAGS= @SHARED_LDFLAGS@ libZeroPAD_LDFLAGS+=-Wl,-soname,@ZEROPAD_SONAME@ libZeroPAD_LDADD=$(libZeroPAD_a_OBJECTS) -libZeroPAD_a_SOURCES = zeropad.cpp Linux/linux.cpp Linux/support.c Linux/interface.c +libZeroPAD_a_SOURCES = joystick.cpp analog.cpp analog.h zeropad.cpp zeropad.h \ +Linux/gui.cpp Linux/linux.cpp Linux/support.c Linux/interface.c keyboard.cpp keyboard.h diff --git a/plugins/zeropad/Windows/ZeroPAD_2008.vcproj b/plugins/zeropad/Windows/ZeroPAD_2008.vcproj index f1e2d0552f..1080fb0720 100644 --- a/plugins/zeropad/Windows/ZeroPAD_2008.vcproj +++ b/plugins/zeropad/Windows/ZeroPAD_2008.vcproj @@ -19,7 +19,7 @@ @@ -113,12 +108,7 @@ /> @@ -184,13 +174,7 @@ /> + + + + + + @@ -256,6 +252,18 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + + + + + @@ -268,6 +276,10 @@ RelativePath=".\resource.h" > + + diff --git a/plugins/zeropad/Windows/gui.cpp b/plugins/zeropad/Windows/gui.cpp new file mode 100644 index 0000000000..a2a6a07fcf --- /dev/null +++ b/plugins/zeropad/Windows/gui.cpp @@ -0,0 +1,110 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + #include "win.h" + + void SaveConfig() +{ + char *szTemp; + char szIniFile[256], szValue[256], szProf[256]; + int i, j; + + GetModuleFileName(GetModuleHandle((LPCSTR)hInst), szIniFile, 256); + szTemp = strrchr(szIniFile, '\\'); + + if (!szTemp) return; + strcpy(szTemp, "\\inis\\zeropad.ini"); + + for (j = 0; j < 2; j++) + { + for (i = 0; i < PADKEYS; i++) + { + sprintf(szProf, "%d_%d", j, i); + sprintf(szValue, "%d", conf.keys[j][i]); + WritePrivateProfileString("Interface", szProf, szValue, szIniFile); + } + } + + sprintf(szValue, "%u", conf.log); + WritePrivateProfileString("Interface", "Logging", szValue, szIniFile); +} + +void LoadConfig() +{ + FILE *fp; + char *szTemp; + char szIniFile[256], szValue[256], szProf[256]; + int i, j; + + memset(&conf, 0, sizeof(conf)); +#ifdef _WIN32 + conf.keys[0][0] = 'W'; // L2 + conf.keys[0][1] = 'O'; // R2 + conf.keys[0][2] = 'A'; // L1 + conf.keys[0][3] = ';'; // R1 + conf.keys[0][4] = 'I'; // TRIANGLE + conf.keys[0][5] = 'L'; // CIRCLE + conf.keys[0][6] = 'K'; // CROSS + conf.keys[0][7] = 'J'; // SQUARE + conf.keys[0][8] = 'V'; // SELECT + conf.keys[0][11] = 'N'; // START + conf.keys[0][12] = 'E'; // UP + conf.keys[0][13] = 'F'; // RIGHT + conf.keys[0][14] = 'D'; // DOWN + conf.keys[0][15] = 'S'; // LEFT +#endif + conf.log = 0; + + GetModuleFileName(GetModuleHandle((LPCSTR)hInst), szIniFile, 256); + szTemp = strrchr(szIniFile, '\\'); + + if (!szTemp) return ; + strcpy(szTemp, "\\inis\\zeropad.ini"); + fp = fopen("inis\\zeropad.ini", "rt");//check if usbnull.ini really exists + if (!fp) + { + CreateDirectory("inis", NULL); + SaveConfig();//save and return + return ; + } + fclose(fp); + + for (j = 0; j < 2; j++) + { + for (i = 0; i < PADKEYS; i++) + { + sprintf(szProf, "%d_%d", j, i); + GetPrivateProfileString("Interface", szProf, NULL, szValue, 20, szIniFile); + conf.keys[j][i] = strtoul(szValue, NULL, 10); + } + } + + GetPrivateProfileString("Interface", "Logging", NULL, szValue, 20, szIniFile); + conf.log = strtoul(szValue, NULL, 10); +} + +void SysMessage(char *fmt, ...) +{ + va_list list; + char tmp[512]; + + va_start(list, fmt); + vsprintf(tmp, fmt, list); + va_end(list); + MessageBox(0, tmp, "PADwinKeyb Msg", 0); +} \ No newline at end of file diff --git a/plugins/zeropad/Windows/resource.h b/plugins/zeropad/Windows/resource.h index 5490aad8ee..029b8d33c1 100644 --- a/plugins/zeropad/Windows/resource.h +++ b/plugins/zeropad/Windows/resource.h @@ -59,7 +59,7 @@ #define IDC_SR2 1063 // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 114 diff --git a/plugins/zeropad/Windows/win.cpp b/plugins/zeropad/Windows/win.cpp index ad9e47e1d8..b396b11270 100644 --- a/plugins/zeropad/Windows/win.cpp +++ b/plugins/zeropad/Windows/win.cpp @@ -1,5 +1,5 @@ /* ZeroPAD - author: zerofrog(@gmail.com) - * Copyright (C) 2006-2007 + * Copyright (C) 2006-2007 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,316 +16,112 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include - -#include "resource.h" -#include "../zeropad.h" - -#include -#include +#include "win.h" using namespace std; -HINSTANCE hInst=NULL; -static pthread_spinlock_t s_mutexStatus; -static u32 s_keyPress[2], s_keyRelease[2]; extern u16 status[2]; extern string s_strIniPath; -LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); -WNDPROC GSwndProc=NULL; -HWND GShwnd=NULL; +WNDPROC GSwndProc = NULL; +HWND GShwnd = NULL; +HINSTANCE hInst = NULL; extern keyEvent event; - -void SaveConfig() -{ - char *szTemp; - char szIniFile[256], szValue[256], szProf[256]; - int i, j; - - GetModuleFileName(GetModuleHandle((LPCSTR)hInst), szIniFile, 256); - szTemp = strrchr(szIniFile, '\\'); - - if(!szTemp) return; - strcpy(szTemp, "\\inis\\zeropad.ini"); - - for (j=0; j<2; j++) { - for (i=0; i=0x60 && key<=0x69) { + strcpy(buff, "NONE"); + else + { + if (key >= 0x60 && key <= 0x69) sprintf(buff, "NumPad %c", '0' + key - 0x60); - } - else sprintf(buff, "%c", key); - } - } - else if (key >= 0x1000 && key < 0x2000) - { - sprintf (buff, "J%d_%d", (key & 0xfff) / 0x100, (key & 0xff) + 1); + else + sprintf(buff, "%c", key); + } } - else if (key >= 0x2000 && key < 0x3000) + else if (key >= 0x1000 && key < 0x2000) //IS_JOYBUTTONS; 0x10000 - 0x20000 + { + sprintf(buff, "J%d_%d", (key & 0xfff) / 0x100, (key & 0xff) + 1); + } + else if (key >= 0x2000 && key < 0x3000) // IS_JOYSTICK; 0x20000 - 0x30000 { static const char name[][4] = { "MIN", "MAX" }; const int axis = (key & 0xff); - sprintf (buff, "J%d_AXIS%d_%s", (key & 0xfff) / 0x100, axis / 2, name[axis % 2]); - if (index >= 17 && index <= 20) - buff[strlen (buff) -4] = '\0'; + + sprintf(buff, "J%d_AXIS%d_%s", (key & 0xfff) / 0x100, axis / 2, name[axis % 2]); + if (index >= 17 && index <= 20) buff[strlen(buff) -4] = '\0'; } - else if (key >= 0x3000 && key < 0x4000) + else if (key >= 0x3000 && key < 0x4000) // IS_POV; 0x30000 - 0x50000 { - static const char name[][7] = { "FOWARD", "RIGHT", "BACK", "LEFT" }; + static const char name[][8] = { "FORWARD", "RIGHT", "BACK", "LEFT" }; const int pov = (key & 0xff); - sprintf (buff, "J%d_POV%d_%s", (key & 0xfff) / 0x100, pov /4, name[pov % 4]); + + sprintf(buff, "J%d_POV%d_%s", (key & 0xfff) / 0x100, pov / 4, name[pov % 4]); } - return buff; + return buff; } -BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { +BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ HWND hWC; - TCITEM tcI; - int i,key, numkeys; - u8* pkeyboard; - static int disabled=0; - static int padn=0; + TCITEM tcI; + int i, key; + int numkeys; + //u8* pkeyboard; + static int disabled = 0; + static int padn = 0; - switch(uMsg) { + switch (uMsg) + { case WM_INITDIALOG: LoadConfig(); - padn = 0; - if (conf.log) CheckDlgButton(hW, IDC_LOG, TRUE); + padn = 0; + if (conf.log) CheckDlgButton(hW, IDC_LOG, TRUE); - for (i=0; i +#include +#include +#include + +#include "resource.h" +#include "../zeropad.h" + +#include +#include + +extern void SaveConfig(); +extern void LoadConfig(); +extern void SysMessage(char *fmt, ...); +extern LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern HINSTANCE hInst; \ No newline at end of file diff --git a/plugins/zeropad/analog.cpp b/plugins/zeropad/analog.cpp new file mode 100644 index 0000000000..14b8489b22 --- /dev/null +++ b/plugins/zeropad/analog.cpp @@ -0,0 +1,162 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + #include "analog.h" +PADAnalog g_lanalog[NUM_OF_PADS], g_ranalog[NUM_OF_PADS]; + +namespace Analog +{ + u8 Pad(int padvalue, u8 i) + { + switch (padvalue) + { + case PAD_LX: + return g_lanalog[i].x; + break; + + case PAD_RX: + return g_ranalog[i].x; + break; + + case PAD_LY: + return g_lanalog[i].y; + break; + + case PAD_RY: + return g_ranalog[i].y; + break; + + default: + return 0; + break; + } + } + + void SetPad(int padvalue, u8 i, u8 value) + { + switch (padvalue) + { + case PAD_LX: + g_lanalog[i].x = value; + break; + + case PAD_RX: + g_ranalog[i].x = value; + break; + + case PAD_LY: + g_lanalog[i].y = value; + break; + + case PAD_RY: + g_ranalog[i].y = value; + break; + + default: + break; + } + } + + void InvertPad(int padvalue, u8 i) + { + SetPad(padvalue, i, -Pad(padvalue, i)); + } + + void ResetPad(int padvalue, u8 i) + { + SetPad(padvalue, i, 0x80); + } + + void Init() + { + for (int i = 0; i < 2; ++i) + { + ResetPad(PAD_LX, i); + ResetPad(PAD_LY, i); + ResetPad(PAD_RX, i); + ResetPad(PAD_RY, i); + } + } + + bool RevertPad(u8 padvalue) + { + switch (padvalue) + { + case PAD_LX: + return ((conf.options & PADOPTION_REVERTLX) != 0); + break; + + case PAD_RX: + return ((conf.options & PADOPTION_REVERTRX) != 0); + break; + + case PAD_LY: + return ((conf.options & PADOPTION_REVERTLY) != 0); + break; + + case PAD_RY: + return ((conf.options & PADOPTION_REVERTRY) != 0); + break; + + default: + return false; + break; + } + } + + void ConfigurePad(int padvalue, u8 i, int value) + { + int temp = Pad(padvalue, i); + SetPad(padvalue, i, value / 256); + if (RevertPad(padvalue)) InvertPad(padvalue, i); + SetPad(padvalue, i, Pad(padvalue, i) + 0x80); + + //PAD_LOG("Setting pad[%d]@%d to %d from %d\n", padvalue, i, value, temp); + } + int AnalogToPad(int padvalue) + { + switch (padvalue) + { + case PAD_R_LEFT: + return PAD_RX; + break; + case PAD_R_UP: + return PAD_RY; + break; + case PAD_L_LEFT: + return PAD_LX; + break; + case PAD_L_UP: + return PAD_LY; + break; + case PAD_R_DOWN: + return PAD_RY; + break; + case PAD_R_RIGHT: + return PAD_RX; + break; + case PAD_L_DOWN: + return PAD_LY; + break; + case PAD_L_RIGHT: + return PAD_LX; + break; + } + return 0; + } +} diff --git a/plugins/zeropad/analog.h b/plugins/zeropad/analog.h new file mode 100644 index 0000000000..ee4055bbf2 --- /dev/null +++ b/plugins/zeropad/analog.h @@ -0,0 +1,33 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + #define NUM_OF_PADS 2 + + #include "zeropad.h" + namespace Analog +{ + extern void Init(); + extern u8 Pad(int padvalue, u8 i); + extern void SetPad(int padvalue, u8 i, u8 value); + extern void InvertPad(int padvalue, u8 i); + extern bool RevertPad(u8 padvalue); + extern void ResetPad(int padvalue, u8 i); + extern void ConfigurePad(int padvalue, u8 i, int value); + extern int KeypadToPad(u8 keypress); + extern int AnalogToPad(int padvalue); +} \ No newline at end of file diff --git a/plugins/zeropad/bitwise.h b/plugins/zeropad/bitwise.h new file mode 100644 index 0000000000..1a6c5ec648 --- /dev/null +++ b/plugins/zeropad/bitwise.h @@ -0,0 +1,41 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + template + static void __forceinline set_bit(T &value, int bit) + { + value |= (1 << bit); + } + + template + static void __forceinline clear_bit(T &value, int bit) + { + value &= ~(1 << bit); + } + + template + static void __forceinline toggle_bit(T &value, int bit) + { + value ^= (1 << bit); + } + + template + static bool __forceinline test_bit(T &value, int bit) + { + return (value & (1 << bit)); + } \ No newline at end of file diff --git a/plugins/zeropad/configure.ac b/plugins/zeropad/configure.ac index 76b2836e4e..5b067f0532 100644 --- a/plugins/zeropad/configure.ac +++ b/plugins/zeropad/configure.ac @@ -1,6 +1,6 @@ -AC_INIT(ZeroPAD,0.2,zerofrog@gmail.com) +AC_INIT(ZeroPAD,0.3,zerofrog@gmail.com) -AM_INIT_AUTOMAKE(ZeroPAD,0.2) +AM_INIT_AUTOMAKE(ZeroPAD,0.3) AC_PROG_CC([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) AC_PROG_CXX([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) @@ -13,13 +13,14 @@ dnl necessary for compiling assembly AM_PROG_AS AC_SUBST(ZEROPAD_CURRENT, 0) -AC_SUBST(ZEROPAD_REVISION, 2) +AC_SUBST(ZEROPAD_REVISION, 3) AC_SUBST(ZEROPAD_AGE, 0) -AC_SUBST(ZEROPAD_RELEASE, libZeroPAD.so.[$ZEROPAD_CURRENT].[$ZEROPAD_REVISION].[$ZEROPAD_AGE]) +AC_SUBST(ZEROPAD_RELEASE, [$ZEROPAD_CURRENT].[$ZEROPAD_REVISION].[$ZEROPAD_AGE]) AC_SUBST(ZEROPAD_SONAME, libZeroPAD.so.[$ZEROPAD_CURRENT].[$ZEROPAD_REVISION].[$ZEROPAD_AGE]) CFLAGS= CXXFLAGS= +CCASFLAGS= dnl Check for debug build AC_MSG_CHECKING(debug build) @@ -27,43 +28,19 @@ AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [debug build]), debug=$enableval,debug=no) if test "x$debug" == xyes then - AC_DEFINE(_DEBUG,1,[_DEBUG]) - CFLAGS+="-g " - CXXFLAGS+="-g " + AC_DEFINE(PCSX2_DEBUG,1,[PCSX2_DEBUG]) + CFLAGS+="-g -m32 -fpic " + CXXFLAGS+="-g -m32 -fpic " + CCASFLAGS+=" -m32 -fpic " else AC_DEFINE(NDEBUG,1,[NDEBUG]) - CFLAGS+="-O2 -fomit-frame-pointer " - CXXFLAGS+="-O2 -fomit-frame-pointer " + CFLAGS+="-O2 -fomit-frame-pointer -m32 -fpic " + CXXFLAGS+="-O2 -fomit-frame-pointer -m32 -fpic " + CCASFLAGS+=" -m32 -fpic " fi AM_CONDITIONAL(DEBUGBUILD, test x$debug = xyes) AC_MSG_RESULT($debug) -dnl Check for 64bit CPU -AC_MSG_CHECKING(for a x86-64 CPU) -dnl if test "$build_os" == "target_os" -dnl then -AC_TRY_RUN([ -int main() -{ -int a = 0; -int*pa = &a; -asm(".intel_syntax\n" - "mov %%rax, %0\n" - "mov %%eax, [%%rax]\n" - ".att_syntax\n" - : : "r"(pa) : "%rax"); -return 0; -} -],cpu64=yes,cpu64=no,) -dnl else -dnl cpu64=no -dnl fi -if test "x$cpu64" == xyes -then -AC_DEFINE(__x86_64__,1,[__x86_64__]) -fi -AC_MSG_RESULT($cpu64) -AM_CONDITIONAL(X86_64, test x$cpu64 = xyes) AC_CHECK_FUNCS([ _aligned_malloc _aligned_free ], AC_DEFINE(HAVE_ALIGNED_MALLOC)) diff --git a/plugins/zeropad/joystick.cpp b/plugins/zeropad/joystick.cpp new file mode 100644 index 0000000000..1b3822d1cb --- /dev/null +++ b/plugins/zeropad/joystick.cpp @@ -0,0 +1,292 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "joystick.h" + +////////////////////////// +// Joystick definitions // +////////////////////////// + +int s_selectedpad = 0; +vector s_vjoysticks; +static u32 s_bSDLInit = false; + +void UpdateJoysticks() +{ + vector::iterator itjoy = s_vjoysticks.begin(); + + SDL_JoystickUpdate(); + + // Save everything in the vector s_vjoysticks. + while (itjoy != s_vjoysticks.end()) + { + (*itjoy)->SaveState(); + itjoy++; + } +} + +const char *HatName(int value) +{ + switch(value) + { + case SDL_HAT_CENTERED: + return "SDL_HAT_CENTERED"; + case SDL_HAT_UP: + return "SDL_HAT_UP"; + case SDL_HAT_RIGHT: + return "SDL_HAT_RIGHT"; + case SDL_HAT_DOWN: + return "SDL_HAT_DOWN"; + case SDL_HAT_LEFT: + return "SDL_HAT_LEFT"; + case SDL_HAT_RIGHTUP: + return "SDL_HAT_RIGHTUP"; + case SDL_HAT_RIGHTDOWN: + return "SDL_HAT_RIGHTDOWN"; + case SDL_HAT_LEFTUP: + return "SDL_HAT_LEFTUP"; + case SDL_HAT_LEFTDOWN: + return "SDL_HAT_LEFTDOWN"; + default: + return "Unknown"; + } + + return "Unknown"; +} + +bool JoystickIdWithinBounds(int joyid) +{ + return ((joyid >= 0) && (joyid < (int)s_vjoysticks.size())); +} +// opens handles to all possible joysticks +void JoystickInfo::EnumerateJoysticks(vector& vjoysticks) +{ + + if (!s_bSDLInit) + { + if (SDL_Init(SDL_INIT_JOYSTICK) < 0) return; + SDL_JoystickEventState(SDL_QUERY); + s_bSDLInit = true; + } + + vector::iterator it = vjoysticks.begin(); + + // Delete everything in the vector vjoysticks. + while (it != vjoysticks.end()) + { + delete *it; + it ++; + } + + vjoysticks.resize(SDL_NumJoysticks()); + + for (int i = 0; i < (int)vjoysticks.size(); ++i) + { + vjoysticks[i] = new JoystickInfo(); + vjoysticks[i]->Init(i, true); + } + + // set the pads + for (int pad = 0; pad < 2; ++pad) + { + // select the right joystick id + int joyid = -1; + + for (int i = 0; i < PADKEYS; ++i) + { + if (IS_JOYSTICK(conf.keys[pad][i]) || IS_JOYBUTTONS(conf.keys[pad][i])) + { + joyid = PAD_GETJOYID(conf.keys[pad][i]); + break; + } + } + + if ((joyid >= 0) && (joyid < (int)s_vjoysticks.size())) s_vjoysticks[joyid]->Assign(pad); + } + +} + +JoystickInfo::JoystickInfo() +{ + joy = NULL; + + _id = -1; + pad = -1; + axisrange = 0x7fff; + deadzone = 2000; +} + +void JoystickInfo::Destroy() +{ + if (joy != NULL) + { + if (SDL_JoystickOpened(_id)) SDL_JoystickClose(joy); + joy = NULL; + } +} + +bool JoystickInfo::Init(int id, bool bStartThread) +{ + Destroy(); + _id = id; + + joy = SDL_JoystickOpen(id); + if (joy == NULL) + { + PAD_LOG("failed to open joystick %d\n", id); + return false; + } + + numaxes = SDL_JoystickNumAxes(joy); + numbuttons = SDL_JoystickNumButtons(joy); + numhats = SDL_JoystickNumHats(joy); + devname = SDL_JoystickName(id); + + vaxisstate.resize(numaxes); + vbuttonstate.resize(numbuttons); + vhatstate.resize(numhats); + + //PAD_LOG("There are %d buttons, %d axises, and %d hats.\n", numbuttons, numaxes, numhats); + return true; +} + +// assigns a joystick to a pad +void JoystickInfo::Assign(int newpad) +{ + if (pad == newpad) return; + pad = newpad; + + if (pad >= 0) + { + for (int i = 0; i < PADKEYS; ++i) + { + if (IS_JOYBUTTONS(conf.keys[pad][i])) + { + conf.keys[pad][i] = PAD_JOYBUTTON(_id, PAD_GETJOYBUTTON(conf.keys[pad][i])); + } + else if (IS_JOYSTICK(conf.keys[pad][i])) + { + conf.keys[pad][i] = PAD_JOYSTICK(_id, PAD_GETJOYBUTTON(conf.keys[pad][i])); + } + } + } +} + +void JoystickInfo::SaveState() +{ + for (int i = 0; i < numbuttons; ++i) + SetButtonState(i, SDL_JoystickGetButton(joy, i)); + for (int i = 0; i < numaxes; ++i) + SetAxisState(i, SDL_JoystickGetAxis(joy, i)); + for (int i = 0; i < numhats; ++i) + SetHatState(i, SDL_JoystickGetHat(joy, i)); +} + +void JoystickInfo::TestForce() +{ +} + +bool JoystickInfo::PollButtons(int &jbutton, u32 &pkey) +{ + // MAKE sure to look for changes in the state!! + for (int i = 0; i < GetNumButtons(); ++i) + { + int but = SDL_JoystickGetButton(GetJoy(), i); + + if (but != GetButtonState(i)) + { + if (!but) // released, we don't really want this + { + SetButtonState(i, 0); + break; + } + + pkey = PAD_JOYBUTTON(GetId(), i); + jbutton = i; + return true; + } + } + + return false; +} + +bool JoystickInfo::PollAxes(bool pov, int &jbutton, bool &negative, u32 &pkey) +{ + for (int i = 0; i < GetNumAxes(); ++i) + { + int value = SDL_JoystickGetAxis(GetJoy(), i); + + if (value != GetAxisState(i)) + { + PAD_LOG("Change in joystick %d: %d.\n", i, value); + + if (abs(value) <= GetAxisState(i)) // we don't want this + { + // released, we don't really want this + SetAxisState(i, value); + break; + } + + if (abs(value) > 0x3fff) + { + jbutton = i; + + if (pov) + { + negative = (value < 0); + pkey = PAD_POV(GetId(), negative, i); + } + else // axis + { + pkey = PAD_JOYSTICK(GetId(), i); + } + return true; + } + } + } + return false; +} + +bool JoystickInfo::PollHats(int &jbutton, int &dir, u32 &pkey) +{ +#ifdef EXPERIMENTAL_POV_CODE + for (int i = 0; i < GetNumHats(); ++i) + { + int value = SDL_JoystickGetHat(GetJoy(), i); + + if (value != SDL_HAT_CENTERED) + { + switch (value) + { + case SDL_HAT_UP: + case SDL_HAT_RIGHT: + case SDL_HAT_DOWN: + case SDL_HAT_LEFT: + pkey = PAD_HAT(GetId(), value, i); + jbutton = i; + dir = value; + PAD_LOG("Hat Pressed!"); + return true; + default: + break; + } + } + } +#endif + return false; +} diff --git a/plugins/zeropad/joystick.h b/plugins/zeropad/joystick.h new file mode 100644 index 0000000000..30d278c496 --- /dev/null +++ b/plugins/zeropad/joystick.h @@ -0,0 +1,148 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __JOYSTICK_H__ +#define __JOYSTICK_H__ + +#ifdef __LINUX__ +#include +#else +#include +#endif + +#include "zeropad.h" + +// holds all joystick info +class JoystickInfo +{ + public: + JoystickInfo(); + ~JoystickInfo() + { + Destroy(); + } + + void Destroy(); + // opens handles to all possible joysticks + static void EnumerateJoysticks(vector& vjoysticks); + + bool Init(int id, bool bStartThread = true); // opens a handle and gets information + void Assign(int pad); // assigns a joystick to a pad + + void TestForce(); + + bool PollButtons(int &jbutton, u32 &pkey); + + bool PollAxes(bool pov, int &jbutton, bool &negative, u32 &pkey); + + bool PollHats(int &jbutton, int &dir, u32 &pkey); + + const string& GetName() + { + return devname; + } + + int GetNumButtons() + { + return numbuttons; + } + + int GetNumAxes() + { + return numaxes; + } + + int GetNumHats() + { + return numhats; + } + + int GetId() + { + return _id; + } + + int GetPAD() + { + return pad; + } + + int GetDeadzone(int axis) + { + return deadzone; + } + + void SaveState(); + + int GetButtonState(int i) + { + return vbuttonstate[i]; + } + + int GetAxisState(int i) + { + return vaxisstate[i]; + } + + int GetHatState(int i) + { + //PAD_LOG("Getting POV State of %d.\n", i); + return vhatstate[i]; + } + + void SetButtonState(int i, int state) + { + vbuttonstate[i] = state; + } + + void SetAxisState(int i, int value) + { + vaxisstate[i] = value; + } + + void SetHatState(int i, int value) + { + //PAD_LOG("We should set %d to %d.\n", i, value); + vhatstate[i] = value; + } + + SDL_Joystick* GetJoy() + { + return joy; + } + + private: + + string devname; // pretty device name + int _id; + int numbuttons, numaxes, numhats; + int axisrange, deadzone; + int pad; + + vector vbuttonstate, vaxisstate, vhatstate; + + SDL_Joystick* joy; +}; + + +extern int s_selectedpad; +extern vector s_vjoysticks; +extern void UpdateJoysticks(); +extern const char *HatName(int value); +extern bool JoystickIdWithinBounds(int joyid); +#endif diff --git a/plugins/zeropad/keyboard.cpp b/plugins/zeropad/keyboard.cpp new file mode 100644 index 0000000000..855bf89a1b --- /dev/null +++ b/plugins/zeropad/keyboard.cpp @@ -0,0 +1,280 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + /* + * Theoretically, this header is for anything to do with keyboard input. + * Pragmatically, event handing's going in here too. + */ + + #include "keyboard.h" + + __forceinline int FindKey(int key, int pad) +{ + for (int p = 0; p < PADSUBKEYS; p++) + for (int i = 0; i < PADKEYS; i++) + if (key == conf.keys[(PadEnum[pad][p])][i]) return i; + return -1; +} + +char* KeysymToChar(int keysym) +{ + #ifdef __LINUX__ + return XKeysymToString(keysym); +#else + LPWORD temp; + + ToAscii((UINT) keysym, NULL, NULL, temp, NULL); + return (char*)temp; + #endif +} + +void PollForKeyboardInput(int pad) +{ + #ifdef __LINUX__ + PollForX11KeyboardInput(pad); +#endif +} + +void SetAutoRepeat(bool autorep) +{ + #ifdef __LINUX__ + if (autorep) + XAutoRepeatOn(GSdsp); + else + XAutoRepeatOff(GSdsp); +#endif +} + + #ifdef __LINUX__ +void PollForX11KeyboardInput(int pad) +{ + XEvent E; + KeySym key; + int keyPress = 0, keyRelease = 0; + int i; + + // keyboard input + while (XPending(GSdsp) > 0) + { + XNextEvent(GSdsp, &E); + switch (E.type) + { + case KeyPress: + key = XLookupKeysym((XKeyEvent *) & E, 0); + + i = FindKey(key, pad); + + // Analog controls. + if ((i > PAD_RY) && (i <= PAD_R_LEFT)) + { + switch (i) + { + case PAD_R_LEFT: + case PAD_R_UP: + case PAD_L_LEFT: + case PAD_L_UP: + Analog::ConfigurePad(Analog::AnalogToPad(i), pad, DEF_VALUE); + break; + case PAD_R_RIGHT: + case PAD_R_DOWN: + case PAD_L_RIGHT: + case PAD_L_DOWN: + Analog::ConfigurePad(Analog::AnalogToPad(i), pad, -DEF_VALUE); + break; + } + i += 0xff00; + } + + if (i != -1) + { + clear_bit(keyRelease, i); + set_bit(keyPress, i); + } + //PAD_LOG("Key pressed:%d\n", i); + + event.evt = KEYPRESS; + event.key = key; + break; + + case KeyRelease: + key = XLookupKeysym((XKeyEvent *) & E, 0); + + i = FindKey(key, pad); + + // Analog Controls. + if ((i > PAD_RY) && (i <= PAD_R_LEFT)) + { + Analog::ResetPad(Analog::AnalogToPad(i), pad); + i += 0xff00; + } + + if (i != -1) + { + clear_bit(keyPress, i); + set_bit(keyRelease, i); + } + + event.evt = KEYRELEASE; + event.key = key; + break; + + case FocusIn: + XAutoRepeatOff(GSdsp); + break; + + case FocusOut: + XAutoRepeatOn(GSdsp); + break; + } + } + + UpdateKeys(pad, keyPress, keyRelease); +} + +bool PollX11Keyboard(char* &temp, u32 &pkey) +{ + GdkEvent *ev = gdk_event_get(); + + if (ev != NULL) + { + if (ev->type == GDK_KEY_PRESS) + { + + if (ev->key.keyval == GDK_Escape) + { + temp = "Unknown"; + pkey = NULL; + } + else + { + temp = KeysymToChar(ev->key.keyval); + pkey = ev->key.keyval; + } + + return true; + } + } + + return false; +} +#else +LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int keyPress[2] = {0}, keyRelease[2] = {0}; + static bool lbutton = false, rbutton = false; + + switch (msg) + { + case WM_KEYDOWN: + if (lParam & 0x40000000) return TRUE; + + for (int pad = 0; pad < 2; ++pad) + { + for (int i = 0; i < PADKEYS; i++) + { + if (wParam == conf.keys[pad][i]) + { + set_bit(keyPress[pad], i); + clear_bit(keyRelease[pad], i); + break; + } + } + } + + event.evt = KEYPRESS; + event.key = wParam; + break; + + case WM_KEYUP: + for (int pad = 0; pad < 2; ++pad) + { + for (int i = 0; i < PADKEYS; i++) + { + if (wParam == conf.keys[pad][i]) + { + set_bit(keyRelease[pad], i); + clear_bit(keyPress[pad], i); + break; + } + } + } + + + event.evt = KEYRELEASE; + event.key = wParam; + break; + + /*case WM_LBUTTONDOWN: + lbutton = true; + break; + + case WM_LBUTTONUP: + g_lanalog[0].x = 0x80; + g_lanalog[0].y = 0x80; + g_lanalog[1].x = 0x80; + g_lanalog[1].y = 0x80; + lbutton = false; + break; + + case WM_RBUTTONDOWN: + rbutton = true; + break; + + case WM_RBUTTONUP: + g_ranalog[0].x = 0x80; + g_ranalog[0].y = 0x80; + g_ranalog[1].x = 0x80; + g_ranalog[1].y = 0x80; + rbutton = false; + break; + + case WM_MOUSEMOVE: + if (lbutton) + { + g_lanalog[0].x = LOWORD(lParam) & 254; + g_lanalog[0].y = HIWORD(lParam) & 254; + g_lanalog[1].x = LOWORD(lParam) & 254; + g_lanalog[1].y = HIWORD(lParam) & 254; + } + if (rbutton) + { + g_ranalog[0].x = LOWORD(lParam) & 254; + g_ranalog[0].y = HIWORD(lParam) & 254; + g_ranalog[1].x = LOWORD(lParam) & 254; + g_ranalog[1].y = HIWORD(lParam) & 254; + } + break;*/ + + case WM_DESTROY: + case WM_QUIT: + event.evt = KEYPRESS; + event.key = VK_ESCAPE; + return GSwndProc(hWnd, msg, wParam, lParam); + + default: + return GSwndProc(hWnd, msg, wParam, lParam); + } + + for (int pad = 0; pad < 2; ++pad) + { + UpdateKeys(pad, keyPress[pad], keyRelease[pad]); + } + + return TRUE; +} +#endif diff --git a/plugins/zeropad/keyboard.h b/plugins/zeropad/keyboard.h new file mode 100644 index 0000000000..1a61fe86c8 --- /dev/null +++ b/plugins/zeropad/keyboard.h @@ -0,0 +1,44 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + #ifndef __KEYBOARD_H__ + #define __KEYBOARD_H__ + +#include "zeropad.h" + +#ifdef __LINUX__ + +#include "Linux/linux.h" + +extern Display *GSdsp; +extern void PollForX11KeyboardInput(int pad); +extern bool PollX11Keyboard(char* &temp, u32 &pkey); + +#else + +extern WNDPROC GSwndProc; +extern HWND GShwnd; + +#endif + +extern char* KeysymToChar(int keysym); +extern void PollForKeyboardInput(int pad); +extern void SetAutoRepeat(bool autorep); +extern __forceinline int FindKey(int key, int pad); + + #endif \ No newline at end of file diff --git a/plugins/zeropad/zeropad.cpp b/plugins/zeropad/zeropad.cpp index 488aac59fc..d71ed9e260 100644 --- a/plugins/zeropad/zeropad.cpp +++ b/plugins/zeropad/zeropad.cpp @@ -1,5 +1,5 @@ /* ZeroPAD - author: zerofrog(@gmail.com) - * Copyright (C) 2006-2007 + * Copyright (C) 2006-2007 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,59 +33,84 @@ char libraryName[256]; -PADAnalog g_lanalog[2], g_ranalog[2]; PADconf conf; keyEvent event; u16 status[2]; int pressure; -string s_strIniPath="inis/zeropad.ini"; +static keyEvent s_event; +string s_strIniPath = "inis/zeropad.ini"; -const unsigned char version = PS2E_PAD_VERSION; -const unsigned char revision = 0; -const unsigned char build = 2; // increase that with each version +const u32 version = PS2E_PAD_VERSION; +const u32 revision = 0; +const u32 build = 3; // increase that with each version +int PadEnum[2][2] = {{0, 2}, {1, 3}}; -u32 pads=0; -u8 stdpar[2][20] = { {0xff, 0x5a, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, - {0xff, 0x5a, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}}; -u8 cmd40[2][8] = { {0xff, 0x5a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x5a}, - {0xff, 0x5a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x5a}}; -u8 cmd41[2][8] = { {0xff, 0x5a, 0xff, 0xff, 0x03, 0x00, 0x00, 0x5a}, - {0xff, 0x5a, 0xff, 0xff, 0x03, 0x00, 0x00, 0x5a}}; -u8 unk46[2][8] = { {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A}, - {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A}}; -u8 unk47[2][8] = { {0xff, 0x5a, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00}, - {0xff, 0x5a, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00}}; -u8 unk4c[2][8] = { {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -u8 unk4d[2][8] = { {0xff, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0xff, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; -u8 cmd4f[2][8] = { {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a}, - {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a}}; -u8 stdcfg[2][8] = { {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; // 2 & 3 = 0 -u8 stdmode[2][8] = { {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -u8 stdmodel[2][8] = { {0xff, 0x5a, - 0x03, // 03 - dualshock2, 01 - dualshock - 0x02, // number of modes - 0x01, // current mode: 01 - analog, 00 - digital - 0x02, - 0x01, - 0x00}, - {0xff, 0x5a, - 0x03, // 03 - dualshock2, 01 - dualshock - 0x02, // number of modes - 0x01, // current mode: 01 - analog, 00 - digital - 0x02, - 0x01, - 0x00}}; +u32 pads = 0; +u8 stdpar[2][20] = { + {0xff, 0x5a, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, + {0xff, 0x5a, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; +u8 cmd40[2][8] = { + {0xff, 0x5a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x5a}, + {0xff, 0x5a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x5a} +}; +u8 cmd41[2][8] = { + {0xff, 0x5a, 0xff, 0xff, 0x03, 0x00, 0x00, 0x5a}, + {0xff, 0x5a, 0xff, 0xff, 0x03, 0x00, 0x00, 0x5a} +}; +u8 unk46[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A}, + {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A} +}; +u8 unk47[2][8] = { + {0xff, 0x5a, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00}, + {0xff, 0x5a, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00} +}; +u8 unk4c[2][8] = { + {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; +u8 unk4d[2][8] = { + {0xff, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0xff, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} +}; +u8 cmd4f[2][8] = { + {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a}, + {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a} +}; +u8 stdcfg[2][8] = { + {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; // 2 & 3 = 0 +u8 stdmode[2][8] = { + {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; +u8 stdmodel[2][8] = { + {0xff, + 0x5a, + 0x03, // 03 - dualshock2, 01 - dualshock + 0x02, // number of modes + 0x01, // current mode: 01 - analog, 00 - digital + 0x02, + 0x01, + 0x00}, + {0xff, + 0x5a, + 0x03, // 03 - dualshock2, 01 - dualshock + 0x02, // number of modes + 0x01, // current mode: 01 - analog, 00 - digital + 0x02, + 0x01, + 0x00} +}; u8 *buf; int padID[2]; @@ -97,179 +122,198 @@ int cmdLen; int ds2mode = 0; // DS Mode at start FILE *padLog = NULL; -int POV(u32 direction, u32 angle){ - if ((direction==0) && (angle>= 0) && (angle< 4500)) return 1;//forward - if ((direction==2) && (angle>= 4500) && (angle<13500)) return 1;//right - if ((direction==1) && (angle>=13500) && (angle<22500)) return 1;//backward - if ((direction==3) && (angle>=22500) && (angle<31500)) return 1;//left - if ((direction==0) && (angle>=31500) && (angle<36000)) return 1;//forward - return 0; -} - -void _KeyPress(int pad, u32 key) -{ - int i; - - for (i=0; i> 8; stdpar[curPad][3] = status[curPad] & 0xff; - stdpar[curPad][4] = g_ranalog[curPad].x; - stdpar[curPad][5] = g_ranalog[curPad].y; - stdpar[curPad][6] = g_lanalog[curPad].x; - stdpar[curPad][7] = g_lanalog[curPad].y; - if (padMode[curPad] == 1) cmdLen = 20; - else cmdLen = 4; + stdpar[curPad][4] = Analog::Pad(PAD_RX, curPad); + stdpar[curPad][5] = Analog::Pad(PAD_RY, curPad); + stdpar[curPad][6] = Analog::Pad(PAD_LX, curPad); + stdpar[curPad][7] = Analog::Pad(PAD_LY, curPad); + + if (padMode[curPad] == 1) + cmdLen = 20; + else + cmdLen = 4; + button_check2 = stdpar[curPad][2] >> 4; - switch(stdpar[curPad][3]) + switch (stdpar[curPad][3]) { - case 0xBF: // X - stdpar[curPad][14] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][16])); - break; - case 0xDF: // Circle - stdpar[curPad][13] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][17])); - break; - case 0xEF: // Triangle - stdpar[curPad][12] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][19])); - break; - case 0x7F: // Square - stdpar[curPad][15] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][18])); - break; - case 0xFB: // L1 - stdpar[curPad][16] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][26])); - break; - case 0xF7: // R1 - stdpar[curPad][17] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][28])); - break; - case 0xFE: // L2 - stdpar[curPad][18] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][27])); - break; - case 0xFD: // R2 - stdpar[curPad][19] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][29])); - break; - default: - stdpar[curPad][14] = 0x00; // Not pressed - stdpar[curPad][13] = 0x00; // Not pressed - stdpar[curPad][12] = 0x00; // Not pressed - stdpar[curPad][15] = 0x00; // Not pressed - stdpar[curPad][16] = 0x00; // Not pressed - stdpar[curPad][17] = 0x00; // Not pressed - stdpar[curPad][18] = 0x00; // Not pressed - stdpar[curPad][19] = 0x00; // Not pressed - break; + case 0xBF: // X + stdpar[curPad][14] = (pressure * 255) / 100; //0xff/(100/(100-conf.keys[curPad][16])); + break; + case 0xDF: // Circle + stdpar[curPad][13] = (pressure * 255) / 100; //0xff/(100/(100-conf.keys[curPad][17])); + break; + case 0xEF: // Triangle + stdpar[curPad][12] = (pressure * 255) / 100; //0xff/(100/(100-conf.keys[curPad][19])); + break; + case 0x7F: // Square + stdpar[curPad][15] = (pressure * 255) / 100; //0xff/(100/(100-conf.keys[curPad][18])); + break; + case 0xFB: // L1 + stdpar[curPad][16] = (pressure * 255) / 100; //0xff/(100/(100-conf.keys[curPad][26])); + break; + case 0xF7: // R1 + stdpar[curPad][17] = (pressure * 255) / 100; //0xff/(100/(100-conf.keys[curPad][28])); + break; + case 0xFE: // L2 + stdpar[curPad][18] = (pressure * 255) / 100; //0xff/(100/(100-conf.keys[curPad][27])); + break; + case 0xFD: // R2 + stdpar[curPad][19] = (pressure * 255) / 100; //0xff/(100/(100-conf.keys[curPad][29])); + break; + default: + stdpar[curPad][14] = 0x00; // Not pressed + stdpar[curPad][13] = 0x00; // Not pressed + stdpar[curPad][12] = 0x00; // Not pressed + stdpar[curPad][15] = 0x00; // Not pressed + stdpar[curPad][16] = 0x00; // Not pressed + stdpar[curPad][17] = 0x00; // Not pressed + stdpar[curPad][18] = 0x00; // Not pressed + stdpar[curPad][19] = 0x00; // Not pressed + break; } - switch(button_check2) + switch (button_check2) { - case 0xE: // UP - stdpar[curPad][10] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][21])); - break; - case 0xB: // DOWN - stdpar[curPad][11] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][22])); - break; - case 0x7: // LEFT - stdpar[curPad][9] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][23])); - break; - case 0xD: // RIGHT - stdpar[curPad][8] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][24])); - break; - default: - stdpar[curPad][8] = 0x00; // Not pressed - stdpar[curPad][9] = 0x00; // Not pressed - stdpar[curPad][10] = 0x00; // Not pressed - stdpar[curPad][11] = 0x00; // Not pressed - break; + case 0xE: // UP + stdpar[curPad][10] = (pressure * 255) / 100; //0xff/(100/(100-conf.keys[curPad][21])); + break; + case 0xB: // DOWN + stdpar[curPad][11] = (pressure * 255) / 100; //0xff/(100/(100-conf.keys[curPad][22])); + break; + case 0x7: // LEFT + stdpar[curPad][9] = (pressure * 255) / 100; //0xff/(100/(100-conf.keys[curPad][23])); + break; + case 0xD: // RIGHT + stdpar[curPad][8] = (pressure * 255) / 100; //0xff/(100/(100-conf.keys[curPad][24])); + break; + default: + stdpar[curPad][8] = 0x00; // Not pressed + stdpar[curPad][9] = 0x00; // Not pressed + stdpar[curPad][10] = 0x00; // Not pressed + stdpar[curPad][11] = 0x00; // Not pressed + break; } buf = stdpar[curPad]; return padID[curPad]; - case 0x43: // CONFIG_MODE + case CMD_CONFIG_MODE: // CONFIG_MODE cmdLen = 8; buf = stdcfg[curPad]; - if (stdcfg[curPad][3] == 0xff) return 0xf3; - else return padID[curPad]; + if (stdcfg[curPad][3] == 0xff) + return 0xf3; + else + return padID[curPad]; - case 0x44: // SET_MODE_AND_LOCK + case CMD_SET_MODE_AND_LOCK: // SET_MODE_AND_LOCK cmdLen = 8; buf = stdmode[curPad]; return 0xf3; - case 0x45: // QUERY_MODEL_AND_MODE + case CMD_QUERY_MODEL_AND_MODE: // QUERY_MODEL_AND_MODE cmdLen = 8; buf = stdmodel[curPad]; buf[4] = padMode[curPad]; return 0xf3; - case 0x46: // ?? + case CMD_QUERY_ACT: // ?? cmdLen = 8; buf = unk46[curPad]; return 0xf3; - case 0x47: // ?? + case CMD_QUERY_COMB: // ?? cmdLen = 8; buf = unk47[curPad]; return 0xf3; - case 0x4c: // QUERY_MODE ?? + case CMD_QUERY_MODE: // QUERY_MODE ?? cmdLen = 8; buf = unk4c[curPad]; return 0xf3; - case 0x4d: + case CMD_VIBRATION_TOGGLE: cmdLen = 8; buf = unk4d[curPad]; return 0xf3; - case 0x4f: // SET_DS2_NATIVE_MODE + case CMD_SET_DS2_NATIVE_MODE: // SET_DS2_NATIVE_MODE cmdLen = 8; padID[curPad] = 0x79; // setting ds2 mode ds2mode = 1; // Set DS2 Mode @@ -443,56 +496,61 @@ u8 _PADpoll(u8 value) { return 0xf3; default: -#ifdef PAD_LOG PAD_LOG("*PADpoll*: unknown cmd %x\n", value); -#endif break; } } - switch (curCmd) { - case 0x43: - if(curByte == 2) + switch (curCmd) + { + case CMD_CONFIG_MODE: + if (curByte == 2) { - switch(value){ - case 0: - buf[2] = 0; - buf[3] = 0; - break; - case 1: - buf[2] = 0xff; - buf[3] = 0xff; - break; + switch (value) + { + case 0: + buf[2] = 0; + buf[3] = 0; + break; + case 1: + buf[2] = 0xff; + buf[3] = 0xff; + break; } } break; - case 0x44: - if (curByte == 2) { + case CMD_SET_MODE_AND_LOCK: + if (curByte == 2) + { PADsetMode(curPad, value); } break; - case 0x46: - if(curByte == 2) { - switch(value) { - case 0: // default - buf[5] = 0x2; - buf[6] = 0x0; - buf[7] = 0xA; - break; - case 1: // Param std conf change - buf[5] = 0x1; - buf[6] = 0x1; - buf[7] = 0x14; - break; + case CMD_QUERY_ACT: + if (curByte == 2) + { + switch (value) + { + case 0: // default + buf[5] = 0x2; + buf[6] = 0x0; + buf[7] = 0xA; + break; + case 1: // Param std conf change + buf[5] = 0x1; + buf[6] = 0x1; + buf[7] = 0x14; + break; } } break; - case 0x4c: - if (curByte == 2) { - switch (value) { + case CMD_QUERY_MODE: + if (curByte == 2) + { + switch (value) + { case 0: // mode 0 - digital mode buf[5] = 0x4; break; @@ -512,18 +570,16 @@ u8 _PADpoll(u8 value) { u8 CALLBACK PADpoll(u8 value) { u8 ret; + ret = _PADpoll(value); -#ifdef PAD_LOG - PAD_LOG("PADpoll: %x (%d: %x)\n", value, curByte, ret); -#endif + //PAD_LOG("PADpoll: %x (%d: %x)\n", value, curByte, ret); return ret; } // PADkeyEvent is called every vsync (return NULL if no event) -static keyEvent s_event; keyEvent* CALLBACK PADkeyEvent() { - s_event = event; - event.evt = 0; - return &s_event; + s_event = event; + event.evt = 0; + return &s_event; } diff --git a/plugins/zeropad/zeropad.h b/plugins/zeropad/zeropad.h index 1ec4a91c00..b91085dfc1 100644 --- a/plugins/zeropad/zeropad.h +++ b/plugins/zeropad/zeropad.h @@ -37,33 +37,45 @@ #include #include #include +#include using namespace std; #define PADdefs -extern "C" { #include "PS2Edefs.h" -} + +#ifdef __LINUX__ +#include "joystick.h" +#endif +#include "analog.h" +#include "bitwise.h" extern char libraryName[256]; -#define FORIT(it, v) for(it = (v).begin(); it != (v).end(); (it)++) +#define IS_KEYBOARD(key) (key < 0x10000) +#define IS_JOYBUTTONS(key) (key >= 0x10000 && key < 0x20000) // buttons +#define IS_JOYSTICK(key) (key >= 0x20000 && key < 0x30000) // analog +#define IS_POV(key) (key >= 0x30000 && key < 0x40000) // uses analog as buttons (cares about sign) +#define IS_HAT(key) (key >= 0x40000 && key < 0x50000) // uses hat as buttons (cares about sign) -#define IS_KEYBOARD(key) (key<0x10000) -#define IS_JOYBUTTONS(key) (key>=0x10000 && key<0x20000) // buttons -#define IS_JOYSTICK(key) (key>=0x20000&&key<0x30000) // analog -#define IS_POV(key) (key>=0x30000&&key<0x40000) // uses analog as buttons (cares about sign) -#define IS_MOUSE(key) (key>=0x40000&&key<0x50000) // mouse +//#define IS_MOUSE(key) (key >= 0x40000 && key < 0x50000) // mouse -#define PAD_GETKEY(key) ((key)&0xffff) -#define PAD_GETJOYID(key) (((key)&0xf000)>>12) -#define PAD_GETJOYBUTTON(key) ((key)&0xff) -#define PAD_GETJOYSTICK_AXIS(key) ((key)&0xff) -#define PAD_JOYBUTTON(joyid, buttonid) (0x10000|((joyid)<<12)|(buttonid)) -#define PAD_JOYSTICK(joyid, axisid) (0x20000|((joyid)<<12)|(axisid)) -#define PAD_POV(joyid, sign, axisid) (0x30000|((joyid)<<12)|((sign)<<8)|(axisid)) -#define PAD_GETPOVSIGN(key) (((key)&0x100)>>8) +#define PAD_GETKEY(key) ((key) & 0xffff) +#define PAD_GETJOYID(key) (((key) & 0xf000) >> 12) +#define PAD_GETJOYBUTTON(key) ((key) & 0xff) +#define PAD_GETJOYSTICK_AXIS(key) ((key) & 0xff) +#define PAD_JOYBUTTON(joyid, buttonid) (0x10000 | ((joyid) << 12) | (buttonid)) +#define PAD_JOYSTICK(joyid, axisid) (0x20000 | ((joyid) << 12) | (axisid)) +#define PAD_POV(joyid, sign, axisid) (0x30000 | ((joyid) << 12) | ((sign) << 8) | (axisid)) +#define PAD_HAT(joyid, dir, axisid) (0x40000 | ((joyid) << 12) | ((dir) << 8) | (axisid)) +#define PAD_GETPOVSIGN(key) (((key) & 0x100) >> 8) +#define PAD_GETHATDIR(key) (((key) & ~ 0x40000) >> 8) + +#ifdef __LINUX__ +#define PADKEYS 28 +#else #define PADKEYS 20 +#endif #define PADOPTION_FORCEFEEDBACK 1 #define PADOPTION_REVERTLX 0x2 @@ -71,42 +83,86 @@ extern char libraryName[256]; #define PADOPTION_REVERTRX 0x8 #define PADOPTION_REVERTRY 0x10 -typedef struct { - unsigned long keys[2][PADKEYS]; - int log; - int options; // upper 16 bits are for pad2 +#ifdef _WIN32 +#define PADSUBKEYS 1 +#else +#define PADSUBKEYS 2 +#endif + +//#define EXPERIMENTAL_POV_CODE +extern int PadEnum[2][2]; + +typedef struct +{ + u32 keys[2 * PADSUBKEYS][PADKEYS]; + u32 log; + u32 options; // upper 16 bits are for pad2 } PADconf; -typedef struct { - u8 x,y; +typedef struct +{ + u8 x, y; } PADAnalog; extern PADconf conf; - extern PADAnalog g_lanalog[2], g_ranalog[2]; extern FILE *padLog; +extern void initLogging(); #define PAD_LOG __Log +//#define PAD_LOG __LogToConsole -#define PAD_RY 19 -#define PAD_LY 18 -#define PAD_RX 17 -#define PAD_LX 16 -#define PAD_LEFT 15 -#define PAD_DOWN 14 -#define PAD_RIGHT 13 -#define PAD_UP 12 -#define PAD_START 11 -#define PAD_R3 10 -#define PAD_L3 9 -#define PAD_SELECT 8 -#define PAD_SQUARE 7 -#define PAD_CROSS 6 -#define PAD_CIRCLE 5 -#define PAD_TRIANGLE 4 -#define PAD_R1 3 -#define PAD_L1 2 -#define PAD_R2 1 -#define PAD_L2 0 +enum PadCommands +{ + CMD_SET_VREF_PARAM = 0x40, + CMD_QUERY_DS2_ANALOG_MODE = 0x41, + CMD_READ_DATA_AND_VIBRATE = 0x42, + CMD_CONFIG_MODE = 0x43, + CMD_SET_MODE_AND_LOCK = 0x44, + CMD_QUERY_MODEL_AND_MODE = 0x45, + CMD_QUERY_ACT = 0x46, // ?? + CMD_QUERY_COMB = 0x47, // ?? + CMD_QUERY_MODE = 0x4C, // QUERY_MODE ?? + CMD_VIBRATION_TOGGLE = 0x4D, + CMD_SET_DS2_NATIVE_MODE = 0x4F // SET_DS2_NATIVE_MODE +}; + +enum gamePadValues +{ + PAD_R_LEFT = 27, + PAD_R_DOWN = 26, + PAD_R_RIGHT = 25, + PAD_R_UP = 24, + PAD_L_LEFT = 23, + PAD_L_DOWN = 22, + PAD_L_RIGHT = 21, + PAD_L_UP = 20, + PAD_RY = 19, + PAD_LY = 18, + PAD_RX = 17, + PAD_LX = 16, + PAD_LEFT = 15, + PAD_DOWN = 14, + PAD_RIGHT = 13, + PAD_UP = 12, + PAD_START = 11, + PAD_R3 = 10, + PAD_L3 = 9, + PAD_SELECT = 8, + PAD_SQUARE = 7, + PAD_CROSS = 6, + PAD_CIRCLE = 5, + PAD_TRIANGLE = 4, + PAD_R1 = 3, + PAD_L1 = 2, + PAD_R2 = 1, + PAD_L2 = 0 +}; + +// Activate bolche's analog controls hack +// DEF_VALUE is the strength you press the control. +// Code taken from http://forums.pcsx2.net/thread-4699.html + +#define DEF_VALUE 32766 /* end of pad.h */ @@ -123,11 +179,13 @@ void _KeyRelease(int pad, u32 key); void PADsetMode(int pad, int mode); void _PADupdate(int pad); -void __Log(char *fmt, ...); +void __Log(const char *fmt, ...); +void __LogToConsole(const char *fmt, ...); void LoadConfig(); void SaveConfig(); void SysMessage(char *fmt, ...); +void UpdateKeys(int pad, int keyPress, int keyRelease); #endif diff --git a/plugins/zerospu2/Makefile.am b/plugins/zerospu2/Makefile.am index 54d3daf5c5..3d6a00768a 100644 --- a/plugins/zerospu2/Makefile.am +++ b/plugins/zerospu2/Makefile.am @@ -6,11 +6,6 @@ INCLUDES = -I@srcdir@/../../common/include -I@srcdir@/../../3rdparty libZeroSPU2_a_CXXFLAGS = $(shell pkg-config --cflags gtk+-2.0) libZeroSPU2_a_CFLAGS = $(shell pkg-config --cflags gtk+-2.0) -if X86_64 -libZeroSPU2_a_CXXFLAGS += -fPIC -libZeroSPU2_a_CFLAGS += -fPIC -endif - # Create a shared object by faking an exe (thanks to ODE makefiles) traplibdir=$(prefix) diff --git a/plugins/zerospu2/Windows/ZeroSPU2.rc b/plugins/zerospu2/Windows/ZeroSPU2.rc index ad23ef7839..a5e85e5384 100644 --- a/plugins/zerospu2/Windows/ZeroSPU2.rc +++ b/plugins/zerospu2/Windows/ZeroSPU2.rc @@ -54,11 +54,6 @@ VS_VERSION_INFO VERSIONINFO FILEVERSION 0,4,6,0 PRODUCTVERSION 0,4,6,0 FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif FILEOS 0x4L FILETYPE 0x2L FILESUBTYPE 0x0L diff --git a/plugins/zerospu2/Windows/ZeroSPU2_2008.vcproj b/plugins/zerospu2/Windows/ZeroSPU2_2008.vcproj index 4d9c45b67b..df6f9ce296 100644 --- a/plugins/zerospu2/Windows/ZeroSPU2_2008.vcproj +++ b/plugins/zerospu2/Windows/ZeroSPU2_2008.vcproj @@ -19,7 +19,7 @@ @@ -114,15 +110,7 @@ /> @@ -192,14 +180,8 @@ /> diff --git a/plugins/zerospu2/configure.ac b/plugins/zerospu2/configure.ac index bebc95f237..119f173f57 100644 --- a/plugins/zerospu2/configure.ac +++ b/plugins/zerospu2/configure.ac @@ -21,6 +21,7 @@ AC_SUBST(ZEROSPU2_SONAME, libZeroSPU2.so.[$ZEROSPU2_CURRENT].[$ZEROSPU2_REVISION CFLAGS= CPPFLAGS= CXXFLAGS= +CCASFLAGS= dnl Check for debug build AC_MSG_CHECKING(debug build) @@ -28,15 +29,17 @@ AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [debug build]), debug=$enableval,debug=no) if test "x$debug" == xyes then - AC_DEFINE(_DEBUG,1,[_DEBUG]) - CFLAGS+="-g -fPIC -Wall -Wno-unused-value " - CPPFLAGS+="-g -fPIC -Wall -Wno-unused-value " - CXXFLAGS+="-g -fPIC -Wall -Wno-unused-value " + AC_DEFINE(PCSX2_DEBUG,1,[PCSX2_DEBUG]) + CFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CPPFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CXXFLAGS+="-g -fPIC -Wall -Wno-unused-value -m32 " + CCASFLAGS+=" -m32 " else AC_DEFINE(NDEBUG,1,[NDEBUG]) - CFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value " - CPPFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value " - CXXFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value " + CFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CPPFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CXXFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value -m32 " + CCASFLAGS+=" -m32 " fi AM_CONDITIONAL(DEBUGBUILD, test x$debug = xyes) AC_MSG_RESULT($debug) @@ -52,33 +55,6 @@ fi AC_MSG_RESULT($devbuild) AM_CONDITIONAL(RELEASE_TO_PUBLIC, test x$devbuild = xno) -dnl Check for 64bit CPU -AC_MSG_CHECKING(for a x86-64 CPU) -dnl if test "$build_os" == "target_os" -dnl then -AC_TRY_RUN([ -int main() -{ -int a = 0; -int*pa = &a; -asm(".intel_syntax\n" - "mov %%rax, %0\n" - "mov %%eax, [%%rax]\n" - ".att_syntax\n" - : : "r"(pa) : "%rax"); -return 0; -} -],cpu64=yes,cpu64=no,) -dnl else -dnl cpu64=no -dnl fi -if test "x$cpu64" == xyes -then -AC_DEFINE(__x86_64__,1,[__x86_64__]) -fi -AC_MSG_RESULT($cpu64) -AM_CONDITIONAL(X86_64, test x$cpu64 = xyes) - AC_CHECK_FUNCS([ _aligned_malloc _aligned_free ], AC_DEFINE(HAVE_ALIGNED_MALLOC)) dnl gtk diff --git a/plugins/zerospu2/misc.h b/plugins/zerospu2/misc.h index 17c3426b45..dab6876483 100644 --- a/plugins/zerospu2/misc.h +++ b/plugins/zerospu2/misc.h @@ -15,15 +15,17 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - - #ifdef __LINUX__ + +#pragma once + +#ifdef __LINUX__ #include #include #include // ftime(), struct timeb #define Sleep(ms) usleep(1000*ms) -inline unsigned long timeGetTime() +inline u32 timeGetTime() { #ifdef _WIN32 _timeb t; @@ -33,11 +35,13 @@ inline unsigned long timeGetTime() ftime(&t); #endif - return (unsigned long)(t.time*1000+t.millitm); + return (u32)(t.time*1000+t.millitm); } #include +#define InterlockedExchangeAdd _InterlockedExchangeAdd + #else #include #include @@ -87,61 +91,3 @@ static __forceinline void pcsx2_aligned_free(void* pmem) #define _aligned_malloc pcsx2_aligned_malloc #define _aligned_free pcsx2_aligned_free #endif - -// Atomic Operations -#if defined (_WIN32) - -#ifndef __x86_64__ -extern "C" LONG __cdecl _InterlockedExchangeAdd(LPLONG volatile Addend, LONG Value); -#endif - -#pragma intrinsic (_InterlockedExchangeAdd) -#define InterlockedExchangeAdd _InterlockedExchangeAdd - -#else - -//typedef void* PVOID; - -static __forceinline long InterlockedExchange(volatile long* Target, long Value) -{ - long result; - /* - * The XCHG instruction always locks the bus with or without the - * LOCKED prefix. This makes it significantly slower than CMPXCHG on - * uni-processor machines. The Windows InterlockedExchange function - * is nearly 3 times faster than the XCHG instruction, so this routine - * is not yet very useful for speeding up pthreads. - */ - - __asm__ __volatile__ ( - "xchgl %2,%1" - :"=r" (result) - :"m" (*Target), "0" (Value)); - - return result; -} - -static __forceinline long InterlockedExchangeAdd(volatile long* Addend, long Value) -{ - __asm__ __volatile__( - ".intel_syntax\n" - "lock xadd [%0], %%eax\n" - ".att_syntax\n" : : "r"(Addend), "a"(Value) : "memory"); -} - -static __forceinline long InterlockedCompareExchange(volatile long *dest, long value, long comp) -{ - long result; - - __asm__ __volatile__ ( - "lock\n\t" - "cmpxchgl %2,%1" /* if (EAX == [location]) */ - /* [location] = value */ - /* else */ - /* EAX = [location] */ - :"=a" (result) - :"m" (*dest), "r" (value), "a" (comp)); - - return result; -} -#endif diff --git a/plugins/zerospu2/voices.cpp b/plugins/zerospu2/voices.cpp index d46ee1592f..bdf8e5e2f2 100644 --- a/plugins/zerospu2/voices.cpp +++ b/plugins/zerospu2/voices.cpp @@ -31,7 +31,7 @@ SPU_CONTROL_* VOICE_PROCESSED::GetCtrl() return ((SPU_CONTROL_*)(spu2regs+memoffset+REG_C0_CTRL)); } -void VOICE_PROCESSED::SetVolume(int iProcessRight) +void VOICE_PROCESSED::SetVolume(s32 iProcessRight) { u16 vol = iProcessRight ? pvoice->right.word : pvoice->left.word; @@ -101,8 +101,8 @@ void VOICE_PROCESSED::InterpolateUp() { if (SB[32]==1) // flag == 1? calc step and set flag... and don't change the value in this pass { - const int id1=SB[30]-SB[29]; // curr delta to next val - const int id2=SB[31]-SB[30]; // and next delta to next-next val :) + const s32 id1=SB[30]-SB[29]; // curr delta to next val + const s32 id2=SB[31]-SB[30]; // and next delta to next-next val :) SB[32]=0; @@ -159,9 +159,9 @@ void VOICE_PROCESSED::InterpolateDown() } } -void VOICE_PROCESSED::FModChangeFrequency(int ns) +void VOICE_PROCESSED::FModChangeFrequency(s32 ns) { - int NP=pvoice->pitch; + s32 NP=pvoice->pitch; NP=((32768L+iFMod[ns])*NP)/32768L; @@ -173,8 +173,7 @@ void VOICE_PROCESSED::FModChangeFrequency(int ns) iActFreq=NP; iUsedFreq=NP; sinc=(((NP/10)<<16)/4800); - if (!sinc) - sinc=1; + if (!sinc) sinc=1; // freq change in simple interpolation mode SB[32]=1; @@ -188,7 +187,7 @@ static void __forceinline GetNoiseValues(s32& VD) if(Seed&0x100) VD = (s32)((Seed&0xff)<<8); - else if(!(Seed&0xffff)) + else if (!(Seed&0xffff)) VD = (s32)0x8000; else VD = (s32)0x7fff; @@ -226,7 +225,7 @@ static void __forceinline GetNoiseValues(s32& VD) // and sometimes the noise will be used as fmod modulation... pfff int VOICE_PROCESSED::iGetNoiseVal() { - int fa; + s32 fa; /*if ((dwNoiseVal<<=1)&0x80000000L) { @@ -248,7 +247,7 @@ int VOICE_PROCESSED::iGetNoiseVal() return fa; } -void VOICE_PROCESSED::StoreInterpolationVal(int fa) +void VOICE_PROCESSED::StoreInterpolationVal(s32 fa) { if (bFMod==2) // fmod freq channel SB[29]=fa; @@ -269,9 +268,9 @@ void VOICE_PROCESSED::StoreInterpolationVal(int fa) } } -int VOICE_PROCESSED::iGetInterpolationVal() +s32 VOICE_PROCESSED::iGetInterpolationVal() { - int fa; + s32 fa; if (bFMod==2) return SB[29]; diff --git a/plugins/zerospu2/zerodma.cpp b/plugins/zerospu2/zerodma.cpp index 85cc6a4a2c..e25c6027c0 100644 --- a/plugins/zerospu2/zerodma.cpp +++ b/plugins/zerospu2/zerodma.cpp @@ -27,7 +27,7 @@ void CALLBACK SPU2readDMAMem(u16 *pMem, int size, int core) { u32 spuaddr; - int i, dma, offset; + s32 i, dma, offset; if ( core == 0) { @@ -44,7 +44,7 @@ void CALLBACK SPU2readDMAMem(u16 *pMem, int size, int core) SPU2_LOG("SPU2 readDMA%dMem size %x, addr: %x\n", dma, size, pMem); - for (i=0; i < size; i++) + for (i = 0; i < size; i++) { *pMem++ = *(u16*)(spu2mem + spuaddr); if ((spu2Rs16(REG_C0_CTRL + offset) & 0x40) && (C_IRQA(core) == spuaddr)) @@ -94,7 +94,7 @@ int ADMASWrite(int core) { u32 spuaddr; ADMA *Adma; - int dma, offset; + s32 dma, offset; if (core == 0) { @@ -159,7 +159,7 @@ void CALLBACK SPU2writeDMAMem(u16* pMem, int size, int core) { u32 spuaddr; ADMA *Adma; - int dma, offset; + s32 dma, offset; if (core == 0) { @@ -240,7 +240,7 @@ void CALLBACK SPU2writeDMA7Mem(u16* pMem, int size) void CALLBACK SPU2interruptDMA(int core) { - int dma, offset; + s32 dma, offset; if (core == 0) { diff --git a/plugins/zerospu2/zerospu2.cpp b/plugins/zerospu2/zerospu2.cpp index 337b7828b8..ead28339a7 100644 --- a/plugins/zerospu2/zerospu2.cpp +++ b/plugins/zerospu2/zerospu2.cpp @@ -44,14 +44,14 @@ u16* spu2mem = NULL; u16* pSpuIrq[2] = {NULL}; u32 dwNewChannel2[2] = {0}; // keeps track of what channels that have been turned on u32 dwEndChannel2[2] = {0}; // keeps track of what channels have ended -unsigned long dwNoiseVal=1; // global noise generator +u32 dwNoiseVal=1; // global noise generator bool g_bPlaySound = true; // if true, will output sound, otherwise no -int iFMod[NSSIZE]; -int s_buffers[NSSIZE][2]; // left and right buffers +s32 iFMod[NSSIZE]; +s32 s_buffers[NSSIZE][2]; // left and right buffers // mixer thread variables static bool s_bThreadExit = true; -static int s_nDropPacket = 0; +static s32 s_nDropPacket = 0; string s_strIniPath="inis/zerospu2.ini"; #ifdef _WIN32 @@ -66,7 +66,7 @@ void* SPU2ThreadProc(void*); #endif static AUDIOBUFFER s_pAudioBuffers[NSPACKETS]; -static int s_nCurBuffer = 0, s_nQueuedBuffers = 0; +static s32 s_nCurBuffer = 0, s_nQueuedBuffers = 0; static s16* s_pCurOutput = NULL; static u32 g_startcount=0xffffffff; static u32 g_packetcount=0; @@ -76,15 +76,15 @@ soundtouch::SoundTouch* pSoundTouch=NULL; WavOutFile* g_pWavRecord=NULL; // used for recording static u64 s_GlobalTimeStamp = 0; -static int s_nDurations[64]={0}; -static int s_nCurDuration=0; -static int s_nTotalDuration=0; +static s32 s_nDurations[64]={0}; +static s32 s_nCurDuration=0; +static s32 s_nTotalDuration=0; -int SPUCycles = 0, SPUWorkerCycles = 0; -int SPUStartCycle[2]; -int SPUTargetCycle[2]; +s32 SPUCycles = 0, SPUWorkerCycles = 0; +s32 SPUStartCycle[2]; +s32 SPUTargetCycle[2]; -int g_logsound=0; +s32 g_logsound=0; int ADMASWrite(int c); @@ -97,7 +97,7 @@ void (*irqCallbackDMA7)()=0; uptr g_pDMABaseAddr=0; -const int f[5][2] = { +const s32 f[5][2] = { { 0, 0 }, { 60, 0 }, { 115, -52 }, @@ -126,7 +126,7 @@ static void InitLibraryName() // subversion revision tags: strcpy( libraryName, "ZeroSPU2" -# ifdef _DEBUG +# ifdef PCSX2_DEBUG "-Debug" # elseif ZEROSPU2_DEVBUILD "-Dev" @@ -138,7 +138,7 @@ static void InitLibraryName() // to label the specific revision: sprintf_s( libraryName, "ZeroSPU2 r%d%s" -# ifdef _DEBUG +# ifdef PCSX2_DEBUG "-Debug" # elif ZEROSPU2_DEVBUILD "-Dev" @@ -151,7 +151,7 @@ static void InitLibraryName() // I'll hook in svn version code later. --arcum42 strcpy( libraryName, "ZeroSPU2 Playground" -# ifdef _DEBUG +# ifdef PCSX2_DEBUG "-Debug" # elif ZEROSPU2_DEVBUILD "-Dev" @@ -239,7 +239,7 @@ s32 CALLBACK SPU2init() memset(voices, 0, sizeof(voices)); // last 24 channels have higher mem offset - for (int i = 0; i < 24; ++i) + for (s32 i = 0; i < 24; ++i) voices[i+24].memoffset = 0x400; // init each channel @@ -305,7 +305,7 @@ s32 CALLBACK SPU2open(void *pDsp) s_pCurOutput = (s16*)s_pAudioBuffers[0].pbuf; assert( s_pCurOutput != NULL); - for (int i = 0; i < ArraySize(s_nDurations); ++i) + for (s32 i = 0; i < ArraySize(s_nDurations); ++i) { s_nDurations[i] = NSFRAMES*1000; } @@ -410,7 +410,7 @@ void CALLBACK SPU2async(u32 cycle) void InitADSR() // INIT ADSR { u32 r,rs,rd; - int i; + s32 i; memset(RateTable,0,sizeof(u32)*160); // build the rate table according to Neill's rules (see at bottom of file) r=3;rs=1;rd=0; @@ -434,7 +434,7 @@ void InitADSR() // INIT ADSR } } -int MixADSR(VOICE_PROCESSED* pvoice) // MIX ADSR +s32 MixADSR(VOICE_PROCESSED* pvoice) // MIX ADSR { u32 rateadd[8] = { 0, 4, 6, 8, 9, 10, 11, 12 }; @@ -536,11 +536,11 @@ int MixADSR(VOICE_PROCESSED* pvoice) // MIX ADSR return 0; } -void MixChannels(int core) +void MixChannels(s32 core) { // mix all channels - int c_offset = 0x0400 * core; - int dma, left_vol, right_vol; + s32 c_offset = 0x0400 * core; + s32 dma, left_vol, right_vol; ADMA *Adma; if (core == 0) @@ -560,12 +560,12 @@ void MixChannels(int core) if ((spu2Ru16(REG_C0_MMIX + c_offset) & 0xF0) && (spu2Ru16(REG_C0_ADMAS + c_offset) & (0x1 + core))) { - for (int ns=0;nsIndex]*(int)spu2Ru16(left_vol))>>16; + s_buffers[ns][0] += (((s16*)spu2mem)[0x2000 + c_offset +Adma->Index]*(s32)spu2Ru16(left_vol))>>16; if ((spu2Ru16(REG_C0_MMIX + c_offset) & 0x40)) - s_buffers[ns][1] += (((short*)spu2mem)[0x2200 + c_offset +Adma->Index]*(int)spu2Ru16(right_vol))>>16; + s_buffers[ns][1] += (((s16*)spu2mem)[0x2200 + c_offset +Adma->Index]*(s32)spu2Ru16(right_vol))>>16; Adma->Index +=1; MemAddr[core] += 4; @@ -602,7 +602,7 @@ void SPU2Worker() { u8* start; u32 nSample; - int ch, predict_nr, shift_factor, flags; + s32 ch, predict_nr, shift_factor, flags; // assume s_buffers are zeroed out if ( dwNewChannel2[0] || dwNewChannel2[1] ) @@ -624,11 +624,11 @@ void SPU2Worker() pChannel->VoiceChangeFrequency(); // loop until 1 ms of data is reached - int ns = 0; + s32 ns = 0; while(nsbFMod==1 && iFMod[ns]) pChannel->FModChangeFrequency(ns); @@ -662,8 +662,8 @@ void SPU2Worker() for (nSample=0; nSample<28; ++start) { - int s; - int d = (int)*start; + s32 s; + s32 d = (s32)*start; s = ((d & 0xf)<<12); if (s & 0x8000) s |= 0xffff0000; @@ -685,7 +685,7 @@ void SPU2Worker() } // irq occurs no matter what core access the address - for (int core = 0; core < 2; ++core) + for (s32 core = 0; core < 2; ++core) { if (((SPU_CONTROL_*)(spu2regs + (0x400 * core) + REG_C0_CTRL))->irq) // some callback and irq active? { @@ -736,7 +736,7 @@ void SPU2Worker() else fa=pChannel->iGetInterpolationVal(); // get sample val - int sval = (MixADSR(pChannel) * fa) / 1023; // mix adsr + s32 sval = (MixADSR(pChannel) * fa) / 1023; // mix adsr if (pChannel->bFMod == 2) // fmod freq channel { @@ -767,7 +767,7 @@ ENDX: { assert( s_pCurOutput != NULL); - for (int ns=0; ns 5000) { WARN_LOG("ZeroSPU2: recording\n"); @@ -840,17 +840,17 @@ ENDX: } // resamples pStereoSamples -void ResampleLinear(s16* pStereoSamples, int oldsamples, s16* pNewSamples, int newsamples) +void ResampleLinear(s16* pStereoSamples, s32 oldsamples, s16* pNewSamples, s32 newsamples) { - for (int i = 0; i < newsamples; ++i) + for (s32 i = 0; i < newsamples; ++i) { - int io = i * oldsamples; - int old = io / newsamples; - int rem = io - old * newsamples; + s32 io = i * oldsamples; + s32 old = io / newsamples; + s32 rem = io - old * newsamples; old *= 2; - int newsampL = pStereoSamples[old] * (newsamples - rem) + pStereoSamples[old+2] * rem; - int newsampR = pStereoSamples[old+1] * (newsamples - rem) + pStereoSamples[old+3] * rem; + s32 newsampL = pStereoSamples[old] * (newsamples - rem) + pStereoSamples[old+2] * rem; + s32 newsampR = pStereoSamples[old+1] * (newsamples - rem) + pStereoSamples[old+3] * rem; pNewSamples[2 * i] = newsampL / newsamples; pNewSamples[2 * i + 1] = newsampR / newsamples; } @@ -868,7 +868,7 @@ DWORD WINAPI SPU2ThreadProc(LPVOID) void* SPU2ThreadProc(void* lpParam) #endif { - int nReadBuf = 0; + s32 nReadBuf = 0; while (!s_bThreadExit) { @@ -901,13 +901,13 @@ void* SPU2ThreadProc(void* lpParam) } - //int ps2delay = timeGetTime() - s_pAudioBuffers[nReadBuf].timestamp; - int NewSamples = s_pAudioBuffers[nReadBuf].avgtime; + //s32 ps2delay = timeGetTime() - s_pAudioBuffers[nReadBuf].timestamp; + s32 NewSamples = s_pAudioBuffers[nReadBuf].avgtime; if ( (conf.options & OPTION_TIMESTRETCH) ) { - int bytesbuf = SoundGetBytesBuffered(); + s32 bytesbuf = SoundGetBytesBuffered(); if ( bytesbuf < 8000 ) NewSamples += 1000; // check the current timestamp, if too far apart, speed up audio @@ -928,25 +928,25 @@ void* SPU2ThreadProc(void* lpParam) NewSamples = min(NewSamples, NSFRAMES * NSSIZE * 3); - int oldsamples = s_pAudioBuffers[nReadBuf].len / 4; + s32 oldsamples = s_pAudioBuffers[nReadBuf].len / 4; if ((nReadBuf & 3) == 0) // wow, this if statement makes the whole difference pSoundTouch->setTempoChange(100.0f*(float)oldsamples/(float)NewSamples - 100.0f); - for( int sx=0; sxputSamples(s_floatBuffer, oldsamples); // extract 2*NSFRAMES ms at a time - int nOutSamples; + s32 nOutSamples; do { nOutSamples = pSoundTouch->receiveSamples(s_floatBuffer, NSSIZE * NSFRAMES * 5); if ( nOutSamples > 0 ) { - for( int sx=0; sx>=1) // loop channels + for (s32 ch=start;ch>=1) // loop channels { if ((val&1) && voices[ch].pStart) // mmm... start has to be set before key on !?! { @@ -983,17 +983,17 @@ void SoundOn(int start,int end,unsigned short val) // SOUND ON PSX COMAND } // turn channels off -void SoundOff(int start,int end,unsigned short val) // SOUND OFF PSX COMMAND +void SoundOff(s32 start,s32 end,u16 val) // SOUND OFF PSX COMMAND { - for (int ch=start;ch>=1) // loop channels + for (s32 ch=start;ch>=1) // loop channels { if (val&1) voices[ch].bStop=true; // && s_chan[i].bOn) mmm... } } -void FModOn(int start,int end,unsigned short val) // FMOD ON PSX COMMAND +void FModOn(s32 start,s32 end,u16 val) // FMOD ON PSX COMMAND { - int ch; + s32 ch; for (ch=start;ch>=1) // loop channels { @@ -1010,9 +1010,9 @@ void FModOn(int start,int end,unsigned short val) // FMOD ON PSX COMMAND } } -void VolumeOn(int start,int end,unsigned short val,int iRight) // VOLUME ON PSX COMMAND +void VolumeOn(s32 start,s32 end,u16 val,s32 iRight) // VOLUME ON PSX COMMAND { - int ch; + s32 ch; for (ch=start;ch>=1) // loop channels { @@ -1048,7 +1048,7 @@ void CALLBACK SPU2write(u32 mem, u16 value) // channel info if ((r<0x0180) || (r>=0x0400 && r<0x0580)) // u32s are always >= 0. { - int ch=0; + s32 ch=0; if (r >= 0x400) ch = ((r - 0x400) >> 4) + 24; else @@ -1064,7 +1064,7 @@ void CALLBACK SPU2write(u32 mem, u16 value) break; case 4: { - int NP; + s32 NP; if (value> 0x3fff) NP=0x3fff; // get pitch val else @@ -1100,8 +1100,8 @@ void CALLBACK SPU2write(u32 mem, u16 value) // more channel info if ((r>=0x01c0 && r<0x02E0)||(r>=0x05c0 && r<0x06E0)) { - int ch=0; - unsigned long rx=r; + s32 ch=0; + u32 rx=r; if (rx>=0x400) { ch=24; @@ -1257,7 +1257,7 @@ u16 CALLBACK SPU2read(u32 mem) // if the register is any of the regs before core 0, or is somewhere between core 0 and 1... if ((r < 0x0180) || (r >= 0x0400 && r < 0x0580)) // u32s are always >= 0. { - int ch = 0; + s32 ch = 0; if (r >= 0x400) ch=((r - 0x400) >> 4) + 24; @@ -1272,8 +1272,8 @@ u16 CALLBACK SPU2read(u32 mem) if ((r>=REG_VA_SSA && r=0x05c0 && r<0x06E0)) // some channel info? { - int ch=0; - unsigned long rx = r; + s32 ch=0; + u32 rx = r; if (rx >=0x400) { @@ -1390,24 +1390,24 @@ s32 CALLBACK SPU2test() } // size is in bytes -void LogPacketSound(void* packet, int memsize) +void LogPacketSound(void* packet, s32 memsize) { u16 buf[28]; u8* pstart = (u8*)packet; - int s_1 = 0, s_2=0; + s32 s_1 = 0, s_2=0; - for (int i = 0; i < memsize; i += 16) + for (s32 i = 0; i < memsize; i += 16) { - int predict_nr=(int)pstart[0]; - int shift_factor=predict_nr&0xf; + s32 predict_nr=(s32)pstart[0]; + s32 shift_factor=predict_nr&0xf; predict_nr >>= 4; pstart += 2; - for (int nSample=0;nSample<28; ++pstart) + for (s32 nSample=0;nSample<28; ++pstart) { - int d=(int)*pstart; - int s, fa; + s32 d=(s32)*pstart; + s32 s, fa; s =((d & 0xf) << 12); SetPacket(s); @@ -1420,7 +1420,7 @@ void LogPacketSound(void* packet, int memsize) } } -void LogRawSound(void* pleft, int leftstride, void* pright, int rightstride, int numsamples) +void LogRawSound(void* pleft, s32 leftstride, void* pright, s32 rightstride, s32 numsamples) { if (g_pWavRecord == NULL ) g_pWavRecord = new WavOutFile(RECORD_FILENAME, SAMPLE_RATE, 16, 2); @@ -1431,7 +1431,7 @@ void LogRawSound(void* pleft, int leftstride, void* pright, int rightstride, int tempbuf.resize(2 * numsamples); - for (int i = 0; i < numsamples; ++i) + for (s32 i = 0; i < numsamples; ++i) { tempbuf[2*i+0] = *(s16*)left; tempbuf[2*i+1] = *(s16*)right; @@ -1462,7 +1462,7 @@ int CALLBACK SPU2setupRecording(int start, void* pData) void save_data(freezeData *data) { SPU2freezeData *spud; - int i; + s32 i; spud = (SPU2freezeData*)data->data; spud->version = 0x70000001; @@ -1470,8 +1470,8 @@ void save_data(freezeData *data) memcpy(spud->spu2regs, spu2regs, 0x10000); memcpy(spud->spu2mem, spu2mem, 0x200000); - spud->nSpuIrq[0] = (int)(pSpuIrq[0] - spu2mem); - spud->nSpuIrq[1] = (int)(pSpuIrq[1] - spu2mem); + spud->nSpuIrq[0] = (s32)(pSpuIrq[0] - spu2mem); + spud->nSpuIrq[1] = (s32)(pSpuIrq[1] - spu2mem); memcpy(spud->dwNewChannel2, dwNewChannel2, 4*2); memcpy(spud->dwEndChannel2, dwEndChannel2, 4*2); @@ -1518,7 +1518,7 @@ void save_data(freezeData *data) void load_data(freezeData *data) { SPU2freezeData *spud; - int i; + s32 i; spud = (SPU2freezeData*)data->data; @@ -1556,7 +1556,7 @@ void load_data(freezeData *data) for (i = 0; i < ArraySize(voices); ++i) { - memcpy(&voices[i], &spud->voices[i], min((int)SPU_VOICE_STATE_SIZE, spud->voicesize)); + memcpy(&voices[i], &spud->voices[i], min((s32)SPU_VOICE_STATE_SIZE, spud->voicesize)); voices[i].pStart = (u8*)((uptr)spud->voices[i].pStart+(uptr)spu2mem); voices[i].pLoop = (u8*)((uptr)spud->voices[i].pLoop+(uptr)spu2mem); voices[i].pCurr = (u8*)((uptr)spud->voices[i].pCurr+(uptr)spu2mem); @@ -1565,7 +1565,7 @@ void load_data(freezeData *data) s_GlobalTimeStamp = 0; g_startcount = 0xffffffff; - for (int i = 0; i < ArraySize(s_nDurations); ++i) + for (s32 i = 0; i < ArraySize(s_nDurations); ++i) { s_nDurations[i] = NSFRAMES*1000; } diff --git a/plugins/zerospu2/zerospu2.h b/plugins/zerospu2/zerospu2.h index d97b9e112c..d68142c779 100644 --- a/plugins/zerospu2/zerospu2.h +++ b/plugins/zerospu2/zerospu2.h @@ -23,10 +23,8 @@ #include #include -extern "C" { #define SPU2defs #include "PS2Edefs.h" -} #include "reg.h" #include "misc.h" @@ -88,24 +86,24 @@ extern FILE *spu2Log; extern s8 *spu2regs; extern u16* spu2mem; -extern int iFMod[NSSIZE]; +extern s32 iFMod[NSSIZE]; extern u32 MemAddr[2]; -extern unsigned long dwNoiseVal; // global noise generator +extern u32 dwNoiseVal; // global noise generator // functions of main emu, called on spu irq extern void (*irqCallbackSPU2)(); extern void (*irqCallbackDMA4)(); extern void (*irqCallbackDMA7)(); -extern int SPUCycles, SPUWorkerCycles; -extern int SPUStartCycle[2]; -extern int SPUTargetCycle[2]; +extern s32 SPUCycles, SPUWorkerCycles; +extern s32 SPUStartCycle[2]; +extern s32 SPUTargetCycle[2]; extern u16 interrupt; typedef struct { - int Log; - int options; + s32 Log; + s32 options; } Config; extern Config conf; @@ -173,7 +171,7 @@ static __forceinline u32 C1_IRQA() return SPU2_GET32BIT(REG_C1_IRQA_LO, REG_C1_IRQA_HI); } -static __forceinline u32 C_IRQA(int c) +static __forceinline u32 C_IRQA(s32 c) { if (c == 0) return C0_IRQA(); @@ -191,7 +189,7 @@ static __forceinline u32 C1_SPUADDR() return SPU2_GET32BIT(REG_C1_SPUADDR_LO, REG_C1_SPUADDR_HI); } -static __forceinline u32 C_SPUADDR(int c) +static __forceinline u32 C_SPUADDR(s32 c) { if (c == 0) return C0_SPUADDR(); @@ -209,7 +207,7 @@ static __forceinline void C1_SPUADDR_SET(u32 value) SPU2_SET32BIT(value, REG_C1_SPUADDR_LO, REG_C1_SPUADDR_HI); } -static __forceinline void C_SPUADDR_SET(u32 value, int c) +static __forceinline void C_SPUADDR_SET(u32 value, s32 c) { if (c == 0) C0_SPUADDR_SET(value); @@ -282,18 +280,18 @@ struct _SPU_VOICE // ADSR INFOS PER CHANNEL struct ADSRInfoEx { - int State; - int AttackModeExp; - int AttackRate; - int DecayRate; - int SustainLevel; - int SustainModeExp; - int SustainIncrease; - int SustainRate; - int ReleaseModeExp; - int ReleaseRate; - int EnvelopeVol; - long lVolume; + s32 State; + s32 AttackModeExp; + s32 AttackRate; + s32 DecayRate; + s32 SustainLevel; + s32 SustainModeExp; + s32 SustainIncrease; + s32 SustainRate; + s32 ReleaseModeExp; + s32 ReleaseRate; + s32 EnvelopeVol; + s32 lVolume; }; #define SPU_VOICE_STATE_SIZE (sizeof(VOICE_PROCESSED)-4*sizeof(void*)) @@ -311,34 +309,34 @@ struct VOICE_PROCESSED void InterpolateUp(); void InterpolateDown(); void FModChangeFrequency(int ns); - int iGetNoiseVal(); + s32 iGetNoiseVal(); void StoreInterpolationVal(int fa); - int iGetInterpolationVal(); + s32 iGetInterpolationVal(); void Stop(); SPU_CONTROL_* GetCtrl(); // start save state - int leftvol, rightvol; // left right volumes + s32 leftvol, rightvol; // left right volumes - int iSBPos; // mixing stuff - int SB[32+32]; - int spos; - int sinc; + s32 iSBPos; // mixing stuff + s32 SB[32+32]; + s32 spos; + s32 sinc; - int iIrqDone; // debug irq done flag - int s_1; // last decoding infos - int s_2; - int iOldNoise; // old noise val for this channel - int iActFreq; // current psx pitch - int iUsedFreq; // current pc pitch + s32 iIrqDone; // debug irq done flag + s32 s_1; // last decoding infos + s32 s_2; + s32 iOldNoise; // old noise val for this channel + s32 iActFreq; // current psx pitch + s32 iUsedFreq; // current pc pitch - int iStartAddr, iLoopAddr, iNextAddr; - int bFMod; + s32 iStartAddr, iLoopAddr, iNextAddr; + s32 bFMod; ADSRInfoEx ADSRX; // next ADSR settings (will be moved to active on sample start) - int memoffset; // if first core, 0, if second, 0x400 - int chanid; // channel id + s32 memoffset; // if first core, 0, if second, 0x400 + s32 chanid; // channel id bool bIgnoreLoop, bNew, bNoise, bReverb, bOn, bStop, bVolChanged; bool bVolumeR, bVolumeL; @@ -363,15 +361,15 @@ struct AUDIOBUFFER // Variable used to smooth out sound by concentrating on new voices u32 timestamp; // in microseconds, only used for time stretching u32 avgtime; - int newchannels; + s32 newchannels; }; struct ADMA { - unsigned short * MemAddr; - int Index; - int AmountLeft; - int Enabled; + u16* MemAddr; + s32 Index; + s32 AmountLeft; + s32 Enabled; // used to make sure that ADMA doesn't get interrupted with a writeDMA call }; @@ -384,19 +382,19 @@ struct SPU2freezeData u8 spu2regs[0x10000]; u8 spu2mem[0x200000]; u16 interrupt; - int nSpuIrq[2]; + s32 nSpuIrq[2]; u32 dwNewChannel2[2], dwEndChannel2[2]; u32 dwNoiseVal; - int iFMod[NSSIZE]; + s32 iFMod[NSSIZE]; u32 MemAddr[2]; ADMA adma[2]; u32 Adma4MemAddr, Adma7MemAddr; - int SPUCycles, SPUWorkerCycles; - int SPUStartCycle[2]; - int SPUTargetCycle[2]; + s32 SPUCycles, SPUWorkerCycles; + s32 SPUStartCycle[2]; + s32 SPUTargetCycle[2]; - int voicesize; + s32 voicesize; VOICE_PROCESSED voices[SPU_NUMBER_VOICES+1]; }; diff --git a/setup/setup.vdproj b/setup/setup.vdproj new file mode 100644 index 0000000000..8e5398236f --- /dev/null +++ b/setup/setup.vdproj @@ -0,0 +1,7862 @@ +"DeployProject" +{ +"VSVersion" = "3:800" +"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:setup" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:" +"SccLocalPath" = "8:" +"SccAuxPath" = "8:" +"SccProvider" = "8:" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_008B1BB47C0A46C0B025FDE5376533F4" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_00ABD03A61124E9F8BEC5E4D2D7F2715" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_03E75E8822CE48BFB4D8378A4FD3A9E8" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_0435A4202F22485295FC9B14FF9E0DEF" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_048B9870FB3E4278ADCB974F47D3AA3D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_069D4ED441804E6F91F93A1BA01C21B8" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_072AB1B5BAC84646894F39D3E1BF092F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_072B429763E648A2AFA3744F69B35FD8" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_07B925C7C3DD4023870E4C350A933F01" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_086724BEF26C4B91964547A4ABCFC33D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_094A3551F77548E28331D27415415CD4" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_0953A3DB125D4969AA9CF0EAEE0174F8" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_0A01FDD1F6A54A43A900C9AC92D4B2D9" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_0AA27B6457FC4913924E4F391F4581DC" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_0AB0A47469D44DC28C0973A8B295B919" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_0ACCF2C8B96C2712D1D5C59C66341354" + "OwnerKey" = "8:_882694E02F0649F29ADA794E68DA525C" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_0C95C45CAB924AE2AC25800B164275B7" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_0D6C5B8003914BC8B1F4C3EC09C58AB2" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_0E8BBD04D986469EA64F1A82EC4DB8FA" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1037D220B29040FDA7B60A0A9DA4865E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_110E08BF1DA04EF69BF2D475585D0500" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1320398166C4413FB4BF04DC2C1FD8EF" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1430E155AE5F4B92A78B32E05FEAF3EF" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_14A843D75DC34B599F3463074612476E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_164C7824F6134DF3A56AF21FB50AE125" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1750E80E95EC4B128595AC231181C330" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_17EF52CE5F174F708988D3792C4EF1FE" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1969096EAD2A4292BA27BED98ACA17FB" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1B2AF463338C40B0AA1AE5F3149D343D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1B7AD03818962FE68D82D1B4D4642FB6" + "OwnerKey" = "8:_6827AD9625DF4C39A8A0E39FB82E3CD0" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1EF4CE3ED84F4057B2C26F87099AED66" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1FA9731E400641839E29839952B10A67" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1FEA719F022CEAF9A269D43AD22AF93F" + "OwnerKey" = "8:_6827AD9625DF4C39A8A0E39FB82E3CD0" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_223105795E5D49B8BD6AD93E12847151" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2286937AE4E6436F95D07AB1A588794C" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_22917529BC854387B3A9A7C7DF33EDAE" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_231B4CAAD95A4D5391BD2A27D1BEA77E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2393441DF8524232AD40E46DF2640189" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_24AD39A905574544A69A1F67C0A3CB16" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_24E2C7FDC2EC4816A9E3D2C1860E5A41" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_252DE06AE3874074A9070423E08DE75A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_25A855DA124946CF878441F4673A48D0" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_25EDB5C49F2745F199D2CF1036A1207F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2753983542094EB781E4AA2FC90CF0D4" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2806AFD2B45345C09E96EA1E139BE213" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_285DF38D8D4043129B7F2E2227603DB5" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2A2B73C24B1541B6A6B380B019877693" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2ADB9B378F3441FAA48C077E968E5929" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2BDA0576A7894E6481660D46B5A01437" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2E849B77EC5944D9A6C38F02C8D1125E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_3148F098C35140D2B38C9EAE570278C7" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_316BCBF5300B4931ACBC48DBC4935C7D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_32CF1A99F5714908AFDEF8B5686EB63E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_33545BED81CC46E2B3D3406385AB4BAB" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_344F82E4D0F14313831E11BF22926517" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_34FCB627708446FA998E61BC379C3274" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_35CF60C53FC643E8BD271C8F4F257F7F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_363B16784029465C9F2F27ED2544DFB2" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_368F66344EEB4252939476AE57FD170A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_385F635F391A45E7AF3C9ECCB8580BBB" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_389BF52BB2004C779C0B34C431B8DF6C" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_399D3AEE4A37416D8C89F4C87D4B2186" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_39C6B9B06D72499680F6F1AC6CB5BC41" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_3C0AF639574546BF806A7C2967B84D64" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_3D004382B4E34EBDA27EC6CB3542C77B" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_3D0E6540B75342C983BD1B81A7D0687F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_3DE636877DB640AFBF78E771B6339E7B" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_40AF38FA32E74704B11F107D51809D67" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_40D1B86DB6384BBC8642DCCF1C19EF44" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_410B722D4B1A40448CBAB425C76BB942" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_439BE780DFAF488CAB0628CA9EE105C1" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_44610C616D8541A7AADF2A907D62CBC3" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_44BA53E81F0FD93AF224C5D26706AA36" + "OwnerKey" = "8:_1FA9731E400641839E29839952B10A67" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_44BA53E81F0FD93AF224C5D26706AA36" + "OwnerKey" = "8:_C5FEBD35C45E4EAE824FD02E9F023FD0" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_44BA53E81F0FD93AF224C5D26706AA36" + "OwnerKey" = "8:_8037556EAB9F4BF298A6AA2BDA834930" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_45B9B43F0312436EB21A3EE185196698" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_45C9A622FD5C48778968D4FB6D6DF5A3" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_497B59E060004BDD8AA9C9117771CC9F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_4C3F6AED1BC84C90867D52A478F93263" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_4DA88C47D7F24AF98C9EA65B22E3963A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_4E78F6174A7940B1A434F71096AE6599" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5083DF2E71904EFD87DF275C566E4DA3" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5108D04A106F4BF0925ECDB0238858A0" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_519BA9151D974A46AB5AB56B0E4AA51F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_52EBADEB628C495898A151D2C9DFCE84" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_55DD5447D0704C5BA1D4485FFCB12750" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_56740A2D926040FB9DAB02218AF22A12" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_56EC8A30479C4EC19744D5D61814D1EE" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5795B3AD60144867AAF76625BF8D12E6" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5816864CB37148EAA1B4E3694087D957" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_583A5A54C626479C895F30381B84C0A0" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5902179EF3C847EB89E23FF72968009A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5ACDADD74B40457B83F1981EFAA7857D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5BB0EB6C5231446AAC5204710D7B80AF" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5DA8B5994E0C45E389DCB5E6A78A606F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5FD67D7865EF469681C9064A909D284B" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_600402FDB5064D0B82810CB4E6DBEEA1" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_601A2EF5BC9E4E18847D198965955979" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_601C974367D84D838C6C6CC9A6B0EF12" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6159CD85FA674476A8500E4D4DBDE249" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6177B9D05A0A4128BE5E565074A64B8A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6330D1F1B93B4ED782294CC53AE58C88" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_647EE324793341ECAF24A8ADE8855B94" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6827AD9625DF4C39A8A0E39FB82E3CD0" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6843982E6E314D768F6CC5F102688B0E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_69328962B15D4340A2F60B4AC76D1BE6" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6B65629ABA014116BCEFB83DAD553D16" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6CE23E7F518243C7BA141E1E65C168CC" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6E07916227C246EB9FBC73A4BE564BE6" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6F2EA43D6CB84A66ADD39614C2DB53ED" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6F5170ED41D34E2696B817A3C44F11D5" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6FB75A46740D4F2B9472C15B4E58AD88" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7064BEB3EECD4A94AEFA90955DA88FA7" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_718A74839C0D4897B1C66283597425E8" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_71BE9607A7510034EDED2B591E6F981E" + "OwnerKey" = "8:_25EDB5C49F2745F199D2CF1036A1207F" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7274EADA979045C380198FDA59E37468" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_741FC4B6CB49412FAF2FD02903557840" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_76BB1C3A20244799AAEAC764389DB226" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_78792FEB009343479E361944DCAF9C36" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_78F8BB67ADA242B1A949C41F909666E2" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_797C85AEE487426EA22D8B0253111FA3" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7AB0994101C146EFA3493863882452B4" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7B327706377AE5F414299F6736D8EC00" + "OwnerKey" = "8:_87A61D50A0B944458FE3B315A47FA221" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7B327706377AE5F414299F6736D8EC00" + "OwnerKey" = "8:_E663A731DB91460B991DAA889BD480EE" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7C0CEAF559A84A0C8723C9328DBADDAE" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7C346BC46D0B44BAB4750A35B70A0B46" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7D493307EEB847228F6CCEEE90D42DAA" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7E94D0A6FD0E48C8A7B7D8421F4D2DE6" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7EA7534B81A9415D89174750F58D27A2" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7EDF89CE07114545909E655CC5567735" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7FF341438FB64A7A9A22CD9B9839C63C" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8037556EAB9F4BF298A6AA2BDA834930" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8196C46459C542B1A8EC49445C14472F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_81D9FBCB8E3D4952A47B9BC4B2567BB2" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_83305974B07F42C18E0AE99DBBF15037" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_84F3D3D23A1447339492C40CC699DD44" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8743DB62D7EF4D72A820BAEC30E97DEC" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_87A61D50A0B944458FE3B315A47FA221" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_87D6D4E907CB469280556CA51B5737E7" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_88207E3137E2456C8D63EEB045A495E7" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_882694E02F0649F29ADA794E68DA525C" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8835232945DD4F2C8333D0E2CACA9DF8" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8897C560DD094D698EA4A9B88C98D0A6" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_88FCE1823EA04CF8B1FE816A1A0E1E3B" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_89BA174439B14C8F8FA942C9E150B718" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8AB21318425441BA811D919F6DC5D6E8" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8AC15EDDB6994E7794DBA7A0A3DCA60B" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8C0EC3CEAEB04DE7B6729EBBCE8C0B36" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8CF26805EE71422CBC1C152A7462FE44" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8E3C8EAC49BD49EE886229B91DF16166" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8E909C0BE4C942A7804FF65AD2DDAFB5" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8F39494E0D4C4FF091091DAF5183388D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_90ED9EDA4346456F8957D9E7EB0D8DD9" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_91C427E57A3B48F399BAA6AF4A588293" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_924E5E9E11C245D383CFFA77545B69FE" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_9356233C1CB34B1E8F0781EA7188920C" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_94DA87D95C7E4D009C9FFF2F647405C2" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_95AA28E96394481AB463DEF29FAA78F8" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_9636D19CCBD441D993A061FDE5FF7807" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_96AB009303B44C2CB19C172EB5D51CE2" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_98FAE27F8FDB404098DC9E605F753E0D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_99C23BC9B7C5EEDB5AD1079051D199C3" + "OwnerKey" = "8:_6827AD9625DF4C39A8A0E39FB82E3CD0" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_9AB559EE78054703AF56D8E7744F3806" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_9C7D1B3E93F0481E804E68339BBEB021" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_9D1F177B2FFA4D3D84F11A8A20D1F611" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_9E96BFE206504BFEBF955CA9CBA846DC" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_A22B625A9A0E4580B7976E1C76B13D93" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_A2652446B2604985A24F992F42F2761E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_A28EBA4DE8914C988801F829035FFEC8" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_A3D55F63E0484B52BD23FBF66915D43D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_A3F76D4DE92743659E861547FE69DE1F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_A40F34AB634C48D7B953C2E420915F07" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_A89761474AC748AE931002EE5E581284" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_A8F09DC7C504415BA06801BA7C5D750B" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_AAB10625A4634D85821952D2CD42642B" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_AB28BFBD30FC423293D42423F112B6BD" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_ADAC04E54F894404A83B379617E7A97E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_ADE00C6618D141C49F057DA07B235947" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_ADE37DD61B5347DB890F2957492F3745" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_AEB84272F38444F5BB708EF3E0833776" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_AF4D152A202841D2BF769FBDF5CEB413" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_AF7C7BE64EA846468642088F15DA4A1F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B2A5C84577F64477896DD21845527BD0" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B2F1836277ED493C958A02184D327E49" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B4A1253749E245B088BD031A677CFB4A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B50F62EC90CD4A07912A63B90AAD3293" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B63084B7B255496B836164646F5D536D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B8FEC8F89AD14BE5AF941C226AAA31AF" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B90FC469B0A7444AA681C869AB6704D4" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_BA8C69F1D2364A2E9268819F2A8085FB" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_BC30361C69EF4CD8869553D0AF1CA80A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_BCED2304BC124DC79A400E6EC3DF991A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_BD602A7A1C334F74815A52DF4C98D0CD" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_BDA20A14A241440B8632ABEBC26E35DB" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_BFE971F656CA46C7A298C91757E9AFF7" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C047CC641D1E4EAF9CF3032B69B49C46" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C10D7A1FC3A44F749156F781C6DB3140" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C188D42682084A7D983722A92046C3EA" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C28E286C209D4FBCBBF1FD46837E0854" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C40BE5E85657415296E733A2F29C985A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C46C31F5523D72D416CDEF1804E2A64D" + "OwnerKey" = "8:_6827AD9625DF4C39A8A0E39FB82E3CD0" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C555162941C34AE1B51CE4CB5352CD4E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C5FEBD35C45E4EAE824FD02E9F023FD0" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C77702CF400646678BD9CC9242B1B6BB" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C80AC3C16BED483D8228AFA835D7F15F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C82D0E331C0F4C368F91EE2A7BD0565D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C980F539DB294419AE3FC77C33A77AEF" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_CCDA5668BC2E426E9E05F8875B752536" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_CDAA2F2C190A4DCB928E78564F76BCA3" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_CE6A0F7079024AF4A0933BB7F9BFE195" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D11A044D40114C19A0FDA835B19D37AF" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D21F33B9B9CA4F28996FF4CB02872772" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D2474D58E6AC4CA0A5FCEF9B4BA6B3E4" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D31ED5CC46194EA6A81F9F9BE3DE5CD1" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D4219ACEADB94026AA93732F128494E3" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D738FF1390814B24A9021A19F95E4290" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D81E0DB3F5674742AB46156B10CCC968" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D92503794DA8471A8BFE082269932306" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D980AD62DE974BABA15438FF6ACFA8BF" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_DAC88B65E7EB4A8E92FBF82174072D28" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_DB95F4450EFC4AAE94E1A2EDE746B2B2" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_DBB4560AE2924E349948FA5BB09FE28E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_DCA1A5B0C13D49259445C449B0E50774" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_DD150D2502704E67A072908310DB66F3" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_DFE2B52C9EDF48DA81BC3E67D6564B0D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E02F836E90974BFC8E673705BE975E95" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E09F4497BBF14351A2528D6E215DE28D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E0E1B281255A4DC5934647A82D674F99" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E17B0DADA8FC4512A4888DE697BC75B3" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E508524696DD452E91B739C7EC466374" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E663A731DB91460B991DAA889BD480EE" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E6DE12DF8D434183B93158C458D72A61" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E71C997965964853BA87889843181711" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_ECC63C4CBBE44D568436E4312BA47908" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_ECD3190AB8F14933A35236EC20488C61" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_EEECC8B200772D4A9F89A5F65A3B97F5" + "OwnerKey" = "8:_BA8C69F1D2364A2E9268819F2A8085FB" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_F00371D156F84024BD88562FE8C9DDBF" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_F165D6BEADEC6B529C157DDC87667E80" + "OwnerKey" = "8:_25EDB5C49F2745F199D2CF1036A1207F" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_F1A181FCDB444332B63B8E51A4EBD448" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_F29E17EBECD5437C9244B842F5038BB1" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_F43E0A4CFF22404996751E7EE5CFC3DE" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_F58D989DCC40429EBC0C9D43AF5D8BA1" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_F6AF071E4E7F4C6CBB28DCDAA6A711C3" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_F72D772B69424F28A3E406E8BCD1878B" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_F84D270966164BAAA768673FDACED3CC" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_F9276AD7A6E840C59B3B10CD18910D35" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_FBBAFABEF4884CCA881660F376B5F6FE" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_FCB2559A1E524CAFA362E24808358B68" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_FD481E6914D27724507EE8D2A4BD4317" + "OwnerKey" = "8:_1FA9731E400641839E29839952B10A67" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_FD481E6914D27724507EE8D2A4BD4317" + "OwnerKey" = "8:_C5FEBD35C45E4EAE824FD02E9F023FD0" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_FD481E6914D27724507EE8D2A4BD4317" + "OwnerKey" = "8:_AF4D152A202841D2BF769FBDF5CEB413" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_FD481E6914D27724507EE8D2A4BD4317" + "OwnerKey" = "8:_882694E02F0649F29ADA794E68DA525C" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_FD481E6914D27724507EE8D2A4BD4317" + "OwnerKey" = "8:_8037556EAB9F4BF298A6AA2BDA834930" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_FD481E6914D27724507EE8D2A4BD4317" + "OwnerKey" = "8:_25EDB5C49F2745F199D2CF1036A1207F" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_FF64089169014510AEEBB6F516BFE6D5" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Release\\pcsx2inst.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:3" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Visual.C++.9.0.x86" + { + "Name" = "8:Visual C++ Runtime Libraries (x86)" + "ProductCode" = "8:Microsoft.Visual.C++.9.0.x86" + } + "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Windows.Installer.3.1" + { + "Name" = "8:Windows Installer 3.1" + "ProductCode" = "8:Microsoft.Windows.Installer.3.1" + } + } + } + } + } + "Deployable" + { + "CustomAction" + { + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "ExternalPersistence" + { + "LaunchCondition" + { + } + } + "File" + { + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_008B1BB47C0A46C0B025FDE5376533F4" + { + "SourcePath" = "8:..\\bin\\patches\\A08C4057.pnach" + "TargetName" = "8:A08C4057.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_00ABD03A61124E9F8BEC5E4D2D7F2715" + { + "SourcePath" = "8:..\\bin\\patches\\5E115FB6.pnach" + "TargetName" = "8:5E115FB6.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_03E75E8822CE48BFB4D8378A4FD3A9E8" + { + "SourcePath" = "8:..\\bin\\patches\\D48A92E1.pnach" + "TargetName" = "8:D48A92E1.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_0435A4202F22485295FC9B14FF9E0DEF" + { + "SourcePath" = "8:..\\bin\\patches\\60013EBD.pnach" + "TargetName" = "8:60013EBD.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_048B9870FB3E4278ADCB974F47D3AA3D" + { + "SourcePath" = "8:..\\bin\\patches\\71584BAC.pnach" + "TargetName" = "8:71584BAC.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_069D4ED441804E6F91F93A1BA01C21B8" + { + "SourcePath" = "8:..\\bin\\patches\\848C6247.pnach" + "TargetName" = "8:848C6247.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_072AB1B5BAC84646894F39D3E1BF092F" + { + "SourcePath" = "8:..\\bin\\patches\\3FB69323.pnach" + "TargetName" = "8:3FB69323.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_072B429763E648A2AFA3744F69B35FD8" + { + "SourcePath" = "8:..\\bin\\patches\\2251E14D.pnach" + "TargetName" = "8:2251E14D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_07B925C7C3DD4023870E4C350A933F01" + { + "SourcePath" = "8:..\\bin\\patches\\512B5046.pnach" + "TargetName" = "8:512B5046.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_086724BEF26C4B91964547A4ABCFC33D" + { + "SourcePath" = "8:..\\bin\\patches\\4043F228.pnach" + "TargetName" = "8:4043F228.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_094A3551F77548E28331D27415415CD4" + { + "SourcePath" = "8:..\\bin\\patches\\33F7D21A.pnach" + "TargetName" = "8:33F7D21A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_0953A3DB125D4969AA9CF0EAEE0174F8" + { + "SourcePath" = "8:..\\bin\\patches\\722BBD62.pnach" + "TargetName" = "8:722BBD62.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_0A01FDD1F6A54A43A900C9AC92D4B2D9" + { + "SourcePath" = "8:..\\bin\\patches\\96B2F56D.pnach" + "TargetName" = "8:96B2F56D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_0AA27B6457FC4913924E4F391F4581DC" + { + "SourcePath" = "8:..\\bin\\patches\\54D6BEE3.pnach" + "TargetName" = "8:54D6BEE3.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_0AB0A47469D44DC28C0973A8B295B919" + { + "SourcePath" = "8:..\\bin\\Langs\\ru_RU\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_69E3FE8CD77E49E3A2EB811D7CF5CE5C" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_0ACCF2C8B96C2712D1D5C59C66341354" + { + "SourcePath" = "8:DINPUT8.dll" + "TargetName" = "8:DINPUT8.dll" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_0C95C45CAB924AE2AC25800B164275B7" + { + "SourcePath" = "8:..\\bin\\Langs\\po_BR\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_9897A3C67AA44BBE97E0185B4254592E" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_0D6C5B8003914BC8B1F4C3EC09C58AB2" + { + "SourcePath" = "8:..\\bin\\patches\\2B2E1535.pnach" + "TargetName" = "8:2B2E1535.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_0E8BBD04D986469EA64F1A82EC4DB8FA" + { + "SourcePath" = "8:..\\bin\\patches\\337B927C.pnach" + "TargetName" = "8:337B927C.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1037D220B29040FDA7B60A0A9DA4865E" + { + "SourcePath" = "8:..\\bin\\patches\\9AAC530D.pnach" + "TargetName" = "8:9AAC530D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_110E08BF1DA04EF69BF2D475585D0500" + { + "SourcePath" = "8:..\\bin\\patches\\7130C553.pnach" + "TargetName" = "8:7130C553.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1320398166C4413FB4BF04DC2C1FD8EF" + { + "SourcePath" = "8:..\\bin\\patches\\B82E4C4B.pnach" + "TargetName" = "8:B82E4C4B.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_14A843D75DC34B599F3463074612476E" + { + "SourcePath" = "8:..\\bin\\patches\\7377BC6F.pnach" + "TargetName" = "8:7377BC6F.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_164C7824F6134DF3A56AF21FB50AE125" + { + "SourcePath" = "8:..\\bin\\patches\\AA31B5BF.pnach" + "TargetName" = "8:AA31B5BF.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1750E80E95EC4B128595AC231181C330" + { + "SourcePath" = "8:..\\bin\\patches\\7F6319C7.pnach" + "TargetName" = "8:7F6319C7.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_17EF52CE5F174F708988D3792C4EF1FE" + { + "SourcePath" = "8:..\\bin\\patches\\A74F99CD.pnach" + "TargetName" = "8:A74F99CD.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1969096EAD2A4292BA27BED98ACA17FB" + { + "SourcePath" = "8:..\\bin\\patches\\1468C474.pnach" + "TargetName" = "8:1468C474.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1B2AF463338C40B0AA1AE5F3149D343D" + { + "SourcePath" = "8:..\\bin\\patches\\163F0461.pnach" + "TargetName" = "8:163F0461.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1B7AD03818962FE68D82D1B4D4642FB6" + { + "SourcePath" = "8:MSVFW32.dll" + "TargetName" = "8:MSVFW32.dll" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1EF4CE3ED84F4057B2C26F87099AED66" + { + "SourcePath" = "8:..\\bin\\Langs\\cz_CZ\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_9BD92FDD1824471A943B71FB9DCC1BFC" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1FEA719F022CEAF9A269D43AD22AF93F" + { + "SourcePath" = "8:d3d9.dll" + "TargetName" = "8:d3d9.dll" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_223105795E5D49B8BD6AD93E12847151" + { + "SourcePath" = "8:..\\bin\\patches\\E906EA37.pnach" + "TargetName" = "8:E906EA37.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2286937AE4E6436F95D07AB1A588794C" + { + "SourcePath" = "8:..\\bin\\patches\\6ADBC24B.pnach" + "TargetName" = "8:6ADBC24B.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_22917529BC854387B3A9A7C7DF33EDAE" + { + "SourcePath" = "8:..\\bin\\patches\\EE838B5C.pnach" + "TargetName" = "8:EE838B5C.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_231B4CAAD95A4D5391BD2A27D1BEA77E" + { + "SourcePath" = "8:..\\bin\\patches\\DC85FC8F.pnach" + "TargetName" = "8:DC85FC8F.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2393441DF8524232AD40E46DF2640189" + { + "SourcePath" = "8:..\\bin\\patches\\015314A2.pnach" + "TargetName" = "8:015314A2.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_24AD39A905574544A69A1F67C0A3CB16" + { + "SourcePath" = "8:..\\bin\\patches\\F6F9A91D.pnach" + "TargetName" = "8:F6F9A91D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_24E2C7FDC2EC4816A9E3D2C1860E5A41" + { + "SourcePath" = "8:..\\bin\\patches\\8B0725D5.pnach" + "TargetName" = "8:8B0725D5.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_252DE06AE3874074A9070423E08DE75A" + { + "SourcePath" = "8:..\\bin\\Langs\\hb_HB\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_A01F7887979C490594F917213A282F1F" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_25A855DA124946CF878441F4673A48D0" + { + "SourcePath" = "8:..\\bin\\patches\\DDA2FA6A.pnach" + "TargetName" = "8:DDA2FA6A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2753983542094EB781E4AA2FC90CF0D4" + { + "SourcePath" = "8:..\\bin\\patches\\0518D275.pnach" + "TargetName" = "8:0518D275.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2806AFD2B45345C09E96EA1E139BE213" + { + "SourcePath" = "8:..\\bin\\patches\\E4A275B2.pnach" + "TargetName" = "8:E4A275B2.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_285DF38D8D4043129B7F2E2227603DB5" + { + "SourcePath" = "8:..\\bin\\patches\\6A4EFE60.pnach" + "TargetName" = "8:6A4EFE60.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2A2B73C24B1541B6A6B380B019877693" + { + "SourcePath" = "8:..\\bin\\patches\\D08648B6.pnach" + "TargetName" = "8:D08648B6.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2ADB9B378F3441FAA48C077E968E5929" + { + "SourcePath" = "8:..\\bin\\patches\\83261085.pnach" + "TargetName" = "8:83261085.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2BDA0576A7894E6481660D46B5A01437" + { + "SourcePath" = "8:..\\bin\\patches\\60FA8C69.pnach" + "TargetName" = "8:60FA8C69.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2E849B77EC5944D9A6C38F02C8D1125E" + { + "SourcePath" = "8:..\\bin\\patches\\C9C145BF.pnach" + "TargetName" = "8:C9C145BF.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3148F098C35140D2B38C9EAE570278C7" + { + "SourcePath" = "8:..\\bin\\patches\\DCC4EEEA.pnach" + "TargetName" = "8:DCC4EEEA.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_316BCBF5300B4931ACBC48DBC4935C7D" + { + "SourcePath" = "8:..\\bin\\Langs\\du_DU\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_9CC70A81B0B14388B8D25978A5DD64F3" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_32CF1A99F5714908AFDEF8B5686EB63E" + { + "SourcePath" = "8:..\\bin\\patches\\77ECAAA0.pnach" + "TargetName" = "8:77ECAAA0.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_33545BED81CC46E2B3D3406385AB4BAB" + { + "SourcePath" = "8:..\\bin\\Langs\\el_EL\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_F2C5FE6DB5FA46F0A9FC0113857E3A8C" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_344F82E4D0F14313831E11BF22926517" + { + "SourcePath" = "8:..\\bin\\Langs\\tr_TR\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_505652862F964FA8A185D0D9D41A3230" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_34FCB627708446FA998E61BC379C3274" + { + "SourcePath" = "8:..\\bin\\patches\\934F9081.pnach" + "TargetName" = "8:934F9081.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_35CF60C53FC643E8BD271C8F4F257F7F" + { + "SourcePath" = "8:..\\bin\\patches\\F6DC728D.pnach" + "TargetName" = "8:F6DC728D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_363B16784029465C9F2F27ED2544DFB2" + { + "SourcePath" = "8:..\\bin\\patches\\4D6DBB75.pnach" + "TargetName" = "8:4D6DBB75.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_368F66344EEB4252939476AE57FD170A" + { + "SourcePath" = "8:..\\bin\\patches\\3E68955A.pnach" + "TargetName" = "8:3E68955A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_385F635F391A45E7AF3C9ECCB8580BBB" + { + "SourcePath" = "8:..\\bin\\patches\\5A7635C1.pnach" + "TargetName" = "8:5A7635C1.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_389BF52BB2004C779C0B34C431B8DF6C" + { + "SourcePath" = "8:..\\bin\\patches\\96B76E56.pnach" + "TargetName" = "8:96B76E56.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_399D3AEE4A37416D8C89F4C87D4B2186" + { + "SourcePath" = "8:..\\bin\\patches\\333F1F59.pnach" + "TargetName" = "8:333F1F59.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_39C6B9B06D72499680F6F1AC6CB5BC41" + { + "SourcePath" = "8:..\\bin\\patches\\AFAC88EF.pnach" + "TargetName" = "8:AFAC88EF.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3C0AF639574546BF806A7C2967B84D64" + { + "SourcePath" = "8:..\\bin\\patches\\624F11F1.pnach" + "TargetName" = "8:624F11F1.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3D004382B4E34EBDA27EC6CB3542C77B" + { + "SourcePath" = "8:..\\bin\\patches\\951555A0.pnach" + "TargetName" = "8:951555A0.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3D0E6540B75342C983BD1B81A7D0687F" + { + "SourcePath" = "8:..\\bin\\patches\\692CBA8E.pnach" + "TargetName" = "8:692CBA8E.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3DE636877DB640AFBF78E771B6339E7B" + { + "SourcePath" = "8:..\\bin\\Langs\\fr_FR\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_AD3D7C491E3D4BFBB8E75C1EADBC803B" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_40AF38FA32E74704B11F107D51809D67" + { + "SourcePath" = "8:..\\bin\\patches\\3BD85DA4.pnach" + "TargetName" = "8:3BD85DA4.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_40D1B86DB6384BBC8642DCCF1C19EF44" + { + "SourcePath" = "8:..\\bin\\Langs\\po_PO\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_55ABDA310DAE41369F53B2CE8F57D600" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_410B722D4B1A40448CBAB425C76BB942" + { + "SourcePath" = "8:..\\bin\\patches\\E0127F2D.pnach" + "TargetName" = "8:E0127F2D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_439BE780DFAF488CAB0628CA9EE105C1" + { + "SourcePath" = "8:..\\bin\\patches\\B2BDE9F3.pnach" + "TargetName" = "8:B2BDE9F3.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_44610C616D8541A7AADF2A907D62CBC3" + { + "SourcePath" = "8:..\\bin\\patches\\4B6DDB6B.pnach" + "TargetName" = "8:4B6DDB6B.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_44BA53E81F0FD93AF224C5D26706AA36" + { + "SourcePath" = "8:DDRAW.dll" + "TargetName" = "8:DDRAW.dll" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_45B9B43F0312436EB21A3EE185196698" + { + "SourcePath" = "8:..\\bin\\patches\\2088950A.pnach" + "TargetName" = "8:2088950A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_45C9A622FD5C48778968D4FB6D6DF5A3" + { + "SourcePath" = "8:..\\bin\\patches\\B130E5BA.pnach" + "TargetName" = "8:B130E5BA.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_497B59E060004BDD8AA9C9117771CC9F" + { + "SourcePath" = "8:..\\bin\\patches\\013E349D.pnach" + "TargetName" = "8:013E349D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4C3F6AED1BC84C90867D52A478F93263" + { + "SourcePath" = "8:..\\bin\\patches\\A3ACF3C7.pnach" + "TargetName" = "8:A3ACF3C7.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4DA88C47D7F24AF98C9EA65B22E3963A" + { + "SourcePath" = "8:..\\bin\\patches\\5162BCCA.pnach" + "TargetName" = "8:5162BCCA.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4E78F6174A7940B1A434F71096AE6599" + { + "SourcePath" = "8:..\\bin\\patches\\32629F36.pnach" + "TargetName" = "8:32629F36.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5083DF2E71904EFD87DF275C566E4DA3" + { + "SourcePath" = "8:..\\bin\\patches\\8BE3D7B2.pnach" + "TargetName" = "8:8BE3D7B2.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5108D04A106F4BF0925ECDB0238858A0" + { + "SourcePath" = "8:..\\bin\\patches\\6D70F0E0.pnach" + "TargetName" = "8:6D70F0E0.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_519BA9151D974A46AB5AB56B0E4AA51F" + { + "SourcePath" = "8:..\\bin\\patches\\B234036E.pnach" + "TargetName" = "8:B234036E.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_52EBADEB628C495898A151D2C9DFCE84" + { + "SourcePath" = "8:..\\bin\\patches\\844B58EE.pnach" + "TargetName" = "8:844B58EE.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_55DD5447D0704C5BA1D4485FFCB12750" + { + "SourcePath" = "8:..\\bin\\patches\\0B359BBF.pnach" + "TargetName" = "8:0B359BBF.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_56740A2D926040FB9DAB02218AF22A12" + { + "SourcePath" = "8:..\\bin\\patches\\F56C7948.pnach" + "TargetName" = "8:F56C7948.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_56EC8A30479C4EC19744D5D61814D1EE" + { + "SourcePath" = "8:..\\bin\\patches\\C4467D30.pnach" + "TargetName" = "8:C4467D30.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5795B3AD60144867AAF76625BF8D12E6" + { + "SourcePath" = "8:..\\bin\\patches\\7FD7A1B9.pnach" + "TargetName" = "8:7FD7A1B9.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5816864CB37148EAA1B4E3694087D957" + { + "SourcePath" = "8:..\\bin\\patches\\09D35D3F.pnach" + "TargetName" = "8:09D35D3F.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_583A5A54C626479C895F30381B84C0A0" + { + "SourcePath" = "8:..\\bin\\patches\\93223BE4.pnach" + "TargetName" = "8:93223BE4.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5902179EF3C847EB89E23FF72968009A" + { + "SourcePath" = "8:..\\bin\\patches\\DA0535FD.pnach" + "TargetName" = "8:DA0535FD.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5ACDADD74B40457B83F1981EFAA7857D" + { + "SourcePath" = "8:..\\bin\\patches\\C04FB5FD.pnach" + "TargetName" = "8:C04FB5FD.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5BB0EB6C5231446AAC5204710D7B80AF" + { + "SourcePath" = "8:..\\bin\\patches\\1510E1D1.pnach" + "TargetName" = "8:1510E1D1.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5DA8B5994E0C45E389DCB5E6A78A606F" + { + "SourcePath" = "8:..\\bin\\patches\\1025D50A.pnach" + "TargetName" = "8:1025D50A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5FD67D7865EF469681C9064A909D284B" + { + "SourcePath" = "8:..\\bin\\patches\\85E92C92.pnach" + "TargetName" = "8:85E92C92.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_601A2EF5BC9E4E18847D198965955979" + { + "SourcePath" = "8:..\\bin\\patches\\116154AD.pnach" + "TargetName" = "8:116154AD.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_601C974367D84D838C6C6CC9A6B0EF12" + { + "SourcePath" = "8:..\\bin\\patches\\302797DF.pnach" + "TargetName" = "8:302797DF.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6159CD85FA674476A8500E4D4DBDE249" + { + "SourcePath" = "8:..\\bin\\Langs\\es_ES\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_F5073354FAFA4B98A39DCBA0BF8E855C" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6177B9D05A0A4128BE5E565074A64B8A" + { + "SourcePath" = "8:..\\bin\\patches\\3CFE3B37.pnach" + "TargetName" = "8:3CFE3B37.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6330D1F1B93B4ED782294CC53AE58C88" + { + "SourcePath" = "8:..\\bin\\patches\\F9E575D0.pnach" + "TargetName" = "8:F9E575D0.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_647EE324793341ECAF24A8ADE8855B94" + { + "SourcePath" = "8:..\\bin\\patches\\5EB127E7.pnach" + "TargetName" = "8:5EB127E7.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6843982E6E314D768F6CC5F102688B0E" + { + "SourcePath" = "8:..\\bin\\patches\\7EBEEBBD.pnach" + "TargetName" = "8:7EBEEBBD.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_69328962B15D4340A2F60B4AC76D1BE6" + { + "SourcePath" = "8:..\\bin\\patches\\7ABDBB5E.pnach" + "TargetName" = "8:7ABDBB5E.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6B65629ABA014116BCEFB83DAD553D16" + { + "SourcePath" = "8:..\\bin\\patches\\4C9EE7DF.pnach" + "TargetName" = "8:4C9EE7DF.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6CE23E7F518243C7BA141E1E65C168CC" + { + "SourcePath" = "8:..\\bin\\patches\\EF5B6AAD.pnach" + "TargetName" = "8:EF5B6AAD.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6E07916227C246EB9FBC73A4BE564BE6" + { + "SourcePath" = "8:..\\bin\\patches\\E1C5F607.pnach" + "TargetName" = "8:E1C5F607.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6F2EA43D6CB84A66ADD39614C2DB53ED" + { + "SourcePath" = "8:..\\bin\\patches\\41A3191C.pnach" + "TargetName" = "8:41A3191C.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6F5170ED41D34E2696B817A3C44F11D5" + { + "SourcePath" = "8:..\\bin\\patches\\9D6F46F0.pnach" + "TargetName" = "8:9D6F46F0.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6FB75A46740D4F2B9472C15B4E58AD88" + { + "SourcePath" = "8:..\\bin\\patches\\A88ACA28.pnach" + "TargetName" = "8:A88ACA28.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7064BEB3EECD4A94AEFA90955DA88FA7" + { + "SourcePath" = "8:..\\bin\\patches\\1D2818AF.pnach" + "TargetName" = "8:1D2818AF.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_718A74839C0D4897B1C66283597425E8" + { + "SourcePath" = "8:..\\bin\\patches\\E1FD9A2D.pnach" + "TargetName" = "8:E1FD9A2D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_71BE9607A7510034EDED2B591E6F981E" + { + "SourcePath" = "8:gnu_gettext.dll" + "TargetName" = "8:gnu_gettext.dll" + "Tag" = "8:" + "Folder" = "8:_A396E583ED3A43A5B9FA30BABB3624E2" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7274EADA979045C380198FDA59E37468" + { + "SourcePath" = "8:..\\bin\\patches\\EDD7E0FF.pnach" + "TargetName" = "8:EDD7E0FF.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_741FC4B6CB49412FAF2FD02903557840" + { + "SourcePath" = "8:..\\bin\\patches\\08FB9DCF.pnach" + "TargetName" = "8:08FB9DCF.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_76BB1C3A20244799AAEAC764389DB226" + { + "SourcePath" = "8:..\\bin\\patches\\0C370E94.pnach" + "TargetName" = "8:0C370E94.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_78792FEB009343479E361944DCAF9C36" + { + "SourcePath" = "8:..\\bin\\Langs\\sw_SW\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_0ACD0ED1DD734B27B3D547E45959012F" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_78F8BB67ADA242B1A949C41F909666E2" + { + "SourcePath" = "8:..\\bin\\patches\\200BC0E6.pnach" + "TargetName" = "8:200BC0E6.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_797C85AEE487426EA22D8B0253111FA3" + { + "SourcePath" = "8:..\\bin\\Langs\\pl_PL\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_39E58661BEE543E8A9B1269F2772FCAC" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7AB0994101C146EFA3493863882452B4" + { + "SourcePath" = "8:..\\bin\\patches\\625AF967.pnach" + "TargetName" = "8:625AF967.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7B327706377AE5F414299F6736D8EC00" + { + "SourcePath" = "8:DSOUND.dll" + "TargetName" = "8:DSOUND.dll" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7C0CEAF559A84A0C8723C9328DBADDAE" + { + "SourcePath" = "8:..\\bin\\patches\\0A342A88.pnach" + "TargetName" = "8:0A342A88.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7C346BC46D0B44BAB4750A35B70A0B46" + { + "SourcePath" = "8:..\\bin\\patches\\B0AE1898.pnach" + "TargetName" = "8:B0AE1898.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7D493307EEB847228F6CCEEE90D42DAA" + { + "SourcePath" = "8:..\\bin\\patches\\C1767D64.pnach" + "TargetName" = "8:C1767D64.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7E94D0A6FD0E48C8A7B7D8421F4D2DE6" + { + "SourcePath" = "8:..\\bin\\patches\\A36CFF6C.pnach" + "TargetName" = "8:A36CFF6C.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7EA7534B81A9415D89174750F58D27A2" + { + "SourcePath" = "8:..\\bin\\patches\\36FEEE3A.pnach" + "TargetName" = "8:36FEEE3A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7EDF89CE07114545909E655CC5567735" + { + "SourcePath" = "8:..\\bin\\patches\\7D8F539A.pnach" + "TargetName" = "8:7D8F539A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7FF341438FB64A7A9A22CD9B9839C63C" + { + "SourcePath" = "8:..\\bin\\patches\\789D6B71.pnach" + "TargetName" = "8:789D6B71.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8196C46459C542B1A8EC49445C14472F" + { + "SourcePath" = "8:..\\bin\\patches\\B884B6E9.pnach" + "TargetName" = "8:B884B6E9.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_81D9FBCB8E3D4952A47B9BC4B2567BB2" + { + "SourcePath" = "8:..\\bin\\patches\\582EED0D.pnach" + "TargetName" = "8:582EED0D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_83305974B07F42C18E0AE99DBBF15037" + { + "SourcePath" = "8:..\\bin\\patches\\F22CDDAF.pnach" + "TargetName" = "8:F22CDDAF.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_84F3D3D23A1447339492C40CC699DD44" + { + "SourcePath" = "8:..\\bin\\patches\\default.xml" + "TargetName" = "8:default.xml" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8743DB62D7EF4D72A820BAEC30E97DEC" + { + "SourcePath" = "8:..\\bin\\Langs\\sh_SH\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_786BE5E01902493590964C4D4F509C2D" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_87D6D4E907CB469280556CA51B5737E7" + { + "SourcePath" = "8:..\\bin\\Langs\\ja_JA\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_DA9C9F5B385A448D97EE2AD52304A4FD" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_88207E3137E2456C8D63EEB045A495E7" + { + "SourcePath" = "8:..\\bin\\Langs\\bg_BG\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_F8763ACD40584CDAA0688B4AEA98D07E" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8835232945DD4F2C8333D0E2CACA9DF8" + { + "SourcePath" = "8:..\\bin\\patches\\E7A35274.pnach" + "TargetName" = "8:E7A35274.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8897C560DD094D698EA4A9B88C98D0A6" + { + "SourcePath" = "8:..\\bin\\patches\\62F6F886.pnach" + "TargetName" = "8:62F6F886.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_88FCE1823EA04CF8B1FE816A1A0E1E3B" + { + "SourcePath" = "8:..\\bin\\patches\\AD9D2B54.pnach" + "TargetName" = "8:AD9D2B54.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_89BA174439B14C8F8FA942C9E150B718" + { + "SourcePath" = "8:..\\bin\\patches\\F1370E83.pnach" + "TargetName" = "8:F1370E83.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8AB21318425441BA811D919F6DC5D6E8" + { + "SourcePath" = "8:..\\bin\\patches\\83D0CE43.pnach" + "TargetName" = "8:83D0CE43.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8AC15EDDB6994E7794DBA7A0A3DCA60B" + { + "SourcePath" = "8:..\\bin\\patches\\38F29E28.pnach" + "TargetName" = "8:38F29E28.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8C0EC3CEAEB04DE7B6729EBBCE8C0B36" + { + "SourcePath" = "8:..\\bin\\patches\\F266B00B.pnach" + "TargetName" = "8:F266B00B.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8CF26805EE71422CBC1C152A7462FE44" + { + "SourcePath" = "8:..\\bin\\patches\\B1BE3E51.pnach" + "TargetName" = "8:B1BE3E51.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8E3C8EAC49BD49EE886229B91DF16166" + { + "SourcePath" = "8:..\\bin\\patches\\06DE61E0.pnach" + "TargetName" = "8:06DE61E0.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8E909C0BE4C942A7804FF65AD2DDAFB5" + { + "SourcePath" = "8:..\\bin\\patches\\54AD76D7.pnach" + "TargetName" = "8:54AD76D7.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8F39494E0D4C4FF091091DAF5183388D" + { + "SourcePath" = "8:..\\bin\\patches\\49DA19CE.pnach" + "TargetName" = "8:49DA19CE.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_90ED9EDA4346456F8957D9E7EB0D8DD9" + { + "SourcePath" = "8:..\\bin\\patches\\CB4EBD11.pnach" + "TargetName" = "8:CB4EBD11.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_91C427E57A3B48F399BAA6AF4A588293" + { + "SourcePath" = "8:..\\bin\\patches\\6926B199.pnach" + "TargetName" = "8:6926B199.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_924E5E9E11C245D383CFFA77545B69FE" + { + "SourcePath" = "8:..\\bin\\patches\\46A7ECA4.pnach" + "TargetName" = "8:46A7ECA4.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_9356233C1CB34B1E8F0781EA7188920C" + { + "SourcePath" = "8:..\\bin\\patches\\05177ECE.pnach" + "TargetName" = "8:05177ECE.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_94DA87D95C7E4D009C9FFF2F647405C2" + { + "SourcePath" = "8:..\\bin\\patches\\D03BEF2A.pnach" + "TargetName" = "8:D03BEF2A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_95AA28E96394481AB463DEF29FAA78F8" + { + "SourcePath" = "8:..\\bin\\patches\\A8083AE6.pnach" + "TargetName" = "8:A8083AE6.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_9636D19CCBD441D993A061FDE5FF7807" + { + "SourcePath" = "8:..\\bin\\patches\\D0E17D26.pnach" + "TargetName" = "8:D0E17D26.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_96AB009303B44C2CB19C172EB5D51CE2" + { + "SourcePath" = "8:..\\bin\\patches\\C1625F14.pnach" + "TargetName" = "8:C1625F14.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_98FAE27F8FDB404098DC9E605F753E0D" + { + "SourcePath" = "8:..\\bin\\patches\\48FE0C71.pnach" + "TargetName" = "8:48FE0C71.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_99C23BC9B7C5EEDB5AD1079051D199C3" + { + "SourcePath" = "8:AVIFIL32.dll" + "TargetName" = "8:AVIFIL32.dll" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_9C7D1B3E93F0481E804E68339BBEB021" + { + "SourcePath" = "8:..\\bin\\patches\\506644B3.pnach" + "TargetName" = "8:506644B3.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_9D1F177B2FFA4D3D84F11A8A20D1F611" + { + "SourcePath" = "8:..\\bin\\patches\\4C4D7072.pnach" + "TargetName" = "8:4C4D7072.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_9E96BFE206504BFEBF955CA9CBA846DC" + { + "SourcePath" = "8:..\\bin\\patches\\8BC95883.pnach" + "TargetName" = "8:8BC95883.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A2652446B2604985A24F992F42F2761E" + { + "SourcePath" = "8:..\\bin\\patches\\DEFA4763.pnach" + "TargetName" = "8:DEFA4763.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A28EBA4DE8914C988801F829035FFEC8" + { + "SourcePath" = "8:..\\bin\\patches\\3EAD47FE.pnach" + "TargetName" = "8:3EAD47FE.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A3D55F63E0484B52BD23FBF66915D43D" + { + "SourcePath" = "8:..\\bin\\patches\\E138094A.pnach" + "TargetName" = "8:E138094A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A40F34AB634C48D7B953C2E420915F07" + { + "SourcePath" = "8:..\\bin\\patches\\95BB1901.pnach" + "TargetName" = "8:95BB1901.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A89761474AC748AE931002EE5E581284" + { + "SourcePath" = "8:..\\bin\\Langs\\pe_PE\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_5FC81602C55A4975B87E5712B58A9781" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A8F09DC7C504415BA06801BA7C5D750B" + { + "SourcePath" = "8:..\\bin\\patches\\C5DEFEA0.pnach" + "TargetName" = "8:C5DEFEA0.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_AAB10625A4634D85821952D2CD42642B" + { + "SourcePath" = "8:..\\bin\\patches\\561BE340.pnach" + "TargetName" = "8:561BE340.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_AB28BFBD30FC423293D42423F112B6BD" + { + "SourcePath" = "8:..\\bin\\patches\\A7A2F7C5.pnach" + "TargetName" = "8:A7A2F7C5.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_ADAC04E54F894404A83B379617E7A97E" + { + "SourcePath" = "8:..\\bin\\patches\\94C56923.pnach" + "TargetName" = "8:94C56923.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_ADE00C6618D141C49F057DA07B235947" + { + "SourcePath" = "8:..\\bin\\patches\\A1B752C7.pnach" + "TargetName" = "8:A1B752C7.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_ADE37DD61B5347DB890F2957492F3745" + { + "SourcePath" = "8:..\\bin\\patches\\9BE3F92D.pnach" + "TargetName" = "8:9BE3F92D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_AEB84272F38444F5BB708EF3E0833776" + { + "SourcePath" = "8:..\\bin\\patches\\A8A76AAC.pnach" + "TargetName" = "8:A8A76AAC.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_AF7C7BE64EA846468642088F15DA4A1F" + { + "SourcePath" = "8:..\\bin\\patches\\BF5D9AEC.pnach" + "TargetName" = "8:BF5D9AEC.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B2A5C84577F64477896DD21845527BD0" + { + "SourcePath" = "8:..\\bin\\patches\\1248FE3A.pnach" + "TargetName" = "8:1248FE3A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B2F1836277ED493C958A02184D327E49" + { + "SourcePath" = "8:..\\bin\\patches\\1CAC8A56.pnach" + "TargetName" = "8:1CAC8A56.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B4A1253749E245B088BD031A677CFB4A" + { + "SourcePath" = "8:..\\bin\\patches\\5CCA0737.pnach" + "TargetName" = "8:5CCA0737.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B50F62EC90CD4A07912A63B90AAD3293" + { + "SourcePath" = "8:..\\bin\\patches\\51F91783.pnach" + "TargetName" = "8:51F91783.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B63084B7B255496B836164646F5D536D" + { + "SourcePath" = "8:..\\bin\\patches\\B338676A.pnach" + "TargetName" = "8:B338676A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B8FEC8F89AD14BE5AF941C226AAA31AF" + { + "SourcePath" = "8:..\\bin\\patches\\3F0452DE.pnach" + "TargetName" = "8:3F0452DE.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B90FC469B0A7444AA681C869AB6704D4" + { + "SourcePath" = "8:..\\bin\\patches\\901AAC09.pnach" + "TargetName" = "8:901AAC09.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BC30361C69EF4CD8869553D0AF1CA80A" + { + "SourcePath" = "8:..\\bin\\patches\\CA6243B9.pnach" + "TargetName" = "8:CA6243B9.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BCED2304BC124DC79A400E6EC3DF991A" + { + "SourcePath" = "8:..\\bin\\Langs\\de_DE\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_E5D304DFDDC94899A964648DA33FFEF3" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BD602A7A1C334F74815A52DF4C98D0CD" + { + "SourcePath" = "8:..\\bin\\patches\\4D228733.pnach" + "TargetName" = "8:4D228733.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BDA20A14A241440B8632ABEBC26E35DB" + { + "SourcePath" = "8:..\\bin\\patches\\2F56CBC9.pnach" + "TargetName" = "8:2F56CBC9.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BFE971F656CA46C7A298C91757E9AFF7" + { + "SourcePath" = "8:..\\bin\\patches\\086273D2.pnach" + "TargetName" = "8:086273D2.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C047CC641D1E4EAF9CF3032B69B49C46" + { + "SourcePath" = "8:..\\bin\\patches\\44A61C8F.pnach" + "TargetName" = "8:44A61C8F.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C10D7A1FC3A44F749156F781C6DB3140" + { + "SourcePath" = "8:..\\bin\\patches\\C502AD6E.pnach" + "TargetName" = "8:C502AD6E.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C188D42682084A7D983722A92046C3EA" + { + "SourcePath" = "8:..\\bin\\patches\\C398F477.pnach" + "TargetName" = "8:C398F477.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C40BE5E85657415296E733A2F29C985A" + { + "SourcePath" = "8:..\\bin\\patches\\A5BF36A8.pnach" + "TargetName" = "8:A5BF36A8.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C46C31F5523D72D416CDEF1804E2A64D" + { + "SourcePath" = "8:d3dx9_41.dll" + "TargetName" = "8:d3dx9_41.dll" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C555162941C34AE1B51CE4CB5352CD4E" + { + "SourcePath" = "8:..\\bin\\patches\\93F8A60B.pnach" + "TargetName" = "8:93F8A60B.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C77702CF400646678BD9CC9242B1B6BB" + { + "SourcePath" = "8:..\\bin\\patches\\78168525.pnach" + "TargetName" = "8:78168525.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C80AC3C16BED483D8228AFA835D7F15F" + { + "SourcePath" = "8:..\\bin\\patches\\4C0C821D.pnach" + "TargetName" = "8:4C0C821D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C82D0E331C0F4C368F91EE2A7BD0565D" + { + "SourcePath" = "8:..\\bin\\patches\\BB3D833A.pnach" + "TargetName" = "8:BB3D833A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C980F539DB294419AE3FC77C33A77AEF" + { + "SourcePath" = "8:..\\bin\\patches\\D4781770.pnach" + "TargetName" = "8:D4781770.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CCDA5668BC2E426E9E05F8875B752536" + { + "SourcePath" = "8:..\\bin\\patches\\6BA2F6B9.pnach" + "TargetName" = "8:6BA2F6B9.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CDAA2F2C190A4DCB928E78564F76BCA3" + { + "SourcePath" = "8:..\\bin\\patches\\6175FE7D.pnach" + "TargetName" = "8:6175FE7D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CE6A0F7079024AF4A0933BB7F9BFE195" + { + "SourcePath" = "8:..\\bin\\patches\\68EAF48F.pnach" + "TargetName" = "8:68EAF48F.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D11A044D40114C19A0FDA835B19D37AF" + { + "SourcePath" = "8:..\\bin\\Langs\\ar_AR\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_B3FF9E06585E4D588B8A11F45580C9C3" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D21F33B9B9CA4F28996FF4CB02872772" + { + "SourcePath" = "8:..\\bin\\patches\\22C36E63.pnach" + "TargetName" = "8:22C36E63.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D2474D58E6AC4CA0A5FCEF9B4BA6B3E4" + { + "SourcePath" = "8:..\\bin\\patches\\C220951A.pnach" + "TargetName" = "8:C220951A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D31ED5CC46194EA6A81F9F9BE3DE5CD1" + { + "SourcePath" = "8:..\\bin\\Langs\\sw_SW\\LC_MESSAGES\\other.po" + "TargetName" = "8:other.po" + "Tag" = "8:" + "Folder" = "8:_0ACD0ED1DD734B27B3D547E45959012F" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D4219ACEADB94026AA93732F128494E3" + { + "SourcePath" = "8:..\\bin\\patches\\25433CBD.pnach" + "TargetName" = "8:25433CBD.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D738FF1390814B24A9021A19F95E4290" + { + "SourcePath" = "8:..\\bin\\patches\\304C115C.pnach" + "TargetName" = "8:304C115C.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D81E0DB3F5674742AB46156B10CCC968" + { + "SourcePath" = "8:..\\bin\\patches\\D4FB6049.pnach" + "TargetName" = "8:D4FB6049.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D92503794DA8471A8BFE082269932306" + { + "SourcePath" = "8:..\\bin\\patches\\C488EC04.pnach" + "TargetName" = "8:C488EC04.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D980AD62DE974BABA15438FF6ACFA8BF" + { + "SourcePath" = "8:..\\bin\\patches\\B99379B7.pnach" + "TargetName" = "8:B99379B7.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DAC88B65E7EB4A8E92FBF82174072D28" + { + "SourcePath" = "8:..\\bin\\patches\\E0DADD1A.pnach" + "TargetName" = "8:E0DADD1A.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DB95F4450EFC4AAE94E1A2EDE746B2B2" + { + "SourcePath" = "8:..\\bin\\patches\\F52FB2BE.pnach" + "TargetName" = "8:F52FB2BE.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DBB4560AE2924E349948FA5BB09FE28E" + { + "SourcePath" = "8:..\\bin\\patches\\B0621C55.pnach" + "TargetName" = "8:B0621C55.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DCA1A5B0C13D49259445C449B0E50774" + { + "SourcePath" = "8:..\\bin\\Langs\\it_IT\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_E70A733A717B4988B3240BB9AA27F6FF" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DD150D2502704E67A072908310DB66F3" + { + "SourcePath" = "8:..\\bin\\patches\\37BA81B1.pnach" + "TargetName" = "8:37BA81B1.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DFE2B52C9EDF48DA81BC3E67D6564B0D" + { + "SourcePath" = "8:..\\bin\\patches\\0518D274.pnach" + "TargetName" = "8:0518D274.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E02F836E90974BFC8E673705BE975E95" + { + "SourcePath" = "8:..\\bin\\patches\\08901101.pnach" + "TargetName" = "8:08901101.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E09F4497BBF14351A2528D6E215DE28D" + { + "SourcePath" = "8:..\\bin\\patches\\129C8600.pnach" + "TargetName" = "8:129C8600.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E0E1B281255A4DC5934647A82D674F99" + { + "SourcePath" = "8:..\\bin\\Langs\\tc_TC\\LC_MESSAGES\\Pcsx2.mo" + "TargetName" = "8:Pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_99D64C98017D4A65B91D7963D17E86FA" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E17B0DADA8FC4512A4888DE697BC75B3" + { + "SourcePath" = "8:..\\bin\\patches\\F4992CC1.pnach" + "TargetName" = "8:F4992CC1.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E508524696DD452E91B739C7EC466374" + { + "SourcePath" = "8:..\\bin\\patches\\FA7E3081.pnach" + "TargetName" = "8:FA7E3081.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E6DE12DF8D434183B93158C458D72A61" + { + "SourcePath" = "8:..\\bin\\Langs\\ro_RO\\LC_MESSAGES\\pcsx2.mo" + "TargetName" = "8:pcsx2.mo" + "Tag" = "8:" + "Folder" = "8:_E02BBD7427474F9694A1DF1FB22A8895" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E71C997965964853BA87889843181711" + { + "SourcePath" = "8:..\\bin\\patches\\EEC3B310.pnach" + "TargetName" = "8:EEC3B310.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_ECC63C4CBBE44D568436E4312BA47908" + { + "SourcePath" = "8:..\\bin\\patches\\EEE2F6A3.pnach" + "TargetName" = "8:EEE2F6A3.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_ECD3190AB8F14933A35236EC20488C61" + { + "SourcePath" = "8:..\\bin\\patches\\0F6B6315.pnach" + "TargetName" = "8:0F6B6315.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_EEECC8B200772D4A9F89A5F65A3B97F5" + { + "SourcePath" = "8:XINPUT1_3.dll" + "TargetName" = "8:XINPUT1_3.dll" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F00371D156F84024BD88562FE8C9DDBF" + { + "SourcePath" = "8:..\\bin\\patches\\9B1EE9EB.pnach" + "TargetName" = "8:9B1EE9EB.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F165D6BEADEC6B529C157DDC87667E80" + { + "SourcePath" = "8:w32pthreads.dll" + "TargetName" = "8:w32pthreads.dll" + "Tag" = "8:" + "Folder" = "8:_A396E583ED3A43A5B9FA30BABB3624E2" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F1A181FCDB444332B63B8E51A4EBD448" + { + "SourcePath" = "8:..\\bin\\patches\\4334E17D.pnach" + "TargetName" = "8:4334E17D.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F29E17EBECD5437C9244B842F5038BB1" + { + "SourcePath" = "8:..\\bin\\patches\\E2F1DB6B.pnach" + "TargetName" = "8:E2F1DB6B.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F43E0A4CFF22404996751E7EE5CFC3DE" + { + "SourcePath" = "8:..\\bin\\patches\\AE3EAA05.pnach" + "TargetName" = "8:AE3EAA05.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F58D989DCC40429EBC0C9D43AF5D8BA1" + { + "SourcePath" = "8:..\\bin\\patches\\2C728173.pnach" + "TargetName" = "8:2C728173.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F6AF071E4E7F4C6CBB28DCDAA6A711C3" + { + "SourcePath" = "8:..\\bin\\patches\\54A548B4.pnach" + "TargetName" = "8:54A548B4.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F72D772B69424F28A3E406E8BCD1878B" + { + "SourcePath" = "8:..\\bin\\patches\\37C07E96.pnach" + "TargetName" = "8:37C07E96.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F84D270966164BAAA768673FDACED3CC" + { + "SourcePath" = "8:..\\bin\\patches\\21068223.pnach" + "TargetName" = "8:21068223.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F9276AD7A6E840C59B3B10CD18910D35" + { + "SourcePath" = "8:..\\bin\\patches\\4F3D3CF0.pnach" + "TargetName" = "8:4F3D3CF0.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FBBAFABEF4884CCA881660F376B5F6FE" + { + "SourcePath" = "8:..\\bin\\patches\\A929A697.pnach" + "TargetName" = "8:A929A697.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FCB2559A1E524CAFA362E24808358B68" + { + "SourcePath" = "8:..\\bin\\patches\\53A803AF.pnach" + "TargetName" = "8:53A803AF.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FD481E6914D27724507EE8D2A4BD4317" + { + "SourcePath" = "8:COMDLG32.dll" + "TargetName" = "8:COMDLG32.dll" + "Tag" = "8:" + "Folder" = "8:_A396E583ED3A43A5B9FA30BABB3624E2" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FF64089169014510AEEBB6F516BFE6D5" + { + "SourcePath" = "8:..\\bin\\patches\\5D67AE48.pnach" + "TargetName" = "8:5D67AE48.pnach" + "Tag" = "8:" + "Folder" = "8:_42F0D922DB0247BBA7D42CB69E6D5400" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + } + "FileType" + { + } + "Folder" + { + "{1525181F-901A-416C-8A58-119130FE478E}:_1CC7E5F7B7C54D23B46312D224266D8C" + { + "Name" = "8:#1919" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramMenuFolder" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_E300D7C3BDA3486FB06E51133B66D4E1" + { + "Name" = "8:PCSX2" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_937B5B2246954BEDB9591CDC327FE5C9" + "Folders" + { + } + } + } + } + "{3C67513D-01DD-4637-8A68-80971EB9504F}:_A396E583ED3A43A5B9FA30BABB3624E2" + { + "DefaultLocation" = "8:[ProgramFilesFolder]\\[ProductName]" + "Name" = "8:#1925" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:TARGETDIR" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_014811CAEAEB4185970A168C81A1ED74" + { + "Name" = "8:logs" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_8C9D12333A374565810ED53F3DDB6307" + "Folders" + { + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_42F0D922DB0247BBA7D42CB69E6D5400" + { + "Name" = "8:patches" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_39491FF8D00B405ABBCF623C423C3706" + "Folders" + { + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_77B443E882584CD681951231FB62CE80" + { + "Name" = "8:sstates" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_606A26E38EEE43C9B6024A46B166F77E" + "Folders" + { + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_7C3FE59FCC0B42FEBEE4701735A879FE" + { + "Name" = "8:Langs" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_69C5D6C711284F54862E1DCCE1D39677" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_01E5C277DD3A4D2AAC51FF70DA6EACBC" + { + "Name" = "8:ro_RO" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_00D97AE40B1445C4AC739BE9A3A40F9F" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_E02BBD7427474F9694A1DF1FB22A8895" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_37346A03E6BF409D962F7245FA86485E" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_0375038C7EE94DB69A1B5BD3BEA63414" + { + "Name" = "8:ru_RU" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_23F859C61BA14E058D26AC0407809D24" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_69E3FE8CD77E49E3A2EB811D7CF5CE5C" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_C6CEE0A81B6342C49DB255189171D622" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_12F57131366E48D7AE8C3052284F2CC6" + { + "Name" = "8:de_DE" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_9DC5B716B1F94558B631096B522E612A" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_E5D304DFDDC94899A964648DA33FFEF3" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_40F4E1964E1F4E12913C9E322849803B" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_13215CA21F634E4D9F89278325AB2D45" + { + "Name" = "8:cz_CZ" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_2AEF36B647EB42EDAAC31A4430ADAFB5" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_9BD92FDD1824471A943B71FB9DCC1BFC" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_78DE886B198144D686203DF423CBEB25" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_1B6BF74437BB4656913901B077447932" + { + "Name" = "8:pl_PL" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_93E4ABB80D104722A06D46372F5F0B7D" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_39E58661BEE543E8A9B1269F2772FCAC" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_3592C8EA69B347F58E48DC87927015B9" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_29FDA1B03B384E3886ED0DF01CA52628" + { + "Name" = "8:it_IT" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_128E740C64A54F829BA06BFDDF1DA4F4" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_E70A733A717B4988B3240BB9AA27F6FF" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_0E5E136C177A4C5D8457872BE45800F0" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_2C97937778D84B9D9F02BC2A2BD043FE" + { + "Name" = "8:fr_FR" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_77525F538BFE46008149951F429B0962" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_AD3D7C491E3D4BFBB8E75C1EADBC803B" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_C6FDF64B1C5A4E62AA8CCBCAB2E9F01E" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_341257C7E02D4489B500EDEB99C6F69A" + { + "Name" = "8:bg_BG" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_D356EA34D59E468B9ED1B322A23905AC" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_F8763ACD40584CDAA0688B4AEA98D07E" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_878B28ED17DB458D823AC94A2FBBDE8B" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_35F59014F8FC4A418EBE02D1A197EA95" + { + "Name" = "8:sw_SW" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_8BEDC2CAA1784C4DA4C00219D64CC850" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_0ACD0ED1DD734B27B3D547E45959012F" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_7FCA640A69F34A6195965B35C3EE3C61" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_53AD5871B9CE4B1AA2A7B22C26580AC4" + { + "Name" = "8:du_DU" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_0E6E870B542C4AAAA1666ED2A348929F" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_9CC70A81B0B14388B8D25978A5DD64F3" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_406AD541D6D24B54BB3E0F8D6DCDFE59" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_600DE4749F964660B825DE8F0B1D3A39" + { + "Name" = "8:tc_TC" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_920D80C27CD44707A9807BC401509352" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_99D64C98017D4A65B91D7963D17E86FA" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_4BB57A6FD6CC45F58CE460CD91111E4B" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_63DB12B5020A4AE08B1226111EB1784E" + { + "Name" = "8:ja_JA" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_BAB1ABDAB2804E91AB54628C0C14F303" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_DA9C9F5B385A448D97EE2AD52304A4FD" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_BC4A8D79D934484CB3BAA421C1DA7C3E" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_67D1D8C22FC54E47A53B4F97C0750579" + { + "Name" = "8:tr_TR" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_D8BBA1D7C7794FEEAA43C629BEC0E920" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_505652862F964FA8A185D0D9D41A3230" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_B275CAB5021A4B8DA52544FCC72E5C52" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_8257D6D3F9894A66B674E1BB13965416" + { + "Name" = "8:ar_AR" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_B610BA080427409B99A4B1D194ACB932" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_B3FF9E06585E4D588B8A11F45580C9C3" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_B6EFD7FC80DA4AE2A8B97CEAB01A77D3" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_A86B4CC44D074516BC0A63FD16BE0D95" + { + "Name" = "8:el_EL" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_E70901717A93433BB85F18256D2EA521" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_F2C5FE6DB5FA46F0A9FC0113857E3A8C" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_6F5119CD1C8A400D9F37BEBB78B8881D" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_B0AE05F92A7643A9B0052585D2923C4C" + { + "Name" = "8:hb_HB" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_CBB815C7D64B41669421C0B6A4E95DC3" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_A01F7887979C490594F917213A282F1F" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_47A561F855604038B02A54400AC54E3F" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_B79BDDA4FC514DB5AFC6159D9036EC31" + { + "Name" = "8:es_ES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_EF2B6BED8451489CA4DC0024401CE2F9" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_F5073354FAFA4B98A39DCBA0BF8E855C" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_FE5FAED3D1194AB4A1EE2D084927B610" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_C5A2C746AA6D4354863D922CDEBCE64D" + { + "Name" = "8:po_PO" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_C59F3B557DE94F9290727FF5EC4F49DC" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_55ABDA310DAE41369F53B2CE8F57D600" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_BCC71DFD8CD349E4BA59513735BFB20A" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_D8A893634F3D4FF9ADFD5E90D268368B" + { + "Name" = "8:po_BR" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_BB33A7058CFF4AF0B4F51142A32C18EE" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_9897A3C67AA44BBE97E0185B4254592E" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_ACBB3399C60F4F67982AE20908306DF2" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_DFFFD1AA546D4113B4256394D9EDE18C" + { + "Name" = "8:pe_PE" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_3001EEE762B84344AEF624CA462126D9" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_5FC81602C55A4975B87E5712B58A9781" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_ECA0410CCBC341959FA8077B5AA7968F" + "Folders" + { + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_F7E2422FFFC44DE9967655C490059E5C" + { + "Name" = "8:sh_SH" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_B9D4503F02964148948D0631F229943E" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_786BE5E01902493590964C4D4F509C2D" + { + "Name" = "8:LC_MESSAGES" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_23A1137251D947CCA6D2DAAF2D3E30DD" + "Folders" + { + } + } + } + } + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_DC69079E129741279361C7BB41BD02B0" + { + "Name" = "8:bios" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_6B5CAF6B23284313A8CB8813D576EBAC" + "Folders" + { + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_E07A974E375F4483BCD3CC8498531D07" + { + "Name" = "8:memcards" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_DD9C448983C04D4783914AE575FF02CA" + "Folders" + { + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_E975DFF5F10D4FDAA6B20DC31EA09815" + { + "Name" = "8:snaps" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_89562EA6C29F407BB0BEE902A037F606" + "Folders" + { + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_ECA4F63E52E54881A027E3FC5951CA6C" + { + "Name" = "8:inis" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_E116C83ED8D84AAEB47B5A408F799D2F" + "Folders" + { + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_F71F199B36BB443EA7E2B933AB80A864" + { + "Name" = "8:plugins" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_92852504E779471CAE3CA0D77F1C4783" + "Folders" + { + } + } + "{9EF0B969-E518-4E46-987F-47570745A589}:_FB5424B7E79743A895E3D51F52960CBA" + { + "Name" = "8:help" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_8703BE3B14694560A140812516440BC3" + "Folders" + { + } + } + } + } + "{1525181F-901A-416C-8A58-119130FE478E}:_B365E41F28F44C7AB0EE737177C6C411" + { + "Name" = "8:#1916" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:DesktopFolder" + "Folders" + { + } + } + } + "LaunchCondition" + { + } + "Locator" + { + } + "MsiBootstrapper" + { + "LangId" = "3:1033" + "RequiresElevation" = "11:FALSE" + } + "Product" + { + "Name" = "8:Microsoft Visual Studio" + "ProductName" = "8:PCSX2" + "ProductCode" = "8:{06D2A88C-85BA-4D97-8B6E-551B9DC899E1}" + "PackageCode" = "8:{319F53C1-4C70-4547-8A0D-1750F488911F}" + "UpgradeCode" = "8:{5237A49B-FA2E-47C4-8C0E-92338FDC9F2A}" + "RestartWWWService" = "11:FALSE" + "RemovePreviousVersions" = "11:FALSE" + "DetectNewerInstalledVersion" = "11:TRUE" + "InstallAllUsers" = "11:TRUE" + "ProductVersion" = "8:0.9.7" + "Manufacturer" = "8:PCSX2 Team" + "ARPHELPTELEPHONE" = "8:" + "ARPHELPLINK" = "8:" + "Title" = "8:PCSX2 Installer" + "Subject" = "8:Playstation 2 Emulator" + "ARPCONTACT" = "8:PCSX2 Team" + "Keywords" = "8:PCSX2 PS2 Playstation Emulation Emulator" + "ARPCOMMENTS" = "8:PCSX2 and Standard Plugins" + "ARPURLINFOABOUT" = "8:http://www.pcsx2.net/" + "ARPPRODUCTICON" = "8:" + "ARPIconIndex" = "3:0" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + "TargetPlatform" = "3:0" + "PreBuildEvent" = "8:" + "PostBuildEvent" = "8:" + "RunPostBuildEvent" = "3:0" + } + "Registry" + { + "HKLM" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_6882F198BAB640B6AD08A6BECF58E3D7" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_C54E3A3195AE4A7FBC022E0BC47E4D68" + { + "Name" = "8:[ProductName]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCU" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_22486194D8CD463F988309CB9F0107B4" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_54C3FD07DA564F13AEBFBAC3BD00C177" + { + "Name" = "8:[ProductName]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Sequences" + { + } + "Shortcut" + { + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_02FAB38531424815A087F986117B6FE4" + { + "Name" = "8:Launch PCSX2" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:108" + "Transitive" = "11:FALSE" + "Target" = "8:_25EDB5C49F2745F199D2CF1036A1207F" + "Folder" = "8:_E300D7C3BDA3486FB06E51133B66D4E1" + "WorkingFolder" = "8:_A396E583ED3A43A5B9FA30BABB3624E2" + "Icon" = "8:_25EDB5C49F2745F199D2CF1036A1207F" + "Feature" = "8:" + } + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_88585802FA764221B23F7188426E6149" + { + "Name" = "8:Uninstall" + "Arguments" = "8:-uninstall [ProductCode]" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:181" + "Transitive" = "11:FALSE" + "Target" = "8:_25EDB5C49F2745F199D2CF1036A1207F" + "Folder" = "8:_E300D7C3BDA3486FB06E51133B66D4E1" + "WorkingFolder" = "8:_A396E583ED3A43A5B9FA30BABB3624E2" + "Icon" = "8:_25EDB5C49F2745F199D2CF1036A1207F" + "Feature" = "8:" + } + } + "UserInterface" + { + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_164CCCD439A8443BB90559A98C4FB040" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_EB23FCF744D04D3F993AA38170892364" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_1B05E4ADE5B7462C8882B361A92D43F6" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_02B0B3DEE0E24A2EA9AA49CB9EE852D5" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_05F82266935D48A58EF00221BFB7F2DB" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "InstallAllUsersVisible" + { + "Name" = "8:InstallAllUsersVisible" + "DisplayName" = "8:#1059" + "Description" = "8:#1159" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_BDE372154ACA4397B8C8B894383AEC27" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:2" + "Value" = "8:Notice: This program falls under some copyleft mumbo-jumbo, more commonly known as the GNU Public License." + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:2" + "Value" = "8:This program will install [ProductName] [Version] and other plugins and components necessary to run [ProductName]." + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_2F9CC5ECB1154884A43A02233FBF9341" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_268033CD1B624867BE2204F9D72A01C7" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_3917D03E774F41ECBB6F4F1249F5041F" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_D6FFAAB0491E47F3B937CBF1776F1F46" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_437AA19BBC474D798EA2DFBF39541EF2" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_E65D6D6A1B734FACB48486AC24563007" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_9B161DDC7E8C4646B8A552A3C0E7800D" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdBasicDialogs.wim" + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_BE376581223F44D897DC3B1F64C3A1F0" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdUserInterface.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_DE3984E5630E441B90E24E37E4582512" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_CDE15B688B694C199796F4F79142C7E9" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_E760CC89C72C433DAF145D583FF290D1" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_0D8EBD1B57DC42909BECF186E12F29E7" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + } + "ProjectOutput" + { + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_1430E155AE5F4B92A78B32E05FEAF3EF" + { + "SourcePath" = "8:..\\bin\\plugins\\DEV9null.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{04439C5F-05FB-4A9C-AAD1-5388C25377DB}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_1FA9731E400641839E29839952B10A67" + { + "SourcePath" = "8:..\\bin\\plugins\\GSdx-SSSE3.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release SSSE3|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{18E42F6F-3A62-41EE-B42F-79366C4F1E95}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_25EDB5C49F2745F199D2CF1036A1207F" + { + "SourcePath" = "8:..\\bin\\pcsx2.exe" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_A396E583ED3A43A5B9FA30BABB3624E2" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_600402FDB5064D0B82810CB4E6DBEEA1" + { + "SourcePath" = "8:..\\bin\\plugins\\USBnull.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_6827AD9625DF4C39A8A0E39FB82E3CD0" + { + "SourcePath" = "8:..\\bin\\plugins\\ZeroGS.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_8037556EAB9F4BF298A6AA2BDA834930" + { + "SourcePath" = "8:..\\bin\\plugins\\GSdx-SSE2.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release SSE2|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{18E42F6F-3A62-41EE-B42F-79366C4F1E95}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_87A61D50A0B944458FE3B315A47FA221" + { + "SourcePath" = "8:..\\bin\\plugins\\SPU2-X.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_882694E02F0649F29ADA794E68DA525C" + { + "SourcePath" = "8:..\\bin\\plugins\\LilyPad.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{E4081455-398C-4610-A87C-90A8A7D72DC3}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_9AB559EE78054703AF56D8E7744F3806" + { + "SourcePath" = "8:..\\bin\\plugins\\CDVDolio.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{FCDF5AE2-EA47-4CC6-9F20-23A0517FEBCB}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_A22B625A9A0E4580B7976E1C76B13D93" + { + "SourcePath" = "8:..\\bin\\plugins\\FWnull.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{3D0EB14D-32F3-4D82-9C6D-B806ADBB859C}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_A3F76D4DE92743659E861547FE69DE1F" + { + "SourcePath" = "8:..\\bin\\w32pthreads.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_A396E583ED3A43A5B9FA30BABB3624E2" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{26511268-2902-4997-8421-ECD7055F9E28}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_AF4D152A202841D2BF769FBDF5CEB413" + { + "SourcePath" = "8:..\\bin\\plugins\\CDVDiso.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_BA8C69F1D2364A2E9268819F2A8085FB" + { + "SourcePath" = "8:..\\bin\\plugins\\xpad.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{6F3C4136-5801-4EBC-AC6E-37DF6FAB150A}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_C28E286C209D4FBCBBF1FD46837E0854" + { + "SourcePath" = "8:..\\bin\\plugins\\ZeroPAD.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{CDD9DB83-3BD9-4ED8-BB83-399A2F65F022}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_C5FEBD35C45E4EAE824FD02E9F023FD0" + { + "SourcePath" = "8:..\\bin\\plugins\\GSdx-SSE4.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Vital" = "11:FALSE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release SSE4|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{18E42F6F-3A62-41EE-B42F-79366C4F1E95}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_E663A731DB91460B991DAA889BD480EE" + { + "SourcePath" = "8:..\\bin\\plugins\\ZeroSPU2.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F71F199B36BB443EA7E2B933AB80A864" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:Release|Win32" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{7F059854-568D-4E08-9D00-1E78E203E4DC}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + } + } +}