Set svn:eol-style=native on all *.c *.cpp *.h

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2894 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
sudonim1 2010-04-24 21:37:39 +00:00
parent 6cb4d35e50
commit a05e9c62be
208 changed files with 53558 additions and 53558 deletions

View File

@ -1,7 +1,7 @@
#ifndef SOUNDTOUCH_CONFIG_H_INCLUDED
#define SOUNDTOUCH_CONFIG_H_INCLUDED
#endif // SOUNDTOUCH_CONFIG_H_INCLUDED
#ifndef SOUNDTOUCH_CONFIG_H_INCLUDED
#define SOUNDTOUCH_CONFIG_H_INCLUDED
#endif // SOUNDTOUCH_CONFIG_H_INCLUDED

View File

@ -1,101 +1,101 @@
#ifndef PA_WIN_DS_H
#define PA_WIN_DS_H
/*
* $Id: $
* PortAudio Portable Real-Time Audio Library
* DirectSound specific extensions
*
* Copyright (c) 1999-2007 Ross Bencina and Phil Burk
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup public_header
@brief DirectSound-specific PortAudio API extension header file.
*/
#include "portaudio.h"
#include "pa_win_waveformat.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#define paWinDirectSoundUseLowLevelLatencyParameters (0x01)
#define paWinDirectSoundUseChannelMask (0x04)
typedef struct PaWinDirectSoundStreamInfo{
unsigned long size; /**< sizeof(PaWinDirectSoundStreamInfo) */
PaHostApiTypeId hostApiType; /**< paDirectSound */
unsigned long version; /**< 1 */
unsigned long flags;
/* low-level latency setting support
TODO ** NOT IMPLEMENTED **
These settings control the number and size of host buffers in order
to set latency. They will be used instead of the generic parameters
to Pa_OpenStream() if flags contains the paWinDirectSoundUseLowLevelLatencyParameters
flag.
If PaWinDirectSoundStreamInfo structures with paWinDirectSoundUseLowLevelLatencyParameters
are supplied for both input and output in a full duplex stream, then the
input and output framesPerBuffer must be the same, or the larger of the
two must be a multiple of the smaller, otherwise a
paIncompatibleHostApiSpecificStreamInfo error will be returned from
Pa_OpenStream().
unsigned long framesPerBuffer;
*/
/*
support for WAVEFORMATEXTENSIBLE channel masks. If flags contains
paWinDirectSoundUseChannelMask this allows you to specify which speakers
to address in a multichannel stream. Constants for channelMask
are specified in pa_win_waveformat.h
*/
PaWinWaveFormatChannelMask channelMask;
}PaWinDirectSoundStreamInfo;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_WIN_DS_H */
#ifndef PA_WIN_DS_H
#define PA_WIN_DS_H
/*
* $Id: $
* PortAudio Portable Real-Time Audio Library
* DirectSound specific extensions
*
* Copyright (c) 1999-2007 Ross Bencina and Phil Burk
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup public_header
@brief DirectSound-specific PortAudio API extension header file.
*/
#include "portaudio.h"
#include "pa_win_waveformat.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#define paWinDirectSoundUseLowLevelLatencyParameters (0x01)
#define paWinDirectSoundUseChannelMask (0x04)
typedef struct PaWinDirectSoundStreamInfo{
unsigned long size; /**< sizeof(PaWinDirectSoundStreamInfo) */
PaHostApiTypeId hostApiType; /**< paDirectSound */
unsigned long version; /**< 1 */
unsigned long flags;
/* low-level latency setting support
TODO ** NOT IMPLEMENTED **
These settings control the number and size of host buffers in order
to set latency. They will be used instead of the generic parameters
to Pa_OpenStream() if flags contains the paWinDirectSoundUseLowLevelLatencyParameters
flag.
If PaWinDirectSoundStreamInfo structures with paWinDirectSoundUseLowLevelLatencyParameters
are supplied for both input and output in a full duplex stream, then the
input and output framesPerBuffer must be the same, or the larger of the
two must be a multiple of the smaller, otherwise a
paIncompatibleHostApiSpecificStreamInfo error will be returned from
Pa_OpenStream().
unsigned long framesPerBuffer;
*/
/*
support for WAVEFORMATEXTENSIBLE channel masks. If flags contains
paWinDirectSoundUseChannelMask this allows you to specify which speakers
to address in a multichannel stream. Constants for channelMask
are specified in pa_win_waveformat.h
*/
PaWinWaveFormatChannelMask channelMask;
}PaWinDirectSoundStreamInfo;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_WIN_DS_H */

View File

@ -1,268 +1,268 @@
#ifndef PA_WIN_WASAPI_H
#define PA_WIN_WASAPI_H
/*
* $Id: $
* PortAudio Portable Real-Time Audio Library
* DirectSound specific extensions
*
* Copyright (c) 1999-2007 Ross Bencina and Phil Burk
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup public_header
@brief WASAPI-specific PortAudio API extension header file.
*/
#include "portaudio.h"
#include "pa_win_waveformat.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/* Setup flags */
typedef enum PaWasapiFlags
{
/* puts WASAPI into exclusive mode */
paWinWasapiExclusive = (1 << 0),
/* allows to skip internal PA processing completely */
paWinWasapiRedirectHostProcessor = (1 << 1),
/* assigns custom channel mask */
paWinWasapiUseChannelMask = (1 << 2),
/* selects non-Event driven method of data read/write
Note: WASAPI Event driven core is capable of 2ms latency!!!, but Polling
method can only provide 15-20ms latency. */
paWinWasapiPolling = (1 << 3),
/* forces custom thread priority setting. must be used if PaWasapiStreamInfo::threadPriority
is set to custom value. */
paWinWasapiThreadPriority = (1 << 4)
}
PaWasapiFlags;
#define paWinWasapiExclusive (paWinWasapiExclusive)
#define paWinWasapiRedirectHostProcessor (paWinWasapiRedirectHostProcessor)
#define paWinWasapiUseChannelMask (paWinWasapiUseChannelMask)
#define paWinWasapiPolling (paWinWasapiPolling)
#define paWinWasapiThreadPriority (paWinWasapiThreadPriority)
/* Host processor. Allows to skip internal PA processing completely.
You must set paWinWasapiRedirectHostProcessor flag to PaWasapiStreamInfo::flags member
in order to have host processor redirected to your callback.
Use with caution! inputFrames and outputFrames depend solely on final device setup (buffer
size is just recommendation) but are not changing during run-time once stream is started.
*/
typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer, long inputFrames,
void *outputBuffer, long outputFrames,
void *userData);
/* Device role */
typedef enum PaWasapiDeviceRole
{
eRoleRemoteNetworkDevice = 0,
eRoleSpeakers,
eRoleLineLevel,
eRoleHeadphones,
eRoleMicrophone,
eRoleHeadset,
eRoleHandset,
eRoleUnknownDigitalPassthrough,
eRoleSPDIF,
eRoleHDMI,
eRoleUnknownFormFactor
}
PaWasapiDeviceRole;
/* Thread priority */
typedef enum PaWasapiThreadPriority
{
eThreadPriorityNone = 0,
eThreadPriorityAudio, //!< Default for Shared mode.
eThreadPriorityCapture,
eThreadPriorityDistribution,
eThreadPriorityGames,
eThreadPriorityPlayback,
eThreadPriorityProAudio, //!< Default for Exclusive mode.
eThreadPriorityWindowManager
}
PaWasapiThreadPriority;
/* Stream descriptor. */
typedef struct PaWasapiStreamInfo
{
unsigned long size; /**< sizeof(PaWasapiStreamInfo) */
PaHostApiTypeId hostApiType; /**< paWASAPI */
unsigned long version; /**< 1 */
unsigned long flags; /**< collection of PaWasapiFlags */
/* Support for WAVEFORMATEXTENSIBLE channel masks. If flags contains
paWinWasapiUseChannelMask this allows you to specify which speakers
to address in a multichannel stream. Constants for channelMask
are specified in pa_win_waveformat.h. Will be used only if
paWinWasapiUseChannelMask flag is specified.
*/
PaWinWaveFormatChannelMask channelMask;
/* Delivers raw data to callback obtained from GetBuffer() methods skipping
internal PortAudio processing inventory completely. userData parameter will
be the same that was passed to Pa_OpenStream method. Will be used only if
paWinWasapiRedirectHostProcessor flag is specified.
*/
PaWasapiHostProcessorCallback hostProcessorOutput;
PaWasapiHostProcessorCallback hostProcessorInput;
/* Specifies thread priority explicitly. Will be used only if paWinWasapiThreadPriority flag
is specified.
Please note, if Input/Output streams are opened simultaniously (Full-Duplex mode)
you shall specify same value for threadPriority or othervise one of the values will be used
to setup thread priority.
*/
PaWasapiThreadPriority threadPriority;
}
PaWasapiStreamInfo;
/** Returns default sound format for device. Format is represented by PaWinWaveFormat or
WAVEFORMATEXTENSIBLE structure.
@param pFormat pointer to PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure.
@param nFormatSize pize of PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure in bytes.
@param nDevice device index.
@return A non-negative value indicating the number of bytes copied into format decriptor
or, a PaErrorCode (which are always negative) if PortAudio is not initialized
or an error is encountered.
*/
int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice );
/** Returns device role (PaWasapiDeviceRole enum).
@param nDevice device index.
@return A non-negative value indicating device role or, a PaErrorCode (which are always negative)
if PortAudio is not initialized or an error is encountered.
*/
int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex nDevice );
/** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread
which makes calls to Pa_WriteStream/Pa_ReadStream.
@param hTask a handle to pointer to priority task. Must be used with PaWasapi_RevertThreadPriority
method to revert thread priority to initial state.
@param nPriorityClass an Id of thread priority of PaWasapiThreadPriority type. Specifying
eThreadPriorityNone does nothing.
@return Error code indicating success or failure.
@see PaWasapi_RevertThreadPriority
*/
PaError PaWasapi_ThreadPriorityBoost( void **hTask, PaWasapiThreadPriority nPriorityClass );
/** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread
which makes calls to Pa_WriteStream/Pa_ReadStream.
@param hTask Task handle obtained by PaWasapi_BoostThreadPriority method.
@return Error code indicating success or failure.
@see PaWasapi_BoostThreadPriority
*/
PaError PaWasapi_ThreadPriorityRevert( void *hTask );
/*
IMPORTANT:
WASAPI is implemented for Callback and Blocking interfaces. It supports Shared and Exclusive
share modes.
Exclusive Mode:
Exclusive mode allows to deliver audio data directly to hardware bypassing
software mixing.
Exclusive mode is specified by 'paWinWasapiExclusive' flag.
Callback Interface:
Provides best audio quality with low latency. Callback interface is implemented in
two versions:
1) Event-Driven:
This is the most powerful WASAPI implementation which is capable to provides glitch-free
audio at 2ms latency in Exclusive mode. Lowest possible latency for this mode is
usually - 2ms for HD Audio class audio chips (including on-board audio, 2ms was achieved
on Realtek ALC888/S/T). For Shared mode latency can not go lower than 20ms.
2) Poll-Driven:
Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven
and provides latency at around 12-13ms. Polling must be used to overcome a system bug
under Windows Vista x64 when application is WOW64(32-bit) and Event-Driven method simply times
out (event handle is never signalled on buffer completion). Please note, such Vista bug
does not exist in Windows 7 x64.
Polling is setup by speciying 'paWinWasapiPolling' flag.
Thread priority can be boosted by specifying 'paWinWasapiBlockingThreadPriorityPro' flag.
Blocking Interface:
Blocking interface is implemented but due to above described Poll-Driven method can not
deliver low latency audio. Specifying too low latency in Shared mode will result in
distorted audio although Exclusive mode adds stability.
Pa_IsFormatSupported:
To check format with correct Share Mode (Exclusive/Shared) you must supply
PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
PaStreamParameters::hostApiSpecificStreamInfo structure.
Pa_OpenStream:
To set desired Share Mode (Exclusive/Shared) you must supply
PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
PaStreamParameters::hostApiSpecificStreamInfo structure.
*/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_WIN_WASAPI_H */
#ifndef PA_WIN_WASAPI_H
#define PA_WIN_WASAPI_H
/*
* $Id: $
* PortAudio Portable Real-Time Audio Library
* DirectSound specific extensions
*
* Copyright (c) 1999-2007 Ross Bencina and Phil Burk
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup public_header
@brief WASAPI-specific PortAudio API extension header file.
*/
#include "portaudio.h"
#include "pa_win_waveformat.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/* Setup flags */
typedef enum PaWasapiFlags
{
/* puts WASAPI into exclusive mode */
paWinWasapiExclusive = (1 << 0),
/* allows to skip internal PA processing completely */
paWinWasapiRedirectHostProcessor = (1 << 1),
/* assigns custom channel mask */
paWinWasapiUseChannelMask = (1 << 2),
/* selects non-Event driven method of data read/write
Note: WASAPI Event driven core is capable of 2ms latency!!!, but Polling
method can only provide 15-20ms latency. */
paWinWasapiPolling = (1 << 3),
/* forces custom thread priority setting. must be used if PaWasapiStreamInfo::threadPriority
is set to custom value. */
paWinWasapiThreadPriority = (1 << 4)
}
PaWasapiFlags;
#define paWinWasapiExclusive (paWinWasapiExclusive)
#define paWinWasapiRedirectHostProcessor (paWinWasapiRedirectHostProcessor)
#define paWinWasapiUseChannelMask (paWinWasapiUseChannelMask)
#define paWinWasapiPolling (paWinWasapiPolling)
#define paWinWasapiThreadPriority (paWinWasapiThreadPriority)
/* Host processor. Allows to skip internal PA processing completely.
You must set paWinWasapiRedirectHostProcessor flag to PaWasapiStreamInfo::flags member
in order to have host processor redirected to your callback.
Use with caution! inputFrames and outputFrames depend solely on final device setup (buffer
size is just recommendation) but are not changing during run-time once stream is started.
*/
typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer, long inputFrames,
void *outputBuffer, long outputFrames,
void *userData);
/* Device role */
typedef enum PaWasapiDeviceRole
{
eRoleRemoteNetworkDevice = 0,
eRoleSpeakers,
eRoleLineLevel,
eRoleHeadphones,
eRoleMicrophone,
eRoleHeadset,
eRoleHandset,
eRoleUnknownDigitalPassthrough,
eRoleSPDIF,
eRoleHDMI,
eRoleUnknownFormFactor
}
PaWasapiDeviceRole;
/* Thread priority */
typedef enum PaWasapiThreadPriority
{
eThreadPriorityNone = 0,
eThreadPriorityAudio, //!< Default for Shared mode.
eThreadPriorityCapture,
eThreadPriorityDistribution,
eThreadPriorityGames,
eThreadPriorityPlayback,
eThreadPriorityProAudio, //!< Default for Exclusive mode.
eThreadPriorityWindowManager
}
PaWasapiThreadPriority;
/* Stream descriptor. */
typedef struct PaWasapiStreamInfo
{
unsigned long size; /**< sizeof(PaWasapiStreamInfo) */
PaHostApiTypeId hostApiType; /**< paWASAPI */
unsigned long version; /**< 1 */
unsigned long flags; /**< collection of PaWasapiFlags */
/* Support for WAVEFORMATEXTENSIBLE channel masks. If flags contains
paWinWasapiUseChannelMask this allows you to specify which speakers
to address in a multichannel stream. Constants for channelMask
are specified in pa_win_waveformat.h. Will be used only if
paWinWasapiUseChannelMask flag is specified.
*/
PaWinWaveFormatChannelMask channelMask;
/* Delivers raw data to callback obtained from GetBuffer() methods skipping
internal PortAudio processing inventory completely. userData parameter will
be the same that was passed to Pa_OpenStream method. Will be used only if
paWinWasapiRedirectHostProcessor flag is specified.
*/
PaWasapiHostProcessorCallback hostProcessorOutput;
PaWasapiHostProcessorCallback hostProcessorInput;
/* Specifies thread priority explicitly. Will be used only if paWinWasapiThreadPriority flag
is specified.
Please note, if Input/Output streams are opened simultaniously (Full-Duplex mode)
you shall specify same value for threadPriority or othervise one of the values will be used
to setup thread priority.
*/
PaWasapiThreadPriority threadPriority;
}
PaWasapiStreamInfo;
/** Returns default sound format for device. Format is represented by PaWinWaveFormat or
WAVEFORMATEXTENSIBLE structure.
@param pFormat pointer to PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure.
@param nFormatSize pize of PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure in bytes.
@param nDevice device index.
@return A non-negative value indicating the number of bytes copied into format decriptor
or, a PaErrorCode (which are always negative) if PortAudio is not initialized
or an error is encountered.
*/
int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice );
/** Returns device role (PaWasapiDeviceRole enum).
@param nDevice device index.
@return A non-negative value indicating device role or, a PaErrorCode (which are always negative)
if PortAudio is not initialized or an error is encountered.
*/
int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex nDevice );
/** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread
which makes calls to Pa_WriteStream/Pa_ReadStream.
@param hTask a handle to pointer to priority task. Must be used with PaWasapi_RevertThreadPriority
method to revert thread priority to initial state.
@param nPriorityClass an Id of thread priority of PaWasapiThreadPriority type. Specifying
eThreadPriorityNone does nothing.
@return Error code indicating success or failure.
@see PaWasapi_RevertThreadPriority
*/
PaError PaWasapi_ThreadPriorityBoost( void **hTask, PaWasapiThreadPriority nPriorityClass );
/** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread
which makes calls to Pa_WriteStream/Pa_ReadStream.
@param hTask Task handle obtained by PaWasapi_BoostThreadPriority method.
@return Error code indicating success or failure.
@see PaWasapi_BoostThreadPriority
*/
PaError PaWasapi_ThreadPriorityRevert( void *hTask );
/*
IMPORTANT:
WASAPI is implemented for Callback and Blocking interfaces. It supports Shared and Exclusive
share modes.
Exclusive Mode:
Exclusive mode allows to deliver audio data directly to hardware bypassing
software mixing.
Exclusive mode is specified by 'paWinWasapiExclusive' flag.
Callback Interface:
Provides best audio quality with low latency. Callback interface is implemented in
two versions:
1) Event-Driven:
This is the most powerful WASAPI implementation which is capable to provides glitch-free
audio at 2ms latency in Exclusive mode. Lowest possible latency for this mode is
usually - 2ms for HD Audio class audio chips (including on-board audio, 2ms was achieved
on Realtek ALC888/S/T). For Shared mode latency can not go lower than 20ms.
2) Poll-Driven:
Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven
and provides latency at around 12-13ms. Polling must be used to overcome a system bug
under Windows Vista x64 when application is WOW64(32-bit) and Event-Driven method simply times
out (event handle is never signalled on buffer completion). Please note, such Vista bug
does not exist in Windows 7 x64.
Polling is setup by speciying 'paWinWasapiPolling' flag.
Thread priority can be boosted by specifying 'paWinWasapiBlockingThreadPriorityPro' flag.
Blocking Interface:
Blocking interface is implemented but due to above described Poll-Driven method can not
deliver low latency audio. Specifying too low latency in Shared mode will result in
distorted audio although Exclusive mode adds stability.
Pa_IsFormatSupported:
To check format with correct Share Mode (Exclusive/Shared) you must supply
PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
PaStreamParameters::hostApiSpecificStreamInfo structure.
Pa_OpenStream:
To set desired Share Mode (Exclusive/Shared) you must supply
PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
PaStreamParameters::hostApiSpecificStreamInfo structure.
*/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_WIN_WASAPI_H */

View File

@ -1,199 +1,199 @@
#ifndef PA_WIN_WAVEFORMAT_H
#define PA_WIN_WAVEFORMAT_H
/*
* PortAudio Portable Real-Time Audio Library
* Windows WAVEFORMAT* data structure utilities
* portaudio.h should be included before this file.
*
* Copyright (c) 2007 Ross Bencina
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup public_header
@brief Windows specific PortAudio API extension and utilities header file.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
The following #defines for speaker channel masks are the same
as those in ksmedia.h, except with PAWIN_ prepended, KSAUDIO_ removed
in some cases, and casts to PaWinWaveFormatChannelMask added.
*/
typedef unsigned long PaWinWaveFormatChannelMask;
/* Speaker Positions: */
#define PAWIN_SPEAKER_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1)
#define PAWIN_SPEAKER_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x2)
#define PAWIN_SPEAKER_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x4)
#define PAWIN_SPEAKER_LOW_FREQUENCY ((PaWinWaveFormatChannelMask)0x8)
#define PAWIN_SPEAKER_BACK_LEFT ((PaWinWaveFormatChannelMask)0x10)
#define PAWIN_SPEAKER_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20)
#define PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER ((PaWinWaveFormatChannelMask)0x40)
#define PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER ((PaWinWaveFormatChannelMask)0x80)
#define PAWIN_SPEAKER_BACK_CENTER ((PaWinWaveFormatChannelMask)0x100)
#define PAWIN_SPEAKER_SIDE_LEFT ((PaWinWaveFormatChannelMask)0x200)
#define PAWIN_SPEAKER_SIDE_RIGHT ((PaWinWaveFormatChannelMask)0x400)
#define PAWIN_SPEAKER_TOP_CENTER ((PaWinWaveFormatChannelMask)0x800)
#define PAWIN_SPEAKER_TOP_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1000)
#define PAWIN_SPEAKER_TOP_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x2000)
#define PAWIN_SPEAKER_TOP_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x4000)
#define PAWIN_SPEAKER_TOP_BACK_LEFT ((PaWinWaveFormatChannelMask)0x8000)
#define PAWIN_SPEAKER_TOP_BACK_CENTER ((PaWinWaveFormatChannelMask)0x10000)
#define PAWIN_SPEAKER_TOP_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20000)
/* Bit mask locations reserved for future use */
#define PAWIN_SPEAKER_RESERVED ((PaWinWaveFormatChannelMask)0x7FFC0000)
/* Used to specify that any possible permutation of speaker configurations */
#define PAWIN_SPEAKER_ALL ((PaWinWaveFormatChannelMask)0x80000000)
/* DirectSound Speaker Config */
#define PAWIN_SPEAKER_DIRECTOUT 0
#define PAWIN_SPEAKER_MONO (PAWIN_SPEAKER_FRONT_CENTER)
#define PAWIN_SPEAKER_STEREO (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT)
#define PAWIN_SPEAKER_QUAD (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT)
#define PAWIN_SPEAKER_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_BACK_CENTER)
#define PAWIN_SPEAKER_5POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \
PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT)
#define PAWIN_SPEAKER_7POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \
PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \
PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER | PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER)
#define PAWIN_SPEAKER_5POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \
PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT)
#define PAWIN_SPEAKER_7POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \
PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \
PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT)
/*
According to the Microsoft documentation:
The following are obsolete 5.1 and 7.1 settings (they lack side speakers). Note this means
that the default 5.1 and 7.1 settings (KSAUDIO_SPEAKER_5POINT1 and KSAUDIO_SPEAKER_7POINT1 are
similarly obsolete but are unchanged for compatibility reasons).
*/
#define PAWIN_SPEAKER_5POINT1_BACK PAWIN_SPEAKER_5POINT1
#define PAWIN_SPEAKER_7POINT1_WIDE PAWIN_SPEAKER_7POINT1
/* DVD Speaker Positions */
#define PAWIN_SPEAKER_GROUND_FRONT_LEFT PAWIN_SPEAKER_FRONT_LEFT
#define PAWIN_SPEAKER_GROUND_FRONT_CENTER PAWIN_SPEAKER_FRONT_CENTER
#define PAWIN_SPEAKER_GROUND_FRONT_RIGHT PAWIN_SPEAKER_FRONT_RIGHT
#define PAWIN_SPEAKER_GROUND_REAR_LEFT PAWIN_SPEAKER_BACK_LEFT
#define PAWIN_SPEAKER_GROUND_REAR_RIGHT PAWIN_SPEAKER_BACK_RIGHT
#define PAWIN_SPEAKER_TOP_MIDDLE PAWIN_SPEAKER_TOP_CENTER
#define PAWIN_SPEAKER_SUPER_WOOFER PAWIN_SPEAKER_LOW_FREQUENCY
/*
PaWinWaveFormat is defined here to provide compatibility with
compilation environments which don't have headers defining
WAVEFORMATEXTENSIBLE (e.g. older versions of MSVC, Borland C++ etc.
The fields for WAVEFORMATEX and WAVEFORMATEXTENSIBLE are declared as an
unsigned char array here to avoid clients who include this file having
a dependency on windows.h and mmsystem.h, and also to to avoid having
to write separate packing pragmas for each compiler.
*/
#define PAWIN_SIZEOF_WAVEFORMATEX 18
#define PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE (PAWIN_SIZEOF_WAVEFORMATEX + 22)
typedef struct{
unsigned char fields[ PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE ];
unsigned long extraLongForAlignment; /* ensure that compiler aligns struct to DWORD */
} PaWinWaveFormat;
/*
WAVEFORMATEXTENSIBLE fields:
union {
WORD wValidBitsPerSample;
WORD wSamplesPerBlock;
WORD wReserved;
} Samples;
DWORD dwChannelMask;
GUID SubFormat;
*/
#define PAWIN_INDEXOF_WVALIDBITSPERSAMPLE (PAWIN_SIZEOF_WAVEFORMATEX+0)
#define PAWIN_INDEXOF_DWCHANNELMASK (PAWIN_SIZEOF_WAVEFORMATEX+2)
#define PAWIN_INDEXOF_SUBFORMAT (PAWIN_SIZEOF_WAVEFORMATEX+6)
/*
Valid values to pass for the waveFormatTag PaWin_InitializeWaveFormatEx and
PaWin_InitializeWaveFormatExtensible functions below. These must match
the standard Windows WAVE_FORMAT_* values.
*/
#define PAWIN_WAVE_FORMAT_PCM (1)
#define PAWIN_WAVE_FORMAT_IEEE_FLOAT (3)
#define PAWIN_WAVE_FORMAT_DOLBY_AC3_SPDIF (0x0092)
#define PAWIN_WAVE_FORMAT_WMA_SPDIF (0x0164)
/*
returns PAWIN_WAVE_FORMAT_PCM or PAWIN_WAVE_FORMAT_IEEE_FLOAT
depending on the sampleFormat parameter.
*/
int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat );
/*
Use the following two functions to initialize the waveformat structure.
*/
void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate );
void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate,
PaWinWaveFormatChannelMask channelMask );
/* Map a channel count to a speaker channel mask */
PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#ifndef PA_WIN_WAVEFORMAT_H
#define PA_WIN_WAVEFORMAT_H
/*
* PortAudio Portable Real-Time Audio Library
* Windows WAVEFORMAT* data structure utilities
* portaudio.h should be included before this file.
*
* Copyright (c) 2007 Ross Bencina
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup public_header
@brief Windows specific PortAudio API extension and utilities header file.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
The following #defines for speaker channel masks are the same
as those in ksmedia.h, except with PAWIN_ prepended, KSAUDIO_ removed
in some cases, and casts to PaWinWaveFormatChannelMask added.
*/
typedef unsigned long PaWinWaveFormatChannelMask;
/* Speaker Positions: */
#define PAWIN_SPEAKER_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1)
#define PAWIN_SPEAKER_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x2)
#define PAWIN_SPEAKER_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x4)
#define PAWIN_SPEAKER_LOW_FREQUENCY ((PaWinWaveFormatChannelMask)0x8)
#define PAWIN_SPEAKER_BACK_LEFT ((PaWinWaveFormatChannelMask)0x10)
#define PAWIN_SPEAKER_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20)
#define PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER ((PaWinWaveFormatChannelMask)0x40)
#define PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER ((PaWinWaveFormatChannelMask)0x80)
#define PAWIN_SPEAKER_BACK_CENTER ((PaWinWaveFormatChannelMask)0x100)
#define PAWIN_SPEAKER_SIDE_LEFT ((PaWinWaveFormatChannelMask)0x200)
#define PAWIN_SPEAKER_SIDE_RIGHT ((PaWinWaveFormatChannelMask)0x400)
#define PAWIN_SPEAKER_TOP_CENTER ((PaWinWaveFormatChannelMask)0x800)
#define PAWIN_SPEAKER_TOP_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1000)
#define PAWIN_SPEAKER_TOP_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x2000)
#define PAWIN_SPEAKER_TOP_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x4000)
#define PAWIN_SPEAKER_TOP_BACK_LEFT ((PaWinWaveFormatChannelMask)0x8000)
#define PAWIN_SPEAKER_TOP_BACK_CENTER ((PaWinWaveFormatChannelMask)0x10000)
#define PAWIN_SPEAKER_TOP_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20000)
/* Bit mask locations reserved for future use */
#define PAWIN_SPEAKER_RESERVED ((PaWinWaveFormatChannelMask)0x7FFC0000)
/* Used to specify that any possible permutation of speaker configurations */
#define PAWIN_SPEAKER_ALL ((PaWinWaveFormatChannelMask)0x80000000)
/* DirectSound Speaker Config */
#define PAWIN_SPEAKER_DIRECTOUT 0
#define PAWIN_SPEAKER_MONO (PAWIN_SPEAKER_FRONT_CENTER)
#define PAWIN_SPEAKER_STEREO (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT)
#define PAWIN_SPEAKER_QUAD (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT)
#define PAWIN_SPEAKER_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_BACK_CENTER)
#define PAWIN_SPEAKER_5POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \
PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT)
#define PAWIN_SPEAKER_7POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \
PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \
PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER | PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER)
#define PAWIN_SPEAKER_5POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \
PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT)
#define PAWIN_SPEAKER_7POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \
PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \
PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT)
/*
According to the Microsoft documentation:
The following are obsolete 5.1 and 7.1 settings (they lack side speakers). Note this means
that the default 5.1 and 7.1 settings (KSAUDIO_SPEAKER_5POINT1 and KSAUDIO_SPEAKER_7POINT1 are
similarly obsolete but are unchanged for compatibility reasons).
*/
#define PAWIN_SPEAKER_5POINT1_BACK PAWIN_SPEAKER_5POINT1
#define PAWIN_SPEAKER_7POINT1_WIDE PAWIN_SPEAKER_7POINT1
/* DVD Speaker Positions */
#define PAWIN_SPEAKER_GROUND_FRONT_LEFT PAWIN_SPEAKER_FRONT_LEFT
#define PAWIN_SPEAKER_GROUND_FRONT_CENTER PAWIN_SPEAKER_FRONT_CENTER
#define PAWIN_SPEAKER_GROUND_FRONT_RIGHT PAWIN_SPEAKER_FRONT_RIGHT
#define PAWIN_SPEAKER_GROUND_REAR_LEFT PAWIN_SPEAKER_BACK_LEFT
#define PAWIN_SPEAKER_GROUND_REAR_RIGHT PAWIN_SPEAKER_BACK_RIGHT
#define PAWIN_SPEAKER_TOP_MIDDLE PAWIN_SPEAKER_TOP_CENTER
#define PAWIN_SPEAKER_SUPER_WOOFER PAWIN_SPEAKER_LOW_FREQUENCY
/*
PaWinWaveFormat is defined here to provide compatibility with
compilation environments which don't have headers defining
WAVEFORMATEXTENSIBLE (e.g. older versions of MSVC, Borland C++ etc.
The fields for WAVEFORMATEX and WAVEFORMATEXTENSIBLE are declared as an
unsigned char array here to avoid clients who include this file having
a dependency on windows.h and mmsystem.h, and also to to avoid having
to write separate packing pragmas for each compiler.
*/
#define PAWIN_SIZEOF_WAVEFORMATEX 18
#define PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE (PAWIN_SIZEOF_WAVEFORMATEX + 22)
typedef struct{
unsigned char fields[ PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE ];
unsigned long extraLongForAlignment; /* ensure that compiler aligns struct to DWORD */
} PaWinWaveFormat;
/*
WAVEFORMATEXTENSIBLE fields:
union {
WORD wValidBitsPerSample;
WORD wSamplesPerBlock;
WORD wReserved;
} Samples;
DWORD dwChannelMask;
GUID SubFormat;
*/
#define PAWIN_INDEXOF_WVALIDBITSPERSAMPLE (PAWIN_SIZEOF_WAVEFORMATEX+0)
#define PAWIN_INDEXOF_DWCHANNELMASK (PAWIN_SIZEOF_WAVEFORMATEX+2)
#define PAWIN_INDEXOF_SUBFORMAT (PAWIN_SIZEOF_WAVEFORMATEX+6)
/*
Valid values to pass for the waveFormatTag PaWin_InitializeWaveFormatEx and
PaWin_InitializeWaveFormatExtensible functions below. These must match
the standard Windows WAVE_FORMAT_* values.
*/
#define PAWIN_WAVE_FORMAT_PCM (1)
#define PAWIN_WAVE_FORMAT_IEEE_FLOAT (3)
#define PAWIN_WAVE_FORMAT_DOLBY_AC3_SPDIF (0x0092)
#define PAWIN_WAVE_FORMAT_WMA_SPDIF (0x0164)
/*
returns PAWIN_WAVE_FORMAT_PCM or PAWIN_WAVE_FORMAT_IEEE_FLOAT
depending on the sampleFormat parameter.
*/
int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat );
/*
Use the following two functions to initialize the waveformat structure.
*/
void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate );
void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate,
PaWinWaveFormatChannelMask channelMask );
/* Map a channel count to a speaker channel mask */
PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_WIN_WAVEFORMAT_H */

View File

@ -1,126 +1,126 @@
/*
* $Id: pa_log.c $
* Portable Audio I/O Library Multi-Host API front end
* Validate function parameters and manage multiple host APIs.
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2006 Ross Bencina, Phil Burk
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup common_src
@brief Implements log function.
PaUtil_SetLogPrintFunction can be user called to replace the provided
DefaultLogPrint function, which writes to stderr.
One can NOT pass var_args across compiler/dll boundaries as it is not
"byte code/abi portable". So the technique used here is to allocate a local
a static array, write in it, then callback the user with a pointer to its
start.
@todo Consider allocating strdump using dynamic allocation.
@todo Consider reentrancy and possibly corrupted strdump buffer.
*/
#include <stdio.h>
#include <stdarg.h>
#include "pa_debugprint.h"
// for OutputDebugStringA
#if defined(_MSC_VER) && defined(PA_ENABLE_MSVC_DEBUG_OUTPUT)
#define WIN32_LEAN_AND_MEAN // exclude rare headers
#include "windows.h"
#endif
// User callback
static PaUtilLogCallback userCB = NULL;
// Sets user callback
void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb)
{
userCB = cb;
}
/*
If your platform doesnt have vsnprintf, you are stuck with a
VERY dangerous alternative, vsprintf (with no n)
*/
#if _MSC_VER
/* Some Windows Mobile SDKs don't define vsnprintf but all define _vsnprintf (hopefully).
According to MSDN "vsnprintf is identical to _vsnprintf". So we use _vsnprintf with MSC.
*/
#define VSNPRINTF _vsnprintf
#else
#define VSNPRINTF vsnprintf
#endif
#define PA_LOG_BUF_SIZE 2048
void PaUtil_DebugPrint( const char *format, ... )
{
// Optional logging into Output console of Visual Studio
#if defined(_MSC_VER) && defined(PA_ENABLE_MSVC_DEBUG_OUTPUT)
{
char buf[PA_LOG_BUF_SIZE];
va_list ap;
va_start(ap, format);
VSNPRINTF(buf, sizeof(buf), format, ap);
buf[sizeof(buf)-1] = 0;
OutputDebugStringA(buf);
va_end(ap);
}
#endif
// Output to User-Callback
if (userCB != NULL)
{
char strdump[PA_LOG_BUF_SIZE];
va_list ap;
va_start(ap, format);
VSNPRINTF(strdump, sizeof(strdump), format, ap);
strdump[sizeof(strdump)-1] = 0;
userCB(strdump);
va_end(ap);
}
else
// Standard output to stderr
{
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fflush(stderr);
}
}
/*
* $Id: pa_log.c $
* Portable Audio I/O Library Multi-Host API front end
* Validate function parameters and manage multiple host APIs.
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2006 Ross Bencina, Phil Burk
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup common_src
@brief Implements log function.
PaUtil_SetLogPrintFunction can be user called to replace the provided
DefaultLogPrint function, which writes to stderr.
One can NOT pass var_args across compiler/dll boundaries as it is not
"byte code/abi portable". So the technique used here is to allocate a local
a static array, write in it, then callback the user with a pointer to its
start.
@todo Consider allocating strdump using dynamic allocation.
@todo Consider reentrancy and possibly corrupted strdump buffer.
*/
#include <stdio.h>
#include <stdarg.h>
#include "pa_debugprint.h"
// for OutputDebugStringA
#if defined(_MSC_VER) && defined(PA_ENABLE_MSVC_DEBUG_OUTPUT)
#define WIN32_LEAN_AND_MEAN // exclude rare headers
#include "windows.h"
#endif
// User callback
static PaUtilLogCallback userCB = NULL;
// Sets user callback
void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb)
{
userCB = cb;
}
/*
If your platform doesnt have vsnprintf, you are stuck with a
VERY dangerous alternative, vsprintf (with no n)
*/
#if _MSC_VER
/* Some Windows Mobile SDKs don't define vsnprintf but all define _vsnprintf (hopefully).
According to MSDN "vsnprintf is identical to _vsnprintf". So we use _vsnprintf with MSC.
*/
#define VSNPRINTF _vsnprintf
#else
#define VSNPRINTF vsnprintf
#endif
#define PA_LOG_BUF_SIZE 2048
void PaUtil_DebugPrint( const char *format, ... )
{
// Optional logging into Output console of Visual Studio
#if defined(_MSC_VER) && defined(PA_ENABLE_MSVC_DEBUG_OUTPUT)
{
char buf[PA_LOG_BUF_SIZE];
va_list ap;
va_start(ap, format);
VSNPRINTF(buf, sizeof(buf), format, ap);
buf[sizeof(buf)-1] = 0;
OutputDebugStringA(buf);
va_end(ap);
}
#endif
// Output to User-Callback
if (userCB != NULL)
{
char strdump[PA_LOG_BUF_SIZE];
va_list ap;
va_start(ap, format);
VSNPRINTF(strdump, sizeof(strdump), format, ap);
strdump[sizeof(strdump)-1] = 0;
userCB(strdump);
va_end(ap);
}
else
// Standard output to stderr
{
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fflush(stderr);
}
}

View File

@ -1,149 +1,149 @@
#ifndef PA_LOG_H
#define PA_LOG_H
/*
* Log file redirector function
* Copyright (c) 1999-2006 Ross Bencina, Phil Burk
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup common_src
*/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void PaUtil_DebugPrint( const char *format, ... );
/*
The basic format for log messages is described below. If you need to
add any log messages, please follow this format.
Function entry (void function):
"FunctionName called.\n"
Function entry (non void function):
"FunctionName called:\n"
"\tParam1Type param1: param1Value\n"
"\tParam2Type param2: param2Value\n" (etc...)
Function exit (no return value):
"FunctionName returned.\n"
Function exit (simple return value):
"FunctionName returned:\n"
"\tReturnType: returnValue\n"
If the return type is an error code, the error text is displayed in ()
If the return type is not an error code, but has taken a special value
because an error occurred, then the reason for the error is shown in []
If the return type is a struct ptr, the struct is dumped.
See the code below for examples
*/
/** PA_DEBUG() provides a simple debug message printing facility. The macro
passes it's argument to a printf-like function called PaUtil_DebugPrint()
which prints to stderr and always flushes the stream after printing.
Because preprocessor macros cannot directly accept variable length argument
lists, calls to the macro must include an additional set of parenthesis, eg:
PA_DEBUG(("errorno: %d", 1001 ));
*/
#ifdef PA_ENABLE_DEBUG_OUTPUT
#define PA_DEBUG(x) PaUtil_DebugPrint x ;
#else
#define PA_DEBUG(x)
#endif
#ifdef PA_LOG_API_CALLS
#define PA_LOGAPI(x) PaUtil_DebugPrint x
#define PA_LOGAPI_ENTER(functionName) PaUtil_DebugPrint( functionName " called.\n" )
#define PA_LOGAPI_ENTER_PARAMS(functionName) PaUtil_DebugPrint( functionName " called:\n" )
#define PA_LOGAPI_EXIT(functionName) PaUtil_DebugPrint( functionName " returned.\n" )
#define PA_LOGAPI_EXIT_PAERROR( functionName, result ) \
PaUtil_DebugPrint( functionName " returned:\n" ); \
PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )
#define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) \
PaUtil_DebugPrint( functionName " returned:\n" ); \
PaUtil_DebugPrint("\t" resultFormatString "\n", result )
#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) \
PaUtil_DebugPrint( functionName " returned:\n" ); \
if( result > 0 ) \
PaUtil_DebugPrint("\t" positiveResultFormatString "\n", result ); \
else \
PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )
#else
#define PA_LOGAPI(x)
#define PA_LOGAPI_ENTER(functionName)
#define PA_LOGAPI_ENTER_PARAMS(functionName)
#define PA_LOGAPI_EXIT(functionName)
#define PA_LOGAPI_EXIT_PAERROR( functionName, result )
#define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result )
#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result )
#endif
typedef void (*PaUtilLogCallback ) (const char *log);
/**
Install user provided log function
*/
void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_LOG_H */
#ifndef PA_LOG_H
#define PA_LOG_H
/*
* Log file redirector function
* Copyright (c) 1999-2006 Ross Bencina, Phil Burk
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup common_src
*/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void PaUtil_DebugPrint( const char *format, ... );
/*
The basic format for log messages is described below. If you need to
add any log messages, please follow this format.
Function entry (void function):
"FunctionName called.\n"
Function entry (non void function):
"FunctionName called:\n"
"\tParam1Type param1: param1Value\n"
"\tParam2Type param2: param2Value\n" (etc...)
Function exit (no return value):
"FunctionName returned.\n"
Function exit (simple return value):
"FunctionName returned:\n"
"\tReturnType: returnValue\n"
If the return type is an error code, the error text is displayed in ()
If the return type is not an error code, but has taken a special value
because an error occurred, then the reason for the error is shown in []
If the return type is a struct ptr, the struct is dumped.
See the code below for examples
*/
/** PA_DEBUG() provides a simple debug message printing facility. The macro
passes it's argument to a printf-like function called PaUtil_DebugPrint()
which prints to stderr and always flushes the stream after printing.
Because preprocessor macros cannot directly accept variable length argument
lists, calls to the macro must include an additional set of parenthesis, eg:
PA_DEBUG(("errorno: %d", 1001 ));
*/
#ifdef PA_ENABLE_DEBUG_OUTPUT
#define PA_DEBUG(x) PaUtil_DebugPrint x ;
#else
#define PA_DEBUG(x)
#endif
#ifdef PA_LOG_API_CALLS
#define PA_LOGAPI(x) PaUtil_DebugPrint x
#define PA_LOGAPI_ENTER(functionName) PaUtil_DebugPrint( functionName " called.\n" )
#define PA_LOGAPI_ENTER_PARAMS(functionName) PaUtil_DebugPrint( functionName " called:\n" )
#define PA_LOGAPI_EXIT(functionName) PaUtil_DebugPrint( functionName " returned.\n" )
#define PA_LOGAPI_EXIT_PAERROR( functionName, result ) \
PaUtil_DebugPrint( functionName " returned:\n" ); \
PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )
#define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) \
PaUtil_DebugPrint( functionName " returned:\n" ); \
PaUtil_DebugPrint("\t" resultFormatString "\n", result )
#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) \
PaUtil_DebugPrint( functionName " returned:\n" ); \
if( result > 0 ) \
PaUtil_DebugPrint("\t" positiveResultFormatString "\n", result ); \
else \
PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )
#else
#define PA_LOGAPI(x)
#define PA_LOGAPI_ENTER(functionName)
#define PA_LOGAPI_ENTER_PARAMS(functionName)
#define PA_LOGAPI_EXIT(functionName)
#define PA_LOGAPI_EXIT_PAERROR( functionName, result )
#define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result )
#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result )
#endif
typedef void (*PaUtilLogCallback ) (const char *log);
/**
Install user provided log function
*/
void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_LOG_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,136 +1,136 @@
/*
* Internal blocking interfaces for PortAudio Apple AUHAL implementation
*
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
*
* Written by Bjorn Roche of XO Audio LLC, from PA skeleton code.
* Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation)
*
* Dominic's code was based on code by Phil Burk, Darren Gibbs,
* Gord Peters, Stephane Letz, and Greg Pfiel.
*
* The following people also deserve acknowledgements:
*
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, Phil Burk
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/**
@file
@ingroup hostapi_src
*/
#ifndef PA_MAC_CORE_BLOCKING_H_
#define PA_MAC_CORE_BLOCKING_H_
#include "pa_ringbuffer.h"
#include "portaudio.h"
#include "pa_mac_core_utilities.h"
/*
* Number of miliseconds to busy wait whil waiting for data in blocking calls.
*/
#define PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL (5)
/*
* Define exactly one of these blocking methods
* PA_MAC_BLIO_MUTEX is not actively maintained.
*/
#define PA_MAC_BLIO_BUSY_WAIT
/*
#define PA_MAC_BLIO_MUTEX
*/
typedef struct {
PaUtilRingBuffer inputRingBuffer;
PaUtilRingBuffer outputRingBuffer;
size_t ringBufferFrames;
PaSampleFormat inputSampleFormat;
size_t inputSampleSizeActual;
size_t inputSampleSizePow2;
PaSampleFormat outputSampleFormat;
size_t outputSampleSizeActual;
size_t outputSampleSizePow2;
size_t framesPerBuffer;
int inChan;
int outChan;
//PaStreamCallbackFlags statusFlags;
uint32_t statusFlags;
PaError errors;
/* Here we handle blocking, using condition variables. */
#ifdef PA_MAC_BLIO_MUTEX
volatile bool isInputEmpty;
pthread_mutex_t inputMutex;
pthread_cond_t inputCond;
volatile bool isOutputFull;
pthread_mutex_t outputMutex;
pthread_cond_t outputCond;
#endif
}
PaMacBlio;
/*
* These functions operate on condition and related variables.
*/
PaError initializeBlioRingBuffers(
PaMacBlio *blio,
PaSampleFormat inputSampleFormat,
PaSampleFormat outputSampleFormat,
size_t framesPerBuffer,
long ringBufferSize,
int inChan,
int outChan );
PaError destroyBlioRingBuffers( PaMacBlio *blio );
PaError resetBlioRingBuffers( PaMacBlio *blio );
int BlioCallback(
const void *input, void *output,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData );
void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio );
#endif /*PA_MAC_CORE_BLOCKING_H_*/
/*
* Internal blocking interfaces for PortAudio Apple AUHAL implementation
*
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
*
* Written by Bjorn Roche of XO Audio LLC, from PA skeleton code.
* Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation)
*
* Dominic's code was based on code by Phil Burk, Darren Gibbs,
* Gord Peters, Stephane Letz, and Greg Pfiel.
*
* The following people also deserve acknowledgements:
*
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, Phil Burk
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/**
@file
@ingroup hostapi_src
*/
#ifndef PA_MAC_CORE_BLOCKING_H_
#define PA_MAC_CORE_BLOCKING_H_
#include "pa_ringbuffer.h"
#include "portaudio.h"
#include "pa_mac_core_utilities.h"
/*
* Number of miliseconds to busy wait whil waiting for data in blocking calls.
*/
#define PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL (5)
/*
* Define exactly one of these blocking methods
* PA_MAC_BLIO_MUTEX is not actively maintained.
*/
#define PA_MAC_BLIO_BUSY_WAIT
/*
#define PA_MAC_BLIO_MUTEX
*/
typedef struct {
PaUtilRingBuffer inputRingBuffer;
PaUtilRingBuffer outputRingBuffer;
size_t ringBufferFrames;
PaSampleFormat inputSampleFormat;
size_t inputSampleSizeActual;
size_t inputSampleSizePow2;
PaSampleFormat outputSampleFormat;
size_t outputSampleSizeActual;
size_t outputSampleSizePow2;
size_t framesPerBuffer;
int inChan;
int outChan;
//PaStreamCallbackFlags statusFlags;
uint32_t statusFlags;
PaError errors;
/* Here we handle blocking, using condition variables. */
#ifdef PA_MAC_BLIO_MUTEX
volatile bool isInputEmpty;
pthread_mutex_t inputMutex;
pthread_cond_t inputCond;
volatile bool isOutputFull;
pthread_mutex_t outputMutex;
pthread_cond_t outputCond;
#endif
}
PaMacBlio;
/*
* These functions operate on condition and related variables.
*/
PaError initializeBlioRingBuffers(
PaMacBlio *blio,
PaSampleFormat inputSampleFormat,
PaSampleFormat outputSampleFormat,
size_t framesPerBuffer,
long ringBufferSize,
int inChan,
int outChan );
PaError destroyBlioRingBuffers( PaMacBlio *blio );
PaError resetBlioRingBuffers( PaMacBlio *blio );
int BlioCallback(
const void *input, void *output,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData );
void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio );
#endif /*PA_MAC_CORE_BLOCKING_H_*/

File diff suppressed because it is too large Load Diff

View File

@ -1,154 +1,154 @@
/*
* PortAudio Portable Real-Time Audio Library
* Windows WAVEFORMAT* data structure utilities
* portaudio.h should be included before this file.
*
* Copyright (c) 2007 Ross Bencina
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
#include <windows.h>
#include <mmsystem.h>
#include "portaudio.h"
#include "pa_win_waveformat.h"
#if !defined(WAVE_FORMAT_EXTENSIBLE)
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
#endif
static GUID pawin_ksDataFormatSubtypeGuidBase =
{ (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 };
int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat )
{
if( sampleFormat == paFloat32 )
return PAWIN_WAVE_FORMAT_IEEE_FLOAT;
return PAWIN_WAVE_FORMAT_PCM;
}
void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate )
{
WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
int bytesPerSample = Pa_GetSampleSize(sampleFormat);
unsigned long bytesPerFrame = numChannels * bytesPerSample;
waveFormatEx->wFormatTag = waveFormatTag;
waveFormatEx->nChannels = (WORD)numChannels;
waveFormatEx->nSamplesPerSec = (DWORD)sampleRate;
waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame;
waveFormatEx->nBlockAlign = (WORD)bytesPerFrame;
waveFormatEx->wBitsPerSample = bytesPerSample * 8;
waveFormatEx->cbSize = 0;
}
void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate,
PaWinWaveFormatChannelMask channelMask )
{
WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
int bytesPerSample = Pa_GetSampleSize(sampleFormat);
unsigned long bytesPerFrame = numChannels * bytesPerSample;
GUID guid;
waveFormatEx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
waveFormatEx->nChannels = (WORD)numChannels;
waveFormatEx->nSamplesPerSec = (DWORD)sampleRate;
waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame;
waveFormatEx->nBlockAlign = (WORD)bytesPerFrame;
waveFormatEx->wBitsPerSample = bytesPerSample * 8;
waveFormatEx->cbSize = 22;
*((WORD*)&waveFormat->fields[PAWIN_INDEXOF_WVALIDBITSPERSAMPLE]) =
waveFormatEx->wBitsPerSample;
*((DWORD*)&waveFormat->fields[PAWIN_INDEXOF_DWCHANNELMASK]) = channelMask;
guid = pawin_ksDataFormatSubtypeGuidBase;
guid.Data1 = (USHORT)waveFormatTag;
*((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = guid;
}
PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels )
{
switch( numChannels ){
case 1:
return PAWIN_SPEAKER_MONO;
case 2:
return PAWIN_SPEAKER_STEREO;
case 3:
return PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_FRONT_RIGHT;
case 4:
return PAWIN_SPEAKER_QUAD;
case 5:
return PAWIN_SPEAKER_QUAD | PAWIN_SPEAKER_FRONT_CENTER;
case 6:
/* The meaning of the PAWIN_SPEAKER_5POINT1 flag has changed over time:
http://msdn2.microsoft.com/en-us/library/aa474707.aspx
We use PAWIN_SPEAKER_5POINT1 (not PAWIN_SPEAKER_5POINT1_SURROUND)
because on some cards (eg Audigy) PAWIN_SPEAKER_5POINT1_SURROUND
results in a virtual mixdown placing the rear output in the
front _and_ rear speakers.
*/
return PAWIN_SPEAKER_5POINT1;
/* case 7: */
case 8:
return PAWIN_SPEAKER_7POINT1;
}
/* Apparently some Audigy drivers will output silence
if the direct-out constant (0) is used. So this is not ideal.
*/
return PAWIN_SPEAKER_DIRECTOUT;
/* Note that Alec Rogers proposed the following as an alternate method to
generate the default channel mask, however it doesn't seem to be an improvement
over the above, since some drivers will matrix outputs mapping to non-present
speakers accross multiple physical speakers.
if(nChannels==1) {
pwfFormat->dwChannelMask = SPEAKER_FRONT_CENTER;
}
else {
pwfFormat->dwChannelMask = 0;
for(i=0; i<nChannels; i++)
pwfFormat->dwChannelMask = (pwfFormat->dwChannelMask << 1) | 0x1;
}
*/
}
/*
* PortAudio Portable Real-Time Audio Library
* Windows WAVEFORMAT* data structure utilities
* portaudio.h should be included before this file.
*
* Copyright (c) 2007 Ross Bencina
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
#include <windows.h>
#include <mmsystem.h>
#include "portaudio.h"
#include "pa_win_waveformat.h"
#if !defined(WAVE_FORMAT_EXTENSIBLE)
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
#endif
static GUID pawin_ksDataFormatSubtypeGuidBase =
{ (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 };
int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat )
{
if( sampleFormat == paFloat32 )
return PAWIN_WAVE_FORMAT_IEEE_FLOAT;
return PAWIN_WAVE_FORMAT_PCM;
}
void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate )
{
WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
int bytesPerSample = Pa_GetSampleSize(sampleFormat);
unsigned long bytesPerFrame = numChannels * bytesPerSample;
waveFormatEx->wFormatTag = waveFormatTag;
waveFormatEx->nChannels = (WORD)numChannels;
waveFormatEx->nSamplesPerSec = (DWORD)sampleRate;
waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame;
waveFormatEx->nBlockAlign = (WORD)bytesPerFrame;
waveFormatEx->wBitsPerSample = bytesPerSample * 8;
waveFormatEx->cbSize = 0;
}
void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate,
PaWinWaveFormatChannelMask channelMask )
{
WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
int bytesPerSample = Pa_GetSampleSize(sampleFormat);
unsigned long bytesPerFrame = numChannels * bytesPerSample;
GUID guid;
waveFormatEx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
waveFormatEx->nChannels = (WORD)numChannels;
waveFormatEx->nSamplesPerSec = (DWORD)sampleRate;
waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame;
waveFormatEx->nBlockAlign = (WORD)bytesPerFrame;
waveFormatEx->wBitsPerSample = bytesPerSample * 8;
waveFormatEx->cbSize = 22;
*((WORD*)&waveFormat->fields[PAWIN_INDEXOF_WVALIDBITSPERSAMPLE]) =
waveFormatEx->wBitsPerSample;
*((DWORD*)&waveFormat->fields[PAWIN_INDEXOF_DWCHANNELMASK]) = channelMask;
guid = pawin_ksDataFormatSubtypeGuidBase;
guid.Data1 = (USHORT)waveFormatTag;
*((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = guid;
}
PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels )
{
switch( numChannels ){
case 1:
return PAWIN_SPEAKER_MONO;
case 2:
return PAWIN_SPEAKER_STEREO;
case 3:
return PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_FRONT_RIGHT;
case 4:
return PAWIN_SPEAKER_QUAD;
case 5:
return PAWIN_SPEAKER_QUAD | PAWIN_SPEAKER_FRONT_CENTER;
case 6:
/* The meaning of the PAWIN_SPEAKER_5POINT1 flag has changed over time:
http://msdn2.microsoft.com/en-us/library/aa474707.aspx
We use PAWIN_SPEAKER_5POINT1 (not PAWIN_SPEAKER_5POINT1_SURROUND)
because on some cards (eg Audigy) PAWIN_SPEAKER_5POINT1_SURROUND
results in a virtual mixdown placing the rear output in the
front _and_ rear speakers.
*/
return PAWIN_SPEAKER_5POINT1;
/* case 7: */
case 8:
return PAWIN_SPEAKER_7POINT1;
}
/* Apparently some Audigy drivers will output silence
if the direct-out constant (0) is used. So this is not ideal.
*/
return PAWIN_SPEAKER_DIRECTOUT;
/* Note that Alec Rogers proposed the following as an alternate method to
generate the default channel mask, however it doesn't seem to be an improvement
over the above, since some drivers will matrix outputs mapping to non-present
speakers accross multiple physical speakers.
if(nChannels==1) {
pwfFormat->dwChannelMask = SPEAKER_FRONT_CENTER;
}
else {
pwfFormat->dwChannelMask = 0;
for(i=0; i<nChannels; i++)
pwfFormat->dwChannelMask = (pwfFormat->dwChannelMask << 1) | 0x1;
}
*/
}

View File

@ -1,293 +1,293 @@
/*
* PortAudio Portable Real-Time Audio Library
* Windows WDM KS utilities
*
* Copyright (c) 1999 - 2007 Andrew Baldwin, Ross Bencina
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
#include <windows.h>
#include <mmreg.h>
#include <ks.h>
#include <ksmedia.h>
#include <stdio.h> // just for some development printfs
#include "portaudio.h"
#include "pa_util.h"
#include "pa_win_wdmks_utils.h"
#ifndef PA_WDMKS_NO_KSGUID_LIB
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
#pragma comment( lib, "ksguid.lib" )
#endif
#define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO
#define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
#define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM
#define pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX KSDATAFORMAT_SUBTYPE_WAVEFORMATEX
#define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard
#define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard
#define pa_KSPROPSETID_Pin KSPROPSETID_Pin
#else
static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX };
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
#endif
#define pa_IS_VALID_WAVEFORMATEX_GUID(Guid)\
(!memcmp(((PUSHORT)&pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT)))
static PaError WdmGetPinPropertySimple(
HANDLE handle,
unsigned long pinId,
unsigned long property,
void* value,
unsigned long valueSize )
{
DWORD bytesReturned;
KSP_PIN ksPProp;
ksPProp.Property.Set = pa_KSPROPSETID_Pin;
ksPProp.Property.Id = property;
ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
ksPProp.PinId = pinId;
ksPProp.Reserved = 0;
if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN),
value, valueSize, &bytesReturned, NULL ) == 0 || bytesReturned != valueSize )
{
return paUnanticipatedHostError;
}
else
{
return paNoError;
}
}
static PaError WdmGetPinPropertyMulti(
HANDLE handle,
unsigned long pinId,
unsigned long property,
KSMULTIPLE_ITEM** ksMultipleItem)
{
unsigned long multipleItemSize = 0;
KSP_PIN ksPProp;
DWORD bytesReturned;
*ksMultipleItem = 0;
ksPProp.Property.Set = pa_KSPROPSETID_Pin;
ksPProp.Property.Id = property;
ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
ksPProp.PinId = pinId;
ksPProp.Reserved = 0;
if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp.Property,
sizeof(KSP_PIN), NULL, 0, &multipleItemSize, NULL ) == 0 && GetLastError() != ERROR_MORE_DATA )
{
return paUnanticipatedHostError;
}
*ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize );
if( !*ksMultipleItem )
{
return paInsufficientMemory;
}
if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN),
(void*)*ksMultipleItem, multipleItemSize, &bytesReturned, NULL ) == 0 || bytesReturned != multipleItemSize )
{
PaUtil_FreeMemory( ksMultipleItem );
return paUnanticipatedHostError;
}
return paNoError;
}
static int GetKSFilterPinCount( HANDLE deviceHandle )
{
DWORD result;
if( WdmGetPinPropertySimple( deviceHandle, 0, KSPROPERTY_PIN_CTYPES, &result, sizeof(result) ) == paNoError ){
return result;
}else{
return 0;
}
}
static KSPIN_COMMUNICATION GetKSFilterPinPropertyCommunication( HANDLE deviceHandle, int pinId )
{
KSPIN_COMMUNICATION result;
if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_COMMUNICATION, &result, sizeof(result) ) == paNoError ){
return result;
}else{
return KSPIN_COMMUNICATION_NONE;
}
}
static KSPIN_DATAFLOW GetKSFilterPinPropertyDataflow( HANDLE deviceHandle, int pinId )
{
KSPIN_DATAFLOW result;
if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_DATAFLOW, &result, sizeof(result) ) == paNoError ){
return result;
}else{
return (KSPIN_DATAFLOW)0;
}
}
static int KSFilterPinPropertyIdentifiersInclude(
HANDLE deviceHandle, int pinId, unsigned long property, const GUID *identifierSet, unsigned long identifierId )
{
KSMULTIPLE_ITEM* item = NULL;
KSIDENTIFIER* identifier;
int i;
int result = 0;
if( WdmGetPinPropertyMulti( deviceHandle, pinId, property, &item) != paNoError )
return 0;
identifier = (KSIDENTIFIER*)(item+1);
for( i = 0; i < (int)item->Count; i++ )
{
if( !memcmp( (void*)&identifier[i].Set, (void*)identifierSet, sizeof( GUID ) ) &&
( identifier[i].Id == identifierId ) )
{
result = 1;
break;
}
}
PaUtil_FreeMemory( item );
return result;
}
/* return the maximum channel count supported by any pin on the device.
if isInput is non-zero we query input pins, otherwise output pins.
*/
int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput )
{
HANDLE deviceHandle;
ULONG i;
int pinCount, pinId;
int result = 0;
KSPIN_DATAFLOW requiredDataflowDirection = (isInput ? KSPIN_DATAFLOW_OUT : KSPIN_DATAFLOW_IN );
if( !wcharDevicePath )
return 0;
deviceHandle = CreateFileW( (LPCWSTR)wcharDevicePath, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
if( deviceHandle == INVALID_HANDLE_VALUE )
return 0;
pinCount = GetKSFilterPinCount( deviceHandle );
for( pinId = 0; pinId < pinCount; ++pinId )
{
KSPIN_COMMUNICATION communication = GetKSFilterPinPropertyCommunication( deviceHandle, pinId );
KSPIN_DATAFLOW dataflow = GetKSFilterPinPropertyDataflow( deviceHandle, pinId );
if( ( dataflow == requiredDataflowDirection ) &&
(( communication == KSPIN_COMMUNICATION_SINK) ||
( communication == KSPIN_COMMUNICATION_BOTH))
&& ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_STREAMING )
|| KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_LOOPED_STREAMING ) )
&& KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
KSPROPERTY_PIN_MEDIUMS, &pa_KSMEDIUMSETID_Standard, KSMEDIUM_STANDARD_DEVIO ) )
{
KSMULTIPLE_ITEM* item = NULL;
if( WdmGetPinPropertyMulti( deviceHandle, pinId, KSPROPERTY_PIN_DATARANGES, &item ) == paNoError )
{
KSDATARANGE *dataRange = (KSDATARANGE*)(item+1);
for( i=0; i < item->Count; ++i ){
if( pa_IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat)
|| memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID) ) == 0
|| memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID) ) == 0
|| ( ( memcmp( (void*)&dataRange->MajorFormat, (void*)&pa_KSDATAFORMAT_TYPE_AUDIO, sizeof(GUID) ) == 0 )
&& ( memcmp( (void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID) ) == 0 ) ) )
{
KSDATARANGE_AUDIO *dataRangeAudio = (KSDATARANGE_AUDIO*)dataRange;
/*
printf( ">>> %d %d %d %d %S\n", isInput, dataflow, communication, dataRangeAudio->MaximumChannels, devicePath );
if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, sizeof(GUID) ) == 0 )
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WAVEFORMATEX\n" );
else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_DSOUND, sizeof(GUID) ) == 0 )
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_DSOUND\n" );
else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WILDCARD, sizeof(GUID) ) == 0 )
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WILDCARD\n" );
else
printf( "\tspecifier: ?\n" );
*/
/*
We assume that very high values for MaximumChannels are not useful and indicate
that the driver isn't prepared to tell us the real number of channels which it supports.
*/
if( dataRangeAudio->MaximumChannels < 0xFFFFUL && (int)dataRangeAudio->MaximumChannels > result )
result = (int)dataRangeAudio->MaximumChannels;
}
dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize);
}
PaUtil_FreeMemory( item );
}
}
}
CloseHandle( deviceHandle );
return result;
}
/*
* PortAudio Portable Real-Time Audio Library
* Windows WDM KS utilities
*
* Copyright (c) 1999 - 2007 Andrew Baldwin, Ross Bencina
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
#include <windows.h>
#include <mmreg.h>
#include <ks.h>
#include <ksmedia.h>
#include <stdio.h> // just for some development printfs
#include "portaudio.h"
#include "pa_util.h"
#include "pa_win_wdmks_utils.h"
#ifndef PA_WDMKS_NO_KSGUID_LIB
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
#pragma comment( lib, "ksguid.lib" )
#endif
#define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO
#define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
#define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM
#define pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX KSDATAFORMAT_SUBTYPE_WAVEFORMATEX
#define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard
#define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard
#define pa_KSPROPSETID_Pin KSPROPSETID_Pin
#else
static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX };
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
#endif
#define pa_IS_VALID_WAVEFORMATEX_GUID(Guid)\
(!memcmp(((PUSHORT)&pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT)))
static PaError WdmGetPinPropertySimple(
HANDLE handle,
unsigned long pinId,
unsigned long property,
void* value,
unsigned long valueSize )
{
DWORD bytesReturned;
KSP_PIN ksPProp;
ksPProp.Property.Set = pa_KSPROPSETID_Pin;
ksPProp.Property.Id = property;
ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
ksPProp.PinId = pinId;
ksPProp.Reserved = 0;
if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN),
value, valueSize, &bytesReturned, NULL ) == 0 || bytesReturned != valueSize )
{
return paUnanticipatedHostError;
}
else
{
return paNoError;
}
}
static PaError WdmGetPinPropertyMulti(
HANDLE handle,
unsigned long pinId,
unsigned long property,
KSMULTIPLE_ITEM** ksMultipleItem)
{
unsigned long multipleItemSize = 0;
KSP_PIN ksPProp;
DWORD bytesReturned;
*ksMultipleItem = 0;
ksPProp.Property.Set = pa_KSPROPSETID_Pin;
ksPProp.Property.Id = property;
ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
ksPProp.PinId = pinId;
ksPProp.Reserved = 0;
if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp.Property,
sizeof(KSP_PIN), NULL, 0, &multipleItemSize, NULL ) == 0 && GetLastError() != ERROR_MORE_DATA )
{
return paUnanticipatedHostError;
}
*ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize );
if( !*ksMultipleItem )
{
return paInsufficientMemory;
}
if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN),
(void*)*ksMultipleItem, multipleItemSize, &bytesReturned, NULL ) == 0 || bytesReturned != multipleItemSize )
{
PaUtil_FreeMemory( ksMultipleItem );
return paUnanticipatedHostError;
}
return paNoError;
}
static int GetKSFilterPinCount( HANDLE deviceHandle )
{
DWORD result;
if( WdmGetPinPropertySimple( deviceHandle, 0, KSPROPERTY_PIN_CTYPES, &result, sizeof(result) ) == paNoError ){
return result;
}else{
return 0;
}
}
static KSPIN_COMMUNICATION GetKSFilterPinPropertyCommunication( HANDLE deviceHandle, int pinId )
{
KSPIN_COMMUNICATION result;
if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_COMMUNICATION, &result, sizeof(result) ) == paNoError ){
return result;
}else{
return KSPIN_COMMUNICATION_NONE;
}
}
static KSPIN_DATAFLOW GetKSFilterPinPropertyDataflow( HANDLE deviceHandle, int pinId )
{
KSPIN_DATAFLOW result;
if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_DATAFLOW, &result, sizeof(result) ) == paNoError ){
return result;
}else{
return (KSPIN_DATAFLOW)0;
}
}
static int KSFilterPinPropertyIdentifiersInclude(
HANDLE deviceHandle, int pinId, unsigned long property, const GUID *identifierSet, unsigned long identifierId )
{
KSMULTIPLE_ITEM* item = NULL;
KSIDENTIFIER* identifier;
int i;
int result = 0;
if( WdmGetPinPropertyMulti( deviceHandle, pinId, property, &item) != paNoError )
return 0;
identifier = (KSIDENTIFIER*)(item+1);
for( i = 0; i < (int)item->Count; i++ )
{
if( !memcmp( (void*)&identifier[i].Set, (void*)identifierSet, sizeof( GUID ) ) &&
( identifier[i].Id == identifierId ) )
{
result = 1;
break;
}
}
PaUtil_FreeMemory( item );
return result;
}
/* return the maximum channel count supported by any pin on the device.
if isInput is non-zero we query input pins, otherwise output pins.
*/
int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput )
{
HANDLE deviceHandle;
ULONG i;
int pinCount, pinId;
int result = 0;
KSPIN_DATAFLOW requiredDataflowDirection = (isInput ? KSPIN_DATAFLOW_OUT : KSPIN_DATAFLOW_IN );
if( !wcharDevicePath )
return 0;
deviceHandle = CreateFileW( (LPCWSTR)wcharDevicePath, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
if( deviceHandle == INVALID_HANDLE_VALUE )
return 0;
pinCount = GetKSFilterPinCount( deviceHandle );
for( pinId = 0; pinId < pinCount; ++pinId )
{
KSPIN_COMMUNICATION communication = GetKSFilterPinPropertyCommunication( deviceHandle, pinId );
KSPIN_DATAFLOW dataflow = GetKSFilterPinPropertyDataflow( deviceHandle, pinId );
if( ( dataflow == requiredDataflowDirection ) &&
(( communication == KSPIN_COMMUNICATION_SINK) ||
( communication == KSPIN_COMMUNICATION_BOTH))
&& ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_STREAMING )
|| KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_LOOPED_STREAMING ) )
&& KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
KSPROPERTY_PIN_MEDIUMS, &pa_KSMEDIUMSETID_Standard, KSMEDIUM_STANDARD_DEVIO ) )
{
KSMULTIPLE_ITEM* item = NULL;
if( WdmGetPinPropertyMulti( deviceHandle, pinId, KSPROPERTY_PIN_DATARANGES, &item ) == paNoError )
{
KSDATARANGE *dataRange = (KSDATARANGE*)(item+1);
for( i=0; i < item->Count; ++i ){
if( pa_IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat)
|| memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID) ) == 0
|| memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID) ) == 0
|| ( ( memcmp( (void*)&dataRange->MajorFormat, (void*)&pa_KSDATAFORMAT_TYPE_AUDIO, sizeof(GUID) ) == 0 )
&& ( memcmp( (void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID) ) == 0 ) ) )
{
KSDATARANGE_AUDIO *dataRangeAudio = (KSDATARANGE_AUDIO*)dataRange;
/*
printf( ">>> %d %d %d %d %S\n", isInput, dataflow, communication, dataRangeAudio->MaximumChannels, devicePath );
if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, sizeof(GUID) ) == 0 )
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WAVEFORMATEX\n" );
else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_DSOUND, sizeof(GUID) ) == 0 )
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_DSOUND\n" );
else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WILDCARD, sizeof(GUID) ) == 0 )
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WILDCARD\n" );
else
printf( "\tspecifier: ?\n" );
*/
/*
We assume that very high values for MaximumChannels are not useful and indicate
that the driver isn't prepared to tell us the real number of channels which it supports.
*/
if( dataRangeAudio->MaximumChannels < 0xFFFFUL && (int)dataRangeAudio->MaximumChannels > result )
result = (int)dataRangeAudio->MaximumChannels;
}
dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize);
}
PaUtil_FreeMemory( item );
}
}
}
CloseHandle( deviceHandle );
return result;
}

View File

@ -1,65 +1,65 @@
#ifndef PA_WIN_WDMKS_UTILS_H
#define PA_WIN_WDMKS_UTILS_H
/*
* PortAudio Portable Real-Time Audio Library
* Windows WDM KS utilities
*
* Copyright (c) 1999 - 2007 Ross Bencina, Andrew Baldwin
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@brief Utilities for working with the Windows WDM KS API
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
Query for the maximum number of channels supported by any pin of the
specified device. Returns 0 if the query fails for any reason.
@param wcharDevicePath A system level PnP interface path, supplied as a WCHAR unicode string.
Declard as void* to avoid introducing a dependency on wchar_t here.
@param isInput A flag specifying whether to query for input (non-zero) or output (zero) channels.
*/
int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#ifndef PA_WIN_WDMKS_UTILS_H
#define PA_WIN_WDMKS_UTILS_H
/*
* PortAudio Portable Real-Time Audio Library
* Windows WDM KS utilities
*
* Copyright (c) 1999 - 2007 Ross Bencina, Andrew Baldwin
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@brief Utilities for working with the Windows WDM KS API
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
Query for the maximum number of channels supported by any pin of the
specified device. Returns 0 if the query fails for any reason.
@param wcharDevicePath A system level PnP interface path, supplied as a WCHAR unicode string.
Declard as void* to avoid introducing a dependency on wchar_t here.
@param isInput A flag specifying whether to query for input (non-zero) or output (zero) channels.
*/
int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_WIN_WDMKS_UTILS_H */

View File

@ -1,76 +1,76 @@
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/string.h"
#include "wx/intl.h"
#include "wx/thread.h"
#endif
#include <ctype.h>
#ifndef __WXWINCE__
#include <errno.h>
#endif
#include <string.h>
#include <stdlib.h>
static HANDLE win32_string_heap = INVALID_HANDLE_VALUE;
static int win32_string_heap_refcount;
static HANDLE win32_object_heap = INVALID_HANDLE_VALUE;
static int win32_object_heap_refcount;
void _allocateHeap_wxString()
{
if( win32_string_heap == INVALID_HANDLE_VALUE )
{
//wxASSERT( win32_string_heap_refcount == 0 );
win32_string_heap = HeapCreate( 0, 0x200000, 0 );
}
}
void _destroyHeap_wxString()
{
if( win32_string_heap == INVALID_HANDLE_VALUE ) return;
}
void* _allocHeap_wxString( size_t size )
{
return (void*)HeapAlloc( win32_string_heap, 0, size );
}
void _freeHeap_wxString( void* ptr )
{
HeapFree( win32_string_heap, 0, ptr );
}
void _allocateHeap_wxObject()
{
if( win32_object_heap == INVALID_HANDLE_VALUE )
{
//wxASSERT( win32_object_heap_refcount == 0 );
win32_object_heap = HeapCreate( 0, 0x200000, 0 );
}
}
void _destroyHeap_wxObject()
{
if( win32_object_heap == INVALID_HANDLE_VALUE ) return;
}
void* _allocHeap_wxObject( size_t size )
{
return (void*)HeapAlloc( win32_object_heap, 0, size );
}
void _freeHeap_wxObject( void* ptr )
{
HeapFree( win32_object_heap, 0, ptr );
}
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/string.h"
#include "wx/intl.h"
#include "wx/thread.h"
#endif
#include <ctype.h>
#ifndef __WXWINCE__
#include <errno.h>
#endif
#include <string.h>
#include <stdlib.h>
static HANDLE win32_string_heap = INVALID_HANDLE_VALUE;
static int win32_string_heap_refcount;
static HANDLE win32_object_heap = INVALID_HANDLE_VALUE;
static int win32_object_heap_refcount;
void _allocateHeap_wxString()
{
if( win32_string_heap == INVALID_HANDLE_VALUE )
{
//wxASSERT( win32_string_heap_refcount == 0 );
win32_string_heap = HeapCreate( 0, 0x200000, 0 );
}
}
void _destroyHeap_wxString()
{
if( win32_string_heap == INVALID_HANDLE_VALUE ) return;
}
void* _allocHeap_wxString( size_t size )
{
return (void*)HeapAlloc( win32_string_heap, 0, size );
}
void _freeHeap_wxString( void* ptr )
{
HeapFree( win32_string_heap, 0, ptr );
}
void _allocateHeap_wxObject()
{
if( win32_object_heap == INVALID_HANDLE_VALUE )
{
//wxASSERT( win32_object_heap_refcount == 0 );
win32_object_heap = HeapCreate( 0, 0x200000, 0 );
}
}
void _destroyHeap_wxObject()
{
if( win32_object_heap == INVALID_HANDLE_VALUE ) return;
}
void* _allocHeap_wxObject( size_t size )
{
return (void*)HeapAlloc( win32_object_heap, 0, size );
}
void _freeHeap_wxObject( void* ptr )
{
HeapFree( win32_object_heap, 0, ptr );
}

View File

@ -1,25 +1,25 @@
/* gzclose.c -- zlib gzclose() function
* Copyright (C) 2004, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "gzguts.h"
/* gzclose() is in a separate file so that it is linked in only if it is used.
That way the other gzclose functions can be used instead to avoid linking in
unneeded compression or decompression routines. */
int ZEXPORT gzclose(file)
gzFile file;
{
#ifndef NO_GZCOMPRESS
gz_statep state;
if (file == NULL)
return Z_STREAM_ERROR;
state = (gz_statep)file;
return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
#else
return gzclose_r(file);
#endif
}
/* gzclose.c -- zlib gzclose() function
* Copyright (C) 2004, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "gzguts.h"
/* gzclose() is in a separate file so that it is linked in only if it is used.
That way the other gzclose functions can be used instead to avoid linking in
unneeded compression or decompression routines. */
int ZEXPORT gzclose(file)
gzFile file;
{
#ifndef NO_GZCOMPRESS
gz_statep state;
if (file == NULL)
return Z_STREAM_ERROR;
state = (gz_statep)file;
return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
#else
return gzclose_r(file);
#endif
}

264
3rdparty/zlib/gzguts.h vendored
View File

@ -1,132 +1,132 @@
/* gzguts.h -- zlib internal header definitions for gz* operations
* Copyright (C) 2004, 2005, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#ifdef _LARGEFILE64_SOURCE
# ifndef _LARGEFILE_SOURCE
# define _LARGEFILE_SOURCE
# endif
# ifdef _FILE_OFFSET_BITS
# undef _FILE_OFFSET_BITS
# endif
#endif
#define ZLIB_INTERNAL
#include <stdio.h>
#include "zlib.h"
#ifdef STDC
# include <string.h>
# include <stdlib.h>
# include <limits.h>
#endif
#include <fcntl.h>
#ifdef NO_DEFLATE /* for compatibility with old definition */
# define NO_GZCOMPRESS
#endif
#ifdef _MSC_VER
# include <io.h>
# define vsnprintf _vsnprintf
#endif
#ifndef local
# define local static
#endif
/* compile with -Dlocal if your debugger can't find static symbols */
/* gz* functions always use library allocation functions */
#ifndef STDC
extern voidp malloc OF((uInt size));
extern void free OF((voidpf ptr));
#endif
/* get errno and strerror definition */
#if defined UNDER_CE && defined NO_ERRNO_H
# include <windows.h>
# define zstrerror() gz_strwinerror((DWORD)GetLastError())
#else
# ifdef STDC
# include <errno.h>
# define zstrerror() strerror(errno)
# else
# define zstrerror() "stdio error (consult errno)"
# endif
#endif
/* MVS fdopen() */
#ifdef __MVS__
#pragma map (fdopen , "\174\174FDOPEN")
FILE *fdopen(int, const char *);
#endif
#ifdef _LARGEFILE64_SOURCE
# define z_off64_t off64_t
#else
# define z_off64_t z_off_t
#endif
/* default i/o buffer size -- double this for output when reading */
#define GZBUFSIZE 8192
/* gzip modes, also provide a little integrity check on the passed structure */
#define GZ_NONE 0
#define GZ_READ 7247
#define GZ_WRITE 31153
#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
/* values for gz_state how */
#define LOOK 0 /* look for a gzip header */
#define COPY 1 /* copy input directly */
#define GZIP 2 /* decompress a gzip stream */
/* internal gzip file state data structure */
typedef struct {
/* used for both reading and writing */
int mode; /* see gzip modes above */
int fd; /* file descriptor */
char *path; /* path or fd for error messages */
z_off64_t pos; /* current position in uncompressed data */
unsigned size; /* buffer size, zero if not allocated yet */
unsigned want; /* requested buffer size, default is GZBUFSIZE */
unsigned char *in; /* input buffer */
unsigned char *out; /* output buffer (double-sized when reading) */
unsigned char *next; /* next output data to deliver or write */
/* just for reading */
unsigned have; /* amount of output data unused at next */
int eof; /* true if end of input file reached */
z_off64_t start; /* where the gzip data started, for rewinding */
z_off64_t raw; /* where the raw data started, for seeking */
int how; /* 0: get header, 1: copy, 2: decompress */
int direct; /* true if last read direct, false if gzip */
/* just for writing */
int level; /* compression level */
int strategy; /* compression strategy */
/* seek request */
z_off64_t skip; /* amount to skip (already rewound if backwards) */
int seek; /* true if seek request pending */
/* error information */
int err; /* error code */
char *msg; /* error message */
/* zlib inflate or deflate stream */
z_stream strm; /* stream structure in-place (not a pointer) */
} gz_state;
typedef gz_state FAR *gz_statep;
/* shared functions */
ZEXTERN void ZEXPORT gz_error OF((gz_statep, int, const char *));
#if defined UNDER_CE && defined NO_ERRNO_H
ZEXTERN char ZEXPORT *gz_strwinerror OF((DWORD error));
#endif
/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
value -- needed when comparing unsigned to z_off64_t, which is signed
(possible z_off64_t types off_t, off64_t, and long are all signed) */
#ifdef INT_MAX
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
#else
ZEXTERN unsigned ZEXPORT gz_intmax OF((void));
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
#endif
/* gzguts.h -- zlib internal header definitions for gz* operations
* Copyright (C) 2004, 2005, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#ifdef _LARGEFILE64_SOURCE
# ifndef _LARGEFILE_SOURCE
# define _LARGEFILE_SOURCE
# endif
# ifdef _FILE_OFFSET_BITS
# undef _FILE_OFFSET_BITS
# endif
#endif
#define ZLIB_INTERNAL
#include <stdio.h>
#include "zlib.h"
#ifdef STDC
# include <string.h>
# include <stdlib.h>
# include <limits.h>
#endif
#include <fcntl.h>
#ifdef NO_DEFLATE /* for compatibility with old definition */
# define NO_GZCOMPRESS
#endif
#ifdef _MSC_VER
# include <io.h>
# define vsnprintf _vsnprintf
#endif
#ifndef local
# define local static
#endif
/* compile with -Dlocal if your debugger can't find static symbols */
/* gz* functions always use library allocation functions */
#ifndef STDC
extern voidp malloc OF((uInt size));
extern void free OF((voidpf ptr));
#endif
/* get errno and strerror definition */
#if defined UNDER_CE && defined NO_ERRNO_H
# include <windows.h>
# define zstrerror() gz_strwinerror((DWORD)GetLastError())
#else
# ifdef STDC
# include <errno.h>
# define zstrerror() strerror(errno)
# else
# define zstrerror() "stdio error (consult errno)"
# endif
#endif
/* MVS fdopen() */
#ifdef __MVS__
#pragma map (fdopen , "\174\174FDOPEN")
FILE *fdopen(int, const char *);
#endif
#ifdef _LARGEFILE64_SOURCE
# define z_off64_t off64_t
#else
# define z_off64_t z_off_t
#endif
/* default i/o buffer size -- double this for output when reading */
#define GZBUFSIZE 8192
/* gzip modes, also provide a little integrity check on the passed structure */
#define GZ_NONE 0
#define GZ_READ 7247
#define GZ_WRITE 31153
#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
/* values for gz_state how */
#define LOOK 0 /* look for a gzip header */
#define COPY 1 /* copy input directly */
#define GZIP 2 /* decompress a gzip stream */
/* internal gzip file state data structure */
typedef struct {
/* used for both reading and writing */
int mode; /* see gzip modes above */
int fd; /* file descriptor */
char *path; /* path or fd for error messages */
z_off64_t pos; /* current position in uncompressed data */
unsigned size; /* buffer size, zero if not allocated yet */
unsigned want; /* requested buffer size, default is GZBUFSIZE */
unsigned char *in; /* input buffer */
unsigned char *out; /* output buffer (double-sized when reading) */
unsigned char *next; /* next output data to deliver or write */
/* just for reading */
unsigned have; /* amount of output data unused at next */
int eof; /* true if end of input file reached */
z_off64_t start; /* where the gzip data started, for rewinding */
z_off64_t raw; /* where the raw data started, for seeking */
int how; /* 0: get header, 1: copy, 2: decompress */
int direct; /* true if last read direct, false if gzip */
/* just for writing */
int level; /* compression level */
int strategy; /* compression strategy */
/* seek request */
z_off64_t skip; /* amount to skip (already rewound if backwards) */
int seek; /* true if seek request pending */
/* error information */
int err; /* error code */
char *msg; /* error message */
/* zlib inflate or deflate stream */
z_stream strm; /* stream structure in-place (not a pointer) */
} gz_state;
typedef gz_state FAR *gz_statep;
/* shared functions */
ZEXTERN void ZEXPORT gz_error OF((gz_statep, int, const char *));
#if defined UNDER_CE && defined NO_ERRNO_H
ZEXTERN char ZEXPORT *gz_strwinerror OF((DWORD error));
#endif
/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
value -- needed when comparing unsigned to z_off64_t, which is signed
(possible z_off64_t types off_t, off64_t, and long are all signed) */
#ifdef INT_MAX
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
#else
ZEXTERN unsigned ZEXPORT gz_intmax OF((void));
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
#endif

1070
3rdparty/zlib/gzlib.c vendored

File diff suppressed because it is too large Load Diff

1304
3rdparty/zlib/gzread.c vendored

File diff suppressed because it is too large Load Diff

1062
3rdparty/zlib/gzwrite.c vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,66 +1,66 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "IopCommon.h"
using namespace R3000A;
void dev9Interrupt()
{
if ((dev9Handler != NULL) && (dev9Handler() != 1)) return;
iopIntcIrq(13);
hwIntcIrq(INTC_SBUS);
}
void dev9Irq(int cycles)
{
PSX_INT(IopEvt_DEV9, cycles);
}
void usbInterrupt()
{
if (usbHandler != NULL && (usbHandler() != 1)) return;
iopIntcIrq(22);
hwIntcIrq(INTC_SBUS);
}
void usbIrq(int cycles)
{
PSX_INT(IopEvt_USB, cycles);
}
void fwIrq()
{
iopIntcIrq(24);
hwIntcIrq(INTC_SBUS);
}
void spu2Irq()
{
#ifdef SPU2IRQTEST
Console.Warning("spu2Irq");
#endif
iopIntcIrq(9);
hwIntcIrq(INTC_SBUS);
}
void iopIntcIrq(uint irqType)
{
psxHu32(0x1070) |= 1 << irqType;
iopTestIntc();
}
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "IopCommon.h"
using namespace R3000A;
void dev9Interrupt()
{
if ((dev9Handler != NULL) && (dev9Handler() != 1)) return;
iopIntcIrq(13);
hwIntcIrq(INTC_SBUS);
}
void dev9Irq(int cycles)
{
PSX_INT(IopEvt_DEV9, cycles);
}
void usbInterrupt()
{
if (usbHandler != NULL && (usbHandler() != 1)) return;
iopIntcIrq(22);
hwIntcIrq(INTC_SBUS);
}
void usbIrq(int cycles)
{
PSX_INT(IopEvt_USB, cycles);
}
void fwIrq()
{
iopIntcIrq(24);
hwIntcIrq(INTC_SBUS);
}
void spu2Irq()
{
#ifdef SPU2IRQTEST
Console.Warning("spu2Irq");
#endif
iopIntcIrq(9);
hwIntcIrq(INTC_SBUS);
}
void iopIntcIrq(uint irqType)
{
psxHu32(0x1070) |= 1 << irqType;
iopTestIntc();
}

View File

@ -1,328 +1,328 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#define _PC_ // disables MIPS opcode macros.
#include "IopCommon.h"
#include "Sif.h"
_sif sif0;
static bool done = false;
static __forceinline void Sif0Init()
{
SIF_LOG("SIF0 DMA start...");
done = false;
sif0.ee.cycles = 0;
sif0.iop.cycles = 0;
}
// Write from Fifo to EE.
static __forceinline bool WriteFifoToEE()
{
const int readSize = min((s32)sif0dma->qwc, sif0.fifo.size >> 2);
tDMA_TAG *ptag;
//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr);
SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0dma->qwc << 2);
ptag = sif0dma->getAddr(sif0dma->madr, DMAC_SIF0, true);
if (ptag == NULL)
{
DevCon.Warning("Write Fifo to EE: ptag == NULL");
return false;
}
sif0.fifo.read((u32*)ptag, readSize << 2);
// Clearing handled by vtlb memory protection and manual blocks.
//Cpu->Clear(sif0dma->madr, readSize*4);
sif0dma->madr += readSize << 4;
sif0.ee.cycles += readSize; // fixme : BIAS is factored in above
sif0dma->qwc -= readSize;
return true;
}
// Write IOP to Fifo.
static __forceinline bool WriteIOPtoFifo()
{
// There's some data ready to transfer into the fifo..
const int writeSize = min(sif0.iop.counter, sif0.fifo.free());
SIF_LOG("Write IOP to Fifo: +++++++++++ %lX of %lX", writeSize, sif0.iop.counter);
sif0.fifo.write((u32*)iopPhysMem(hw_dma(9).madr), writeSize);
hw_dma(9).madr += writeSize << 2;
// iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords).
sif0.iop.cycles += (writeSize >> 2) * BIAS; // fixme : should be >> 4
sif0.iop.counter -= writeSize;
return true;
}
// Read Fifo into an ee tag, transfer it to sif0dma, and process it.
static __forceinline bool ProcessEETag()
{
static __aligned16 u32 tag[4];
sif0.fifo.read((u32*)&tag[0], 4); // Tag
SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]);
sif0dma->unsafeTransfer(((tDMA_TAG*)(tag)));
sif0dma->madr = tag[1];
tDMA_TAG ptag(tag[0]);
SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)",
sif0dma->madr, sif0dma->qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]);
if (sif0dma->chcr.TIE && ptag.IRQ)
{
//Console.WriteLn("SIF0 TIE");
sif0.ee.end = true;
}
switch (ptag.ID)
{
case TAG_REFE:
sif0.ee.end = true;
if (dmacRegs->ctrl.STS != NO_STS)
dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);
break;
case TAG_REFS:
if (dmacRegs->ctrl.STS != NO_STS)
dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);
break;
case TAG_END:
sif0.ee.end = true;
break;
}
return true;
}
// Read Fifo into an iop tag, and transfer it to hw_dma(9). And presumably process it.
static __forceinline bool ProcessIOPTag()
{
// Process DMA tag at hw_dma(9).tadr
sif0.iop.data = *(sifData *)iopPhysMem(hw_dma(9).tadr);
sif0.iop.data.words = (sif0.iop.data.words + 3) & 0xfffffffc; // Round up to nearest 4.
sif0.fifo.write((u32*)iopPhysMem(hw_dma(9).tadr + 8), 4);
hw_dma(9).tadr += 16; ///hw_dma(9).madr + 16 + sif0.sifData.words << 2;
// We're only copying the first 24 bits.
hw_dma(9).madr = sif0data & 0xFFFFFF;
sif0.iop.counter = sif0words;
if (sif0tag.IRQ || (sif0tag.ID & 4)) sif0.iop.end = true;
SIF_LOG("SIF0 IOP Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)", hw_dma(9).madr, hw_dma(9).tadr, sif0.iop.counter, sif0words, sif0data);
return true;
}
// Stop transferring ee, and signal an interrupt.
static __forceinline void EndEE()
{
SIF_LOG("Sif0: End EE");
sif0.ee.end = false;
sif0.ee.busy = false;
if (sif0.ee.cycles == 0)
{
SIF_LOG("SIF0 EE: cycles = 0");
sif0.ee.cycles = 1;
}
CPU_INT(DMAC_SIF0, sif0.ee.cycles*BIAS);
}
// Stop transferring iop, and signal an interrupt.
static __forceinline void EndIOP()
{
SIF_LOG("Sif0: End IOP");
sif0data = 0;
sif0.iop.end = false;
sif0.iop.busy = false;
if (sif0.iop.cycles == 0)
{
DevCon.Warning("SIF0 IOP: cycles = 0");
sif0.iop.cycles = 1;
}
// iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords)
// So when we're all done, the equation looks like thus:
//PSX_INT(IopEvt_SIF0, ( ( sif0.iop.cycles*BIAS ) / 4 ) / 8);
PSX_INT(IopEvt_SIF0, sif0.iop.cycles);
}
// Handle the EE transfer.
static __forceinline void HandleEETransfer()
{
if (dmacRegs->ctrl.STS == STS_SIF0)
{
DevCon.Warning("SIF0 stall control");
}
if (sif0dma->qwc == 0)
if (sif0dma->chcr.MOD == NORMAL_MODE)
if (!sif0.ee.end){
DevCon.Warning("sif0 irq prevented");
done = true;
return;
}
if (sif0dma->qwc <= 0)
{
if ((sif0dma->chcr.MOD == NORMAL_MODE) || sif0.ee.end)
{
// Stop transferring ee, and signal an interrupt.
done = true;
EndEE();
}
else if (sif0.fifo.size >= 4) // Read a tag
{
// Read Fifo into an ee tag, transfer it to sif0dma
// and process it.
ProcessEETag();
}
}
if (sif0dma->qwc > 0) // If we're writing something, continue to do so.
{
// Write from Fifo to EE.
if (sif0.fifo.size > 0)
{
WriteFifoToEE();
}
}
}
// Handle the IOP transfer.
// Note: Test any changes in this function against Grandia III.
// What currently happens is this:
// SIF0 DMA start...
// SIF + 4 = 4 (pos=4)
// SIF0 IOP Tag: madr=19870, tadr=179cc, counter=8 (00000008_80019870)
// SIF - 4 = 0 (pos=4)
// SIF0 EE read tag: 90000002 935c0 0 0
// SIF0 EE dest chain tag madr:000935C0 qwc:0002 id:1 irq:1(000935C0_90000002)
// Write Fifo to EE: ----------- 0 of 8
// SIF - 0 = 0 (pos=4)
// Write IOP to Fifo: +++++++++++ 8 of 8
// SIF + 8 = 8 (pos=12)
// Write Fifo to EE: ----------- 8 of 8
// SIF - 8 = 0 (pos=12)
// Sif0: End IOP
// Sif0: End EE
// SIF0 DMA end...
// What happens if (sif0.iop.counter > 0) is handled first is this
// SIF0 DMA start...
// ...
// SIF + 8 = 8 (pos=12)
// Sif0: End IOP
// Write Fifo to EE: ----------- 8 of 8
// SIF - 8 = 0 (pos=12)
// SIF0 DMA end...
static __forceinline void HandleIOPTransfer()
{
if (sif0.iop.counter <= 0) // If there's no more to transfer
{
if (sif0.iop.end)
{
// Stop transferring iop, and signal an interrupt.
done = true;
EndIOP();
}
else
{
// Read Fifo into an iop tag, and transfer it to hw_dma(9).
// And presumably process it.
ProcessIOPTag();
}
}
else
{
// Write IOP to Fifo.
if (sif0.fifo.free() > 0)
{
WriteIOPtoFifo();
}
}
}
static __forceinline void Sif0End()
{
SIF_LOG("SIF0 DMA end...");
}
// Transfer IOP to EE, putting data in the fifo as an intermediate step.
__forceinline void SIF0Dma()
{
Sif0Init();
do
{
if (sif0.iop.busy) HandleIOPTransfer();
if (sif0.ee.busy) HandleEETransfer();
} while (!done); // Substituting (sif0.ee.busy || sif0.iop.busy) breaks things.
Sif0End();
}
__forceinline void sif0Interrupt()
{
HW_DMA9_CHCR &= ~0x01000000;
psxDmaInterrupt2(2);
}
__forceinline void EEsif0Interrupt()
{
hwDmacIrq(DMAC_SIF0);
sif0dma->chcr.STR = false;
}
__forceinline void dmaSIF0()
{
SIF_LOG(wxString(L"dmaSIF0" + sif0dma->cmqt_to_str()).To8BitData());
if (sif0.fifo.readPos != sif0.fifo.writePos)
{
SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos");
}
if(sif0dma->chcr.MOD == CHAIN_MODE && sif0dma->qwc > 0) DevCon.Warning(L"SIF0 QWC on Chain CHCR " + sif0dma->chcr.desc());
psHu32(SBUS_F240) |= 0x2000;
sif0.ee.busy = true;
if (sif0.iop.busy)
{
XMMRegisters::Freeze();
hwIntcIrq(INTC_SBUS);
SIF0Dma();
psHu32(SBUS_F240) &= ~0x20;
psHu32(SBUS_F240) &= ~0x2000;
XMMRegisters::Thaw();
}
}
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#define _PC_ // disables MIPS opcode macros.
#include "IopCommon.h"
#include "Sif.h"
_sif sif0;
static bool done = false;
static __forceinline void Sif0Init()
{
SIF_LOG("SIF0 DMA start...");
done = false;
sif0.ee.cycles = 0;
sif0.iop.cycles = 0;
}
// Write from Fifo to EE.
static __forceinline bool WriteFifoToEE()
{
const int readSize = min((s32)sif0dma->qwc, sif0.fifo.size >> 2);
tDMA_TAG *ptag;
//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr);
SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0dma->qwc << 2);
ptag = sif0dma->getAddr(sif0dma->madr, DMAC_SIF0, true);
if (ptag == NULL)
{
DevCon.Warning("Write Fifo to EE: ptag == NULL");
return false;
}
sif0.fifo.read((u32*)ptag, readSize << 2);
// Clearing handled by vtlb memory protection and manual blocks.
//Cpu->Clear(sif0dma->madr, readSize*4);
sif0dma->madr += readSize << 4;
sif0.ee.cycles += readSize; // fixme : BIAS is factored in above
sif0dma->qwc -= readSize;
return true;
}
// Write IOP to Fifo.
static __forceinline bool WriteIOPtoFifo()
{
// There's some data ready to transfer into the fifo..
const int writeSize = min(sif0.iop.counter, sif0.fifo.free());
SIF_LOG("Write IOP to Fifo: +++++++++++ %lX of %lX", writeSize, sif0.iop.counter);
sif0.fifo.write((u32*)iopPhysMem(hw_dma(9).madr), writeSize);
hw_dma(9).madr += writeSize << 2;
// iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords).
sif0.iop.cycles += (writeSize >> 2) * BIAS; // fixme : should be >> 4
sif0.iop.counter -= writeSize;
return true;
}
// Read Fifo into an ee tag, transfer it to sif0dma, and process it.
static __forceinline bool ProcessEETag()
{
static __aligned16 u32 tag[4];
sif0.fifo.read((u32*)&tag[0], 4); // Tag
SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]);
sif0dma->unsafeTransfer(((tDMA_TAG*)(tag)));
sif0dma->madr = tag[1];
tDMA_TAG ptag(tag[0]);
SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)",
sif0dma->madr, sif0dma->qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]);
if (sif0dma->chcr.TIE && ptag.IRQ)
{
//Console.WriteLn("SIF0 TIE");
sif0.ee.end = true;
}
switch (ptag.ID)
{
case TAG_REFE:
sif0.ee.end = true;
if (dmacRegs->ctrl.STS != NO_STS)
dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);
break;
case TAG_REFS:
if (dmacRegs->ctrl.STS != NO_STS)
dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);
break;
case TAG_END:
sif0.ee.end = true;
break;
}
return true;
}
// Read Fifo into an iop tag, and transfer it to hw_dma(9). And presumably process it.
static __forceinline bool ProcessIOPTag()
{
// Process DMA tag at hw_dma(9).tadr
sif0.iop.data = *(sifData *)iopPhysMem(hw_dma(9).tadr);
sif0.iop.data.words = (sif0.iop.data.words + 3) & 0xfffffffc; // Round up to nearest 4.
sif0.fifo.write((u32*)iopPhysMem(hw_dma(9).tadr + 8), 4);
hw_dma(9).tadr += 16; ///hw_dma(9).madr + 16 + sif0.sifData.words << 2;
// We're only copying the first 24 bits.
hw_dma(9).madr = sif0data & 0xFFFFFF;
sif0.iop.counter = sif0words;
if (sif0tag.IRQ || (sif0tag.ID & 4)) sif0.iop.end = true;
SIF_LOG("SIF0 IOP Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)", hw_dma(9).madr, hw_dma(9).tadr, sif0.iop.counter, sif0words, sif0data);
return true;
}
// Stop transferring ee, and signal an interrupt.
static __forceinline void EndEE()
{
SIF_LOG("Sif0: End EE");
sif0.ee.end = false;
sif0.ee.busy = false;
if (sif0.ee.cycles == 0)
{
SIF_LOG("SIF0 EE: cycles = 0");
sif0.ee.cycles = 1;
}
CPU_INT(DMAC_SIF0, sif0.ee.cycles*BIAS);
}
// Stop transferring iop, and signal an interrupt.
static __forceinline void EndIOP()
{
SIF_LOG("Sif0: End IOP");
sif0data = 0;
sif0.iop.end = false;
sif0.iop.busy = false;
if (sif0.iop.cycles == 0)
{
DevCon.Warning("SIF0 IOP: cycles = 0");
sif0.iop.cycles = 1;
}
// iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords)
// So when we're all done, the equation looks like thus:
//PSX_INT(IopEvt_SIF0, ( ( sif0.iop.cycles*BIAS ) / 4 ) / 8);
PSX_INT(IopEvt_SIF0, sif0.iop.cycles);
}
// Handle the EE transfer.
static __forceinline void HandleEETransfer()
{
if (dmacRegs->ctrl.STS == STS_SIF0)
{
DevCon.Warning("SIF0 stall control");
}
if (sif0dma->qwc == 0)
if (sif0dma->chcr.MOD == NORMAL_MODE)
if (!sif0.ee.end){
DevCon.Warning("sif0 irq prevented");
done = true;
return;
}
if (sif0dma->qwc <= 0)
{
if ((sif0dma->chcr.MOD == NORMAL_MODE) || sif0.ee.end)
{
// Stop transferring ee, and signal an interrupt.
done = true;
EndEE();
}
else if (sif0.fifo.size >= 4) // Read a tag
{
// Read Fifo into an ee tag, transfer it to sif0dma
// and process it.
ProcessEETag();
}
}
if (sif0dma->qwc > 0) // If we're writing something, continue to do so.
{
// Write from Fifo to EE.
if (sif0.fifo.size > 0)
{
WriteFifoToEE();
}
}
}
// Handle the IOP transfer.
// Note: Test any changes in this function against Grandia III.
// What currently happens is this:
// SIF0 DMA start...
// SIF + 4 = 4 (pos=4)
// SIF0 IOP Tag: madr=19870, tadr=179cc, counter=8 (00000008_80019870)
// SIF - 4 = 0 (pos=4)
// SIF0 EE read tag: 90000002 935c0 0 0
// SIF0 EE dest chain tag madr:000935C0 qwc:0002 id:1 irq:1(000935C0_90000002)
// Write Fifo to EE: ----------- 0 of 8
// SIF - 0 = 0 (pos=4)
// Write IOP to Fifo: +++++++++++ 8 of 8
// SIF + 8 = 8 (pos=12)
// Write Fifo to EE: ----------- 8 of 8
// SIF - 8 = 0 (pos=12)
// Sif0: End IOP
// Sif0: End EE
// SIF0 DMA end...
// What happens if (sif0.iop.counter > 0) is handled first is this
// SIF0 DMA start...
// ...
// SIF + 8 = 8 (pos=12)
// Sif0: End IOP
// Write Fifo to EE: ----------- 8 of 8
// SIF - 8 = 0 (pos=12)
// SIF0 DMA end...
static __forceinline void HandleIOPTransfer()
{
if (sif0.iop.counter <= 0) // If there's no more to transfer
{
if (sif0.iop.end)
{
// Stop transferring iop, and signal an interrupt.
done = true;
EndIOP();
}
else
{
// Read Fifo into an iop tag, and transfer it to hw_dma(9).
// And presumably process it.
ProcessIOPTag();
}
}
else
{
// Write IOP to Fifo.
if (sif0.fifo.free() > 0)
{
WriteIOPtoFifo();
}
}
}
static __forceinline void Sif0End()
{
SIF_LOG("SIF0 DMA end...");
}
// Transfer IOP to EE, putting data in the fifo as an intermediate step.
__forceinline void SIF0Dma()
{
Sif0Init();
do
{
if (sif0.iop.busy) HandleIOPTransfer();
if (sif0.ee.busy) HandleEETransfer();
} while (!done); // Substituting (sif0.ee.busy || sif0.iop.busy) breaks things.
Sif0End();
}
__forceinline void sif0Interrupt()
{
HW_DMA9_CHCR &= ~0x01000000;
psxDmaInterrupt2(2);
}
__forceinline void EEsif0Interrupt()
{
hwDmacIrq(DMAC_SIF0);
sif0dma->chcr.STR = false;
}
__forceinline void dmaSIF0()
{
SIF_LOG(wxString(L"dmaSIF0" + sif0dma->cmqt_to_str()).To8BitData());
if (sif0.fifo.readPos != sif0.fifo.writePos)
{
SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos");
}
if(sif0dma->chcr.MOD == CHAIN_MODE && sif0dma->qwc > 0) DevCon.Warning(L"SIF0 QWC on Chain CHCR " + sif0dma->chcr.desc());
psHu32(SBUS_F240) |= 0x2000;
sif0.ee.busy = true;
if (sif0.iop.busy)
{
XMMRegisters::Freeze();
hwIntcIrq(INTC_SBUS);
SIF0Dma();
psHu32(SBUS_F240) &= ~0x20;
psHu32(SBUS_F240) &= ~0x2000;
XMMRegisters::Thaw();
}
}

View File

@ -1,102 +1,102 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "VUmicro.h"
#define useDeltaTime 1
#if useDeltaTime
// Executes a Block based on EE delta time
void BaseVUmicroCPU::ExecuteBlock(bool startUp) {
const u32& stat = VU0.VI[REG_VPU_STAT].UL;
const int test = m_Idx ? 0x100 : 1;
const int s = 1024*6; // Kick Start Cycles (Silver Surfer needs this amount)
const int c = 1024*1; // Continue Cycles
if (!(stat & test)) return;
if (startUp) { // Start Executing a microprogram
Execute(s); // Kick start VU
// Let VUs run behind EE instead of ahead
if (stat & test) {
cpuSetNextBranchDelta((s+c)*2);
m_lastEEcycles = cpuRegs.cycle + (s*2);
}
}
else { // Continue Executing (VU roughly half the mhz of EE)
s32 delta = (s32)(u32)(cpuRegs.cycle - m_lastEEcycles) & ~1;
if (delta > 0) { // Enough time has passed
delta >>= 1; // Divide by 2 (unsigned)
Execute(delta); // Execute the time since the last call
if (stat & test) {
cpuSetNextBranchDelta(c*2);
m_lastEEcycles = cpuRegs.cycle;
}
}
else cpuSetNextBranchDelta(-delta); // Haven't caught-up from kick start
}
}
// This function is called by VU0 Macro (COP2) after transferring some
// EE data to VU0's registers. We want to run VU0 Micro right after this
// to ensure that the register is used at the correct time.
// This fixes spinning/hanging in some games like Ratchet and Clank's Intro.
void __fastcall BaseVUmicroCPU::ExecuteBlockJIT(BaseVUmicroCPU* cpu) {
const u32& stat = VU0.VI[REG_VPU_STAT].UL;
const int test = cpu->m_Idx ? 0x100 : 1;
const int c = 128; // VU Execution Cycles
if (stat & test) { // VU is running
cpu->Execute(c); // Execute VU
if (stat & test) {
cpu->m_lastEEcycles+=(c*2);
cpuSetNextBranchDelta(c*2);
}
}
}
#else
// Executes a Block based on static preset cycles
void BaseVUmicroCPU::ExecuteBlock(bool startUp) {
const int vuRunning = m_Idx ? 0x100 : 1;
if (!(VU0.VI[REG_VPU_STAT].UL & vuRunning)) return;
if (startUp) { // Start Executing a microprogram
Execute(vu0RunCycles); // Kick start VU
// If the VU0 program didn't finish then we'll want to finish it up
// pretty soon. This fixes vmhacks in some games (Naruto Ultimate Ninja 2)
if(VU0.VI[REG_VPU_STAT].UL & vuRunning)
cpuSetNextBranchDelta( 192 ); // fixme : ideally this should be higher, like 512 or so.
}
else {
Execute(vu0RunCycles);
//DevCon.Warning("VU0 running when in BranchTest");
// This helps keep the EE and VU0 in sync.
// Check Silver Surfer. Currently has SPS varying with different branch deltas set below.
if(VU0.VI[REG_VPU_STAT].UL & vuRunning)
cpuSetNextBranchDelta( 768 );
}
}
// This function is called by VU0 Macro (COP2) after transferring
// EE data to a VU0 register...
void __fastcall BaseVUmicroCPU::ExecuteBlockJIT(BaseVUmicroCPU* cpu) {
cpu->Execute(128);
}
#endif
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "VUmicro.h"
#define useDeltaTime 1
#if useDeltaTime
// Executes a Block based on EE delta time
void BaseVUmicroCPU::ExecuteBlock(bool startUp) {
const u32& stat = VU0.VI[REG_VPU_STAT].UL;
const int test = m_Idx ? 0x100 : 1;
const int s = 1024*6; // Kick Start Cycles (Silver Surfer needs this amount)
const int c = 1024*1; // Continue Cycles
if (!(stat & test)) return;
if (startUp) { // Start Executing a microprogram
Execute(s); // Kick start VU
// Let VUs run behind EE instead of ahead
if (stat & test) {
cpuSetNextBranchDelta((s+c)*2);
m_lastEEcycles = cpuRegs.cycle + (s*2);
}
}
else { // Continue Executing (VU roughly half the mhz of EE)
s32 delta = (s32)(u32)(cpuRegs.cycle - m_lastEEcycles) & ~1;
if (delta > 0) { // Enough time has passed
delta >>= 1; // Divide by 2 (unsigned)
Execute(delta); // Execute the time since the last call
if (stat & test) {
cpuSetNextBranchDelta(c*2);
m_lastEEcycles = cpuRegs.cycle;
}
}
else cpuSetNextBranchDelta(-delta); // Haven't caught-up from kick start
}
}
// This function is called by VU0 Macro (COP2) after transferring some
// EE data to VU0's registers. We want to run VU0 Micro right after this
// to ensure that the register is used at the correct time.
// This fixes spinning/hanging in some games like Ratchet and Clank's Intro.
void __fastcall BaseVUmicroCPU::ExecuteBlockJIT(BaseVUmicroCPU* cpu) {
const u32& stat = VU0.VI[REG_VPU_STAT].UL;
const int test = cpu->m_Idx ? 0x100 : 1;
const int c = 128; // VU Execution Cycles
if (stat & test) { // VU is running
cpu->Execute(c); // Execute VU
if (stat & test) {
cpu->m_lastEEcycles+=(c*2);
cpuSetNextBranchDelta(c*2);
}
}
}
#else
// Executes a Block based on static preset cycles
void BaseVUmicroCPU::ExecuteBlock(bool startUp) {
const int vuRunning = m_Idx ? 0x100 : 1;
if (!(VU0.VI[REG_VPU_STAT].UL & vuRunning)) return;
if (startUp) { // Start Executing a microprogram
Execute(vu0RunCycles); // Kick start VU
// If the VU0 program didn't finish then we'll want to finish it up
// pretty soon. This fixes vmhacks in some games (Naruto Ultimate Ninja 2)
if(VU0.VI[REG_VPU_STAT].UL & vuRunning)
cpuSetNextBranchDelta( 192 ); // fixme : ideally this should be higher, like 512 or so.
}
else {
Execute(vu0RunCycles);
//DevCon.Warning("VU0 running when in BranchTest");
// This helps keep the EE and VU0 in sync.
// Check Silver Surfer. Currently has SPS varying with different branch deltas set below.
if(VU0.VI[REG_VPU_STAT].UL & vuRunning)
cpuSetNextBranchDelta( 768 );
}
}
// This function is called by VU0 Macro (COP2) after transferring
// EE data to a VU0 register...
void __fastcall BaseVUmicroCPU::ExecuteBlockJIT(BaseVUmicroCPU* cpu) {
cpu->Execute(128);
}
#endif

View File

@ -1,220 +1,220 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "Vif_Dma.h"
#include "VUmicro.h"
#include "newVif.h"
// Run VU0 until finish, don't add cycles to EE
// because its vif stalling not the EE core...
__forceinline void vif0FLUSH()
{
if (!(VU0.VI[REG_VPU_STAT].UL & 1)) return;
int _cycles = VU0.cycle;
vu0Finish();
g_vifCycles += (VU0.cycle - _cycles) * BIAS;
}
bool _VIF0chain()
{
u32 *pMem;
if (vif0ch->qwc == 0)
{
vif0.inprogress = 0;
return true;
}
pMem = (u32*)dmaGetAddr(vif0ch->madr, false);
if (pMem == NULL)
{
vif0.cmd = 0;
vif0.tag.size = 0;
vif0ch->qwc = 0;
return true;
}
VIF_LOG("VIF0chain size=%d, madr=%lx, tadr=%lx",
vif0ch->qwc, vif0ch->madr, vif0ch->tadr);
if (vif0.vifstalled)
return VIF0transfer(pMem + vif0.irqoffset, vif0ch->qwc * 4 - vif0.irqoffset, false);
else
return VIF0transfer(pMem, vif0ch->qwc * 4, false);
}
__forceinline void vif0SetupTransfer()
{
tDMA_TAG *ptag;
switch (vif0.dmamode)
{
case VIF_NORMAL_TO_MEM_MODE:
vif0.inprogress = 1;
vif0.done = true;
g_vifCycles = 2;
break;
case VIF_CHAIN_MODE:
ptag = dmaGetAddr(vif0ch->tadr, false); //Set memory pointer to TADR
if (!(vif0ch->transfer("vif0 Tag", ptag))) return;
vif0ch->madr = ptag[1]._u32; //MADR = ADDR field + SPR
g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag
// Transfer dma tag if tte is set
VIF_LOG("vif0 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n",
ptag[1]._u32, ptag[0]._u32, vif0ch->qwc, ptag->ID, vif0ch->madr, vif0ch->tadr);
vif0.inprogress = 1;
if (vif0ch->chcr.TTE)
{
bool ret;
if (vif0.vifstalled)
ret = VIF0transfer((u32*)ptag + (2 + vif0.irqoffset), 2 - vif0.irqoffset, true); //Transfer Tag on stall
else
ret = VIF0transfer((u32*)ptag + 2, 2, true); //Transfer Tag
if ((ret == false) && vif0.irqoffset < 2)
{
vif0.inprogress = 0; //Better clear this so it has to do it again (Jak 1)
return; //There has been an error or an interrupt
}
}
vif0.irqoffset = 0;
vif0.done |= hwDmacSrcChainWithStack(vif0ch, ptag->ID);
//Check TIE bit of CHCR and IRQ bit of tag
if (vif0ch->chcr.TIE && ptag->IRQ)
{
VIF_LOG("dmaIrq Set");
//End Transfer
vif0.done = true;
return;
}
break;
}
}
__forceinline void vif0Interrupt()
{
VIF_LOG("vif0Interrupt: %8.8x", cpuRegs.cycle);
g_vifCycles = 0;
if (!(vif0ch->chcr.STR)) Console.WriteLn("vif0 running when CHCR == %x", vif0ch->chcr._u32);
if (vif0.irq && vif0.tag.size == 0)
{
vif0Regs->stat.INT = true;
hwIntcIrq(VIF0intc);
--vif0.irq;
if (vif0Regs->stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
{
vif0Regs->stat.FQC = 0;
// One game doesn't like vif stalling at end, can't remember what. Spiderman isn't keen on it tho
vif0ch->chcr.STR = false;
return;
}
else if ((vif0ch->qwc > 0) || (vif0.irqoffset > 0))
{
if (vif0.stallontag)
vif0SetupTransfer();
else
_VIF0chain();//CPU_INT(DMAC_STALL_SIS, vif0ch->qwc * BIAS);
}
}
if (vif0.inprogress & 0x1)
{
_VIF0chain();
// VIF_NORMAL_FROM_MEM_MODE is a very slow operation.
// Timesplitters 2 depends on this beeing a bit higher than 128.
if (vif0.dmamode == VIF_NORMAL_FROM_MEM_MODE ) CPU_INT(DMAC_VIF0, 1024);
else CPU_INT(DMAC_VIF0, g_vifCycles);
return;
}
if (!vif0.done)
{
if (!(dmacRegs->ctrl.DMAE))
{
Console.WriteLn("vif0 dma masked");
return;
}
if ((vif0.inprogress & 0x1) == 0) vif0SetupTransfer();
CPU_INT(DMAC_VIF0, g_vifCycles);
return;
}
if (vif0.vifstalled && vif0.irq)
{
DevCon.WriteLn("VIF0 looping on stall\n");
CPU_INT(DMAC_VIF0, 0);
return; //Dont want to end if vif is stalled.
}
#ifdef PCSX2_DEVBUILD
if (vif0ch->qwc > 0) Console.WriteLn("vif0 Ending with %x QWC left");
if (vif0.cmd != 0) Console.WriteLn("vif0.cmd still set %x tag size %x", vif0.cmd, vif0.tag.size);
#endif
vif0Regs->stat.VPS = VPS_IDLE; //Vif goes idle as the stall happened between commands;
vif0ch->chcr.STR = false;
g_vifCycles = 0;
hwDmacIrq(DMAC_VIF0);
vif0Regs->stat.FQC = 0;
}
void dmaVIF0()
{
VIF_LOG("dmaVIF0 chcr = %lx, madr = %lx, qwc = %lx\n"
" tadr = %lx, asr0 = %lx, asr1 = %lx",
vif0ch->chcr._u32, vif0ch->madr, vif0ch->qwc,
vif0ch->tadr, vif0ch->asr0, vif0ch->asr1);
g_vifCycles = 0;
vif0.inprogress = 0;
if ((vif0ch->chcr.MOD == NORMAL_MODE) || vif0ch->qwc > 0) // Normal Mode
{
vif0.dmamode = VIF_NORMAL_TO_MEM_MODE;
if(vif0ch->chcr.MOD == CHAIN_MODE && vif0ch->qwc > 0) DevCon.Warning(L"VIF0 QWC on Chain CHCR " + vif0ch->chcr.desc());
}
else
{
vif0.dmamode = VIF_CHAIN_MODE;
}
if (vif0.dmamode != VIF_NORMAL_FROM_MEM_MODE)
vif0Regs->stat.FQC = 0x8;
else
vif0Regs->stat.FQC = min((u16)0x8, vif0ch->qwc);
// Chain Mode
vif0.done = false;
vif0Interrupt();
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "Vif_Dma.h"
#include "VUmicro.h"
#include "newVif.h"
// Run VU0 until finish, don't add cycles to EE
// because its vif stalling not the EE core...
__forceinline void vif0FLUSH()
{
if (!(VU0.VI[REG_VPU_STAT].UL & 1)) return;
int _cycles = VU0.cycle;
vu0Finish();
g_vifCycles += (VU0.cycle - _cycles) * BIAS;
}
bool _VIF0chain()
{
u32 *pMem;
if (vif0ch->qwc == 0)
{
vif0.inprogress = 0;
return true;
}
pMem = (u32*)dmaGetAddr(vif0ch->madr, false);
if (pMem == NULL)
{
vif0.cmd = 0;
vif0.tag.size = 0;
vif0ch->qwc = 0;
return true;
}
VIF_LOG("VIF0chain size=%d, madr=%lx, tadr=%lx",
vif0ch->qwc, vif0ch->madr, vif0ch->tadr);
if (vif0.vifstalled)
return VIF0transfer(pMem + vif0.irqoffset, vif0ch->qwc * 4 - vif0.irqoffset, false);
else
return VIF0transfer(pMem, vif0ch->qwc * 4, false);
}
__forceinline void vif0SetupTransfer()
{
tDMA_TAG *ptag;
switch (vif0.dmamode)
{
case VIF_NORMAL_TO_MEM_MODE:
vif0.inprogress = 1;
vif0.done = true;
g_vifCycles = 2;
break;
case VIF_CHAIN_MODE:
ptag = dmaGetAddr(vif0ch->tadr, false); //Set memory pointer to TADR
if (!(vif0ch->transfer("vif0 Tag", ptag))) return;
vif0ch->madr = ptag[1]._u32; //MADR = ADDR field + SPR
g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag
// Transfer dma tag if tte is set
VIF_LOG("vif0 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n",
ptag[1]._u32, ptag[0]._u32, vif0ch->qwc, ptag->ID, vif0ch->madr, vif0ch->tadr);
vif0.inprogress = 1;
if (vif0ch->chcr.TTE)
{
bool ret;
if (vif0.vifstalled)
ret = VIF0transfer((u32*)ptag + (2 + vif0.irqoffset), 2 - vif0.irqoffset, true); //Transfer Tag on stall
else
ret = VIF0transfer((u32*)ptag + 2, 2, true); //Transfer Tag
if ((ret == false) && vif0.irqoffset < 2)
{
vif0.inprogress = 0; //Better clear this so it has to do it again (Jak 1)
return; //There has been an error or an interrupt
}
}
vif0.irqoffset = 0;
vif0.done |= hwDmacSrcChainWithStack(vif0ch, ptag->ID);
//Check TIE bit of CHCR and IRQ bit of tag
if (vif0ch->chcr.TIE && ptag->IRQ)
{
VIF_LOG("dmaIrq Set");
//End Transfer
vif0.done = true;
return;
}
break;
}
}
__forceinline void vif0Interrupt()
{
VIF_LOG("vif0Interrupt: %8.8x", cpuRegs.cycle);
g_vifCycles = 0;
if (!(vif0ch->chcr.STR)) Console.WriteLn("vif0 running when CHCR == %x", vif0ch->chcr._u32);
if (vif0.irq && vif0.tag.size == 0)
{
vif0Regs->stat.INT = true;
hwIntcIrq(VIF0intc);
--vif0.irq;
if (vif0Regs->stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
{
vif0Regs->stat.FQC = 0;
// One game doesn't like vif stalling at end, can't remember what. Spiderman isn't keen on it tho
vif0ch->chcr.STR = false;
return;
}
else if ((vif0ch->qwc > 0) || (vif0.irqoffset > 0))
{
if (vif0.stallontag)
vif0SetupTransfer();
else
_VIF0chain();//CPU_INT(DMAC_STALL_SIS, vif0ch->qwc * BIAS);
}
}
if (vif0.inprogress & 0x1)
{
_VIF0chain();
// VIF_NORMAL_FROM_MEM_MODE is a very slow operation.
// Timesplitters 2 depends on this beeing a bit higher than 128.
if (vif0.dmamode == VIF_NORMAL_FROM_MEM_MODE ) CPU_INT(DMAC_VIF0, 1024);
else CPU_INT(DMAC_VIF0, g_vifCycles);
return;
}
if (!vif0.done)
{
if (!(dmacRegs->ctrl.DMAE))
{
Console.WriteLn("vif0 dma masked");
return;
}
if ((vif0.inprogress & 0x1) == 0) vif0SetupTransfer();
CPU_INT(DMAC_VIF0, g_vifCycles);
return;
}
if (vif0.vifstalled && vif0.irq)
{
DevCon.WriteLn("VIF0 looping on stall\n");
CPU_INT(DMAC_VIF0, 0);
return; //Dont want to end if vif is stalled.
}
#ifdef PCSX2_DEVBUILD
if (vif0ch->qwc > 0) Console.WriteLn("vif0 Ending with %x QWC left");
if (vif0.cmd != 0) Console.WriteLn("vif0.cmd still set %x tag size %x", vif0.cmd, vif0.tag.size);
#endif
vif0Regs->stat.VPS = VPS_IDLE; //Vif goes idle as the stall happened between commands;
vif0ch->chcr.STR = false;
g_vifCycles = 0;
hwDmacIrq(DMAC_VIF0);
vif0Regs->stat.FQC = 0;
}
void dmaVIF0()
{
VIF_LOG("dmaVIF0 chcr = %lx, madr = %lx, qwc = %lx\n"
" tadr = %lx, asr0 = %lx, asr1 = %lx",
vif0ch->chcr._u32, vif0ch->madr, vif0ch->qwc,
vif0ch->tadr, vif0ch->asr0, vif0ch->asr1);
g_vifCycles = 0;
vif0.inprogress = 0;
if ((vif0ch->chcr.MOD == NORMAL_MODE) || vif0ch->qwc > 0) // Normal Mode
{
vif0.dmamode = VIF_NORMAL_TO_MEM_MODE;
if(vif0ch->chcr.MOD == CHAIN_MODE && vif0ch->qwc > 0) DevCon.Warning(L"VIF0 QWC on Chain CHCR " + vif0ch->chcr.desc());
}
else
{
vif0.dmamode = VIF_CHAIN_MODE;
}
if (vif0.dmamode != VIF_NORMAL_FROM_MEM_MODE)
vif0Regs->stat.FQC = 0x8;
else
vif0Regs->stat.FQC = min((u16)0x8, vif0ch->qwc);
// Chain Mode
vif0.done = false;
vif0Interrupt();
}

View File

@ -1,347 +1,347 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "Vif_Dma.h"
#include "GS.h"
#include "Gif.h"
#include "VUmicro.h"
#include "newVif.h"
__forceinline void vif1FLUSH()
{
if (!(VU0.VI[REG_VPU_STAT].UL & 0x100)) return;
int _cycles = VU1.cycle;
vu1Finish();
g_vifCycles += (VU1.cycle - _cycles) * BIAS;
}
void vif1TransferToMemory()
{
int size;
u64* pMem = (u64*)dmaGetAddr(vif1ch->madr, false);
// VIF from gsMemory
if (pMem == NULL) //Is vif0ptag empty?
{
Console.WriteLn("Vif1 Tag BUSERR");
dmacRegs->stat.BEIS = true; //Bus Error
vif1Regs->stat.FQC = 0;
vif1ch->qwc = 0;
vif1.done = true;
CPU_INT(DMAC_VIF1, 0);
return; //An error has occurred.
}
// MTGS concerns: The MTGS is inherently disagreeable with the idea of downloading
// stuff from the GS. The *only* way to handle this case safely is to flush the GS
// completely and execute the transfer there-after.
//Console.Warning("Real QWC %x", vif1ch->qwc);
XMMRegisters::Freeze();
if (GSreadFIFO2 == NULL)
{
for (size = vif1ch->qwc; size > 0; --size)
{
if (size > 1)
{
GetMTGS().WaitGS();
GSreadFIFO(&psHu64(VIF1_FIFO));
}
pMem[0] = psHu64(VIF1_FIFO);
pMem[1] = psHu64(VIF1_FIFO + 8);
pMem += 2;
}
}
else
{
GetMTGS().WaitGS();
GSreadFIFO2(pMem, vif1ch->qwc);
// set incase read
psHu64(VIF1_FIFO) = pMem[2*vif1ch->qwc-2];
psHu64(VIF1_FIFO + 8) = pMem[2*vif1ch->qwc-1];
}
XMMRegisters::Thaw();
g_vifCycles += vif1ch->qwc * 2;
vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes
if(vif1.GSLastTRXPOS > vif1ch->qwc)
vif1Regs->stat.FQC = vif1.GSLastTRXPOS - vif1ch->qwc;
else
vif1Regs->stat.FQC = 0;
vif1ch->qwc = 0;
}
bool _VIF1chain()
{
u32 *pMem;
if (vif1ch->qwc == 0)
{
vif1.inprogress = 0;
return true;
}
// Clarification - this is TO memory mode, for some reason i used the other way round >.<
if (vif1.dmamode == VIF_NORMAL_TO_MEM_MODE)
{
vif1TransferToMemory();
vif1.inprogress = 0;
return true;
}
pMem = (u32*)dmaGetAddr(vif1ch->madr, !vif1ch->chcr.DIR);
if (pMem == NULL)
{
vif1.cmd = 0;
vif1.tag.size = 0;
vif1ch->qwc = 0;
return true;
}
VIF_LOG("VIF1chain size=%d, madr=%lx, tadr=%lx",
vif1ch->qwc, vif1ch->madr, vif1ch->tadr);
if (vif1.vifstalled)
return VIF1transfer(pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset, false);
else
return VIF1transfer(pMem, vif1ch->qwc * 4, false);
}
__forceinline void vif1SetupTransfer()
{
tDMA_TAG *ptag;
switch (vif1.dmamode)
{
case VIF_NORMAL_TO_MEM_MODE:
case VIF_NORMAL_FROM_MEM_MODE:
vif1.inprogress = 1;
vif1.done = true;
g_vifCycles = 2;
break;
case VIF_CHAIN_MODE:
ptag = dmaGetAddr(vif1ch->tadr, false); //Set memory pointer to TADR
if (!(vif1ch->transfer("Vif1 Tag", ptag))) return;
vif1ch->madr = ptag[1]._u32; //MADR = ADDR field + SPR
g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag
// Transfer dma tag if tte is set
VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n",
ptag[1]._u32, ptag[0]._u32, vif1ch->qwc, ptag->ID, vif1ch->madr, vif1ch->tadr);
if (!vif1.done && ((dmacRegs->ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1
{
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
if ((vif1ch->madr + vif1ch->qwc * 16) >= dmacRegs->stadr.ADDR)
{
// stalled
hwDmacIrq(DMAC_STALL_SIS);
return;
}
}
vif1.inprogress = 1;
if (vif1ch->chcr.TTE)
{
bool ret;
if (vif1.vifstalled)
ret = VIF1transfer((u32*)ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset, true); //Transfer Tag on stall
else
ret = VIF1transfer((u32*)ptag + 2, 2, true); //Transfer Tag
if ((ret == false) && 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
}
}
vif1.irqoffset = 0;
vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID);
//Check TIE bit of CHCR and IRQ bit of tag
if (vif1ch->chcr.TIE && ptag->IRQ)
{
VIF_LOG("dmaIrq Set");
//End Transfer
vif1.done = true;
return;
}
break;
}
}
__forceinline void vif1Interrupt()
{
VIF_LOG("vif1Interrupt: %8.8x", cpuRegs.cycle);
g_vifCycles = 0;
//Some games (Fahrenheit being one) start vif first, let it loop through blankness while it sets MFIFO mode, so we need to check it here.
if (dmacRegs->ctrl.MFD == MFD_VIF1) // VIF MFIFO
{
//Console.WriteLn("VIFMFIFO\n");
// Test changed because the Final Fantasy 12 opening somehow has the tag in *Undefined* mode, which is not in the documentation that I saw.
if (vif1ch->chcr.MOD == NORMAL_MODE) Console.WriteLn("MFIFO mode is normal (which isn't normal here)! %x", vif1ch->chcr._u32);
vif1Regs->stat.FQC = min((u16)0x10, vif1ch->qwc);
vifMFIFOInterrupt();
return;
}
if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
//Simulated GS transfer time done, clear the flags
if(gifRegs->stat.APATH == GIF_APATH2 && (vif1.cmd & 0x70) != 0x50)
{
gifRegs->stat.clear_flags(GIF_STAT_APATH2|GIF_STAT_OPH);
}
if (schedulepath3msk) Vif1MskPath3();
if ((vif1Regs->stat.VGW))
{
if (GSTransferStatus.PTH3 < STOPPED_MODE || GSTransferStatus.PTH1 != STOPPED_MODE)
{
CPU_INT(DMAC_VIF1, 4);
return;
}
else
{
vif1Regs->stat.VGW = false;
}
}
if (!(vif1ch->chcr.STR)) Console.WriteLn("Vif1 running when CHCR == %x", vif1ch->chcr._u32);
if (vif1.irq && vif1.tag.size == 0)
{
vif1Regs->stat.INT = true;
hwIntcIrq(VIF1intc);
--vif1.irq;
if (vif1Regs->stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
{
//vif1Regs->stat.FQC = 0;
// One game doesn't like vif stalling at end, can't remember what. Spiderman isn't keen on it tho
vif1ch->chcr.STR = false;
return;
}
else if ((vif1ch->qwc > 0) || (vif1.irqoffset > 0))
{
if (vif1.stallontag)
vif1SetupTransfer();
else
_VIF1chain();//CPU_INT(DMAC_STALL_SIS, vif1ch->qwc * BIAS);
}
}
if (vif1.inprogress & 0x1)
{
_VIF1chain();
// VIF_NORMAL_FROM_MEM_MODE is a very slow operation.
// Timesplitters 2 depends on this beeing a bit higher than 128.
if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
// Refraction - Removing voodoo timings for now, completely messes a lot of Path3 masked games.
/*if (vif1.dmamode == VIF_NORMAL_FROM_MEM_MODE ) CPU_INT(DMAC_VIF1, 1024);
else */CPU_INT(DMAC_VIF1, g_vifCycles /*VifCycleVoodoo*/);
return;
}
if (!vif1.done)
{
if (!(dmacRegs->ctrl.DMAE))
{
Console.WriteLn("vif1 dma masked");
return;
}
if ((vif1.inprogress & 0x1) == 0) vif1SetupTransfer();
if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
CPU_INT(DMAC_VIF1, g_vifCycles);
return;
}
if (vif1.vifstalled && vif1.irq)
{
DevCon.WriteLn("VIF1 looping on stall\n");
CPU_INT(DMAC_VIF1, 0);
return; //Dont want to end if vif is stalled.
}
#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 tag size %x", vif1.cmd, vif1.tag.size);
#endif
vif1Regs->stat.VPS = VPS_IDLE; //Vif goes idle as the stall happened between commands;
vif1ch->chcr.STR = false;
g_vifCycles = 0;
hwDmacIrq(DMAC_VIF1);
}
void dmaVIF1()
{
VIF_LOG("dmaVIF1 chcr = %lx, madr = %lx, qwc = %lx\n"
" tadr = %lx, asr0 = %lx, asr1 = %lx",
vif1ch->chcr._u32, vif1ch->madr, vif1ch->qwc,
vif1ch->tadr, vif1ch->asr0, vif1ch->asr1);
vif1.done = false;
g_vifCycles = 0;
vif1.inprogress = 0;
#ifdef PCSX2_DEVBUILD
if (dmacRegs->ctrl.STD == STD_VIF1)
{
//DevCon.WriteLn("VIF Stall Control Source = %x, Drain = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3);
}
#endif
if ((vif1ch->chcr.MOD == NORMAL_MODE) || vif1ch->qwc > 0) // Normal Mode
{
if (dmacRegs->ctrl.STD == STD_VIF1)
Console.WriteLn("DMA Stall Control on VIF1 normal");
if (vif1ch->chcr.DIR) // to Memory
vif1.dmamode = VIF_NORMAL_FROM_MEM_MODE;
else
vif1.dmamode = VIF_NORMAL_TO_MEM_MODE;
if(vif1ch->chcr.MOD == CHAIN_MODE && vif1ch->qwc > 0) DevCon.Warning(L"VIF1 QWC on Chain CHCR " + vif1ch->chcr.desc());
}
else
{
vif1.dmamode = VIF_CHAIN_MODE;
}
vif1Regs->stat.FQC = min((u16)0x10, vif1ch->qwc);
// Chain Mode
vif1Interrupt();
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "Vif_Dma.h"
#include "GS.h"
#include "Gif.h"
#include "VUmicro.h"
#include "newVif.h"
__forceinline void vif1FLUSH()
{
if (!(VU0.VI[REG_VPU_STAT].UL & 0x100)) return;
int _cycles = VU1.cycle;
vu1Finish();
g_vifCycles += (VU1.cycle - _cycles) * BIAS;
}
void vif1TransferToMemory()
{
int size;
u64* pMem = (u64*)dmaGetAddr(vif1ch->madr, false);
// VIF from gsMemory
if (pMem == NULL) //Is vif0ptag empty?
{
Console.WriteLn("Vif1 Tag BUSERR");
dmacRegs->stat.BEIS = true; //Bus Error
vif1Regs->stat.FQC = 0;
vif1ch->qwc = 0;
vif1.done = true;
CPU_INT(DMAC_VIF1, 0);
return; //An error has occurred.
}
// MTGS concerns: The MTGS is inherently disagreeable with the idea of downloading
// stuff from the GS. The *only* way to handle this case safely is to flush the GS
// completely and execute the transfer there-after.
//Console.Warning("Real QWC %x", vif1ch->qwc);
XMMRegisters::Freeze();
if (GSreadFIFO2 == NULL)
{
for (size = vif1ch->qwc; size > 0; --size)
{
if (size > 1)
{
GetMTGS().WaitGS();
GSreadFIFO(&psHu64(VIF1_FIFO));
}
pMem[0] = psHu64(VIF1_FIFO);
pMem[1] = psHu64(VIF1_FIFO + 8);
pMem += 2;
}
}
else
{
GetMTGS().WaitGS();
GSreadFIFO2(pMem, vif1ch->qwc);
// set incase read
psHu64(VIF1_FIFO) = pMem[2*vif1ch->qwc-2];
psHu64(VIF1_FIFO + 8) = pMem[2*vif1ch->qwc-1];
}
XMMRegisters::Thaw();
g_vifCycles += vif1ch->qwc * 2;
vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes
if(vif1.GSLastTRXPOS > vif1ch->qwc)
vif1Regs->stat.FQC = vif1.GSLastTRXPOS - vif1ch->qwc;
else
vif1Regs->stat.FQC = 0;
vif1ch->qwc = 0;
}
bool _VIF1chain()
{
u32 *pMem;
if (vif1ch->qwc == 0)
{
vif1.inprogress = 0;
return true;
}
// Clarification - this is TO memory mode, for some reason i used the other way round >.<
if (vif1.dmamode == VIF_NORMAL_TO_MEM_MODE)
{
vif1TransferToMemory();
vif1.inprogress = 0;
return true;
}
pMem = (u32*)dmaGetAddr(vif1ch->madr, !vif1ch->chcr.DIR);
if (pMem == NULL)
{
vif1.cmd = 0;
vif1.tag.size = 0;
vif1ch->qwc = 0;
return true;
}
VIF_LOG("VIF1chain size=%d, madr=%lx, tadr=%lx",
vif1ch->qwc, vif1ch->madr, vif1ch->tadr);
if (vif1.vifstalled)
return VIF1transfer(pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset, false);
else
return VIF1transfer(pMem, vif1ch->qwc * 4, false);
}
__forceinline void vif1SetupTransfer()
{
tDMA_TAG *ptag;
switch (vif1.dmamode)
{
case VIF_NORMAL_TO_MEM_MODE:
case VIF_NORMAL_FROM_MEM_MODE:
vif1.inprogress = 1;
vif1.done = true;
g_vifCycles = 2;
break;
case VIF_CHAIN_MODE:
ptag = dmaGetAddr(vif1ch->tadr, false); //Set memory pointer to TADR
if (!(vif1ch->transfer("Vif1 Tag", ptag))) return;
vif1ch->madr = ptag[1]._u32; //MADR = ADDR field + SPR
g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag
// Transfer dma tag if tte is set
VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n",
ptag[1]._u32, ptag[0]._u32, vif1ch->qwc, ptag->ID, vif1ch->madr, vif1ch->tadr);
if (!vif1.done && ((dmacRegs->ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1
{
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
if ((vif1ch->madr + vif1ch->qwc * 16) >= dmacRegs->stadr.ADDR)
{
// stalled
hwDmacIrq(DMAC_STALL_SIS);
return;
}
}
vif1.inprogress = 1;
if (vif1ch->chcr.TTE)
{
bool ret;
if (vif1.vifstalled)
ret = VIF1transfer((u32*)ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset, true); //Transfer Tag on stall
else
ret = VIF1transfer((u32*)ptag + 2, 2, true); //Transfer Tag
if ((ret == false) && 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
}
}
vif1.irqoffset = 0;
vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID);
//Check TIE bit of CHCR and IRQ bit of tag
if (vif1ch->chcr.TIE && ptag->IRQ)
{
VIF_LOG("dmaIrq Set");
//End Transfer
vif1.done = true;
return;
}
break;
}
}
__forceinline void vif1Interrupt()
{
VIF_LOG("vif1Interrupt: %8.8x", cpuRegs.cycle);
g_vifCycles = 0;
//Some games (Fahrenheit being one) start vif first, let it loop through blankness while it sets MFIFO mode, so we need to check it here.
if (dmacRegs->ctrl.MFD == MFD_VIF1) // VIF MFIFO
{
//Console.WriteLn("VIFMFIFO\n");
// Test changed because the Final Fantasy 12 opening somehow has the tag in *Undefined* mode, which is not in the documentation that I saw.
if (vif1ch->chcr.MOD == NORMAL_MODE) Console.WriteLn("MFIFO mode is normal (which isn't normal here)! %x", vif1ch->chcr._u32);
vif1Regs->stat.FQC = min((u16)0x10, vif1ch->qwc);
vifMFIFOInterrupt();
return;
}
if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
//Simulated GS transfer time done, clear the flags
if(gifRegs->stat.APATH == GIF_APATH2 && (vif1.cmd & 0x70) != 0x50)
{
gifRegs->stat.clear_flags(GIF_STAT_APATH2|GIF_STAT_OPH);
}
if (schedulepath3msk) Vif1MskPath3();
if ((vif1Regs->stat.VGW))
{
if (GSTransferStatus.PTH3 < STOPPED_MODE || GSTransferStatus.PTH1 != STOPPED_MODE)
{
CPU_INT(DMAC_VIF1, 4);
return;
}
else
{
vif1Regs->stat.VGW = false;
}
}
if (!(vif1ch->chcr.STR)) Console.WriteLn("Vif1 running when CHCR == %x", vif1ch->chcr._u32);
if (vif1.irq && vif1.tag.size == 0)
{
vif1Regs->stat.INT = true;
hwIntcIrq(VIF1intc);
--vif1.irq;
if (vif1Regs->stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
{
//vif1Regs->stat.FQC = 0;
// One game doesn't like vif stalling at end, can't remember what. Spiderman isn't keen on it tho
vif1ch->chcr.STR = false;
return;
}
else if ((vif1ch->qwc > 0) || (vif1.irqoffset > 0))
{
if (vif1.stallontag)
vif1SetupTransfer();
else
_VIF1chain();//CPU_INT(DMAC_STALL_SIS, vif1ch->qwc * BIAS);
}
}
if (vif1.inprogress & 0x1)
{
_VIF1chain();
// VIF_NORMAL_FROM_MEM_MODE is a very slow operation.
// Timesplitters 2 depends on this beeing a bit higher than 128.
if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
// Refraction - Removing voodoo timings for now, completely messes a lot of Path3 masked games.
/*if (vif1.dmamode == VIF_NORMAL_FROM_MEM_MODE ) CPU_INT(DMAC_VIF1, 1024);
else */CPU_INT(DMAC_VIF1, g_vifCycles /*VifCycleVoodoo*/);
return;
}
if (!vif1.done)
{
if (!(dmacRegs->ctrl.DMAE))
{
Console.WriteLn("vif1 dma masked");
return;
}
if ((vif1.inprogress & 0x1) == 0) vif1SetupTransfer();
if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
CPU_INT(DMAC_VIF1, g_vifCycles);
return;
}
if (vif1.vifstalled && vif1.irq)
{
DevCon.WriteLn("VIF1 looping on stall\n");
CPU_INT(DMAC_VIF1, 0);
return; //Dont want to end if vif is stalled.
}
#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 tag size %x", vif1.cmd, vif1.tag.size);
#endif
vif1Regs->stat.VPS = VPS_IDLE; //Vif goes idle as the stall happened between commands;
vif1ch->chcr.STR = false;
g_vifCycles = 0;
hwDmacIrq(DMAC_VIF1);
}
void dmaVIF1()
{
VIF_LOG("dmaVIF1 chcr = %lx, madr = %lx, qwc = %lx\n"
" tadr = %lx, asr0 = %lx, asr1 = %lx",
vif1ch->chcr._u32, vif1ch->madr, vif1ch->qwc,
vif1ch->tadr, vif1ch->asr0, vif1ch->asr1);
vif1.done = false;
g_vifCycles = 0;
vif1.inprogress = 0;
#ifdef PCSX2_DEVBUILD
if (dmacRegs->ctrl.STD == STD_VIF1)
{
//DevCon.WriteLn("VIF Stall Control Source = %x, Drain = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3);
}
#endif
if ((vif1ch->chcr.MOD == NORMAL_MODE) || vif1ch->qwc > 0) // Normal Mode
{
if (dmacRegs->ctrl.STD == STD_VIF1)
Console.WriteLn("DMA Stall Control on VIF1 normal");
if (vif1ch->chcr.DIR) // to Memory
vif1.dmamode = VIF_NORMAL_FROM_MEM_MODE;
else
vif1.dmamode = VIF_NORMAL_TO_MEM_MODE;
if(vif1ch->chcr.MOD == CHAIN_MODE && vif1ch->qwc > 0) DevCon.Warning(L"VIF1 QWC on Chain CHCR " + vif1ch->chcr.desc());
}
else
{
vif1.dmamode = VIF_CHAIN_MODE;
}
vif1Regs->stat.FQC = min((u16)0x10, vif1ch->qwc);
// Chain Mode
vif1Interrupt();
}

View File

@ -1,307 +1,307 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "Vif.h"
#include "Gif.h"
#include "Vif_Dma.h"
VIFregisters *vifRegs;
vifStruct *vif;
u16 vifqwc = 0;
int g_vifCycles = 0;
__aligned16 VifMaskTypes g_vifmask;
extern int g_vifCycles;
static __forceinline bool mfifoVIF1rbTransfer()
{
u32 maddr = dmacRegs->rbor.ADDR;
u32 msize = dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16;
u16 mfifoqwc = std::min(vif1ch->qwc, vifqwc);
u32 *src;
bool ret;
/* Check if the transfer should wrap around the ring buffer */
if ((vif1ch->madr + (mfifoqwc << 4)) > (msize))
{
int s1 = ((msize) - vif1ch->madr) >> 2;
SPR_LOG("Split MFIFO");
/* it does, so first copy 's1' bytes from 'addr' to 'data' */
src = (u32*)PSM(vif1ch->madr);
if (src == NULL) return false;
if (vif1.vifstalled)
ret = VIF1transfer(src + vif1.irqoffset, s1 - vif1.irqoffset, false);
else
ret = VIF1transfer(src, s1, false);
if (ret)
{
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
vif1ch->madr = maddr;
src = (u32*)PSM(maddr);
if (src == NULL) return false;
VIF1transfer(src, ((mfifoqwc << 2) - s1), false);
}
}
else
{
SPR_LOG("Direct MFIFO");
/* it doesn't, so just transfer 'qwc*4' words */
src = (u32*)PSM(vif1ch->madr);
if (src == NULL) return false;
if (vif1.vifstalled)
ret = VIF1transfer(src + vif1.irqoffset, mfifoqwc * 4 - vif1.irqoffset, false);
else
ret = VIF1transfer(src, mfifoqwc << 2, false);
}
return ret;
}
static __forceinline bool mfifo_VIF1chain()
{
bool ret;
/* Is QWC = 0? if so there is nothing to transfer */
if ((vif1ch->qwc == 0) && (!vif1.vifstalled))
{
vif1.inprogress &= ~1;
return true;
}
if (vif1ch->madr >= dmacRegs->rbor.ADDR &&
vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
{
u16 startqwc = vif1ch->qwc;
ret = mfifoVIF1rbTransfer();
vifqwc -= startqwc - vif1ch->qwc;
}
else
{
tDMA_TAG *pMem = dmaGetAddr(vif1ch->madr, !vif1ch->chcr.DIR);
SPR_LOG("Non-MFIFO Location");
if (pMem == NULL) return false;
if (vif1.vifstalled)
ret = VIF1transfer((u32*)pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset, false);
else
ret = VIF1transfer((u32*)pMem, vif1ch->qwc << 2, false);
}
return ret;
}
static u32 qwctag(u32 mask)
{
return (dmacRegs->rbor.ADDR + (mask & dmacRegs->rbsr.RMSK));
}
void mfifoVIF1transfer(int qwc)
{
tDMA_TAG *ptag;
g_vifCycles = 0;
if (qwc > 0)
{
vifqwc += qwc;
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch->chcr._u32, vif1.vifstalled, vif1.done);
if (vif1.inprogress & 0x10)
{
if (vif1ch->madr >= dmacRegs->rbor.ADDR && vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
CPU_INT(10, 0);
else
CPU_INT(10, vif1ch->qwc * BIAS);
vif1Regs->stat.FQC = 0x10; // FQC=16
}
vif1.inprogress &= ~0x10;
return;
}
if (vif1ch->qwc == 0 && vifqwc > 0)
{
ptag = dmaGetAddr(vif1ch->tadr, false);
if (vif1ch->chcr.TTE)
{
bool ret;
if (vif1.stallontag)
ret = VIF1transfer((u32*)ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset, true); //Transfer Tag on Stall
else
ret = VIF1transfer((u32*)ptag + 2, 2, true); //Transfer Tag
if (!(ret))
{
VIF_LOG("MFIFO Stall on tag");
vif1.stallontag = true;
return; //IRQ set by VIFTransfer
}
}
vif1ch->unsafeTransfer(ptag);
vif1ch->madr = ptag[1]._u32;
vifqwc--;
SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x",
ptag[1]._u32, ptag[0]._u32, vif1ch->qwc, ptag->ID, vif1ch->madr, vif1ch->tadr, vifqwc, spr0->madr);
switch (ptag->ID)
{
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
vif1ch->tadr = qwctag(vif1ch->tadr + 16);
vif1.done = true; //End Transfer
break;
case TAG_CNT: // CNT - Transfer QWC following the tag.
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to QW after Tag
vif1ch->tadr = qwctag(vif1ch->madr + (vif1ch->qwc << 4)); //Set TADR to QW following the data
vif1.done = false;
break;
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
{
int temp = vif1ch->madr; //Temporarily Store ADDR
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to QW following the tag
vif1ch->tadr = temp; //Copy temporarily stored ADDR to Tag
if ((temp & dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("Next tag = %x outside ring %x size %x", temp, psHu32(DMAC_RBOR), psHu32(DMAC_RBSR));
vif1.done = false;
break;
}
case TAG_REF: // Ref - Transfer QWC from ADDR field
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
vif1ch->tadr = qwctag(vif1ch->tadr + 16); //Set TADR to next tag
vif1.done = false;
break;
case TAG_END: // End - Transfer QWC following the tag
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to data following the tag
vif1ch->tadr = qwctag(vif1ch->madr + (vif1ch->qwc << 4)); //Set TADR to QW following the data
vif1.done = true; //End Transfer
break;
}
if (vif1ch->chcr.TIE && ptag->IRQ)
{
VIF_LOG("dmaIrq Set");
vif1.done = true;
}
}
vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
vif1.inprogress |= 1;
SPR_LOG("mfifoVIF1transfer end %x madr %x, tadr %x vifqwc %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr, vifqwc);
}
void vifMFIFOInterrupt()
{
g_vifCycles = 0;
VIF_LOG("vif mfifo interrupt");
if (schedulepath3msk) Vif1MskPath3();
if ((vif1Regs->stat.VGW))
{
if (GSTransferStatus.PTH3 < STOPPED_MODE || GSTransferStatus.PTH1 != STOPPED_MODE)
{
CPU_INT(10, 4);
return;
}
else
{
vif1Regs->stat.VGW = false;
}
}
if ((spr0->chcr.STR) && (spr0->qwc == 0))
{
spr0->chcr.STR = false;
hwDmacIrq(DMAC_FROM_SPR);
}
if (vif1.irq && vif1.tag.size == 0)
{
vif1Regs->stat.INT = true;
hwIntcIrq(INTC_VIF1);
--vif1.irq;
if (vif1Regs->stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
{
vif1Regs->stat.FQC = 0; // FQC=0
vif1ch->chcr.STR = false;
return;
}
}
if (vif1.done == false || vif1ch->qwc)
{
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.FQC = 0;
hwDmacIrq(DMAC_MFIFO_EMPTY);
return;
}
mfifoVIF1transfer(0);
if ((vif1ch->madr >= dmacRegs->rbor.ADDR) && (vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK)))
CPU_INT(10, 0);
else
CPU_INT(10, vif1ch->qwc * BIAS);
return;
case 1: //Transfer data
mfifo_VIF1chain();
CPU_INT(10, 0);
return;
}
return;
}
/*if (vifqwc <= 0)
{
//Console.WriteLn("Empty 2");
//vif1.inprogress |= 0x10;
vif1Regs->stat.FQC = 0; // FQC=0
hwDmacIrq(DMAC_MFIFO_EMPTY);
}*/
vif1.done = 1;
g_vifCycles = 0;
vif1ch->chcr.STR = false;
hwDmacIrq(DMAC_VIF1);
VIF_LOG("vif mfifo dma end");
vif1Regs->stat.FQC = 0;
}
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "Vif.h"
#include "Gif.h"
#include "Vif_Dma.h"
VIFregisters *vifRegs;
vifStruct *vif;
u16 vifqwc = 0;
int g_vifCycles = 0;
__aligned16 VifMaskTypes g_vifmask;
extern int g_vifCycles;
static __forceinline bool mfifoVIF1rbTransfer()
{
u32 maddr = dmacRegs->rbor.ADDR;
u32 msize = dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16;
u16 mfifoqwc = std::min(vif1ch->qwc, vifqwc);
u32 *src;
bool ret;
/* Check if the transfer should wrap around the ring buffer */
if ((vif1ch->madr + (mfifoqwc << 4)) > (msize))
{
int s1 = ((msize) - vif1ch->madr) >> 2;
SPR_LOG("Split MFIFO");
/* it does, so first copy 's1' bytes from 'addr' to 'data' */
src = (u32*)PSM(vif1ch->madr);
if (src == NULL) return false;
if (vif1.vifstalled)
ret = VIF1transfer(src + vif1.irqoffset, s1 - vif1.irqoffset, false);
else
ret = VIF1transfer(src, s1, false);
if (ret)
{
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
vif1ch->madr = maddr;
src = (u32*)PSM(maddr);
if (src == NULL) return false;
VIF1transfer(src, ((mfifoqwc << 2) - s1), false);
}
}
else
{
SPR_LOG("Direct MFIFO");
/* it doesn't, so just transfer 'qwc*4' words */
src = (u32*)PSM(vif1ch->madr);
if (src == NULL) return false;
if (vif1.vifstalled)
ret = VIF1transfer(src + vif1.irqoffset, mfifoqwc * 4 - vif1.irqoffset, false);
else
ret = VIF1transfer(src, mfifoqwc << 2, false);
}
return ret;
}
static __forceinline bool mfifo_VIF1chain()
{
bool ret;
/* Is QWC = 0? if so there is nothing to transfer */
if ((vif1ch->qwc == 0) && (!vif1.vifstalled))
{
vif1.inprogress &= ~1;
return true;
}
if (vif1ch->madr >= dmacRegs->rbor.ADDR &&
vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
{
u16 startqwc = vif1ch->qwc;
ret = mfifoVIF1rbTransfer();
vifqwc -= startqwc - vif1ch->qwc;
}
else
{
tDMA_TAG *pMem = dmaGetAddr(vif1ch->madr, !vif1ch->chcr.DIR);
SPR_LOG("Non-MFIFO Location");
if (pMem == NULL) return false;
if (vif1.vifstalled)
ret = VIF1transfer((u32*)pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset, false);
else
ret = VIF1transfer((u32*)pMem, vif1ch->qwc << 2, false);
}
return ret;
}
static u32 qwctag(u32 mask)
{
return (dmacRegs->rbor.ADDR + (mask & dmacRegs->rbsr.RMSK));
}
void mfifoVIF1transfer(int qwc)
{
tDMA_TAG *ptag;
g_vifCycles = 0;
if (qwc > 0)
{
vifqwc += qwc;
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch->chcr._u32, vif1.vifstalled, vif1.done);
if (vif1.inprogress & 0x10)
{
if (vif1ch->madr >= dmacRegs->rbor.ADDR && vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
CPU_INT(10, 0);
else
CPU_INT(10, vif1ch->qwc * BIAS);
vif1Regs->stat.FQC = 0x10; // FQC=16
}
vif1.inprogress &= ~0x10;
return;
}
if (vif1ch->qwc == 0 && vifqwc > 0)
{
ptag = dmaGetAddr(vif1ch->tadr, false);
if (vif1ch->chcr.TTE)
{
bool ret;
if (vif1.stallontag)
ret = VIF1transfer((u32*)ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset, true); //Transfer Tag on Stall
else
ret = VIF1transfer((u32*)ptag + 2, 2, true); //Transfer Tag
if (!(ret))
{
VIF_LOG("MFIFO Stall on tag");
vif1.stallontag = true;
return; //IRQ set by VIFTransfer
}
}
vif1ch->unsafeTransfer(ptag);
vif1ch->madr = ptag[1]._u32;
vifqwc--;
SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x",
ptag[1]._u32, ptag[0]._u32, vif1ch->qwc, ptag->ID, vif1ch->madr, vif1ch->tadr, vifqwc, spr0->madr);
switch (ptag->ID)
{
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
vif1ch->tadr = qwctag(vif1ch->tadr + 16);
vif1.done = true; //End Transfer
break;
case TAG_CNT: // CNT - Transfer QWC following the tag.
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to QW after Tag
vif1ch->tadr = qwctag(vif1ch->madr + (vif1ch->qwc << 4)); //Set TADR to QW following the data
vif1.done = false;
break;
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
{
int temp = vif1ch->madr; //Temporarily Store ADDR
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to QW following the tag
vif1ch->tadr = temp; //Copy temporarily stored ADDR to Tag
if ((temp & dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("Next tag = %x outside ring %x size %x", temp, psHu32(DMAC_RBOR), psHu32(DMAC_RBSR));
vif1.done = false;
break;
}
case TAG_REF: // Ref - Transfer QWC from ADDR field
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
vif1ch->tadr = qwctag(vif1ch->tadr + 16); //Set TADR to next tag
vif1.done = false;
break;
case TAG_END: // End - Transfer QWC following the tag
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to data following the tag
vif1ch->tadr = qwctag(vif1ch->madr + (vif1ch->qwc << 4)); //Set TADR to QW following the data
vif1.done = true; //End Transfer
break;
}
if (vif1ch->chcr.TIE && ptag->IRQ)
{
VIF_LOG("dmaIrq Set");
vif1.done = true;
}
}
vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
vif1.inprogress |= 1;
SPR_LOG("mfifoVIF1transfer end %x madr %x, tadr %x vifqwc %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr, vifqwc);
}
void vifMFIFOInterrupt()
{
g_vifCycles = 0;
VIF_LOG("vif mfifo interrupt");
if (schedulepath3msk) Vif1MskPath3();
if ((vif1Regs->stat.VGW))
{
if (GSTransferStatus.PTH3 < STOPPED_MODE || GSTransferStatus.PTH1 != STOPPED_MODE)
{
CPU_INT(10, 4);
return;
}
else
{
vif1Regs->stat.VGW = false;
}
}
if ((spr0->chcr.STR) && (spr0->qwc == 0))
{
spr0->chcr.STR = false;
hwDmacIrq(DMAC_FROM_SPR);
}
if (vif1.irq && vif1.tag.size == 0)
{
vif1Regs->stat.INT = true;
hwIntcIrq(INTC_VIF1);
--vif1.irq;
if (vif1Regs->stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
{
vif1Regs->stat.FQC = 0; // FQC=0
vif1ch->chcr.STR = false;
return;
}
}
if (vif1.done == false || vif1ch->qwc)
{
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.FQC = 0;
hwDmacIrq(DMAC_MFIFO_EMPTY);
return;
}
mfifoVIF1transfer(0);
if ((vif1ch->madr >= dmacRegs->rbor.ADDR) && (vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK)))
CPU_INT(10, 0);
else
CPU_INT(10, vif1ch->qwc * BIAS);
return;
case 1: //Transfer data
mfifo_VIF1chain();
CPU_INT(10, 0);
return;
}
return;
}
/*if (vifqwc <= 0)
{
//Console.WriteLn("Empty 2");
//vif1.inprogress |= 0x10;
vif1Regs->stat.FQC = 0; // FQC=0
hwDmacIrq(DMAC_MFIFO_EMPTY);
}*/
vif1.done = 1;
g_vifCycles = 0;
vif1ch->chcr.STR = false;
hwDmacIrq(DMAC_VIF1);
VIF_LOG("vif mfifo dma end");
vif1Regs->stat.FQC = 0;
}

View File

@ -1,475 +1,475 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "GS.h"
#include "Gif.h"
#include "Vif_Dma.h"
#include "newVif.h"
#include "VUmicro.h"
#define vifOp(vifCodeName) _vifT int __fastcall vifCodeName(int pass, u32 *data)
#define pass1 if (pass == 0)
#define pass2 if (pass == 1)
#define pass3 if (pass == 2)
#define vif1Only() { if (!idx) return vifCode_Null<idx>(pass, (u32*)data); }
vifOp(vifCode_Null);
//------------------------------------------------------------------
// Vif0/Vif1 Misc Functions
//------------------------------------------------------------------
static _f void vifFlush(int idx) {
if (!idx) vif0FLUSH();
else vif1FLUSH();
}
static _f void vuExecMicro(int idx, u32 addr) {
VURegs* VU = nVif[idx].VU;
vifFlush(idx);
if (VU->vifRegs->itops > (idx ? 0x3ffu : 0xffu)) {
Console.WriteLn("VIF%d ITOP overrun! %x", idx, VU->vifRegs->itops);
VU->vifRegs->itops &= (idx ? 0x3ffu : 0xffu);
}
VU->vifRegs->itop = VU->vifRegs->itops;
if (idx) {
// in case we're handling a VIF1 execMicro, set the top with the tops value
VU->vifRegs->top = VU->vifRegs->tops & 0x3ff;
// is DBF flag set in VIF_STAT?
if (VU->vifRegs->stat.DBF) {
// it is, so set tops with base, and clear the stat DBF flag
VU->vifRegs->tops = VU->vifRegs->base;
VU->vifRegs->stat.DBF = false;
}
else {
// it is not, so set tops with base + offset, and set stat DBF flag
VU->vifRegs->tops = VU->vifRegs->base + VU->vifRegs->ofst;
VU->vifRegs->stat.DBF = true;
}
}
if (!idx) vu0ExecMicro(addr);
else vu1ExecMicro(addr);
}
u8 schedulepath3msk = 0;
void Vif1MskPath3() {
vif1Regs->mskpath3 = schedulepath3msk & 0x1;
//Console.WriteLn("VIF MSKPATH3 %x", vif1Regs->mskpath3);
gifRegs->stat.M3P = vif1Regs->mskpath3;
if (!vif1Regs->mskpath3) {
//Let the Gif know it can transfer again (making sure any vif stall isnt unset prematurely)
if(gif->chcr.STR == true)
{
GSTransferStatus.PTH3 = 3;
CPU_INT(DMAC_GIF, 4);
}
}
else gifRegs->stat.M3P = true;
schedulepath3msk = 0;
}
//------------------------------------------------------------------
// Vif0/Vif1 Code Implementations
//------------------------------------------------------------------
vifOp(vifCode_Base) {
vif1Only();
pass1 { vif1Regs->base = vif1Regs->code & 0x3ff; vif1.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_Base"); }
return 0;
}
template<int idx> _f int _vifCode_Direct(int pass, u8* data, bool isDirectHL) {
pass1 {
vif1Only();
int vifImm = (u16)vif1Regs->code;
vif1.tag.size = vifImm ? (vifImm*4) : (65536*4);
return 1;
}
pass2 {
vif1Only();
//return vifTrans_DirectHL<idx>((u32*)data);
gifRegs->stat.P2Q = true;
//Should probably do this for both types of transfer seen as the GS hates taking 2 seperate chunks
//if (isDirectHL) {
if (GSTransferStatus.PTH3 < STOPPED_MODE || GSTransferStatus.PTH1 != STOPPED_MODE)
{
/*if(!isDirectHL) DevCon.WriteLn("Direct: Waiting for Path3 to finish!");
else DevCon.WriteLn("DirectHL: Waiting for Path3 to finish!");*/
//VIF_LOG("Mask %x, GIF STR %x, PTH1 %x, PTH2 %x, PTH3 %x", vif1Regs->mskpath3, gif->chcr.STR, GSTransferStatus.PTH1, GSTransferStatus.PTH2, GSTransferStatus.PTH3);
vif1Regs->stat.VGW = true; // PATH3 is in image mode, so wait for end of transfer
vif1.vifstalled = true;
return 0;
}
//}
gifRegs->stat.clear_flags(GIF_STAT_P2Q);
gifRegs->stat.APATH = GIF_APATH2;
gifRegs->stat.OPH = true;
Registers::Freeze();
nVifStruct& v = nVif[1];
const int ret = aMin(vif1.vifpacketsize, vif1.tag.size);
u32 size = ret << 2;
if (ret == v.vif->tag.size) { // Full Transfer
if (v.bSize) { // Last transfer was partial
memcpy_fast(&v.buffer[v.bSize], data, size);
v.bSize += size;
data = v.buffer;
size = v.bSize;
}
if (!size) { DevCon.WriteLn("Path2: No Data Transfer?"); }
const uint count = GetMTGS().PrepDataPacket(GIF_PATH_2, data, size >> 4);
memcpy_fast(GetMTGS().GetDataPacketPtr(), data, count << 4);
GetMTGS().SendDataPacket();
vif1.tag.size = 0;
vif1.cmd = 0;
v.bSize = 0;
gifRegs->stat.clear_flags(GIF_STAT_APATH2 | GIF_STAT_OPH);
}
else { // Partial Transfer
//DevCon.WriteLn("DirectHL: Partial Transfer [%d]", size);
gifRegs->stat.set_flags(GIF_STAT_APATH2 | GIF_STAT_OPH);
memcpy_fast(&v.buffer[v.bSize], data, size);
v.bSize += size;
vif1.tag.size -= ret;
}
Registers::Thaw();
return ret;
}
return 0;
}
vifOp(vifCode_Direct) {
pass3 { DevCon.WriteLn("vifCode_Direct"); }
return _vifCode_Direct<idx>(pass, (u8*)data, 0);
}
vifOp(vifCode_DirectHL) {
pass3 { DevCon.WriteLn("vifCode_DirectHL"); }
return _vifCode_Direct<idx>(pass, (u8*)data, 1);
}
// ToDo: FixMe
vifOp(vifCode_Flush) {
vif1Only();
pass1 { vifFlush(idx); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_Flush"); }
return 0;
}
// ToDo: FixMe
vifOp(vifCode_FlushA) {
vif1Only();
pass1 {
// Gif is already transferring so wait for it.
if (GSTransferStatus.PTH3 < STOPPED_MODE) {
//DevCon.WriteLn("FlushA path3 Wait! PTH3 MD %x STR %x", GSTransferStatus.PTH3, gif->chcr.STR);
vif1Regs->stat.VGW = true;
vifX.vifstalled = true;
}
vifFlush(idx);
vifX.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_FlushA"); }
return 0;
}
// ToDo: FixMe
vifOp(vifCode_FlushE) {
pass1 { vifFlush(idx); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_FlushE"); }
return 0;
}
vifOp(vifCode_ITop) {
pass1 { vifXRegs->itops = vifXRegs->code & 0x3ff; vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_ITop"); }
return 0;
}
vifOp(vifCode_Mark) {
pass1 {
vifXRegs->mark = (u16)vifXRegs->code;
vifXRegs->stat.MRK = true;
vifX.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_Mark"); }
return 0;
}
_f void _vifCode_MPG(int idx, u32 addr, u32 *data, int size) {
VURegs& VUx = idx ? VU1 : VU0;
pxAssume(VUx.Micro > 0);
if (memcmp(VUx.Micro + addr, data, size << 2)) {
if (!idx) CpuVU0->Clear(addr, size << 2); // Clear before writing!
else CpuVU1->Clear(addr, size << 2); // Clear before writing!
memcpy_fast(VUx.Micro + addr, data, size << 2);
}
}
vifOp(vifCode_MPG) {
pass1 {
int vifNum = (u8)(vifXRegs->code >> 16);
vifX.tag.addr = (u16)(vifXRegs->code << 3) & (idx ? 0x3fff : 0xfff);
vifX.tag.size = vifNum ? (vifNum*2) : 512;
return 1;
}
pass2 {
vifFlush(idx);
if (vifX.vifpacketsize < vifX.tag.size) { // Partial Transfer
if((vifX.tag.addr + vifX.vifpacketsize) > (idx ? 0x4000 : 0x1000)) {
DevCon.Warning("Vif%d MPG Split Overflow", idx);
}
_vifCode_MPG(idx, vifX.tag.addr, data, vifX.vifpacketsize);
vifX.tag.addr += vifX.vifpacketsize << 2;
vifX.tag.size -= vifX.vifpacketsize;
return vifX.vifpacketsize;
}
else { // Full Transfer
if((vifX.tag.addr + vifX.tag.size) > (idx ? 0x4000 : 0x1000)) {
DevCon.Warning("Vif%d MPG Split Overflow", idx);
}
_vifCode_MPG(idx, vifX.tag.addr, data, vifX.tag.size);
int ret = vifX.tag.size;
vifX.tag.size = 0;
vifX.cmd = 0;
return ret;
}
}
pass3 { DevCon.WriteLn("vifCode_MPG"); }
return 0;
}
vifOp(vifCode_MSCAL) {
pass1 { vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_MSCAL"); }
return 0;
}
vifOp(vifCode_MSCALF) {
pass1 { vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_MSCALF"); }
return 0;
}
vifOp(vifCode_MSCNT) {
pass1 { vuExecMicro(idx, -1); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_MSCNT"); }
return 0;
}
// ToDo: FixMe
vifOp(vifCode_MskPath3) {
vif1Only();
pass1 {
if (vif1ch->chcr.STR) {
schedulepath3msk = 0x10 | ((vif1Regs->code >> 15) & 0x1);
vif1.vifstalled = true;
}
else {
schedulepath3msk = (vif1Regs->code >> 15) & 0x1;
Vif1MskPath3();
}
vifX.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_MskPath3"); }
return 0;
}
vifOp(vifCode_Nop) {
pass1 { vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_Nop"); }
return 0;
}
// ToDo: Review Flags
vifOp(vifCode_Null) {
pass1 {
// if ME1, then force the vif to interrupt
if (!(vifXRegs->err.ME1)) { // Ignore vifcode and tag mismatch error
Console.WriteLn("Vif%d: Unknown VifCmd! [%x]", idx, vifX.cmd);
vifXRegs->stat.ER1 = true;
vifX.vifstalled = true;
//vifX.irq++;
}
vifX.cmd = 0;
}
pass2 { Console.Error("Vif%d bad vifcode! [CMD = %x]", idx, vifX.cmd); }
pass3 { DevCon.WriteLn("vifCode_Null"); }
return 0;
}
vifOp(vifCode_Offset) {
vif1Only();
pass1 {
vif1Regs->stat.DBF = false;
vif1Regs->ofst = vif1Regs->code & 0x3ff;
vif1Regs->tops = vif1Regs->base;
vifX.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_Offset"); }
return 0;
}
template<int idx> _f int _vifCode_STColRow(u32* data, u32* pmem1, u32* pmem2) {
int ret;
ret = min(4 - vifX.tag.addr, vifX.vifpacketsize);
pxAssume(vifX.tag.addr < 4);
pxAssume(ret > 0);
switch (ret) {
case 4:
pmem1[12] = data[3];
pmem2[3] = data[3];
case 3:
pmem1[8] = data[2];
pmem2[2] = data[2];
case 2:
pmem1[4] = data[1];
pmem2[1] = data[1];
case 1:
pmem1[0] = data[0];
pmem2[0] = data[0];
break;
jNO_DEFAULT
}
vifX.tag.addr += ret;
vifX.tag.size -= ret;
if (!vifX.tag.size) vifX.cmd = 0;
return ret;
}
vifOp(vifCode_STCol) {
pass1 {
vifX.tag.addr = 0;
vifX.tag.size = 4;
return 1;
}
pass2 {
u32* cols = idx ? g_vifmask.Col1 : g_vifmask.Col0;
u32* pmem1 = &vifXRegs->c0 + (vifX.tag.addr << 2);
u32* pmem2 = cols + vifX.tag.addr;
return _vifCode_STColRow<idx>(data, pmem1, pmem2);
}
pass3 { DevCon.WriteLn("vifCode_STCol"); }
return 0;
}
vifOp(vifCode_STRow) {
pass1 {
vifX.tag.addr = 0;
vifX.tag.size = 4;
return 1;
}
pass2 {
u32* rows = idx ? g_vifmask.Row1 : g_vifmask.Row0;
u32* pmem1 = &vifXRegs->r0 + (vifX.tag.addr << 2);
u32* pmem2 = rows + vifX.tag.addr;
return _vifCode_STColRow<idx>(data, pmem1, pmem2);
}
pass3 { DevCon.WriteLn("vifCode_STRow"); }
return 0;
}
vifOp(vifCode_STCycl) {
pass1 {
vifXRegs->cycle.cl = (u8)(vifXRegs->code);
vifXRegs->cycle.wl = (u8)(vifXRegs->code >> 8);
vifX.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_STCycl"); }
return 0;
}
vifOp(vifCode_STMask) {
pass1 { vifX.tag.size = 1; }
pass2 { vifXRegs->mask = data[0]; vifX.tag.size = 0; vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_STMask"); }
return 1;
}
vifOp(vifCode_STMod) {
pass1 { vifXRegs->mode = vifXRegs->code & 0x3; vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_STMod"); }
return 0;
}
vifOp(vifCode_Unpack) {
pass1 {
if (!idx) vif0UnpackSetup(data);
else vif1UnpackSetup(data);
return 1;
}
pass2 { return nVifUnpack(idx, (u8*)data); }
pass3 { DevCon.WriteLn("vifCode_Unpack"); }
return 0;
}
//------------------------------------------------------------------
// Vif0/Vif1 Code Tables
//------------------------------------------------------------------
int (__fastcall *vif0Code[128])(int pass, u32 *data) = {
vifCode_Nop<0> , vifCode_STCycl<0> , vifCode_Offset<0> , vifCode_Base<0> , vifCode_ITop<0> , vifCode_STMod<0> , vifCode_MskPath3<0>, vifCode_Mark<0>, /*0x00*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x08*/
vifCode_FlushE<0> , vifCode_Flush<0> , vifCode_Null<0> , vifCode_FlushA<0> , vifCode_MSCAL<0> , vifCode_MSCALF<0> , vifCode_Null<0> , vifCode_MSCNT<0>, /*0x10*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x18*/
vifCode_STMask<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x20*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x28*/
vifCode_STRow<0> , vifCode_STCol<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x30*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x38*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x40*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_MPG<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x48*/
vifCode_Direct<0> , vifCode_DirectHL<0>, vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x50*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x58*/
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Null<0>, /*0x60*/
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0>, /*0x68*/
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Null<0>, /*0x70*/
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Null<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> /*0x78*/
};
int (__fastcall *vif1Code[128])(int pass, u32 *data) = {
vifCode_Nop<1> , vifCode_STCycl<1> , vifCode_Offset<1> , vifCode_Base<1> , vifCode_ITop<1> , vifCode_STMod<1> , vifCode_MskPath3<1>, vifCode_Mark<1>, /*0x00*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x08*/
vifCode_FlushE<1> , vifCode_Flush<1> , vifCode_Null<1> , vifCode_FlushA<1> , vifCode_MSCAL<1> , vifCode_MSCALF<1> , vifCode_Null<1> , vifCode_MSCNT<1>, /*0x10*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x18*/
vifCode_STMask<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x20*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x28*/
vifCode_STRow<1> , vifCode_STCol<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x30*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x38*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x40*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_MPG<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x48*/
vifCode_Direct<1> , vifCode_DirectHL<1>, vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x50*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x58*/
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Null<1>, /*0x60*/
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1>, /*0x68*/
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Null<1>, /*0x70*/
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Null<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> /*0x78*/
};
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "GS.h"
#include "Gif.h"
#include "Vif_Dma.h"
#include "newVif.h"
#include "VUmicro.h"
#define vifOp(vifCodeName) _vifT int __fastcall vifCodeName(int pass, u32 *data)
#define pass1 if (pass == 0)
#define pass2 if (pass == 1)
#define pass3 if (pass == 2)
#define vif1Only() { if (!idx) return vifCode_Null<idx>(pass, (u32*)data); }
vifOp(vifCode_Null);
//------------------------------------------------------------------
// Vif0/Vif1 Misc Functions
//------------------------------------------------------------------
static _f void vifFlush(int idx) {
if (!idx) vif0FLUSH();
else vif1FLUSH();
}
static _f void vuExecMicro(int idx, u32 addr) {
VURegs* VU = nVif[idx].VU;
vifFlush(idx);
if (VU->vifRegs->itops > (idx ? 0x3ffu : 0xffu)) {
Console.WriteLn("VIF%d ITOP overrun! %x", idx, VU->vifRegs->itops);
VU->vifRegs->itops &= (idx ? 0x3ffu : 0xffu);
}
VU->vifRegs->itop = VU->vifRegs->itops;
if (idx) {
// in case we're handling a VIF1 execMicro, set the top with the tops value
VU->vifRegs->top = VU->vifRegs->tops & 0x3ff;
// is DBF flag set in VIF_STAT?
if (VU->vifRegs->stat.DBF) {
// it is, so set tops with base, and clear the stat DBF flag
VU->vifRegs->tops = VU->vifRegs->base;
VU->vifRegs->stat.DBF = false;
}
else {
// it is not, so set tops with base + offset, and set stat DBF flag
VU->vifRegs->tops = VU->vifRegs->base + VU->vifRegs->ofst;
VU->vifRegs->stat.DBF = true;
}
}
if (!idx) vu0ExecMicro(addr);
else vu1ExecMicro(addr);
}
u8 schedulepath3msk = 0;
void Vif1MskPath3() {
vif1Regs->mskpath3 = schedulepath3msk & 0x1;
//Console.WriteLn("VIF MSKPATH3 %x", vif1Regs->mskpath3);
gifRegs->stat.M3P = vif1Regs->mskpath3;
if (!vif1Regs->mskpath3) {
//Let the Gif know it can transfer again (making sure any vif stall isnt unset prematurely)
if(gif->chcr.STR == true)
{
GSTransferStatus.PTH3 = 3;
CPU_INT(DMAC_GIF, 4);
}
}
else gifRegs->stat.M3P = true;
schedulepath3msk = 0;
}
//------------------------------------------------------------------
// Vif0/Vif1 Code Implementations
//------------------------------------------------------------------
vifOp(vifCode_Base) {
vif1Only();
pass1 { vif1Regs->base = vif1Regs->code & 0x3ff; vif1.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_Base"); }
return 0;
}
template<int idx> _f int _vifCode_Direct(int pass, u8* data, bool isDirectHL) {
pass1 {
vif1Only();
int vifImm = (u16)vif1Regs->code;
vif1.tag.size = vifImm ? (vifImm*4) : (65536*4);
return 1;
}
pass2 {
vif1Only();
//return vifTrans_DirectHL<idx>((u32*)data);
gifRegs->stat.P2Q = true;
//Should probably do this for both types of transfer seen as the GS hates taking 2 seperate chunks
//if (isDirectHL) {
if (GSTransferStatus.PTH3 < STOPPED_MODE || GSTransferStatus.PTH1 != STOPPED_MODE)
{
/*if(!isDirectHL) DevCon.WriteLn("Direct: Waiting for Path3 to finish!");
else DevCon.WriteLn("DirectHL: Waiting for Path3 to finish!");*/
//VIF_LOG("Mask %x, GIF STR %x, PTH1 %x, PTH2 %x, PTH3 %x", vif1Regs->mskpath3, gif->chcr.STR, GSTransferStatus.PTH1, GSTransferStatus.PTH2, GSTransferStatus.PTH3);
vif1Regs->stat.VGW = true; // PATH3 is in image mode, so wait for end of transfer
vif1.vifstalled = true;
return 0;
}
//}
gifRegs->stat.clear_flags(GIF_STAT_P2Q);
gifRegs->stat.APATH = GIF_APATH2;
gifRegs->stat.OPH = true;
Registers::Freeze();
nVifStruct& v = nVif[1];
const int ret = aMin(vif1.vifpacketsize, vif1.tag.size);
u32 size = ret << 2;
if (ret == v.vif->tag.size) { // Full Transfer
if (v.bSize) { // Last transfer was partial
memcpy_fast(&v.buffer[v.bSize], data, size);
v.bSize += size;
data = v.buffer;
size = v.bSize;
}
if (!size) { DevCon.WriteLn("Path2: No Data Transfer?"); }
const uint count = GetMTGS().PrepDataPacket(GIF_PATH_2, data, size >> 4);
memcpy_fast(GetMTGS().GetDataPacketPtr(), data, count << 4);
GetMTGS().SendDataPacket();
vif1.tag.size = 0;
vif1.cmd = 0;
v.bSize = 0;
gifRegs->stat.clear_flags(GIF_STAT_APATH2 | GIF_STAT_OPH);
}
else { // Partial Transfer
//DevCon.WriteLn("DirectHL: Partial Transfer [%d]", size);
gifRegs->stat.set_flags(GIF_STAT_APATH2 | GIF_STAT_OPH);
memcpy_fast(&v.buffer[v.bSize], data, size);
v.bSize += size;
vif1.tag.size -= ret;
}
Registers::Thaw();
return ret;
}
return 0;
}
vifOp(vifCode_Direct) {
pass3 { DevCon.WriteLn("vifCode_Direct"); }
return _vifCode_Direct<idx>(pass, (u8*)data, 0);
}
vifOp(vifCode_DirectHL) {
pass3 { DevCon.WriteLn("vifCode_DirectHL"); }
return _vifCode_Direct<idx>(pass, (u8*)data, 1);
}
// ToDo: FixMe
vifOp(vifCode_Flush) {
vif1Only();
pass1 { vifFlush(idx); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_Flush"); }
return 0;
}
// ToDo: FixMe
vifOp(vifCode_FlushA) {
vif1Only();
pass1 {
// Gif is already transferring so wait for it.
if (GSTransferStatus.PTH3 < STOPPED_MODE) {
//DevCon.WriteLn("FlushA path3 Wait! PTH3 MD %x STR %x", GSTransferStatus.PTH3, gif->chcr.STR);
vif1Regs->stat.VGW = true;
vifX.vifstalled = true;
}
vifFlush(idx);
vifX.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_FlushA"); }
return 0;
}
// ToDo: FixMe
vifOp(vifCode_FlushE) {
pass1 { vifFlush(idx); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_FlushE"); }
return 0;
}
vifOp(vifCode_ITop) {
pass1 { vifXRegs->itops = vifXRegs->code & 0x3ff; vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_ITop"); }
return 0;
}
vifOp(vifCode_Mark) {
pass1 {
vifXRegs->mark = (u16)vifXRegs->code;
vifXRegs->stat.MRK = true;
vifX.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_Mark"); }
return 0;
}
_f void _vifCode_MPG(int idx, u32 addr, u32 *data, int size) {
VURegs& VUx = idx ? VU1 : VU0;
pxAssume(VUx.Micro > 0);
if (memcmp(VUx.Micro + addr, data, size << 2)) {
if (!idx) CpuVU0->Clear(addr, size << 2); // Clear before writing!
else CpuVU1->Clear(addr, size << 2); // Clear before writing!
memcpy_fast(VUx.Micro + addr, data, size << 2);
}
}
vifOp(vifCode_MPG) {
pass1 {
int vifNum = (u8)(vifXRegs->code >> 16);
vifX.tag.addr = (u16)(vifXRegs->code << 3) & (idx ? 0x3fff : 0xfff);
vifX.tag.size = vifNum ? (vifNum*2) : 512;
return 1;
}
pass2 {
vifFlush(idx);
if (vifX.vifpacketsize < vifX.tag.size) { // Partial Transfer
if((vifX.tag.addr + vifX.vifpacketsize) > (idx ? 0x4000 : 0x1000)) {
DevCon.Warning("Vif%d MPG Split Overflow", idx);
}
_vifCode_MPG(idx, vifX.tag.addr, data, vifX.vifpacketsize);
vifX.tag.addr += vifX.vifpacketsize << 2;
vifX.tag.size -= vifX.vifpacketsize;
return vifX.vifpacketsize;
}
else { // Full Transfer
if((vifX.tag.addr + vifX.tag.size) > (idx ? 0x4000 : 0x1000)) {
DevCon.Warning("Vif%d MPG Split Overflow", idx);
}
_vifCode_MPG(idx, vifX.tag.addr, data, vifX.tag.size);
int ret = vifX.tag.size;
vifX.tag.size = 0;
vifX.cmd = 0;
return ret;
}
}
pass3 { DevCon.WriteLn("vifCode_MPG"); }
return 0;
}
vifOp(vifCode_MSCAL) {
pass1 { vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_MSCAL"); }
return 0;
}
vifOp(vifCode_MSCALF) {
pass1 { vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_MSCALF"); }
return 0;
}
vifOp(vifCode_MSCNT) {
pass1 { vuExecMicro(idx, -1); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_MSCNT"); }
return 0;
}
// ToDo: FixMe
vifOp(vifCode_MskPath3) {
vif1Only();
pass1 {
if (vif1ch->chcr.STR) {
schedulepath3msk = 0x10 | ((vif1Regs->code >> 15) & 0x1);
vif1.vifstalled = true;
}
else {
schedulepath3msk = (vif1Regs->code >> 15) & 0x1;
Vif1MskPath3();
}
vifX.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_MskPath3"); }
return 0;
}
vifOp(vifCode_Nop) {
pass1 { vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_Nop"); }
return 0;
}
// ToDo: Review Flags
vifOp(vifCode_Null) {
pass1 {
// if ME1, then force the vif to interrupt
if (!(vifXRegs->err.ME1)) { // Ignore vifcode and tag mismatch error
Console.WriteLn("Vif%d: Unknown VifCmd! [%x]", idx, vifX.cmd);
vifXRegs->stat.ER1 = true;
vifX.vifstalled = true;
//vifX.irq++;
}
vifX.cmd = 0;
}
pass2 { Console.Error("Vif%d bad vifcode! [CMD = %x]", idx, vifX.cmd); }
pass3 { DevCon.WriteLn("vifCode_Null"); }
return 0;
}
vifOp(vifCode_Offset) {
vif1Only();
pass1 {
vif1Regs->stat.DBF = false;
vif1Regs->ofst = vif1Regs->code & 0x3ff;
vif1Regs->tops = vif1Regs->base;
vifX.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_Offset"); }
return 0;
}
template<int idx> _f int _vifCode_STColRow(u32* data, u32* pmem1, u32* pmem2) {
int ret;
ret = min(4 - vifX.tag.addr, vifX.vifpacketsize);
pxAssume(vifX.tag.addr < 4);
pxAssume(ret > 0);
switch (ret) {
case 4:
pmem1[12] = data[3];
pmem2[3] = data[3];
case 3:
pmem1[8] = data[2];
pmem2[2] = data[2];
case 2:
pmem1[4] = data[1];
pmem2[1] = data[1];
case 1:
pmem1[0] = data[0];
pmem2[0] = data[0];
break;
jNO_DEFAULT
}
vifX.tag.addr += ret;
vifX.tag.size -= ret;
if (!vifX.tag.size) vifX.cmd = 0;
return ret;
}
vifOp(vifCode_STCol) {
pass1 {
vifX.tag.addr = 0;
vifX.tag.size = 4;
return 1;
}
pass2 {
u32* cols = idx ? g_vifmask.Col1 : g_vifmask.Col0;
u32* pmem1 = &vifXRegs->c0 + (vifX.tag.addr << 2);
u32* pmem2 = cols + vifX.tag.addr;
return _vifCode_STColRow<idx>(data, pmem1, pmem2);
}
pass3 { DevCon.WriteLn("vifCode_STCol"); }
return 0;
}
vifOp(vifCode_STRow) {
pass1 {
vifX.tag.addr = 0;
vifX.tag.size = 4;
return 1;
}
pass2 {
u32* rows = idx ? g_vifmask.Row1 : g_vifmask.Row0;
u32* pmem1 = &vifXRegs->r0 + (vifX.tag.addr << 2);
u32* pmem2 = rows + vifX.tag.addr;
return _vifCode_STColRow<idx>(data, pmem1, pmem2);
}
pass3 { DevCon.WriteLn("vifCode_STRow"); }
return 0;
}
vifOp(vifCode_STCycl) {
pass1 {
vifXRegs->cycle.cl = (u8)(vifXRegs->code);
vifXRegs->cycle.wl = (u8)(vifXRegs->code >> 8);
vifX.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_STCycl"); }
return 0;
}
vifOp(vifCode_STMask) {
pass1 { vifX.tag.size = 1; }
pass2 { vifXRegs->mask = data[0]; vifX.tag.size = 0; vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_STMask"); }
return 1;
}
vifOp(vifCode_STMod) {
pass1 { vifXRegs->mode = vifXRegs->code & 0x3; vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_STMod"); }
return 0;
}
vifOp(vifCode_Unpack) {
pass1 {
if (!idx) vif0UnpackSetup(data);
else vif1UnpackSetup(data);
return 1;
}
pass2 { return nVifUnpack(idx, (u8*)data); }
pass3 { DevCon.WriteLn("vifCode_Unpack"); }
return 0;
}
//------------------------------------------------------------------
// Vif0/Vif1 Code Tables
//------------------------------------------------------------------
int (__fastcall *vif0Code[128])(int pass, u32 *data) = {
vifCode_Nop<0> , vifCode_STCycl<0> , vifCode_Offset<0> , vifCode_Base<0> , vifCode_ITop<0> , vifCode_STMod<0> , vifCode_MskPath3<0>, vifCode_Mark<0>, /*0x00*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x08*/
vifCode_FlushE<0> , vifCode_Flush<0> , vifCode_Null<0> , vifCode_FlushA<0> , vifCode_MSCAL<0> , vifCode_MSCALF<0> , vifCode_Null<0> , vifCode_MSCNT<0>, /*0x10*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x18*/
vifCode_STMask<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x20*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x28*/
vifCode_STRow<0> , vifCode_STCol<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x30*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x38*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x40*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_MPG<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x48*/
vifCode_Direct<0> , vifCode_DirectHL<0>, vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x50*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x58*/
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Null<0>, /*0x60*/
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0>, /*0x68*/
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Null<0>, /*0x70*/
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Null<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> /*0x78*/
};
int (__fastcall *vif1Code[128])(int pass, u32 *data) = {
vifCode_Nop<1> , vifCode_STCycl<1> , vifCode_Offset<1> , vifCode_Base<1> , vifCode_ITop<1> , vifCode_STMod<1> , vifCode_MskPath3<1>, vifCode_Mark<1>, /*0x00*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x08*/
vifCode_FlushE<1> , vifCode_Flush<1> , vifCode_Null<1> , vifCode_FlushA<1> , vifCode_MSCAL<1> , vifCode_MSCALF<1> , vifCode_Null<1> , vifCode_MSCNT<1>, /*0x10*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x18*/
vifCode_STMask<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x20*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x28*/
vifCode_STRow<1> , vifCode_STCol<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x30*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x38*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x40*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_MPG<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x48*/
vifCode_Direct<1> , vifCode_DirectHL<1>, vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x50*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x58*/
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Null<1>, /*0x60*/
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1>, /*0x68*/
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Null<1>, /*0x70*/
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Null<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> /*0x78*/
};

View File

@ -1,111 +1,111 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "Vif_Unpack.h"
struct vifCode {
u32 addr;
u32 size;
u32 cmd;
u16 wl;
u16 cl;
};
union tBITBLT {
struct {
u32 reserved : 8;
u32 BLTDIVIDE : 8; // This is the value we want to work out the divider for the reverse transfer
u32 reserved2 : 6;
u32 TRXPOS : 16;
};
u32 _u32;
};
// NOTE, if debugging vif stalls, use sega classics, spyro, gt4, and taito
struct vifStruct {
vifCode tag;
int cmd;
int irq;
int cl;
int qwcalign;
u8 usn;
bool done;
bool vifstalled;
bool stallontag;
tBITBLT TRXPOS; //used for reversed fifo operations, sometimes only the GS knows how big (like on HW register fifo read)!
u32 GSLastTRXPOS;
u8 irqoffset; // 32bit offset where next vif code is
u32 savedtag; // need this for backwards compat with save states
u32 vifpacketsize;
u8 inprogress;
u8 dmamode;
};
extern vifStruct* vif;
extern vifStruct vif0, vif1;
extern u8 schedulepath3msk;
extern void vif0Init();
extern void vif0Interrupt();
extern void vif0Write32(u32 mem, u32 value);
extern void vif0Reset();
extern void vif1Interrupt();
extern void vif1Init();
extern void Vif1MskPath3();
extern void vif1Write32(u32 mem, u32 value);
extern void vif1Reset();
extern int (__fastcall *vif0Code[128])(int pass, u32 *data);
extern int (__fastcall *vif1Code[128])(int pass, u32 *data);
__forceinline static int _limit(int a, int max)
{
return ((a > max) ? max : a);
}
enum VifModes
{
VIF_NORMAL_TO_MEM_MODE = 0,
VIF_NORMAL_FROM_MEM_MODE = 1,
VIF_CHAIN_MODE = 2
};
// Generic constants
static const unsigned int VIF0intc = 4;
static const unsigned int VIF1intc = 5;
extern int g_vifCycles;
extern void vif0FLUSH();
extern void vif1FLUSH();
//------------------------------------------------------------------
// newVif SSE-optimized Row/Col Structs
//------------------------------------------------------------------
struct VifMaskTypes
{
u32 Row0[4], Col0[4];
u32 Row1[4], Col1[4];
};
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "Vif_Unpack.h"
struct vifCode {
u32 addr;
u32 size;
u32 cmd;
u16 wl;
u16 cl;
};
union tBITBLT {
struct {
u32 reserved : 8;
u32 BLTDIVIDE : 8; // This is the value we want to work out the divider for the reverse transfer
u32 reserved2 : 6;
u32 TRXPOS : 16;
};
u32 _u32;
};
// NOTE, if debugging vif stalls, use sega classics, spyro, gt4, and taito
struct vifStruct {
vifCode tag;
int cmd;
int irq;
int cl;
int qwcalign;
u8 usn;
bool done;
bool vifstalled;
bool stallontag;
tBITBLT TRXPOS; //used for reversed fifo operations, sometimes only the GS knows how big (like on HW register fifo read)!
u32 GSLastTRXPOS;
u8 irqoffset; // 32bit offset where next vif code is
u32 savedtag; // need this for backwards compat with save states
u32 vifpacketsize;
u8 inprogress;
u8 dmamode;
};
extern vifStruct* vif;
extern vifStruct vif0, vif1;
extern u8 schedulepath3msk;
extern void vif0Init();
extern void vif0Interrupt();
extern void vif0Write32(u32 mem, u32 value);
extern void vif0Reset();
extern void vif1Interrupt();
extern void vif1Init();
extern void Vif1MskPath3();
extern void vif1Write32(u32 mem, u32 value);
extern void vif1Reset();
extern int (__fastcall *vif0Code[128])(int pass, u32 *data);
extern int (__fastcall *vif1Code[128])(int pass, u32 *data);
__forceinline static int _limit(int a, int max)
{
return ((a > max) ? max : a);
}
enum VifModes
{
VIF_NORMAL_TO_MEM_MODE = 0,
VIF_NORMAL_FROM_MEM_MODE = 1,
VIF_CHAIN_MODE = 2
};
// Generic constants
static const unsigned int VIF0intc = 4;
static const unsigned int VIF1intc = 5;
extern int g_vifCycles;
extern void vif0FLUSH();
extern void vif1FLUSH();
//------------------------------------------------------------------
// newVif SSE-optimized Row/Col Structs
//------------------------------------------------------------------
struct VifMaskTypes
{
u32 Row0[4], Col0[4];
u32 Row1[4], Col1[4];
};
extern __aligned16 VifMaskTypes g_vifmask; // This struct is used by newVif

View File

@ -1,133 +1,133 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "Vif_Dma.h"
#include "newVif.h"
//------------------------------------------------------------------
// VifCode Transfer Interpreter (Vif0/Vif1)
//------------------------------------------------------------------
// Doesn't stall if the next vifCode is the Mark command
_vifT bool runMark(u32* &data) {
if (((vifXRegs->code >> 24) & 0x7f) == 0x7) {
Console.WriteLn("Vif%d: Running Mark with I-bit", idx);
return 1; // No Stall?
}
return 1; // Stall
}
// Returns 1 if i-bit && finished vifcode && i-bit not masked
_vifT bool analyzeIbit(u32* &data, int iBit) {
if (iBit && !vifX.cmd && !vifXRegs->err.MII) {
//DevCon.WriteLn("Vif I-Bit IRQ");
vifX.irq++;
// On i-bit, the command is run, vif stalls etc,
// however if the vifcode is MARK, you do NOT stall, just send IRQ. - Max Payne shows this up.
//if(((vifXRegs->code >> 24) & 0x7f) == 0x7) return 0;
// If we have a vifcode with i-bit, the following instruction
// should stall unless its MARK?.. we test that case here...
// Not 100% sure if this is the correct behavior, so printing
// a console message to see games that use this. (cottonvibes)
// Okay did some testing with Max Payne, it does this
// VifMark value = 0x666 (i know, evil!)
// NOP with I Bit
// VifMark value = 0
//
// If you break after the 2nd Mark has run, the game reports invalid mark 0 and the game dies.
// So it has to occur here, testing a theory that it only doesn't stall if the command with
// the iBit IS mark, but still sends the IRQ to let the cpu know the mark is there. (Refraction)
return runMark<idx>(data);
}
return 0;
}
// Interprets packet
_vifT void vifTransferLoop(u32* &data) {
u32& pSize = vifX.vifpacketsize;
int iBit = vifX.cmd >> 7;
vifXRegs->stat.VPS |= VPS_TRANSFERRING;
vifXRegs->stat.ER1 = false;
while (pSize > 0 && !vifX.vifstalled) {
if(!vifX.cmd) { // Get new VifCode
vifXRegs->code = data[0];
vifX.cmd = data[0] >> 24;
iBit = data[0] >> 31;
VIF_LOG("New VifCMD %x tagsize %x", vifX.cmd, vifX.tag.size);
vifXCode[vifX.cmd & 0x7f](0, data);
data++; pSize--;
if (analyzeIbit<idx>(data, iBit)) break;
continue;
}
int ret = vifXCode[vifX.cmd & 0x7f](1, data);
data += ret;
pSize -= ret;
if (analyzeIbit<idx>(data, iBit)) break;
}
if (vifX.cmd) vifXRegs->stat.VPS = VPS_WAITING;
else vifXRegs->stat.VPS = VPS_IDLE;
if (pSize) vifX.vifstalled = true;
}
_vifT _f bool vifTransfer(u32 *data, int size) {
// irqoffset necessary to add up the right qws, or else will spin (spiderman)
int transferred = vifX.vifstalled ? vifX.irqoffset : 0;
vifX.irqoffset = 0;
vifX.vifstalled = false;
vifX.stallontag = false;
vifX.vifpacketsize = size;
vifTransferLoop<idx>(data);
transferred += size - vifX.vifpacketsize;
g_vifCycles +=(transferred >> 2) * BIAS; /* guessing */
vifX.irqoffset = transferred % 4; // cannot lose the offset
transferred = transferred >> 2;
vifXch->madr +=(transferred << 4);
vifXch->qwc -= transferred;
if (!vifXch->qwc && !vifX.irqoffset) vifX.inprogress &= ~0x1;
if (vifX.irq && vifX.cmd == 0) {
//DevCon.WriteLn("Vif IRQ!");
if(((vifXRegs->code >> 24) & 0x7f) != 0x7)
{
vifX.vifstalled = true;
vifXRegs->stat.VIS = true; // Note: commenting this out fixes WALL-E?
}
if (!vifXch->qwc && !vifX.irqoffset) vifX.inprogress = 0;
return false;
}
return !vifX.vifstalled;
}
bool VIF0transfer(u32 *data, int size, bool istag) {
return vifTransfer<0>(data, size);
}
bool VIF1transfer(u32 *data, int size, bool istag) {
return vifTransfer<1>(data, size);
}
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "Vif_Dma.h"
#include "newVif.h"
//------------------------------------------------------------------
// VifCode Transfer Interpreter (Vif0/Vif1)
//------------------------------------------------------------------
// Doesn't stall if the next vifCode is the Mark command
_vifT bool runMark(u32* &data) {
if (((vifXRegs->code >> 24) & 0x7f) == 0x7) {
Console.WriteLn("Vif%d: Running Mark with I-bit", idx);
return 1; // No Stall?
}
return 1; // Stall
}
// Returns 1 if i-bit && finished vifcode && i-bit not masked
_vifT bool analyzeIbit(u32* &data, int iBit) {
if (iBit && !vifX.cmd && !vifXRegs->err.MII) {
//DevCon.WriteLn("Vif I-Bit IRQ");
vifX.irq++;
// On i-bit, the command is run, vif stalls etc,
// however if the vifcode is MARK, you do NOT stall, just send IRQ. - Max Payne shows this up.
//if(((vifXRegs->code >> 24) & 0x7f) == 0x7) return 0;
// If we have a vifcode with i-bit, the following instruction
// should stall unless its MARK?.. we test that case here...
// Not 100% sure if this is the correct behavior, so printing
// a console message to see games that use this. (cottonvibes)
// Okay did some testing with Max Payne, it does this
// VifMark value = 0x666 (i know, evil!)
// NOP with I Bit
// VifMark value = 0
//
// If you break after the 2nd Mark has run, the game reports invalid mark 0 and the game dies.
// So it has to occur here, testing a theory that it only doesn't stall if the command with
// the iBit IS mark, but still sends the IRQ to let the cpu know the mark is there. (Refraction)
return runMark<idx>(data);
}
return 0;
}
// Interprets packet
_vifT void vifTransferLoop(u32* &data) {
u32& pSize = vifX.vifpacketsize;
int iBit = vifX.cmd >> 7;
vifXRegs->stat.VPS |= VPS_TRANSFERRING;
vifXRegs->stat.ER1 = false;
while (pSize > 0 && !vifX.vifstalled) {
if(!vifX.cmd) { // Get new VifCode
vifXRegs->code = data[0];
vifX.cmd = data[0] >> 24;
iBit = data[0] >> 31;
VIF_LOG("New VifCMD %x tagsize %x", vifX.cmd, vifX.tag.size);
vifXCode[vifX.cmd & 0x7f](0, data);
data++; pSize--;
if (analyzeIbit<idx>(data, iBit)) break;
continue;
}
int ret = vifXCode[vifX.cmd & 0x7f](1, data);
data += ret;
pSize -= ret;
if (analyzeIbit<idx>(data, iBit)) break;
}
if (vifX.cmd) vifXRegs->stat.VPS = VPS_WAITING;
else vifXRegs->stat.VPS = VPS_IDLE;
if (pSize) vifX.vifstalled = true;
}
_vifT _f bool vifTransfer(u32 *data, int size) {
// irqoffset necessary to add up the right qws, or else will spin (spiderman)
int transferred = vifX.vifstalled ? vifX.irqoffset : 0;
vifX.irqoffset = 0;
vifX.vifstalled = false;
vifX.stallontag = false;
vifX.vifpacketsize = size;
vifTransferLoop<idx>(data);
transferred += size - vifX.vifpacketsize;
g_vifCycles +=(transferred >> 2) * BIAS; /* guessing */
vifX.irqoffset = transferred % 4; // cannot lose the offset
transferred = transferred >> 2;
vifXch->madr +=(transferred << 4);
vifXch->qwc -= transferred;
if (!vifXch->qwc && !vifX.irqoffset) vifX.inprogress &= ~0x1;
if (vifX.irq && vifX.cmd == 0) {
//DevCon.WriteLn("Vif IRQ!");
if(((vifXRegs->code >> 24) & 0x7f) != 0x7)
{
vifX.vifstalled = true;
vifXRegs->stat.VIS = true; // Note: commenting this out fixes WALL-E?
}
if (!vifXch->qwc && !vifX.irqoffset) vifX.inprogress = 0;
return false;
}
return !vifX.vifstalled;
}
bool VIF0transfer(u32 *data, int size, bool istag) {
return vifTransfer<0>(data, size);
}
bool VIF1transfer(u32 *data, int size, bool istag) {
return vifTransfer<1>(data, size);
}

View File

@ -1,339 +1,339 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "Vif.h"
#include "Vif_Dma.h"
enum UnpackOffset {
OFFSET_X = 0,
OFFSET_Y = 1,
OFFSET_Z = 2,
OFFSET_W = 3
};
static __forceinline u32 setVifRowRegs(u32 reg, u32 data) {
switch (reg) {
case 0: vifRegs->r0 = data; break;
case 1: vifRegs->r1 = data; break;
case 2: vifRegs->r2 = data; break;
case 3: vifRegs->r3 = data; break;
jNO_DEFAULT;
}
return data;
}
static __forceinline u32 getVifRowRegs(u32 reg) {
switch (reg) {
case 0: return vifRegs->r0; break;
case 1: return vifRegs->r1; break;
case 2: return vifRegs->r2; break;
case 3: return vifRegs->r3; break;
jNO_DEFAULT;
}
return 0; // unreachable...
}
static __forceinline u32 getVifColRegs(u32 reg) {
switch (reg) {
case 0: return vifRegs->c0; break;
case 1: return vifRegs->c1; break;
case 2: return vifRegs->c2; break;
default: return vifRegs->c3; break;
}
return 0; // unreachable...
}
template< bool doMask >
static __releaseinline void writeXYZW(u32 offnum, u32 &dest, u32 data) {
u32 vifRowReg = getVifRowRegs(offnum);
int n = 0;
if (doMask) {
switch (vif->cl) {
case 0: n = (vifRegs->mask >> (offnum * 2)) & 0x3; break;
case 1: n = (vifRegs->mask >> ( 8 + (offnum * 2))) & 0x3; break;
case 2: n = (vifRegs->mask >> (16 + (offnum * 2))) & 0x3; break;
default: n = (vifRegs->mask >> (24 + (offnum * 2))) & 0x3; break;
}
}
switch (n) {
case 0:
if ((vif->cmd & 0x6F) != 0x6f) {
switch (vifRegs->mode) {
case 1: dest = data + vifRowReg; break;
case 2: dest = setVifRowRegs(offnum, vifRowReg + data); break;
default: dest = data; break;
}
}
else dest = data; // v4-5 Unpack Mode
break;
case 1: dest = vifRowReg; break;
case 2: dest = getVifColRegs(vif->cl); break;
case 3: break;
}
}
template < bool doMask, class T >
static __forceinline void __fastcall UNPACK_S(u32 *dest, T *data, int size)
{
//S-# will always be a complete packet, no matter what. So we can skip the offset bits
writeXYZW<doMask>(OFFSET_X, *dest++, *data);
writeXYZW<doMask>(OFFSET_Y, *dest++, *data);
writeXYZW<doMask>(OFFSET_Z, *dest++, *data);
writeXYZW<doMask>(OFFSET_W, *dest , *data);
}
template <bool doMask, class T>
static __forceinline void __fastcall UNPACK_V2(u32 *dest, T *data, int size)
{
if (vifRegs->offset == OFFSET_X)
{
if (size > 0)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *data++);
vifRegs->offset = OFFSET_Y;
size--;
}
}
if (vifRegs->offset == OFFSET_Y)
{
if (size > 0)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *data);
vifRegs->offset = OFFSET_Z;
size--;
}
}
if (vifRegs->offset == OFFSET_Z)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *dest-2);
vifRegs->offset = OFFSET_W;
}
if (vifRegs->offset == OFFSET_W)
{
writeXYZW<doMask>(vifRegs->offset, *dest, *data);
vifRegs->offset = OFFSET_X;
}
}
template <bool doMask, class T>
static __forceinline void __fastcall UNPACK_V3(u32 *dest, T *data, int size)
{
if(vifRegs->offset == OFFSET_X)
{
if (size > 0)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *data++);
vifRegs->offset = OFFSET_Y;
size--;
}
}
if(vifRegs->offset == OFFSET_Y)
{
if (size > 0)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *data++);
vifRegs->offset = OFFSET_Z;
size--;
}
}
if(vifRegs->offset == OFFSET_Z)
{
if (size > 0)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *data++);
vifRegs->offset = OFFSET_W;
size--;
}
}
if(vifRegs->offset == OFFSET_W)
{
// V3-# does some bizarre thing with alignment, every 6qw of data the W becomes 0 (strange console!)
// Ape Escape doesn't seem to like it tho (what the hell?) gonna have to investigate
writeXYZW<doMask>(vifRegs->offset, *dest, *data);
vifRegs->offset = OFFSET_X;
}
}
template <bool doMask, class T>
static __forceinline void __fastcall UNPACK_V4(u32 *dest, T *data , int size)
{
while (size > 0)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *data++);
vifRegs->offset++;
size--;
}
if (vifRegs->offset > OFFSET_W) vifRegs->offset = OFFSET_X;
}
template< bool doMask >
static __releaseinline void __fastcall UNPACK_V4_5(u32 *dest, u32 *data, int size)
{
//As with S-#, this will always be a complete packet
writeXYZW<doMask>(OFFSET_X, *dest++, ((*data & 0x001f) << 3));
writeXYZW<doMask>(OFFSET_Y, *dest++, ((*data & 0x03e0) >> 2));
writeXYZW<doMask>(OFFSET_Z, *dest++, ((*data & 0x7c00) >> 7));
writeXYZW<doMask>(OFFSET_W, *dest, ((*data & 0x8000) >> 8));
}
// =====================================================================================================
template < bool doMask, int size, class T >
static void __fastcall fUNPACK_S(u32 *dest, T *data)
{
UNPACK_S<doMask>( dest, data, size );
}
template <bool doMask, int size, class T>
static void __fastcall fUNPACK_V2(u32 *dest, T *data)
{
UNPACK_V2<doMask>( dest, data, size );
}
template <bool doMask, int size, class T>
static void __fastcall fUNPACK_V3(u32 *dest, T *data)
{
UNPACK_V3<doMask>( dest, data, size );
}
template <bool doMask, int size, class T>
static void __fastcall fUNPACK_V4(u32 *dest, T *data)
{
UNPACK_V4<doMask>( dest, data, size );
}
template< bool doMask >
static void __fastcall fUNPACK_V4_5(u32 *dest, u32 *data)
{
UNPACK_V4_5<doMask>(dest, data, 0); // size is ignored.
}
// --------------------------------------------------------------------------------------
// Main table for function unpacking.
// --------------------------------------------------------------------------------------
// The extra data bsize/dsize/etc are all duplicated between the doMask enabled and
// disabled versions. This is probably simpler and more efficient than bothering
// to generate separate tables.
//
// The double-cast function pointer nonsense is to appease GCC, which gives some rather
// cryptic error about being unable to deduce the type parameters (I think it's a bug
// relating to __fastcall, which I recall having some other places as well). It's fixed
// by explicitly casting the function to itself prior to casting it to what we need it
// to be cast as. --air
//
#define _upk (UNPACKFUNCTYPE)
#define _odd (UNPACKFUNCTYPE_ODD)
#define _unpk_s(bits) (UNPACKFUNCTYPE_S##bits)
#define _odd_s(bits) (UNPACKFUNCTYPE_ODD_S##bits)
#define _unpk_u(bits) (UNPACKFUNCTYPE_U##bits)
#define _odd_u(bits) (UNPACKFUNCTYPE_ODD_U##bits)
// 32-bits versions are unsigned-only!!
#define UnpackFuncPair32( sizefac, vt, doMask ) \
(UNPACKFUNCTYPE)_unpk_u(32) fUNPACK_##vt<doMask, sizefac, u32>, \
(UNPACKFUNCTYPE)_unpk_u(32) fUNPACK_##vt<doMask, sizefac, u32>, \
(UNPACKFUNCTYPE_ODD)_odd_u(32) UNPACK_##vt<doMask, u32>, \
(UNPACKFUNCTYPE_ODD)_odd_u(32) UNPACK_##vt<doMask, u32>,
#define UnpackFuncPair( sizefac, vt, bits, doMask ) \
(UNPACKFUNCTYPE)_unpk_u(bits) fUNPACK_##vt<doMask, sizefac, u##bits>, \
(UNPACKFUNCTYPE)_unpk_s(bits) fUNPACK_##vt<doMask, sizefac, s##bits>, \
(UNPACKFUNCTYPE_ODD)_odd_u(bits) UNPACK_##vt<doMask, u##bits>, \
(UNPACKFUNCTYPE_ODD)_odd_s(bits) UNPACK_##vt<doMask, s##bits>,
#define UnpackFuncSet( doMask ) \
{ UnpackFuncPair32( 4, S, doMask ) 1, 4, 4, 4 }, /* 0x0 - S-32 */ \
{ UnpackFuncPair ( 4, S, 16, doMask ) 2, 2, 2, 4 }, /* 0x1 - S-16 */ \
{ UnpackFuncPair ( 4, S, 8, doMask ) 4, 1, 1, 4 }, /* 0x2 - S-8 */ \
{ NULL, NULL, NULL, NULL, 0, 0, 0, 0 }, /* 0x3 (NULL) */ \
{ UnpackFuncPair32( 2, V2, doMask ) 24, 4, 8, 2 }, /* 0x4 - V2-32 */ \
{ UnpackFuncPair ( 2, V2, 16, doMask ) 12, 2, 4, 2 }, /* 0x5 - V2-16 */ \
{ UnpackFuncPair ( 2, V2, 8, doMask ) 6, 1, 2, 2 }, /* 0x6 - V2-8 */ \
{ NULL, NULL, NULL, NULL,0, 0, 0, 0 }, /* 0x7 (NULL) */ \
{ UnpackFuncPair32( 3, V3, doMask ) 36, 4, 12, 3 }, /* 0x8 - V3-32 */ \
{ UnpackFuncPair ( 3, V3, 16, doMask ) 18, 2, 6, 3 }, /* 0x9 - V3-16 */ \
{ UnpackFuncPair ( 3, V3, 8, doMask ) 9, 1, 3, 3 }, /* 0xA - V3-8 */ \
{ NULL, NULL, NULL, NULL,0, 0, 0, 0 }, /* 0xB (NULL) */ \
{ UnpackFuncPair32( 4, V4, doMask ) 48, 4, 16, 4 }, /* 0xC - V4-32 */ \
{ UnpackFuncPair ( 4, V4, 16, doMask ) 24, 2, 8, 4 }, /* 0xD - V4-16 */ \
{ UnpackFuncPair ( 4, V4, 8, doMask ) 12, 1, 4, 4 }, /* 0xE - V4-8 */ \
{ /* 0xF - V4-5 */ \
(UNPACKFUNCTYPE)_unpk_u(32) fUNPACK_V4_5<doMask>, \
(UNPACKFUNCTYPE)_unpk_u(32) fUNPACK_V4_5<doMask>, \
(UNPACKFUNCTYPE_ODD)_odd_u(32) UNPACK_V4_5<doMask>, \
(UNPACKFUNCTYPE_ODD)_odd_u(32) UNPACK_V4_5<doMask>, \
6, 2, 2, 4 },
const __aligned16 VIFUnpackFuncTable VIFfuncTable[32] =
{
UnpackFuncSet( false )
UnpackFuncSet( true )
};
//----------------------------------------------------------------------------
// Unpack Setup Code
//----------------------------------------------------------------------------
_vifT void vifUnpackSetup(u32 *data) {
if ((vifXRegs->cycle.wl == 0) && (vifXRegs->cycle.wl < vifXRegs->cycle.cl)) {
Console.WriteLn("Vif%d CL %d, WL %d", idx, vifXRegs->cycle.cl, vifXRegs->cycle.wl);
vifX.cmd = 0;
return; // Skipping write and 0 write-cycles, so do nothing!
}
if (!idx) vif0FLUSH(); // Only VU0?
vifX.usn = (vifXRegs->code >> 14) & 0x01;
int vifNum = (vifXRegs->code >> 16) & 0xff;
if (vifNum == 0) vifNum = 256;
vifXRegs->num = vifNum;
if (vifXRegs->cycle.wl <= vifXRegs->cycle.cl) {
if (!idx) vif0.tag.size = ((vifNum * VIFfuncTable[ vif0.cmd & 0xf ].gsize) + 3) >> 2;
else vif1.tag.size = ((vifNum * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2;
}
else {
int n = vifXRegs->cycle.cl * (vifNum / vifXRegs->cycle.wl) +
_limit(vifNum % vifXRegs->cycle.wl, vifXRegs->cycle.cl);
if (!idx) vif0.tag.size = ((n * VIFfuncTable[ vif0.cmd & 0xf ].gsize) + 3) >> 2;
else vif1.tag.size = ((n * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2;
}
u32 addr = vifXRegs->code;
if (idx && ((addr>>15)&1)) addr += vif1Regs->tops;
vifX.tag.addr = (addr<<4) & (idx ? 0x3ff0 : 0xff0);
vifX.cl = 0;
vifX.tag.cmd = vifX.cmd;
vifXRegs->offset = 0;
}
void vif0UnpackSetup(u32 *data) { vifUnpackSetup<0>(data); }
void vif1UnpackSetup(u32 *data) { vifUnpackSetup<1>(data); }
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "Vif.h"
#include "Vif_Dma.h"
enum UnpackOffset {
OFFSET_X = 0,
OFFSET_Y = 1,
OFFSET_Z = 2,
OFFSET_W = 3
};
static __forceinline u32 setVifRowRegs(u32 reg, u32 data) {
switch (reg) {
case 0: vifRegs->r0 = data; break;
case 1: vifRegs->r1 = data; break;
case 2: vifRegs->r2 = data; break;
case 3: vifRegs->r3 = data; break;
jNO_DEFAULT;
}
return data;
}
static __forceinline u32 getVifRowRegs(u32 reg) {
switch (reg) {
case 0: return vifRegs->r0; break;
case 1: return vifRegs->r1; break;
case 2: return vifRegs->r2; break;
case 3: return vifRegs->r3; break;
jNO_DEFAULT;
}
return 0; // unreachable...
}
static __forceinline u32 getVifColRegs(u32 reg) {
switch (reg) {
case 0: return vifRegs->c0; break;
case 1: return vifRegs->c1; break;
case 2: return vifRegs->c2; break;
default: return vifRegs->c3; break;
}
return 0; // unreachable...
}
template< bool doMask >
static __releaseinline void writeXYZW(u32 offnum, u32 &dest, u32 data) {
u32 vifRowReg = getVifRowRegs(offnum);
int n = 0;
if (doMask) {
switch (vif->cl) {
case 0: n = (vifRegs->mask >> (offnum * 2)) & 0x3; break;
case 1: n = (vifRegs->mask >> ( 8 + (offnum * 2))) & 0x3; break;
case 2: n = (vifRegs->mask >> (16 + (offnum * 2))) & 0x3; break;
default: n = (vifRegs->mask >> (24 + (offnum * 2))) & 0x3; break;
}
}
switch (n) {
case 0:
if ((vif->cmd & 0x6F) != 0x6f) {
switch (vifRegs->mode) {
case 1: dest = data + vifRowReg; break;
case 2: dest = setVifRowRegs(offnum, vifRowReg + data); break;
default: dest = data; break;
}
}
else dest = data; // v4-5 Unpack Mode
break;
case 1: dest = vifRowReg; break;
case 2: dest = getVifColRegs(vif->cl); break;
case 3: break;
}
}
template < bool doMask, class T >
static __forceinline void __fastcall UNPACK_S(u32 *dest, T *data, int size)
{
//S-# will always be a complete packet, no matter what. So we can skip the offset bits
writeXYZW<doMask>(OFFSET_X, *dest++, *data);
writeXYZW<doMask>(OFFSET_Y, *dest++, *data);
writeXYZW<doMask>(OFFSET_Z, *dest++, *data);
writeXYZW<doMask>(OFFSET_W, *dest , *data);
}
template <bool doMask, class T>
static __forceinline void __fastcall UNPACK_V2(u32 *dest, T *data, int size)
{
if (vifRegs->offset == OFFSET_X)
{
if (size > 0)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *data++);
vifRegs->offset = OFFSET_Y;
size--;
}
}
if (vifRegs->offset == OFFSET_Y)
{
if (size > 0)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *data);
vifRegs->offset = OFFSET_Z;
size--;
}
}
if (vifRegs->offset == OFFSET_Z)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *dest-2);
vifRegs->offset = OFFSET_W;
}
if (vifRegs->offset == OFFSET_W)
{
writeXYZW<doMask>(vifRegs->offset, *dest, *data);
vifRegs->offset = OFFSET_X;
}
}
template <bool doMask, class T>
static __forceinline void __fastcall UNPACK_V3(u32 *dest, T *data, int size)
{
if(vifRegs->offset == OFFSET_X)
{
if (size > 0)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *data++);
vifRegs->offset = OFFSET_Y;
size--;
}
}
if(vifRegs->offset == OFFSET_Y)
{
if (size > 0)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *data++);
vifRegs->offset = OFFSET_Z;
size--;
}
}
if(vifRegs->offset == OFFSET_Z)
{
if (size > 0)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *data++);
vifRegs->offset = OFFSET_W;
size--;
}
}
if(vifRegs->offset == OFFSET_W)
{
// V3-# does some bizarre thing with alignment, every 6qw of data the W becomes 0 (strange console!)
// Ape Escape doesn't seem to like it tho (what the hell?) gonna have to investigate
writeXYZW<doMask>(vifRegs->offset, *dest, *data);
vifRegs->offset = OFFSET_X;
}
}
template <bool doMask, class T>
static __forceinline void __fastcall UNPACK_V4(u32 *dest, T *data , int size)
{
while (size > 0)
{
writeXYZW<doMask>(vifRegs->offset, *dest++, *data++);
vifRegs->offset++;
size--;
}
if (vifRegs->offset > OFFSET_W) vifRegs->offset = OFFSET_X;
}
template< bool doMask >
static __releaseinline void __fastcall UNPACK_V4_5(u32 *dest, u32 *data, int size)
{
//As with S-#, this will always be a complete packet
writeXYZW<doMask>(OFFSET_X, *dest++, ((*data & 0x001f) << 3));
writeXYZW<doMask>(OFFSET_Y, *dest++, ((*data & 0x03e0) >> 2));
writeXYZW<doMask>(OFFSET_Z, *dest++, ((*data & 0x7c00) >> 7));
writeXYZW<doMask>(OFFSET_W, *dest, ((*data & 0x8000) >> 8));
}
// =====================================================================================================
template < bool doMask, int size, class T >
static void __fastcall fUNPACK_S(u32 *dest, T *data)
{
UNPACK_S<doMask>( dest, data, size );
}
template <bool doMask, int size, class T>
static void __fastcall fUNPACK_V2(u32 *dest, T *data)
{
UNPACK_V2<doMask>( dest, data, size );
}
template <bool doMask, int size, class T>
static void __fastcall fUNPACK_V3(u32 *dest, T *data)
{
UNPACK_V3<doMask>( dest, data, size );
}
template <bool doMask, int size, class T>
static void __fastcall fUNPACK_V4(u32 *dest, T *data)
{
UNPACK_V4<doMask>( dest, data, size );
}
template< bool doMask >
static void __fastcall fUNPACK_V4_5(u32 *dest, u32 *data)
{
UNPACK_V4_5<doMask>(dest, data, 0); // size is ignored.
}
// --------------------------------------------------------------------------------------
// Main table for function unpacking.
// --------------------------------------------------------------------------------------
// The extra data bsize/dsize/etc are all duplicated between the doMask enabled and
// disabled versions. This is probably simpler and more efficient than bothering
// to generate separate tables.
//
// The double-cast function pointer nonsense is to appease GCC, which gives some rather
// cryptic error about being unable to deduce the type parameters (I think it's a bug
// relating to __fastcall, which I recall having some other places as well). It's fixed
// by explicitly casting the function to itself prior to casting it to what we need it
// to be cast as. --air
//
#define _upk (UNPACKFUNCTYPE)
#define _odd (UNPACKFUNCTYPE_ODD)
#define _unpk_s(bits) (UNPACKFUNCTYPE_S##bits)
#define _odd_s(bits) (UNPACKFUNCTYPE_ODD_S##bits)
#define _unpk_u(bits) (UNPACKFUNCTYPE_U##bits)
#define _odd_u(bits) (UNPACKFUNCTYPE_ODD_U##bits)
// 32-bits versions are unsigned-only!!
#define UnpackFuncPair32( sizefac, vt, doMask ) \
(UNPACKFUNCTYPE)_unpk_u(32) fUNPACK_##vt<doMask, sizefac, u32>, \
(UNPACKFUNCTYPE)_unpk_u(32) fUNPACK_##vt<doMask, sizefac, u32>, \
(UNPACKFUNCTYPE_ODD)_odd_u(32) UNPACK_##vt<doMask, u32>, \
(UNPACKFUNCTYPE_ODD)_odd_u(32) UNPACK_##vt<doMask, u32>,
#define UnpackFuncPair( sizefac, vt, bits, doMask ) \
(UNPACKFUNCTYPE)_unpk_u(bits) fUNPACK_##vt<doMask, sizefac, u##bits>, \
(UNPACKFUNCTYPE)_unpk_s(bits) fUNPACK_##vt<doMask, sizefac, s##bits>, \
(UNPACKFUNCTYPE_ODD)_odd_u(bits) UNPACK_##vt<doMask, u##bits>, \
(UNPACKFUNCTYPE_ODD)_odd_s(bits) UNPACK_##vt<doMask, s##bits>,
#define UnpackFuncSet( doMask ) \
{ UnpackFuncPair32( 4, S, doMask ) 1, 4, 4, 4 }, /* 0x0 - S-32 */ \
{ UnpackFuncPair ( 4, S, 16, doMask ) 2, 2, 2, 4 }, /* 0x1 - S-16 */ \
{ UnpackFuncPair ( 4, S, 8, doMask ) 4, 1, 1, 4 }, /* 0x2 - S-8 */ \
{ NULL, NULL, NULL, NULL, 0, 0, 0, 0 }, /* 0x3 (NULL) */ \
{ UnpackFuncPair32( 2, V2, doMask ) 24, 4, 8, 2 }, /* 0x4 - V2-32 */ \
{ UnpackFuncPair ( 2, V2, 16, doMask ) 12, 2, 4, 2 }, /* 0x5 - V2-16 */ \
{ UnpackFuncPair ( 2, V2, 8, doMask ) 6, 1, 2, 2 }, /* 0x6 - V2-8 */ \
{ NULL, NULL, NULL, NULL,0, 0, 0, 0 }, /* 0x7 (NULL) */ \
{ UnpackFuncPair32( 3, V3, doMask ) 36, 4, 12, 3 }, /* 0x8 - V3-32 */ \
{ UnpackFuncPair ( 3, V3, 16, doMask ) 18, 2, 6, 3 }, /* 0x9 - V3-16 */ \
{ UnpackFuncPair ( 3, V3, 8, doMask ) 9, 1, 3, 3 }, /* 0xA - V3-8 */ \
{ NULL, NULL, NULL, NULL,0, 0, 0, 0 }, /* 0xB (NULL) */ \
{ UnpackFuncPair32( 4, V4, doMask ) 48, 4, 16, 4 }, /* 0xC - V4-32 */ \
{ UnpackFuncPair ( 4, V4, 16, doMask ) 24, 2, 8, 4 }, /* 0xD - V4-16 */ \
{ UnpackFuncPair ( 4, V4, 8, doMask ) 12, 1, 4, 4 }, /* 0xE - V4-8 */ \
{ /* 0xF - V4-5 */ \
(UNPACKFUNCTYPE)_unpk_u(32) fUNPACK_V4_5<doMask>, \
(UNPACKFUNCTYPE)_unpk_u(32) fUNPACK_V4_5<doMask>, \
(UNPACKFUNCTYPE_ODD)_odd_u(32) UNPACK_V4_5<doMask>, \
(UNPACKFUNCTYPE_ODD)_odd_u(32) UNPACK_V4_5<doMask>, \
6, 2, 2, 4 },
const __aligned16 VIFUnpackFuncTable VIFfuncTable[32] =
{
UnpackFuncSet( false )
UnpackFuncSet( true )
};
//----------------------------------------------------------------------------
// Unpack Setup Code
//----------------------------------------------------------------------------
_vifT void vifUnpackSetup(u32 *data) {
if ((vifXRegs->cycle.wl == 0) && (vifXRegs->cycle.wl < vifXRegs->cycle.cl)) {
Console.WriteLn("Vif%d CL %d, WL %d", idx, vifXRegs->cycle.cl, vifXRegs->cycle.wl);
vifX.cmd = 0;
return; // Skipping write and 0 write-cycles, so do nothing!
}
if (!idx) vif0FLUSH(); // Only VU0?
vifX.usn = (vifXRegs->code >> 14) & 0x01;
int vifNum = (vifXRegs->code >> 16) & 0xff;
if (vifNum == 0) vifNum = 256;
vifXRegs->num = vifNum;
if (vifXRegs->cycle.wl <= vifXRegs->cycle.cl) {
if (!idx) vif0.tag.size = ((vifNum * VIFfuncTable[ vif0.cmd & 0xf ].gsize) + 3) >> 2;
else vif1.tag.size = ((vifNum * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2;
}
else {
int n = vifXRegs->cycle.cl * (vifNum / vifXRegs->cycle.wl) +
_limit(vifNum % vifXRegs->cycle.wl, vifXRegs->cycle.cl);
if (!idx) vif0.tag.size = ((n * VIFfuncTable[ vif0.cmd & 0xf ].gsize) + 3) >> 2;
else vif1.tag.size = ((n * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2;
}
u32 addr = vifXRegs->code;
if (idx && ((addr>>15)&1)) addr += vif1Regs->tops;
vifX.tag.addr = (addr<<4) & (idx ? 0x3ff0 : 0xff0);
vifX.cl = 0;
vifX.tag.cmd = vifX.cmd;
vifXRegs->offset = 0;
}
void vif0UnpackSetup(u32 *data) { vifUnpackSetup<0>(data); }
void vif1UnpackSetup(u32 *data) { vifUnpackSetup<1>(data); }

View File

@ -1,59 +1,59 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
typedef void (__fastcall *UNPACKFUNCTYPE)(u32 *dest, u32 *data);
typedef void (__fastcall *UNPACKFUNCTYPE_ODD)(u32 *dest, u32 *data, int size);
typedef int (*UNPACKPARTFUNCTYPESSE)(u32 *dest, u32 *data, int size);
#define create_unpack_u_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_U##bits)(u32 *dest, u##bits *data);
#define create_unpack_odd_u_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_ODD_U##bits)(u32 *dest, u##bits *data, int size);
#define create_unpack_s_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_S##bits)(u32 *dest, s##bits *data);
#define create_unpack_odd_s_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_ODD_S##bits)(u32 *dest, s##bits *data, int size);
#define create_some_unpacks(bits) \
create_unpack_u_type(bits); \
create_unpack_odd_u_type(bits); \
create_unpack_s_type(bits); \
create_unpack_odd_s_type(bits);
create_some_unpacks(32);
create_some_unpacks(16);
create_some_unpacks(8);
struct VIFUnpackFuncTable
{
UNPACKFUNCTYPE funcU;
UNPACKFUNCTYPE funcS;
UNPACKFUNCTYPE_ODD oddU; // needed for old-style vif only, remove when old vif is removed.
UNPACKFUNCTYPE_ODD oddS; // needed for old-style vif only, remove when old vif is removed.
u8 bsize; // currently unused
u8 dsize; // byte size of one channel
u8 gsize; // size of data in bytes used for each write cycle
u8 qsize; // used for unpack parts, num of vectors that
// will be decompressed from data for 1 cycle
};
extern const __aligned16 VIFUnpackFuncTable VIFfuncTable[32];
extern int nVifUnpack (int idx, u8 *data);
extern void initNewVif (int idx);
extern void resetNewVif(int idx);
extern __forceinline void vif0UnpackSetup(u32 *data);
extern __forceinline void vif1UnpackSetup(u32 *data);
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
typedef void (__fastcall *UNPACKFUNCTYPE)(u32 *dest, u32 *data);
typedef void (__fastcall *UNPACKFUNCTYPE_ODD)(u32 *dest, u32 *data, int size);
typedef int (*UNPACKPARTFUNCTYPESSE)(u32 *dest, u32 *data, int size);
#define create_unpack_u_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_U##bits)(u32 *dest, u##bits *data);
#define create_unpack_odd_u_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_ODD_U##bits)(u32 *dest, u##bits *data, int size);
#define create_unpack_s_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_S##bits)(u32 *dest, s##bits *data);
#define create_unpack_odd_s_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_ODD_S##bits)(u32 *dest, s##bits *data, int size);
#define create_some_unpacks(bits) \
create_unpack_u_type(bits); \
create_unpack_odd_u_type(bits); \
create_unpack_s_type(bits); \
create_unpack_odd_s_type(bits);
create_some_unpacks(32);
create_some_unpacks(16);
create_some_unpacks(8);
struct VIFUnpackFuncTable
{
UNPACKFUNCTYPE funcU;
UNPACKFUNCTYPE funcS;
UNPACKFUNCTYPE_ODD oddU; // needed for old-style vif only, remove when old vif is removed.
UNPACKFUNCTYPE_ODD oddS; // needed for old-style vif only, remove when old vif is removed.
u8 bsize; // currently unused
u8 dsize; // byte size of one channel
u8 gsize; // size of data in bytes used for each write cycle
u8 qsize; // used for unpack parts, num of vectors that
// will be decompressed from data for 1 cycle
};
extern const __aligned16 VIFUnpackFuncTable VIFfuncTable[32];
extern int nVifUnpack (int idx, u8 *data);
extern void initNewVif (int idx);
extern void resetNewVif(int idx);
extern __forceinline void vif0UnpackSetup(u32 *data);
extern __forceinline void vif1UnpackSetup(u32 *data);

View File

@ -1,244 +1,244 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "Utilities/EventSource.h"
enum CoreThreadStatus
{
CoreThread_Indeterminate,
CoreThread_Started,
CoreThread_Resumed,
CoreThread_Suspended,
CoreThread_Reset,
CoreThread_Stopped,
};
enum AppEventType
{
AppStatus_SettingsLoaded,
AppStatus_SettingsSaved,
AppStatus_SettingsApplied,
AppStatus_Exiting
};
enum PluginEventType
{
CorePlugins_Loaded,
CorePlugins_Init,
CorePlugins_Opening, // dispatched prior to plugins being opened
CorePlugins_Opened, // dispatched after plugins are opened
CorePlugins_Closing, // dispatched prior to plugins being closed
CorePlugins_Closed, // dispatched after plugins are closed
CorePlugins_Shutdown,
CorePlugins_Unloaded,
};
struct AppEventInfo
{
AppEventType evt_type;
AppEventInfo( AppEventType type )
{
evt_type = type;
}
};
struct AppSettingsEventInfo : AppEventInfo
{
IniInterface& m_ini;
AppSettingsEventInfo( IniInterface& ini );
IniInterface& GetIni() const
{
return const_cast<IniInterface&>(m_ini);
}
};
// --------------------------------------------------------------------------------------
// IEventListener_CoreThread
// --------------------------------------------------------------------------------------
class IEventListener_CoreThread : public IEventDispatcher<CoreThreadStatus>
{
public:
typedef CoreThreadStatus EvtParams;
public:
virtual ~IEventListener_CoreThread() throw() {}
virtual void DispatchEvent( const CoreThreadStatus& status );
protected:
virtual void CoreThread_OnStarted() {}
virtual void CoreThread_OnResumed() {}
virtual void CoreThread_OnSuspended() {}
virtual void CoreThread_OnReset() {}
virtual void CoreThread_OnStopped() {}
};
class EventListener_CoreThread : public IEventListener_CoreThread
{
public:
EventListener_CoreThread();
virtual ~EventListener_CoreThread() throw();
};
// --------------------------------------------------------------------------------------
// IEventListener_Plugins
// --------------------------------------------------------------------------------------
class IEventListener_Plugins : public IEventDispatcher<PluginEventType>
{
public:
typedef PluginEventType EvtParams;
public:
virtual ~IEventListener_Plugins() throw() {}
virtual void DispatchEvent( const PluginEventType& pevt );
protected:
virtual void CorePlugins_OnLoaded() {}
virtual void CorePlugins_OnInit() {}
virtual void CorePlugins_OnOpening() {} // dispatched prior to plugins being opened
virtual void CorePlugins_OnOpened() {} // dispatched after plugins are opened
virtual void CorePlugins_OnClosing() {} // dispatched prior to plugins being closed
virtual void CorePlugins_OnClosed() {} // dispatched after plugins are closed
virtual void CorePlugins_OnShutdown() {}
virtual void CorePlugins_OnUnloaded() {}
};
class EventListener_Plugins : public IEventListener_Plugins
{
public:
EventListener_Plugins();
virtual ~EventListener_Plugins() throw();
};
// --------------------------------------------------------------------------------------
// IEventListener_AppStatus
// --------------------------------------------------------------------------------------
class IEventListener_AppStatus : public IEventDispatcher<AppEventInfo>
{
public:
typedef AppEventInfo EvtParams;
public:
virtual ~IEventListener_AppStatus() throw() {}
virtual void DispatchEvent( const AppEventInfo& evtinfo );
protected:
virtual void AppStatusEvent_OnSettingsLoadSave( const AppSettingsEventInfo& evtinfo ) {}
virtual void AppStatusEvent_OnSettingsApplied() {}
virtual void AppStatusEvent_OnExit() {}
};
class EventListener_AppStatus : public IEventListener_AppStatus
{
public:
EventListener_AppStatus();
virtual ~EventListener_AppStatus() throw();
};
// --------------------------------------------------------------------------------------
// EventListenerHelpers (CoreThread / Plugins / AppStatus)
// --------------------------------------------------------------------------------------
// Welcome to the awkward world of C++ multi-inheritence. wxWidgets' Connect() system is
// incompatible because of limitations in C++ class member function pointers, so we need
// this second layer class to act as a bridge between the event system and the class's
// handler implementations.
//
template< typename TypeToDispatchTo >
class EventListenerHelper_CoreThread : public EventListener_CoreThread
{
public:
TypeToDispatchTo& Owner;
public:
EventListenerHelper_CoreThread( TypeToDispatchTo& dispatchTo )
: Owner( dispatchTo ) { }
EventListenerHelper_CoreThread( TypeToDispatchTo* dispatchTo )
: Owner( *dispatchTo )
{
pxAssume(dispatchTo != NULL);
}
virtual ~EventListenerHelper_CoreThread() throw() {}
protected:
void OnCoreThread_Indeterminate() { Owner.OnCoreThread_Indeterminate(); }
void CoreThread_OnStarted() { Owner.OnCoreThread_Started(); }
void CoreThread_OnResumed() { Owner.OnCoreThread_Resumed(); }
void CoreThread_OnSuspended() { Owner.OnCoreThread_Suspended(); }
void CoreThread_OnReset() { Owner.OnCoreThread_Reset(); }
void CoreThread_OnStopped() { Owner.OnCoreThread_Stopped(); }
};
template< typename TypeToDispatchTo >
class EventListenerHelper_Plugins : public EventListener_Plugins
{
public:
TypeToDispatchTo& Owner;
public:
EventListenerHelper_Plugins( TypeToDispatchTo& dispatchTo )
: Owner( dispatchTo ) { }
EventListenerHelper_Plugins( TypeToDispatchTo* dispatchTo )
: Owner( *dispatchTo )
{
pxAssume(dispatchTo != NULL);
}
virtual ~EventListenerHelper_Plugins() throw() {}
protected:
void CorePlugins_OnLoaded() { Owner.OnCorePlugins_Loaded(); }
void CorePlugins_OnInit() { Owner.OnCorePlugins_Init(); }
void CorePlugins_OnOpening() { Owner.OnCorePlugins_Opening(); }
void CorePlugins_OnOpened() { Owner.OnCorePlugins_Opened(); }
void CorePlugins_OnClosing() { Owner.OnCorePlugins_Closing(); }
void CorePlugins_OnClosed() { Owner.OnCorePlugins_Closed(); }
void CorePlugins_OnShutdown() { Owner.OnCorePlugins_Shutdown(); }
void CorePlugins_OnUnloaded() { Owner.OnCorePlugins_Unloaded(); }
};
template< typename TypeToDispatchTo >
class EventListenerHelper_AppStatus : public EventListener_AppStatus
{
public:
TypeToDispatchTo& Owner;
public:
EventListenerHelper_AppStatus( TypeToDispatchTo& dispatchTo )
: Owner( dispatchTo ) { }
EventListenerHelper_AppStatus( TypeToDispatchTo* dispatchTo )
: Owner( *dispatchTo )
{
pxAssume(dispatchTo != NULL);
}
virtual ~EventListenerHelper_AppStatus() throw() {}
protected:
virtual void AppStatusEvent_OnSettingsLoadSave( const AppSettingsEventInfo& evtinfo ) { Owner.AppStatusEvent_OnSettingsLoadSave( evtinfo ); }
virtual void AppStatusEvent_OnSettingsApplied() { Owner.AppStatusEvent_OnSettingsApplied(); }
virtual void AppStatusEvent_OnExit() { Owner.AppStatusEvent_OnExit(); }
};
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "Utilities/EventSource.h"
enum CoreThreadStatus
{
CoreThread_Indeterminate,
CoreThread_Started,
CoreThread_Resumed,
CoreThread_Suspended,
CoreThread_Reset,
CoreThread_Stopped,
};
enum AppEventType
{
AppStatus_SettingsLoaded,
AppStatus_SettingsSaved,
AppStatus_SettingsApplied,
AppStatus_Exiting
};
enum PluginEventType
{
CorePlugins_Loaded,
CorePlugins_Init,
CorePlugins_Opening, // dispatched prior to plugins being opened
CorePlugins_Opened, // dispatched after plugins are opened
CorePlugins_Closing, // dispatched prior to plugins being closed
CorePlugins_Closed, // dispatched after plugins are closed
CorePlugins_Shutdown,
CorePlugins_Unloaded,
};
struct AppEventInfo
{
AppEventType evt_type;
AppEventInfo( AppEventType type )
{
evt_type = type;
}
};
struct AppSettingsEventInfo : AppEventInfo
{
IniInterface& m_ini;
AppSettingsEventInfo( IniInterface& ini );
IniInterface& GetIni() const
{
return const_cast<IniInterface&>(m_ini);
}
};
// --------------------------------------------------------------------------------------
// IEventListener_CoreThread
// --------------------------------------------------------------------------------------
class IEventListener_CoreThread : public IEventDispatcher<CoreThreadStatus>
{
public:
typedef CoreThreadStatus EvtParams;
public:
virtual ~IEventListener_CoreThread() throw() {}
virtual void DispatchEvent( const CoreThreadStatus& status );
protected:
virtual void CoreThread_OnStarted() {}
virtual void CoreThread_OnResumed() {}
virtual void CoreThread_OnSuspended() {}
virtual void CoreThread_OnReset() {}
virtual void CoreThread_OnStopped() {}
};
class EventListener_CoreThread : public IEventListener_CoreThread
{
public:
EventListener_CoreThread();
virtual ~EventListener_CoreThread() throw();
};
// --------------------------------------------------------------------------------------
// IEventListener_Plugins
// --------------------------------------------------------------------------------------
class IEventListener_Plugins : public IEventDispatcher<PluginEventType>
{
public:
typedef PluginEventType EvtParams;
public:
virtual ~IEventListener_Plugins() throw() {}
virtual void DispatchEvent( const PluginEventType& pevt );
protected:
virtual void CorePlugins_OnLoaded() {}
virtual void CorePlugins_OnInit() {}
virtual void CorePlugins_OnOpening() {} // dispatched prior to plugins being opened
virtual void CorePlugins_OnOpened() {} // dispatched after plugins are opened
virtual void CorePlugins_OnClosing() {} // dispatched prior to plugins being closed
virtual void CorePlugins_OnClosed() {} // dispatched after plugins are closed
virtual void CorePlugins_OnShutdown() {}
virtual void CorePlugins_OnUnloaded() {}
};
class EventListener_Plugins : public IEventListener_Plugins
{
public:
EventListener_Plugins();
virtual ~EventListener_Plugins() throw();
};
// --------------------------------------------------------------------------------------
// IEventListener_AppStatus
// --------------------------------------------------------------------------------------
class IEventListener_AppStatus : public IEventDispatcher<AppEventInfo>
{
public:
typedef AppEventInfo EvtParams;
public:
virtual ~IEventListener_AppStatus() throw() {}
virtual void DispatchEvent( const AppEventInfo& evtinfo );
protected:
virtual void AppStatusEvent_OnSettingsLoadSave( const AppSettingsEventInfo& evtinfo ) {}
virtual void AppStatusEvent_OnSettingsApplied() {}
virtual void AppStatusEvent_OnExit() {}
};
class EventListener_AppStatus : public IEventListener_AppStatus
{
public:
EventListener_AppStatus();
virtual ~EventListener_AppStatus() throw();
};
// --------------------------------------------------------------------------------------
// EventListenerHelpers (CoreThread / Plugins / AppStatus)
// --------------------------------------------------------------------------------------
// Welcome to the awkward world of C++ multi-inheritence. wxWidgets' Connect() system is
// incompatible because of limitations in C++ class member function pointers, so we need
// this second layer class to act as a bridge between the event system and the class's
// handler implementations.
//
template< typename TypeToDispatchTo >
class EventListenerHelper_CoreThread : public EventListener_CoreThread
{
public:
TypeToDispatchTo& Owner;
public:
EventListenerHelper_CoreThread( TypeToDispatchTo& dispatchTo )
: Owner( dispatchTo ) { }
EventListenerHelper_CoreThread( TypeToDispatchTo* dispatchTo )
: Owner( *dispatchTo )
{
pxAssume(dispatchTo != NULL);
}
virtual ~EventListenerHelper_CoreThread() throw() {}
protected:
void OnCoreThread_Indeterminate() { Owner.OnCoreThread_Indeterminate(); }
void CoreThread_OnStarted() { Owner.OnCoreThread_Started(); }
void CoreThread_OnResumed() { Owner.OnCoreThread_Resumed(); }
void CoreThread_OnSuspended() { Owner.OnCoreThread_Suspended(); }
void CoreThread_OnReset() { Owner.OnCoreThread_Reset(); }
void CoreThread_OnStopped() { Owner.OnCoreThread_Stopped(); }
};
template< typename TypeToDispatchTo >
class EventListenerHelper_Plugins : public EventListener_Plugins
{
public:
TypeToDispatchTo& Owner;
public:
EventListenerHelper_Plugins( TypeToDispatchTo& dispatchTo )
: Owner( dispatchTo ) { }
EventListenerHelper_Plugins( TypeToDispatchTo* dispatchTo )
: Owner( *dispatchTo )
{
pxAssume(dispatchTo != NULL);
}
virtual ~EventListenerHelper_Plugins() throw() {}
protected:
void CorePlugins_OnLoaded() { Owner.OnCorePlugins_Loaded(); }
void CorePlugins_OnInit() { Owner.OnCorePlugins_Init(); }
void CorePlugins_OnOpening() { Owner.OnCorePlugins_Opening(); }
void CorePlugins_OnOpened() { Owner.OnCorePlugins_Opened(); }
void CorePlugins_OnClosing() { Owner.OnCorePlugins_Closing(); }
void CorePlugins_OnClosed() { Owner.OnCorePlugins_Closed(); }
void CorePlugins_OnShutdown() { Owner.OnCorePlugins_Shutdown(); }
void CorePlugins_OnUnloaded() { Owner.OnCorePlugins_Unloaded(); }
};
template< typename TypeToDispatchTo >
class EventListenerHelper_AppStatus : public EventListener_AppStatus
{
public:
TypeToDispatchTo& Owner;
public:
EventListenerHelper_AppStatus( TypeToDispatchTo& dispatchTo )
: Owner( dispatchTo ) { }
EventListenerHelper_AppStatus( TypeToDispatchTo* dispatchTo )
: Owner( *dispatchTo )
{
pxAssume(dispatchTo != NULL);
}
virtual ~EventListenerHelper_AppStatus() throw() {}
protected:
virtual void AppStatusEvent_OnSettingsLoadSave( const AppSettingsEventInfo& evtinfo ) { Owner.AppStatusEvent_OnSettingsLoadSave( evtinfo ); }
virtual void AppStatusEvent_OnSettingsApplied() { Owner.AppStatusEvent_OnSettingsApplied(); }
virtual void AppStatusEvent_OnExit() { Owner.AppStatusEvent_OnExit(); }
};

View File

@ -1,104 +1,104 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "App.h"
#include "IniInterface.h"
#include "Utilities/EventSource.inl"
template class EventSource< IEventListener_CoreThread >;
template class EventSource< IEventListener_Plugins >;
template class EventSource< IEventListener_AppStatus >;
AppSettingsEventInfo::AppSettingsEventInfo( IniInterface& ini )
: AppEventInfo( ini.IsSaving() ? AppStatus_SettingsSaved : AppStatus_SettingsLoaded )
, m_ini( ini )
{
}
EventListener_CoreThread::EventListener_CoreThread()
{
wxGetApp().AddListener( this );
}
EventListener_CoreThread::~EventListener_CoreThread() throw()
{
wxGetApp().RemoveListener( this );
}
void IEventListener_CoreThread::DispatchEvent( const CoreThreadStatus& status )
{
switch( status )
{
case CoreThread_Started: CoreThread_OnStarted(); break;
case CoreThread_Resumed: CoreThread_OnResumed(); break;
case CoreThread_Suspended: CoreThread_OnSuspended(); break;
case CoreThread_Reset: CoreThread_OnReset(); break;
case CoreThread_Stopped: CoreThread_OnStopped(); break;
jNO_DEFAULT;
}
}
EventListener_Plugins::EventListener_Plugins()
{
wxGetApp().AddListener( this );
}
EventListener_Plugins::~EventListener_Plugins() throw()
{
wxGetApp().RemoveListener( this );
}
void IEventListener_Plugins::DispatchEvent( const PluginEventType& pevt )
{
switch( pevt )
{
case CorePlugins_Loaded: CorePlugins_OnLoaded(); break;
case CorePlugins_Init: CorePlugins_OnInit(); break;
case CorePlugins_Opening: CorePlugins_OnOpening(); break;
case CorePlugins_Opened: CorePlugins_OnOpened(); break;
case CorePlugins_Closing: CorePlugins_OnClosing(); break;
case CorePlugins_Closed: CorePlugins_OnClosed(); break;
case CorePlugins_Shutdown: CorePlugins_OnShutdown(); break;
case CorePlugins_Unloaded: CorePlugins_OnUnloaded(); break;
jNO_DEFAULT;
}
}
EventListener_AppStatus::EventListener_AppStatus()
{
wxGetApp().AddListener( this );
}
EventListener_AppStatus::~EventListener_AppStatus() throw()
{
wxGetApp().RemoveListener( this );
}
void IEventListener_AppStatus::DispatchEvent( const AppEventInfo& evtinfo )
{
switch( evtinfo.evt_type )
{
case AppStatus_SettingsLoaded:
case AppStatus_SettingsSaved:
AppStatusEvent_OnSettingsLoadSave( (const AppSettingsEventInfo&)evtinfo );
break;
case AppStatus_SettingsApplied: AppStatusEvent_OnSettingsApplied(); break;
case AppStatus_Exiting: AppStatusEvent_OnExit(); break;
}
}
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "App.h"
#include "IniInterface.h"
#include "Utilities/EventSource.inl"
template class EventSource< IEventListener_CoreThread >;
template class EventSource< IEventListener_Plugins >;
template class EventSource< IEventListener_AppStatus >;
AppSettingsEventInfo::AppSettingsEventInfo( IniInterface& ini )
: AppEventInfo( ini.IsSaving() ? AppStatus_SettingsSaved : AppStatus_SettingsLoaded )
, m_ini( ini )
{
}
EventListener_CoreThread::EventListener_CoreThread()
{
wxGetApp().AddListener( this );
}
EventListener_CoreThread::~EventListener_CoreThread() throw()
{
wxGetApp().RemoveListener( this );
}
void IEventListener_CoreThread::DispatchEvent( const CoreThreadStatus& status )
{
switch( status )
{
case CoreThread_Started: CoreThread_OnStarted(); break;
case CoreThread_Resumed: CoreThread_OnResumed(); break;
case CoreThread_Suspended: CoreThread_OnSuspended(); break;
case CoreThread_Reset: CoreThread_OnReset(); break;
case CoreThread_Stopped: CoreThread_OnStopped(); break;
jNO_DEFAULT;
}
}
EventListener_Plugins::EventListener_Plugins()
{
wxGetApp().AddListener( this );
}
EventListener_Plugins::~EventListener_Plugins() throw()
{
wxGetApp().RemoveListener( this );
}
void IEventListener_Plugins::DispatchEvent( const PluginEventType& pevt )
{
switch( pevt )
{
case CorePlugins_Loaded: CorePlugins_OnLoaded(); break;
case CorePlugins_Init: CorePlugins_OnInit(); break;
case CorePlugins_Opening: CorePlugins_OnOpening(); break;
case CorePlugins_Opened: CorePlugins_OnOpened(); break;
case CorePlugins_Closing: CorePlugins_OnClosing(); break;
case CorePlugins_Closed: CorePlugins_OnClosed(); break;
case CorePlugins_Shutdown: CorePlugins_OnShutdown(); break;
case CorePlugins_Unloaded: CorePlugins_OnUnloaded(); break;
jNO_DEFAULT;
}
}
EventListener_AppStatus::EventListener_AppStatus()
{
wxGetApp().AddListener( this );
}
EventListener_AppStatus::~EventListener_AppStatus() throw()
{
wxGetApp().RemoveListener( this );
}
void IEventListener_AppStatus::DispatchEvent( const AppEventInfo& evtinfo )
{
switch( evtinfo.evt_type )
{
case AppStatus_SettingsLoaded:
case AppStatus_SettingsSaved:
AppStatusEvent_OnSettingsLoadSave( (const AppSettingsEventInfo&)evtinfo );
break;
case AppStatus_SettingsApplied: AppStatusEvent_OnSettingsApplied(); break;
case AppStatus_Exiting: AppStatusEvent_OnExit(); break;
}
}

View File

@ -1,50 +1,50 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// AppForwardDefs.h
//
// Purpose:
// This header file is meant to be a dependency-free include that provides a relatively
// full compliment of forward defines for PCSX2/App and wxwidgets types. When
// forward defined in this way, these types can be used by method and class definitions
// as either pointers or handles without running into complicated header file
// inter-dependence.
//
class MainEmuFrame;
class GSFrame;
class ConsoleLogFrame;
class PipeRedirectionBase;
class AppCoreThread;
class pxInvokeAppMethodEvent;
class IniInterface;
// wxWidgets forward declarations
class wxConfigBase;
class wxFileConfig;
class wxDirPickerCtrl;
class wxFilePickerCtrl;
class wxFileDirPickerEvent;
class wxListBox;
class wxListCtrl;
class wxListView;
class wxListbook;
class wxSpinCtrl;
class wxBookCtrlBase;
class wxListEvent;
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// AppForwardDefs.h
//
// Purpose:
// This header file is meant to be a dependency-free include that provides a relatively
// full compliment of forward defines for PCSX2/App and wxwidgets types. When
// forward defined in this way, these types can be used by method and class definitions
// as either pointers or handles without running into complicated header file
// inter-dependence.
//
class MainEmuFrame;
class GSFrame;
class ConsoleLogFrame;
class PipeRedirectionBase;
class AppCoreThread;
class pxInvokeAppMethodEvent;
class IniInterface;
// wxWidgets forward declarations
class wxConfigBase;
class wxFileConfig;
class wxDirPickerCtrl;
class wxFilePickerCtrl;
class wxFileDirPickerEvent;
class wxListBox;
class wxListCtrl;
class wxListView;
class wxListbook;
class wxSpinCtrl;
class wxBookCtrlBase;
class wxListEvent;

View File

@ -1,52 +1,52 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "App.h"
#include "Dialogs/ModalPopups.h"
using namespace pxSizerFlags;
using namespace Threading;
Dialogs::StuckThreadDialog::StuckThreadDialog( wxWindow* parent, StuckThreadActionType action, PersistentThread& stuck_thread )
: wxDialogWithHelpers( parent, _("PCSX2 Thread is not responding"), wxVERTICAL )
{
//m_idealWidth = 720;
stuck_thread.AddListener( this );
*this += Heading( wxsFormat(
pxE( ".Dialog:StuckThread:Heading",
L"The thread '%s' is not responding. It could be deadlocked, or it might "
L"just be running *really* slowly."
),
stuck_thread.GetName().data()
) );
*this += Heading(
L"\nDo you want to stop the program [Yes/No]?"
L"\nOr press [Ignore] to suppress further assertions."
);
*this += new ModalButtonPanel( this, MsgButtons().Cancel().Custom(L"Wait") ) | StdCenter();
if( wxWindow* idyes = FindWindowById( wxID_YES ) )
idyes->SetFocus();
}
void Dialogs::StuckThreadDialog::OnThreadCleanup()
{
}
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "App.h"
#include "Dialogs/ModalPopups.h"
using namespace pxSizerFlags;
using namespace Threading;
Dialogs::StuckThreadDialog::StuckThreadDialog( wxWindow* parent, StuckThreadActionType action, PersistentThread& stuck_thread )
: wxDialogWithHelpers( parent, _("PCSX2 Thread is not responding"), wxVERTICAL )
{
//m_idealWidth = 720;
stuck_thread.AddListener( this );
*this += Heading( wxsFormat(
pxE( ".Dialog:StuckThread:Heading",
L"The thread '%s' is not responding. It could be deadlocked, or it might "
L"just be running *really* slowly."
),
stuck_thread.GetName().data()
) );
*this += Heading(
L"\nDo you want to stop the program [Yes/No]?"
L"\nOr press [Ignore] to suppress further assertions."
);
*this += new ModalButtonPanel( this, MsgButtons().Cancel().Custom(L"Wait") ) | StdCenter();
if( wxWindow* idyes = FindWindowById( wxID_YES ) )
idyes->SetFocus();
}
void Dialogs::StuckThreadDialog::OnThreadCleanup()
{
}

View File

@ -1,206 +1,206 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "App.h"
#include "ConfigurationPanels.h"
#include "Dialogs/ConfigurationDialog.h"
#include <wx/bookctrl.h>
using namespace Dialogs;
// -----------------------------------------------------------------------
// This method should be called by the parent dalog box of a configuration
// on dialog destruction. It asserts if the ApplyList hasn't been cleaned up
// and then cleans it up forcefully.
//
void ApplyStateStruct::DoCleanup() throw()
{
pxAssertMsg( PanelList.size() != 0, L"PanelList list hasn't been cleaned up." );
PanelList.clear();
ParentBook = NULL;
}
void ApplyStateStruct::StartBook( wxBookCtrlBase* book )
{
pxAssertDev( ParentBook == NULL, "An ApplicableConfig session is already in progress." );
ParentBook = book;
}
void ApplyStateStruct::StartWizard()
{
pxAssertDev( ParentBook == NULL, "An ApplicableConfig session is already in progress." );
}
// -----------------------------------------------------------------------
//
// Parameters:
// pageid - identifier of the page to apply settings for. All other pages will be
// skipped. If pageid is negative (-1) then all pages are applied.
//
// Returns false if one of the panels fails input validation (in which case dialogs
// should not be closed, etc).
//
bool ApplyStateStruct::ApplyPage( int pageid )
{
bool retval = true;
// Save these settings so we can restore them if the Apply fails.
DocsModeType oldDocsMode = DocsFolderMode;
wxDirName oldSettingsFolder = SettingsFolder;
bool oldUseDefSet = UseDefaultSettingsFolder;
AppConfig confcopy( *g_Conf );
try
{
PanelApplyList_t::iterator yay = PanelList.begin();
while( yay != PanelList.end() )
{
//DbgCon.Status( L"Writing settings for: " + (*yay)->GetLabel() );
if( (pageid < 0) || (*yay)->IsOnPage( pageid ) )
(*yay)->Apply();
yay++;
}
// If an exception is thrown above, this code below won't get run.
// (conveniently skipping any option application! :D)
// Note: apply first, then save -- in case the apply fails.
AppApplySettings( &confcopy );
}
catch( Exception::CannotApplySettings& ex )
{
DocsFolderMode = oldDocsMode;
SettingsFolder = oldSettingsFolder;
UseDefaultSettingsFolder = oldUseDefSet;
*g_Conf = confcopy;
if( ex.IsVerbose )
{
wxMessageBox( ex.FormatDisplayMessage(), _("Cannot apply settings...") );
if( ex.GetPanel() != NULL )
ex.GetPanel()->SetFocusToMe();
}
retval = false;
}
catch( ... )
{
DocsFolderMode = oldDocsMode;
SettingsFolder = oldSettingsFolder;
UseDefaultSettingsFolder = oldUseDefSet;
*g_Conf = confcopy;
throw;
}
return retval;
}
// Returns false if one of the panels fails input validation (in which case dialogs
// should not be closed, etc).
bool ApplyStateStruct::ApplyAll()
{
return ApplyPage( -1 );
}
// --------------------------------------------------------------------------------------
// BaseApplicableConfigPanel Implementations
// --------------------------------------------------------------------------------------
IApplyState* BaseApplicableConfigPanel::FindApplyStateManager() const
{
wxWindow* millrun = this->GetParent();
while( millrun != NULL )
{
if( BaseApplicableDialog* dialog = wxDynamicCast( millrun, BaseApplicableDialog ) )
return (IApplyState*)dialog;
if( ApplicableWizardPage* wizpage = wxDynamicCast( millrun, ApplicableWizardPage ) )
return (IApplyState*)wizpage;
millrun = millrun->GetParent();
}
return NULL;
}
BaseApplicableConfigPanel::~BaseApplicableConfigPanel() throw()
{
if( IApplyState* iapp = FindApplyStateManager() )
iapp->GetApplyState().PanelList.remove( this );
}
BaseApplicableConfigPanel::BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient )
: wxPanelWithHelpers( parent, orient )
, m_AppStatusHelper( this )
{
Init();
}
BaseApplicableConfigPanel::BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient, const wxString& staticLabel )
: wxPanelWithHelpers( parent, orient, staticLabel )
, m_AppStatusHelper( this )
{
Init();
}
void BaseApplicableConfigPanel::SetFocusToMe()
{
if( (m_OwnerBook == NULL) || (m_OwnerPage == wxID_NONE) ) return;
m_OwnerBook->SetSelection( m_OwnerPage );
}
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE( pxEvt_ApplySettings, -1 )
END_DECLARE_EVENT_TYPES()
DEFINE_EVENT_TYPE( pxEvt_ApplySettings )
void BaseApplicableConfigPanel::Init()
{
// We need to bind to an event that occurs *after* all window and child
// window mess has been created. Unfortunately the WindowCreate event handler
// is immediate, and depends on the platform for how it "works", and thus
// useless. Solution: Create our own! :)
//Connect( wxEVT_CREATE, wxWindowCreateEventHandler (BaseApplicableConfigPanel::OnCreateWindow) );
Connect( pxEvt_ApplySettings, wxCommandEventHandler (BaseApplicableConfigPanel::OnSettingsApplied) );
if( IApplyState* iapp = FindApplyStateManager() )
{
ApplyStateStruct& applyState( iapp->GetApplyState() );
m_OwnerPage = applyState.CurOwnerPage;
m_OwnerBook = applyState.ParentBook;
applyState.PanelList.push_back( this );
}
wxCommandEvent applyEvent( pxEvt_ApplySettings );
applyEvent.SetId( GetId() );
AddPendingEvent( applyEvent );
}
//void BaseApplicableConfigPanel::OnCreateWindow( wxWindowCreateEvent& evt )
void BaseApplicableConfigPanel::OnSettingsApplied( wxCommandEvent& evt )
{
evt.Skip();
if( evt.GetId() == GetId() ) AppStatusEvent_OnSettingsApplied();
}
void BaseApplicableConfigPanel::AppStatusEvent_OnSettingsApplied() {}
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "App.h"
#include "ConfigurationPanels.h"
#include "Dialogs/ConfigurationDialog.h"
#include <wx/bookctrl.h>
using namespace Dialogs;
// -----------------------------------------------------------------------
// This method should be called by the parent dalog box of a configuration
// on dialog destruction. It asserts if the ApplyList hasn't been cleaned up
// and then cleans it up forcefully.
//
void ApplyStateStruct::DoCleanup() throw()
{
pxAssertMsg( PanelList.size() != 0, L"PanelList list hasn't been cleaned up." );
PanelList.clear();
ParentBook = NULL;
}
void ApplyStateStruct::StartBook( wxBookCtrlBase* book )
{
pxAssertDev( ParentBook == NULL, "An ApplicableConfig session is already in progress." );
ParentBook = book;
}
void ApplyStateStruct::StartWizard()
{
pxAssertDev( ParentBook == NULL, "An ApplicableConfig session is already in progress." );
}
// -----------------------------------------------------------------------
//
// Parameters:
// pageid - identifier of the page to apply settings for. All other pages will be
// skipped. If pageid is negative (-1) then all pages are applied.
//
// Returns false if one of the panels fails input validation (in which case dialogs
// should not be closed, etc).
//
bool ApplyStateStruct::ApplyPage( int pageid )
{
bool retval = true;
// Save these settings so we can restore them if the Apply fails.
DocsModeType oldDocsMode = DocsFolderMode;
wxDirName oldSettingsFolder = SettingsFolder;
bool oldUseDefSet = UseDefaultSettingsFolder;
AppConfig confcopy( *g_Conf );
try
{
PanelApplyList_t::iterator yay = PanelList.begin();
while( yay != PanelList.end() )
{
//DbgCon.Status( L"Writing settings for: " + (*yay)->GetLabel() );
if( (pageid < 0) || (*yay)->IsOnPage( pageid ) )
(*yay)->Apply();
yay++;
}
// If an exception is thrown above, this code below won't get run.
// (conveniently skipping any option application! :D)
// Note: apply first, then save -- in case the apply fails.
AppApplySettings( &confcopy );
}
catch( Exception::CannotApplySettings& ex )
{
DocsFolderMode = oldDocsMode;
SettingsFolder = oldSettingsFolder;
UseDefaultSettingsFolder = oldUseDefSet;
*g_Conf = confcopy;
if( ex.IsVerbose )
{
wxMessageBox( ex.FormatDisplayMessage(), _("Cannot apply settings...") );
if( ex.GetPanel() != NULL )
ex.GetPanel()->SetFocusToMe();
}
retval = false;
}
catch( ... )
{
DocsFolderMode = oldDocsMode;
SettingsFolder = oldSettingsFolder;
UseDefaultSettingsFolder = oldUseDefSet;
*g_Conf = confcopy;
throw;
}
return retval;
}
// Returns false if one of the panels fails input validation (in which case dialogs
// should not be closed, etc).
bool ApplyStateStruct::ApplyAll()
{
return ApplyPage( -1 );
}
// --------------------------------------------------------------------------------------
// BaseApplicableConfigPanel Implementations
// --------------------------------------------------------------------------------------
IApplyState* BaseApplicableConfigPanel::FindApplyStateManager() const
{
wxWindow* millrun = this->GetParent();
while( millrun != NULL )
{
if( BaseApplicableDialog* dialog = wxDynamicCast( millrun, BaseApplicableDialog ) )
return (IApplyState*)dialog;
if( ApplicableWizardPage* wizpage = wxDynamicCast( millrun, ApplicableWizardPage ) )
return (IApplyState*)wizpage;
millrun = millrun->GetParent();
}
return NULL;
}
BaseApplicableConfigPanel::~BaseApplicableConfigPanel() throw()
{
if( IApplyState* iapp = FindApplyStateManager() )
iapp->GetApplyState().PanelList.remove( this );
}
BaseApplicableConfigPanel::BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient )
: wxPanelWithHelpers( parent, orient )
, m_AppStatusHelper( this )
{
Init();
}
BaseApplicableConfigPanel::BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient, const wxString& staticLabel )
: wxPanelWithHelpers( parent, orient, staticLabel )
, m_AppStatusHelper( this )
{
Init();
}
void BaseApplicableConfigPanel::SetFocusToMe()
{
if( (m_OwnerBook == NULL) || (m_OwnerPage == wxID_NONE) ) return;
m_OwnerBook->SetSelection( m_OwnerPage );
}
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE( pxEvt_ApplySettings, -1 )
END_DECLARE_EVENT_TYPES()
DEFINE_EVENT_TYPE( pxEvt_ApplySettings )
void BaseApplicableConfigPanel::Init()
{
// We need to bind to an event that occurs *after* all window and child
// window mess has been created. Unfortunately the WindowCreate event handler
// is immediate, and depends on the platform for how it "works", and thus
// useless. Solution: Create our own! :)
//Connect( wxEVT_CREATE, wxWindowCreateEventHandler (BaseApplicableConfigPanel::OnCreateWindow) );
Connect( pxEvt_ApplySettings, wxCommandEventHandler (BaseApplicableConfigPanel::OnSettingsApplied) );
if( IApplyState* iapp = FindApplyStateManager() )
{
ApplyStateStruct& applyState( iapp->GetApplyState() );
m_OwnerPage = applyState.CurOwnerPage;
m_OwnerBook = applyState.ParentBook;
applyState.PanelList.push_back( this );
}
wxCommandEvent applyEvent( pxEvt_ApplySettings );
applyEvent.SetId( GetId() );
AddPendingEvent( applyEvent );
}
//void BaseApplicableConfigPanel::OnCreateWindow( wxWindowCreateEvent& evt )
void BaseApplicableConfigPanel::OnSettingsApplied( wxCommandEvent& evt )
{
evt.Skip();
if( evt.GetId() == GetId() ) AppStatusEvent_OnSettingsApplied();
}
void BaseApplicableConfigPanel::AppStatusEvent_OnSettingsApplied() {}

View File

@ -1,195 +1,195 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "ConfigurationPanels.h"
#include "MemoryCardListView.h"
#include <wx/filepicker.h>
#include <wx/ffile.h>
#include <wx/dir.h>
using namespace pxSizerFlags;
using namespace Panels;
static bool IsMcdFormatted( wxFFile& fhand )
{
static const char formatted_string[] = "Sony PS2 Memory Card Format";
static const int fmtstrlen = sizeof( formatted_string )-1;
char dest[fmtstrlen];
fhand.Read( dest, fmtstrlen );
return memcmp( formatted_string, dest, fmtstrlen ) == 0;
}
static bool EnumerateMemoryCard( McdListItem& dest, const wxString& filename )
{
Console.WriteLn( filename.c_str() );
wxFFile mcdFile( filename );
if( !mcdFile.IsOpened() ) return false; // wx should log the error for us.
if( mcdFile.Length() < (1024*528) )
{
Console.Warning( "... MemoryCard appears to be truncated. Ignoring." );
return false;
}
dest.Filename = filename;
dest.SizeInMB = (uint)(mcdFile.Length() / (1024 * 528 * 2));
dest.IsFormatted = IsMcdFormatted( mcdFile );
wxFileName(filename).GetTimes( NULL, &dest.DateModified, &dest.DateCreated );
return true;
}
static int EnumerateMemoryCards( McdList& dest, const wxArrayString& files )
{
int pushed = 0;
Console.WriteLn( Color_StrongBlue, "Enumerating MemoryCards..." );
for( size_t i=0; i<files.GetCount(); ++i )
{
ConsoleIndentScope con_indent;
McdListItem mcdItem;
if( EnumerateMemoryCard(mcdItem, files[i]) )
{
dest.push_back( mcdItem );
++pushed;
}
}
if( pushed > 0 )
Console.WriteLn( Color_StrongBlue, "MemoryCard Enumeration Complete." );
else
Console.WriteLn( Color_StrongBlue, "No valid MemoryCards found." );
return pushed;
}
// =====================================================================================================
// MemoryCardListPanel
// =====================================================================================================
MemoryCardListPanel::MemoryCardListPanel( wxWindow* parent )
: BaseSelectorPanel( parent )
{
m_FolderPicker = new DirPickerPanel( this, FolderId_MemoryCards,
//_("MemoryCard Search Path:"), // static box label
_("Select folder with PS2 MemoryCards") // dir picker popup label
);
m_listview = new MemoryCardListView(this);
wxButton* button_Create = new wxButton(this, wxID_ANY, _("Create new card..."));
//Connect( m_list_AllKnownCards->GetId(), wxEVT_COMMAND_LEFT_CLICK, MemoryCardsPanel::OnListDrag);
// ------------------------------------
// Sizer / Layout Section
// ------------------------------------
wxBoxSizer& s_buttons (*new wxBoxSizer( wxHORIZONTAL ));
wxBoxSizer& s_leftside (*new wxBoxSizer( wxHORIZONTAL ));
wxBoxSizer& s_rightside (*new wxBoxSizer( wxHORIZONTAL ));
s_leftside += button_Create | StdSpace();
s_buttons += s_leftside | pxAlignLeft;
s_buttons += pxStretchSpacer();
s_buttons += s_rightside | pxAlignRight;
*this += m_FolderPicker | pxExpand;
*this += m_listview | pxExpand;
*this += s_buttons | pxExpand;
m_listview->SetMinSize( wxSize( wxDefaultCoord, 120 ) );
AppStatusEvent_OnSettingsApplied();
Disable();
}
void MemoryCardListPanel::Apply()
{
}
void MemoryCardListPanel::AppStatusEvent_OnSettingsApplied()
{
}
bool Panels::MemoryCardListPanel::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
{
if( filenames.GetCount() == 1 && wxFileName(filenames[0]).IsDir() )
{
m_FolderPicker->SetPath( filenames[0] );
return true;
}
return false;
}
bool MemoryCardListPanel::ValidateEnumerationStatus()
{
bool validated = true;
// Impl Note: ScopedPtr used so that resources get cleaned up if an exception
// occurs during file enumeration.
ScopedPtr<McdList> mcdlist( new McdList() );
if( m_FolderPicker->GetPath().Exists() )
{
wxArrayString files;
wxDir::GetAllFiles( m_FolderPicker->GetPath().ToString(), &files, L"*.ps2", wxDIR_FILES );
EnumerateMemoryCards( *mcdlist, files );
}
if( !m_KnownCards || (*mcdlist != *m_KnownCards) )
validated = false;
m_listview->AssignCardsList( NULL );
m_KnownCards.SwapPtr( mcdlist );
return validated;
}
void MemoryCardListPanel::DoRefresh()
{
if( !m_KnownCards ) return;
//m_listview->ClearAll();
//m_listview->CreateColumns();
for( size_t i=0; i<m_KnownCards->size(); ++i )
{
McdListItem& mcditem( (*m_KnownCards)[i] );
for( int port=0; port<2; ++port )
for( int slot=0; slot<4; ++slot )
{
wxFileName right( g_Conf->FullpathToMcd(port, slot) );
right.MakeAbsolute();
wxFileName left( mcditem.Filename );
left.MakeAbsolute();
if( left == right )
{
mcditem.Port = port;
mcditem.Slot = slot;
}
}
}
m_listview->AssignCardsList( m_KnownCards );
}
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "ConfigurationPanels.h"
#include "MemoryCardListView.h"
#include <wx/filepicker.h>
#include <wx/ffile.h>
#include <wx/dir.h>
using namespace pxSizerFlags;
using namespace Panels;
static bool IsMcdFormatted( wxFFile& fhand )
{
static const char formatted_string[] = "Sony PS2 Memory Card Format";
static const int fmtstrlen = sizeof( formatted_string )-1;
char dest[fmtstrlen];
fhand.Read( dest, fmtstrlen );
return memcmp( formatted_string, dest, fmtstrlen ) == 0;
}
static bool EnumerateMemoryCard( McdListItem& dest, const wxString& filename )
{
Console.WriteLn( filename.c_str() );
wxFFile mcdFile( filename );
if( !mcdFile.IsOpened() ) return false; // wx should log the error for us.
if( mcdFile.Length() < (1024*528) )
{
Console.Warning( "... MemoryCard appears to be truncated. Ignoring." );
return false;
}
dest.Filename = filename;
dest.SizeInMB = (uint)(mcdFile.Length() / (1024 * 528 * 2));
dest.IsFormatted = IsMcdFormatted( mcdFile );
wxFileName(filename).GetTimes( NULL, &dest.DateModified, &dest.DateCreated );
return true;
}
static int EnumerateMemoryCards( McdList& dest, const wxArrayString& files )
{
int pushed = 0;
Console.WriteLn( Color_StrongBlue, "Enumerating MemoryCards..." );
for( size_t i=0; i<files.GetCount(); ++i )
{
ConsoleIndentScope con_indent;
McdListItem mcdItem;
if( EnumerateMemoryCard(mcdItem, files[i]) )
{
dest.push_back( mcdItem );
++pushed;
}
}
if( pushed > 0 )
Console.WriteLn( Color_StrongBlue, "MemoryCard Enumeration Complete." );
else
Console.WriteLn( Color_StrongBlue, "No valid MemoryCards found." );
return pushed;
}
// =====================================================================================================
// MemoryCardListPanel
// =====================================================================================================
MemoryCardListPanel::MemoryCardListPanel( wxWindow* parent )
: BaseSelectorPanel( parent )
{
m_FolderPicker = new DirPickerPanel( this, FolderId_MemoryCards,
//_("MemoryCard Search Path:"), // static box label
_("Select folder with PS2 MemoryCards") // dir picker popup label
);
m_listview = new MemoryCardListView(this);
wxButton* button_Create = new wxButton(this, wxID_ANY, _("Create new card..."));
//Connect( m_list_AllKnownCards->GetId(), wxEVT_COMMAND_LEFT_CLICK, MemoryCardsPanel::OnListDrag);
// ------------------------------------
// Sizer / Layout Section
// ------------------------------------
wxBoxSizer& s_buttons (*new wxBoxSizer( wxHORIZONTAL ));
wxBoxSizer& s_leftside (*new wxBoxSizer( wxHORIZONTAL ));
wxBoxSizer& s_rightside (*new wxBoxSizer( wxHORIZONTAL ));
s_leftside += button_Create | StdSpace();
s_buttons += s_leftside | pxAlignLeft;
s_buttons += pxStretchSpacer();
s_buttons += s_rightside | pxAlignRight;
*this += m_FolderPicker | pxExpand;
*this += m_listview | pxExpand;
*this += s_buttons | pxExpand;
m_listview->SetMinSize( wxSize( wxDefaultCoord, 120 ) );
AppStatusEvent_OnSettingsApplied();
Disable();
}
void MemoryCardListPanel::Apply()
{
}
void MemoryCardListPanel::AppStatusEvent_OnSettingsApplied()
{
}
bool Panels::MemoryCardListPanel::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
{
if( filenames.GetCount() == 1 && wxFileName(filenames[0]).IsDir() )
{
m_FolderPicker->SetPath( filenames[0] );
return true;
}
return false;
}
bool MemoryCardListPanel::ValidateEnumerationStatus()
{
bool validated = true;
// Impl Note: ScopedPtr used so that resources get cleaned up if an exception
// occurs during file enumeration.
ScopedPtr<McdList> mcdlist( new McdList() );
if( m_FolderPicker->GetPath().Exists() )
{
wxArrayString files;
wxDir::GetAllFiles( m_FolderPicker->GetPath().ToString(), &files, L"*.ps2", wxDIR_FILES );
EnumerateMemoryCards( *mcdlist, files );
}
if( !m_KnownCards || (*mcdlist != *m_KnownCards) )
validated = false;
m_listview->AssignCardsList( NULL );
m_KnownCards.SwapPtr( mcdlist );
return validated;
}
void MemoryCardListPanel::DoRefresh()
{
if( !m_KnownCards ) return;
//m_listview->ClearAll();
//m_listview->CreateColumns();
for( size_t i=0; i<m_KnownCards->size(); ++i )
{
McdListItem& mcditem( (*m_KnownCards)[i] );
for( int port=0; port<2; ++port )
for( int slot=0; slot<4; ++slot )
{
wxFileName right( g_Conf->FullpathToMcd(port, slot) );
right.MakeAbsolute();
wxFileName left( mcditem.Filename );
left.MakeAbsolute();
if( left == right )
{
mcditem.Port = port;
mcditem.Slot = slot;
}
}
}
m_listview->AssignCardsList( m_KnownCards );
}

View File

@ -1,212 +1,212 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "IopCommon.h"
#include "Utilities/Console.h"
#ifndef __LINUX__
#include <io.h>
//#include "dirent.h"
#else
#include <dirent.h>
#endif
#pragma optimize("", off)
#define PS2E_FIO_OPEN_CMD 0xcc2e0101
#define PS2E_FIO_CLOSE_CMD 0xcc2e0102
#define PS2E_FIO_READ_CMD 0xcc2e0103
#define PS2E_FIO_WRITE_CMD 0xcc2e0104
#define PS2E_FIO_LSEEK_CMD 0xcc2e0105
#define PS2E_FIO_OPENDIR_CMD 0xcc2e0106
#define PS2E_FIO_CLOSEDIR_CMD 0xcc2e0107
#define PS2E_FIO_READDIR_CMD 0xcc2e0108
#define PS2E_FIO_REMOVE_CMD 0xcc2e0109
#define PS2E_FIO_MKDIR_CMD 0xcc2e010a
#define PS2E_FIO_RMDIR_CMD 0xcc2e010b
#define PS2E_FIO_PRINTF_CMD 0xcc2e0201
#define PS2E_FIO_MAGIC 'E2SP'
u32 functionId;
u32 paramsAddress;
u32 paramsLength;
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "IopCommon.h"
#include "Utilities/Console.h"
#ifndef __LINUX__
#include <io.h>
//#include "dirent.h"
#else
#include <dirent.h>
#endif
#pragma optimize("", off)
#define PS2E_FIO_OPEN_CMD 0xcc2e0101
#define PS2E_FIO_CLOSE_CMD 0xcc2e0102
#define PS2E_FIO_READ_CMD 0xcc2e0103
#define PS2E_FIO_WRITE_CMD 0xcc2e0104
#define PS2E_FIO_LSEEK_CMD 0xcc2e0105
#define PS2E_FIO_OPENDIR_CMD 0xcc2e0106
#define PS2E_FIO_CLOSEDIR_CMD 0xcc2e0107
#define PS2E_FIO_READDIR_CMD 0xcc2e0108
#define PS2E_FIO_REMOVE_CMD 0xcc2e0109
#define PS2E_FIO_MKDIR_CMD 0xcc2e010a
#define PS2E_FIO_RMDIR_CMD 0xcc2e010b
#define PS2E_FIO_PRINTF_CMD 0xcc2e0201
#define PS2E_FIO_MAGIC 'E2SP'
u32 functionId;
u32 paramsAddress;
u32 paramsLength;
u32 returnValue;
#ifndef O_BINARY
# define O_BINARY 0
#endif
#define IOP_RDONLY 0x0001
#define IOP_WRONLY 0x0002
#define IOP_RDWR 0x0003
#define IOP_NBLOCK 0x0010
#define IOP_APPEND 0x0100
#define IOP_CREAT 0x0200
#define IOP_TRUNC 0x0400
#define IOP_NOWAIT 0x8000
int pcsx2fio_open_file(char *path, int flags)
{
int mode = O_BINARY;
switch(flags&IOP_RDWR)
{
case IOP_RDONLY:
mode |= O_RDONLY;
break;
case IOP_WRONLY:
mode |= O_WRONLY;
break;
case IOP_RDWR:
mode |= O_RDWR;
break;
}
if(flags&IOP_CREAT)
mode |= O_CREAT;
if(flags&IOP_APPEND)
mode |= O_APPEND;
if(flags&IOP_TRUNC)
mode |= O_TRUNC;
return open(path,mode);
}
int pcsx2fio_close_file(int fd)
{
return close(fd);
}
int pcsx2fio_lseek_file(int fd, unsigned int offset, int whence)
{
return lseek(fd,offset,whence);
}
int pcsx2fio_write_file(int fd, char *buf, int length)
{
return write(fd,buf,length);
}
int pcsx2fio_read_file(int fd, char *buf, int length)
{
return read(fd,buf,length);
}
int pcsx2fio_remove(char *name)
{
return unlink(name);
}
int pcsx2fio_mkdir(char *name, int mode)
{
#ifdef __LINUX__
return mkdir(name,mode);
#else
return mkdir(name);
#endif
}
int pcsx2fio_rmdir(char *name)
{
return rmdir(name);
}
int pcsx2fio_open_dir(char *path)
{
return -1;
}
int pcsx2fio_read_dir(int fd, void *buf)
{
return -1;
}
int pcsx2fio_close_dir(int fd)
{
return -1;
}
int pcsx2fio_write_tty(const char* text, int length)
{
wxString s = wxString::FromUTF8(text,length);
return printf("%s",s.ToAscii().data());
}
#define PARAM(offset,type) (*(type*)(buffer+(offset)))
#define PARAMP(offset,type) (type*)iopPhysMem(PARAM(offset,u32))
#define PARAMSTR(offset) ((char*)(buffer+(offset)))
void Pcsx2HostFsExec()
{
u8* buffer = (u8*)iopPhysMem(paramsAddress);
switch(functionId)
{
case PS2E_FIO_OPEN_CMD: returnValue = pcsx2fio_open_file(PARAMSTR(4),PARAM(0,s32)); break;
case PS2E_FIO_CLOSE_CMD: returnValue = pcsx2fio_close_file(PARAM(0,s32)); break;
case PS2E_FIO_READ_CMD: returnValue = pcsx2fio_read_file(PARAM(0,s32),PARAMP(4,char),PARAM(8,s32)); break;
case PS2E_FIO_WRITE_CMD: returnValue = pcsx2fio_write_file(PARAM(0,s32),PARAMP(4,char),PARAM(8,s32)); break;
case PS2E_FIO_LSEEK_CMD: returnValue = pcsx2fio_lseek_file(PARAM(0,s32),PARAM(4,s32),PARAM(8,s32)); break;
case PS2E_FIO_REMOVE_CMD: returnValue = pcsx2fio_remove(PARAMSTR(0)); break;
case PS2E_FIO_OPENDIR_CMD: returnValue = pcsx2fio_open_dir(PARAMSTR(0)); break;
case PS2E_FIO_CLOSEDIR_CMD: returnValue = pcsx2fio_close_dir(PARAM(0,s32)); break;
case PS2E_FIO_READDIR_CMD: returnValue = pcsx2fio_read_dir(PARAM(0,s32),PARAMP(4,void)); break;
case PS2E_FIO_MKDIR_CMD: returnValue = pcsx2fio_mkdir(PARAMSTR(4),PARAM(0,s32)); break;
case PS2E_FIO_RMDIR_CMD: returnValue = pcsx2fio_rmdir(PARAMSTR(0)); break;
case PS2E_FIO_PRINTF_CMD: returnValue = pcsx2fio_write_tty(PARAMSTR(0),paramsLength); break;
}
}
void Pcsx2HostFSwrite32(u32 addr, u32 value)
{
switch(addr&0xF)
{
case 0:
if(value==1)
Pcsx2HostFsExec();
break;
case 4:
paramsLength = value;
break;
case 8:
paramsAddress = value;
break;
case 12:
functionId = value;
break;
}
}
u32 Pcsx2HostFSread32(u32 addr)
{
switch(addr&0xF)
{
case 0:
return PS2E_FIO_MAGIC;
break;
case 4:
break;
case 8:
break;
case 12:
return returnValue;
break;
}
return 0;
}
#define IOP_RDONLY 0x0001
#define IOP_WRONLY 0x0002
#define IOP_RDWR 0x0003
#define IOP_NBLOCK 0x0010
#define IOP_APPEND 0x0100
#define IOP_CREAT 0x0200
#define IOP_TRUNC 0x0400
#define IOP_NOWAIT 0x8000
int pcsx2fio_open_file(char *path, int flags)
{
int mode = O_BINARY;
switch(flags&IOP_RDWR)
{
case IOP_RDONLY:
mode |= O_RDONLY;
break;
case IOP_WRONLY:
mode |= O_WRONLY;
break;
case IOP_RDWR:
mode |= O_RDWR;
break;
}
if(flags&IOP_CREAT)
mode |= O_CREAT;
if(flags&IOP_APPEND)
mode |= O_APPEND;
if(flags&IOP_TRUNC)
mode |= O_TRUNC;
return open(path,mode);
}
int pcsx2fio_close_file(int fd)
{
return close(fd);
}
int pcsx2fio_lseek_file(int fd, unsigned int offset, int whence)
{
return lseek(fd,offset,whence);
}
int pcsx2fio_write_file(int fd, char *buf, int length)
{
return write(fd,buf,length);
}
int pcsx2fio_read_file(int fd, char *buf, int length)
{
return read(fd,buf,length);
}
int pcsx2fio_remove(char *name)
{
return unlink(name);
}
int pcsx2fio_mkdir(char *name, int mode)
{
#ifdef __LINUX__
return mkdir(name,mode);
#else
return mkdir(name);
#endif
}
int pcsx2fio_rmdir(char *name)
{
return rmdir(name);
}
int pcsx2fio_open_dir(char *path)
{
return -1;
}
int pcsx2fio_read_dir(int fd, void *buf)
{
return -1;
}
int pcsx2fio_close_dir(int fd)
{
return -1;
}
int pcsx2fio_write_tty(const char* text, int length)
{
wxString s = wxString::FromUTF8(text,length);
return printf("%s",s.ToAscii().data());
}
#define PARAM(offset,type) (*(type*)(buffer+(offset)))
#define PARAMP(offset,type) (type*)iopPhysMem(PARAM(offset,u32))
#define PARAMSTR(offset) ((char*)(buffer+(offset)))
void Pcsx2HostFsExec()
{
u8* buffer = (u8*)iopPhysMem(paramsAddress);
switch(functionId)
{
case PS2E_FIO_OPEN_CMD: returnValue = pcsx2fio_open_file(PARAMSTR(4),PARAM(0,s32)); break;
case PS2E_FIO_CLOSE_CMD: returnValue = pcsx2fio_close_file(PARAM(0,s32)); break;
case PS2E_FIO_READ_CMD: returnValue = pcsx2fio_read_file(PARAM(0,s32),PARAMP(4,char),PARAM(8,s32)); break;
case PS2E_FIO_WRITE_CMD: returnValue = pcsx2fio_write_file(PARAM(0,s32),PARAMP(4,char),PARAM(8,s32)); break;
case PS2E_FIO_LSEEK_CMD: returnValue = pcsx2fio_lseek_file(PARAM(0,s32),PARAM(4,s32),PARAM(8,s32)); break;
case PS2E_FIO_REMOVE_CMD: returnValue = pcsx2fio_remove(PARAMSTR(0)); break;
case PS2E_FIO_OPENDIR_CMD: returnValue = pcsx2fio_open_dir(PARAMSTR(0)); break;
case PS2E_FIO_CLOSEDIR_CMD: returnValue = pcsx2fio_close_dir(PARAM(0,s32)); break;
case PS2E_FIO_READDIR_CMD: returnValue = pcsx2fio_read_dir(PARAM(0,s32),PARAMP(4,void)); break;
case PS2E_FIO_MKDIR_CMD: returnValue = pcsx2fio_mkdir(PARAMSTR(4),PARAM(0,s32)); break;
case PS2E_FIO_RMDIR_CMD: returnValue = pcsx2fio_rmdir(PARAMSTR(0)); break;
case PS2E_FIO_PRINTF_CMD: returnValue = pcsx2fio_write_tty(PARAMSTR(0),paramsLength); break;
}
}
void Pcsx2HostFSwrite32(u32 addr, u32 value)
{
switch(addr&0xF)
{
case 0:
if(value==1)
Pcsx2HostFsExec();
break;
case 4:
paramsLength = value;
break;
case 8:
paramsAddress = value;
break;
case 12:
functionId = value;
break;
}
}
u32 Pcsx2HostFSread32(u32 addr)
{
switch(addr&0xF)
{
case 0:
return PS2E_FIO_MAGIC;
break;
case 4:
break;
case 8:
break;
case 12:
return returnValue;
break;
}
return 0;
}

View File

@ -1,77 +1,77 @@
#include "PrecompiledHeader.h"
#include "Utilities/Console.h"
#include "MSWstuff.h"
#include <wx/msw/wrapwin.h>
#include <wx/dynlib.h>
#include <dwmapi.h>
typedef HRESULT WINAPI Fntype_DwmEnableMMCSS(DWORD enable);
typedef HRESULT WINAPI Fntype_DwmSetPresentParameters( HWND hwnd, DWM_PRESENT_PARAMETERS *pPresentParams );
static wxDynamicLibrary lib_dwmapi;
// This could potentially reduce lag while running in Aero,
// by telling the DWM the application requires
// multimedia-class scheduling for smooth display.
void pxDwm_Load()
{
wxDoNotLogInThisScope please;
// Version test is not needed since we're using LoadLibrary. --air
/*OSVERSIONINFOEX info = {0};
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
info.dwMajorVersion = 6;
DWORDLONG mask=0;
VER_SET_CONDITION(mask,VER_MAJORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(mask,VER_MINORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(mask,VER_SERVICEPACKMAJOR,VER_GREATER_EQUAL);
VER_SET_CONDITION(mask,VER_SERVICEPACKMINOR,VER_GREATER_EQUAL);
//info
if(VerifyVersionInfo(&info,
VER_MAJORVERSION|VER_MINORVERSION|VER_SERVICEPACKMAJOR|VER_SERVICEPACKMINOR,
mask))*/
lib_dwmapi.Load( L"dwmapi.dll" );
if( !lib_dwmapi.IsLoaded() ) return;
if( Fntype_DwmEnableMMCSS* pDwmEnableMMCSS = (Fntype_DwmEnableMMCSS*)lib_dwmapi.GetSymbol(L"DwmEnableMMCSS") )
{
Console.WriteLn( "[Dwm] Desktop Window Manager detected." );
if(FAILED(pDwmEnableMMCSS(TRUE)))
Console.WriteLn("[Dwm] DwmEnableMMCSS returned a failure code.");
}
}
// wnd - this parameter should be the GS display panel or the top level frame that holds it (not
// sure if it's supposed to be the actual gsPanel or the top level window/frame that the
// panel belongs to)
//
void pxDwm_SetPresentParams( WXWidget wnd )
{
if( !lib_dwmapi.IsLoaded() ) return;
Fntype_DwmSetPresentParameters* pDwmSetPresentParameters = (Fntype_DwmSetPresentParameters*)lib_dwmapi.GetSymbol(L"DwmSetPresentParameters");
if( pDwmSetPresentParameters == NULL ) return;
DWM_PRESENT_PARAMETERS params;
params.cbSize = sizeof(DWM_PRESENT_PARAMETERS);
params.fQueue = FALSE;
if(FAILED(pDwmSetPresentParameters( (HWND)wnd, &params )))
Console.WriteLn("[Dwm] DwmSetPresentParameters returned a failure code.");
//DwmSetDxFrameDuration(hMainWindow,1);
}
void pxDwm_Unload()
{
lib_dwmapi.Unload();
#include "PrecompiledHeader.h"
#include "Utilities/Console.h"
#include "MSWstuff.h"
#include <wx/msw/wrapwin.h>
#include <wx/dynlib.h>
#include <dwmapi.h>
typedef HRESULT WINAPI Fntype_DwmEnableMMCSS(DWORD enable);
typedef HRESULT WINAPI Fntype_DwmSetPresentParameters( HWND hwnd, DWM_PRESENT_PARAMETERS *pPresentParams );
static wxDynamicLibrary lib_dwmapi;
// This could potentially reduce lag while running in Aero,
// by telling the DWM the application requires
// multimedia-class scheduling for smooth display.
void pxDwm_Load()
{
wxDoNotLogInThisScope please;
// Version test is not needed since we're using LoadLibrary. --air
/*OSVERSIONINFOEX info = {0};
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
info.dwMajorVersion = 6;
DWORDLONG mask=0;
VER_SET_CONDITION(mask,VER_MAJORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(mask,VER_MINORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(mask,VER_SERVICEPACKMAJOR,VER_GREATER_EQUAL);
VER_SET_CONDITION(mask,VER_SERVICEPACKMINOR,VER_GREATER_EQUAL);
//info
if(VerifyVersionInfo(&info,
VER_MAJORVERSION|VER_MINORVERSION|VER_SERVICEPACKMAJOR|VER_SERVICEPACKMINOR,
mask))*/
lib_dwmapi.Load( L"dwmapi.dll" );
if( !lib_dwmapi.IsLoaded() ) return;
if( Fntype_DwmEnableMMCSS* pDwmEnableMMCSS = (Fntype_DwmEnableMMCSS*)lib_dwmapi.GetSymbol(L"DwmEnableMMCSS") )
{
Console.WriteLn( "[Dwm] Desktop Window Manager detected." );
if(FAILED(pDwmEnableMMCSS(TRUE)))
Console.WriteLn("[Dwm] DwmEnableMMCSS returned a failure code.");
}
}
// wnd - this parameter should be the GS display panel or the top level frame that holds it (not
// sure if it's supposed to be the actual gsPanel or the top level window/frame that the
// panel belongs to)
//
void pxDwm_SetPresentParams( WXWidget wnd )
{
if( !lib_dwmapi.IsLoaded() ) return;
Fntype_DwmSetPresentParameters* pDwmSetPresentParameters = (Fntype_DwmSetPresentParameters*)lib_dwmapi.GetSymbol(L"DwmSetPresentParameters");
if( pDwmSetPresentParameters == NULL ) return;
DWM_PRESENT_PARAMETERS params;
params.cbSize = sizeof(DWM_PRESENT_PARAMETERS);
params.fQueue = FALSE;
if(FAILED(pDwmSetPresentParameters( (HWND)wnd, &params )))
Console.WriteLn("[Dwm] DwmSetPresentParameters returned a failure code.");
//DwmSetDxFrameDuration(hMainWindow,1);
}
void pxDwm_Unload()
{
lib_dwmapi.Unload();
}

View File

@ -1,20 +1,20 @@
#include "PrecompiledHeader.h"
#include "IopCommon.h"
#include "Sif.h"
#if FALSE
const u32 fifoSize = 0x1000; // in bytes
s32 PrepareEEWrite()
{
return 0;
}
s32 PrepareEERead()
{
#include "PrecompiledHeader.h"
#include "IopCommon.h"
#include "Sif.h"
#if FALSE
const u32 fifoSize = 0x1000; // in bytes
s32 PrepareEEWrite()
{
return 0;
}
s32 PrepareEERead()
{
static __aligned16 u32 tag[4];
// Process DMA tag at hw_dma(9).tadr
@ -63,32 +63,32 @@ s32 PrepareEERead()
sif0.ee.end = true;
break;
}
return true;
}
void FinalizeEERead()
{
return true;
}
void FinalizeEERead()
{
SIF_LOG("Sif0: End EE");
sif0.ee.end = false;
sif0.ee.busy = false;
SIF_LOG("CPU INT FIRED SIF0");
CPU_INT(DMAC_SIF0, 16);
}
s32 DoSIFWrite(u32 iopAvailable)
{
u32 eeAvailable = PrepareEEWrite();
}
s32 DoSifRead(u32 iopAvailable)
{
u32 eeAvailable = PrepareEERead();
u32 transferSizeBytes = min(min(iopAvailable,eeAvailable),fifoSize);
u32 transferSizeWords = transferSizeBytes >> 2;
u32 transferSizeQWords = transferSizeBytes >> 4;
}
s32 DoSIFWrite(u32 iopAvailable)
{
u32 eeAvailable = PrepareEEWrite();
}
s32 DoSifRead(u32 iopAvailable)
{
u32 eeAvailable = PrepareEERead();
u32 transferSizeBytes = min(min(iopAvailable,eeAvailable),fifoSize);
u32 transferSizeWords = transferSizeBytes >> 2;
u32 transferSizeQWords = transferSizeBytes >> 4;
SIF_LOG("Write IOP to EE: +++++++++++ %lX of %lX", transferSizeWords, sif0.iop.counter);
tDMA_TAG *ptag = sif0dma->getAddr(sif0dma->madr, DMAC_SIF0, true);
@ -106,55 +106,55 @@ s32 DoSifRead(u32 iopAvailable)
sif0dma->madr += transferSizeBytes;
sif0.ee.cycles += transferSizeQWords * 2;
sif0dma->qwc -= transferSizeQWords;
return transferSizeBytes;
}
s32 CALLBACK sif0DmaRead (s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
{
s32 processed = DoSIFWrite(bytesLeft);
if(processed>0)
{
bytesLeft -= processed;
if(bytesLeft == 0)
FinalizeEERead();
*bytesProcessed = processed;
return 0;
}
*bytesProcessed=0;
return -processed;
}
s32 CALLBACK sif0DmaWrite (s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
{
DevCon.Warning("SIF0 Dma Write to iop?!");
*bytesProcessed=0; return 0;
}
void CALLBACK sif0DmaInterrupt (s32 channel)
{
}
s32 CALLBACK sif1DmaRead (s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
{
DevCon.Warning("SIF1 Dma Read from iop?!");
*bytesProcessed=0; return 0;
}
s32 CALLBACK sif1DmaWrite (s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
{
*bytesProcessed=0;
return 0;
}
void CALLBACK sif1DmaInterrupt (s32 channel)
{
}
#endif
return transferSizeBytes;
}
s32 CALLBACK sif0DmaRead (s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
{
s32 processed = DoSIFWrite(bytesLeft);
if(processed>0)
{
bytesLeft -= processed;
if(bytesLeft == 0)
FinalizeEERead();
*bytesProcessed = processed;
return 0;
}
*bytesProcessed=0;
return -processed;
}
s32 CALLBACK sif0DmaWrite (s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
{
DevCon.Warning("SIF0 Dma Write to iop?!");
*bytesProcessed=0; return 0;
}
void CALLBACK sif0DmaInterrupt (s32 channel)
{
}
s32 CALLBACK sif1DmaRead (s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
{
DevCon.Warning("SIF1 Dma Read from iop?!");
*bytesProcessed=0; return 0;
}
s32 CALLBACK sif1DmaWrite (s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
{
*bytesProcessed=0;
return 0;
}
void CALLBACK sif1DmaInterrupt (s32 channel)
{
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,435 +1,435 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include "stdio.h"
#include <tamtypes.h>
#include <kernel.h>
#include <sifrpc.h>
#include <loadfile.h>
#include <iopcontrol.h>
#include <fileio.h>
#include <string.h>
#include "debug.h"
#include "excepHandler.h"
#include "byteorder.h"
#include "ps2regs.h"
#include "hostlink.h"
//#define scr_printf(args...) printf(args)
//#define init_scr() do { } while(0)
#ifdef DEBUG
#define dbgprintf(args...) printf(args)
#else
#define dbgprintf(args...) do { } while(0)
#endif
#if HOOK_THREADS
extern void KillActiveThreads(void);
#endif
////////////////////////////////////////////////////////////////////////
// Prototypes
static int cmdThread(void);
static int pkoStopVU(pko_pkt_stop_vu *);
static int pkoStartVU(pko_pkt_start_vu *);
static int pkoDumpMem(pko_pkt_mem_io *);
static int pkoDumpReg(pko_pkt_dump_regs *);
void pkoReset(void);
static int pkoLoadElf(char *path);
static int pkoGSExec(pko_pkt_gsexec_req *);
static int pkoWriteMem(pko_pkt_mem_io *);
// Flags for which type of boot (oh crap, make a header file dammit)
#define B_CD 1
#define B_MC 2
#define B_HOST 3
#define B_CC 4
#define B_UNKN 5
////////////////////////////////////////////////////////////////////////
// Globals
extern u32 _start;
extern int _gp;
extern int boot;
extern char elfName[];
int userThreadID = 0;
static int cmdThreadID = 0;
static char userThreadStack[16*1024] __attribute__((aligned(16)));
static char cmdThreadStack[16*1024] __attribute__((aligned(64)));
static char dataBuffer[16384] __attribute__((aligned(16)));
// The 'global' argv string area
static char argvStrings[PKO_MAX_PATH];
////////////////////////////////////////////////////////////////////////
// How about that header file again?
#define MAX_ARGS 16
#define MAX_ARGLEN 256
struct argData
{
int flag; // Contains thread id atm
int argc;
char *argv[MAX_ARGS];
} __attribute__((packed)) userArgs;
////////////////////////////////////////////////////////////////////////
int sifCmdSema;
int sif0HandlerId = 0;
// XXX: Hardcoded address atm.. Should be configurable!!
unsigned int *sifDmaDataPtr =(unsigned int*)(0x20100000-2048);
int excepscrdump = 1;
extern int pkoExecEE(pko_pkt_execee_req *cmd);
////////////////////////////////////////////////////////////////////////
// Create the argument struct to send to the user thread
int
makeArgs(int cmdargc, char *cmdargv, struct argData *arg_data)
{
int i;
int t;
int argc;
argc = 0;
if (cmdargc > MAX_ARGS)
cmdargc = MAX_ARGS;
cmdargv[PKO_MAX_PATH-1] = '\0';
memcpy(argvStrings, cmdargv, PKO_MAX_PATH);
dbgprintf("cmd->argc %d, argv[0]: %s\n", cmdargc, cmdargv);
i = 0;
t = 0;
do {
arg_data->argv[i] = &argvStrings[t];
dbgprintf("arg_data[%d]=%s\n", i, arg_data->argv[i]);
dbgprintf("argvStrings[%d]=%s\n", t, &argvStrings[t]);
t += strlen(&argvStrings[t]);
t++;
i++;
} while ((i < cmdargc) && (t < PKO_MAX_PATH));
arg_data->argc = i;
return 0;
}
////////////////////////////////////////////////////////////////////////
// Load the actual elf, and create a thread for it
// Return the thread id
static int
pkoLoadElf(char *path)
{
ee_thread_t th_attr;
t_ExecData elfdata;
int ret;
int pid;
ret = SifLoadElf(path, &elfdata);
FlushCache(0);
FlushCache(2);
dbgprintf("EE: LoadElf returned %d\n", ret);
dbgprintf("EE: Creating user thread (ent: %x, gp: %x, st: %x)\n",
elfdata.epc, elfdata.gp, elfdata.sp);
if (elfdata.epc == 0) {
dbgprintf("EE: Could not load file\n");
return -1;
}
th_attr.func = (void *)elfdata.epc;
th_attr.stack = userThreadStack;
th_attr.stack_size = sizeof(userThreadStack);
th_attr.gp_reg = (void *)elfdata.gp;
th_attr.initial_priority = 64;
pid = CreateThread(&th_attr);
if (pid < 0) {
printf("EE: Create user thread failed %d\n", pid);
return -1;
}
dbgprintf("EE: Created user thread: %d\n", pid);
return pid;
}
////////////////////////////////////////////////////////////////////////
// Load and start the requested elf
extern int pkoExecEE(pko_pkt_execee_req *cmd)
{
char path[PKO_MAX_PATH];
int ret;
int pid;
if (userThreadID) {
return -1;
}
dbgprintf("EE: Executing file %s...\n", cmd->argv);
memcpy(path, cmd->argv, PKO_MAX_PATH);
scr_printf("Executing file %s...\n", path);
pid = pkoLoadElf(path);
if (pid < 0) {
scr_printf("Could not execute file %s\n", path);
return -1;
}
FlushCache(0);
FlushCache(2);
userThreadID = pid;
makeArgs(ntohl(cmd->argc), path, &userArgs);
// Hack away..
userArgs.flag = (int)&userThreadID;
ret = StartThread(userThreadID, &userArgs);
if (ret < 0) {
printf("EE: Start user thread failed %d\n", ret);
cmdThreadID = 0;
DeleteThread(userThreadID);
return -1;
}
return ret;
}
////////////////////////////////////////////////////////////////////////
// takes cmd->data and sends it to GIF via path1
static int
pkoGSExec(pko_pkt_gsexec_req *cmd) {
int fd;
int len;
fd = fioOpen(cmd->file, O_RDONLY);
if ( fd < 0 ) {
return fd;
}
len = fioRead(fd, dataBuffer, 128);
fioClose(fd);
// stop/reset dma02
// dmasend via GIF channel
asm __volatile__(
"move $10, %0;"
"move $11, %1;"
"lui $8, 0x1001;"
"sw $11, -24544($8);"
"sw $10, -24560($8);"
"ori $9, $0, 0x101;"
"sw $9, -24576($8);"
:: "r" (dataBuffer), "r" ((ntohs(cmd->size))/16) );
// dmawait for GIF channel
asm __volatile__(
"lui $8, 0x1001;"
"dmawait:"
"lw $9, -24576($8);"
"nop;"
"andi $9, $9, 0x100;"
"nop;"
"bnez $9, dmawait;"
"nop;"
);
return 0;
}
////////////////////////////////////////////////////////////////////////
// command to dump cmd->size bytes of memory from cmd->offset
static int
pkoDumpMem(pko_pkt_mem_io *cmd) {
int fd;
int total, len;
unsigned int offset;
unsigned int size;
char path[PKO_MAX_PATH];
int ret = 0;
size = ntohl(cmd->size);
offset = ntohl(cmd->offset);
scr_printf("dump mem from 0x%x, size %d\n",
ntohl(cmd->offset), ntohl(cmd->size)
);
memcpy(path, cmd->argv, PKO_MAX_PATH);
fd = fioOpen(path, O_WRONLY|O_CREAT);
total = 0;
len = 16*1024;
if ( fd > 0 ) {
while(total < size) {
if ( size < len) {
len = size;
} else if ((size - total) < len) {
len = size - total;
}
memcpy(dataBuffer, (void *)offset, len);
if ((ret = fioWrite(fd, (void *)dataBuffer, len)) > 0) {
} else {
printf("EE: pkoDumpMem() fioWrite failed\n");
return fd;
}
offset = offset + len;
total += len;
}
}
fioClose(fd);
return ret;
}
static int
pkoWriteMem(pko_pkt_mem_io *cmd) {
int fd, len, total;
unsigned int offset;
unsigned int size;
char path[PKO_MAX_PATH];
int ret = 0;
size = ntohl(cmd->size);
offset = ntohl(cmd->offset);
scr_printf("write mem to 0x%x, size %d\n",
ntohl(cmd->offset), ntohl(cmd->size)
);
memcpy(path, cmd->argv, PKO_MAX_PATH);
fd = fioOpen(path, O_RDONLY);
total = 0;
len = 16*1024;
if( fd > 0) {
while(total < size) {
if ( size < len) {
len = size;
} else if ((size - total) < len) {
len = size - total;
}
if ((ret = fioRead(fd, (void *)dataBuffer, len)) > 0) {
} else {
printf("EE: pkoDumpMem() fioWrite failed\n");
return fd;
}
memcpy((void *)offset, dataBuffer, len);
offset = offset + len;
total += len;
}
}
fioClose(fd);
return ret;
}
////////////////////////////////////////////////////////////////////////
// command to stop VU0/1 and VIF0/1
static int
pkoStopVU(pko_pkt_stop_vu *cmd) {
if ( ntohs(cmd->vpu) == 0 ) {
asm(
"ori $25, $0, 0x1;"
"ctc2 $25, $28;"
"sync.p;"
"vnop;"
);
VIF0_FBRST = 0x2;
} else if ( ntohs(cmd->vpu) == 1 ) {
asm(
"ori $25, $0, 0x100;"
"ctc2 $25, $28;"
"sync.p;"
"vnop;"
);
VIF1_FBRST = 0x2;
}
return 0;
}
////////////////////////////////////////////////////////////////////////
// command to reset VU0/1 VIF0/1
static int
pkoStartVU(pko_pkt_start_vu *cmd) {
if ( ntohs(cmd->vpu) == 0 ) {
asm(
"ori $25, $0, 0x2;"
"ctc2 $25, $28;"
"sync.p;"
"vnop;"
);
VIF0_FBRST = 0x8;
} else if ( ntohs(cmd->vpu) == 1 ) {
asm(
"ori $25, $0, 0x200;"
"ctc2 $25, $28;"
"sync.p;"
"vnop;"
);
VIF1_FBRST = 0x8;
}
return 0;
}
////////////////////////////////////////////////////////////////////////
void
pkoReset(void)
{
char *argv[1];
// Check if user thread is running, if so kill it
#if 1
#if HOOK_THREADS
KillActiveThreads();
#else
if (userThreadID) {
TerminateThread(userThreadID);
DeleteThread(userThreadID);
}
#endif
#endif
userThreadID = 0;
RemoveDmacHandler(5, sif0HandlerId);
sif0HandlerId = 0;
SifInitRpc(0);
//cdvdInit(CDVD_INIT_NOWAIT);
//cdvdInit(CDVD_EXIT);
SifIopReset(NULL, 0);
SifExitRpc();
while(SifIopSync());
#if 1
SifInitRpc(0);
//cdvdExit();
SifExitRpc();
#endif
FlushCache(0);
#ifdef USE_CACHED_CFG
argv[0] = elfName;
SifLoadFileExit();
ExecPS2(&_start, 0, 1, argv);
return;
#endif
if ((boot == B_MC) || (boot == B_HOST) || (boot == B_UNKN) || (boot == B_CC)) {
argv[0] = elfName;
SifLoadFileExit();
ExecPS2(&_start, 0, 1, argv);
}
else {
LoadExecPS2(elfName, 0, NULL);
}
}
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include "stdio.h"
#include <tamtypes.h>
#include <kernel.h>
#include <sifrpc.h>
#include <loadfile.h>
#include <iopcontrol.h>
#include <fileio.h>
#include <string.h>
#include "debug.h"
#include "excepHandler.h"
#include "byteorder.h"
#include "ps2regs.h"
#include "hostlink.h"
//#define scr_printf(args...) printf(args)
//#define init_scr() do { } while(0)
#ifdef DEBUG
#define dbgprintf(args...) printf(args)
#else
#define dbgprintf(args...) do { } while(0)
#endif
#if HOOK_THREADS
extern void KillActiveThreads(void);
#endif
////////////////////////////////////////////////////////////////////////
// Prototypes
static int cmdThread(void);
static int pkoStopVU(pko_pkt_stop_vu *);
static int pkoStartVU(pko_pkt_start_vu *);
static int pkoDumpMem(pko_pkt_mem_io *);
static int pkoDumpReg(pko_pkt_dump_regs *);
void pkoReset(void);
static int pkoLoadElf(char *path);
static int pkoGSExec(pko_pkt_gsexec_req *);
static int pkoWriteMem(pko_pkt_mem_io *);
// Flags for which type of boot (oh crap, make a header file dammit)
#define B_CD 1
#define B_MC 2
#define B_HOST 3
#define B_CC 4
#define B_UNKN 5
////////////////////////////////////////////////////////////////////////
// Globals
extern u32 _start;
extern int _gp;
extern int boot;
extern char elfName[];
int userThreadID = 0;
static int cmdThreadID = 0;
static char userThreadStack[16*1024] __attribute__((aligned(16)));
static char cmdThreadStack[16*1024] __attribute__((aligned(64)));
static char dataBuffer[16384] __attribute__((aligned(16)));
// The 'global' argv string area
static char argvStrings[PKO_MAX_PATH];
////////////////////////////////////////////////////////////////////////
// How about that header file again?
#define MAX_ARGS 16
#define MAX_ARGLEN 256
struct argData
{
int flag; // Contains thread id atm
int argc;
char *argv[MAX_ARGS];
} __attribute__((packed)) userArgs;
////////////////////////////////////////////////////////////////////////
int sifCmdSema;
int sif0HandlerId = 0;
// XXX: Hardcoded address atm.. Should be configurable!!
unsigned int *sifDmaDataPtr =(unsigned int*)(0x20100000-2048);
int excepscrdump = 1;
extern int pkoExecEE(pko_pkt_execee_req *cmd);
////////////////////////////////////////////////////////////////////////
// Create the argument struct to send to the user thread
int
makeArgs(int cmdargc, char *cmdargv, struct argData *arg_data)
{
int i;
int t;
int argc;
argc = 0;
if (cmdargc > MAX_ARGS)
cmdargc = MAX_ARGS;
cmdargv[PKO_MAX_PATH-1] = '\0';
memcpy(argvStrings, cmdargv, PKO_MAX_PATH);
dbgprintf("cmd->argc %d, argv[0]: %s\n", cmdargc, cmdargv);
i = 0;
t = 0;
do {
arg_data->argv[i] = &argvStrings[t];
dbgprintf("arg_data[%d]=%s\n", i, arg_data->argv[i]);
dbgprintf("argvStrings[%d]=%s\n", t, &argvStrings[t]);
t += strlen(&argvStrings[t]);
t++;
i++;
} while ((i < cmdargc) && (t < PKO_MAX_PATH));
arg_data->argc = i;
return 0;
}
////////////////////////////////////////////////////////////////////////
// Load the actual elf, and create a thread for it
// Return the thread id
static int
pkoLoadElf(char *path)
{
ee_thread_t th_attr;
t_ExecData elfdata;
int ret;
int pid;
ret = SifLoadElf(path, &elfdata);
FlushCache(0);
FlushCache(2);
dbgprintf("EE: LoadElf returned %d\n", ret);
dbgprintf("EE: Creating user thread (ent: %x, gp: %x, st: %x)\n",
elfdata.epc, elfdata.gp, elfdata.sp);
if (elfdata.epc == 0) {
dbgprintf("EE: Could not load file\n");
return -1;
}
th_attr.func = (void *)elfdata.epc;
th_attr.stack = userThreadStack;
th_attr.stack_size = sizeof(userThreadStack);
th_attr.gp_reg = (void *)elfdata.gp;
th_attr.initial_priority = 64;
pid = CreateThread(&th_attr);
if (pid < 0) {
printf("EE: Create user thread failed %d\n", pid);
return -1;
}
dbgprintf("EE: Created user thread: %d\n", pid);
return pid;
}
////////////////////////////////////////////////////////////////////////
// Load and start the requested elf
extern int pkoExecEE(pko_pkt_execee_req *cmd)
{
char path[PKO_MAX_PATH];
int ret;
int pid;
if (userThreadID) {
return -1;
}
dbgprintf("EE: Executing file %s...\n", cmd->argv);
memcpy(path, cmd->argv, PKO_MAX_PATH);
scr_printf("Executing file %s...\n", path);
pid = pkoLoadElf(path);
if (pid < 0) {
scr_printf("Could not execute file %s\n", path);
return -1;
}
FlushCache(0);
FlushCache(2);
userThreadID = pid;
makeArgs(ntohl(cmd->argc), path, &userArgs);
// Hack away..
userArgs.flag = (int)&userThreadID;
ret = StartThread(userThreadID, &userArgs);
if (ret < 0) {
printf("EE: Start user thread failed %d\n", ret);
cmdThreadID = 0;
DeleteThread(userThreadID);
return -1;
}
return ret;
}
////////////////////////////////////////////////////////////////////////
// takes cmd->data and sends it to GIF via path1
static int
pkoGSExec(pko_pkt_gsexec_req *cmd) {
int fd;
int len;
fd = fioOpen(cmd->file, O_RDONLY);
if ( fd < 0 ) {
return fd;
}
len = fioRead(fd, dataBuffer, 128);
fioClose(fd);
// stop/reset dma02
// dmasend via GIF channel
asm __volatile__(
"move $10, %0;"
"move $11, %1;"
"lui $8, 0x1001;"
"sw $11, -24544($8);"
"sw $10, -24560($8);"
"ori $9, $0, 0x101;"
"sw $9, -24576($8);"
:: "r" (dataBuffer), "r" ((ntohs(cmd->size))/16) );
// dmawait for GIF channel
asm __volatile__(
"lui $8, 0x1001;"
"dmawait:"
"lw $9, -24576($8);"
"nop;"
"andi $9, $9, 0x100;"
"nop;"
"bnez $9, dmawait;"
"nop;"
);
return 0;
}
////////////////////////////////////////////////////////////////////////
// command to dump cmd->size bytes of memory from cmd->offset
static int
pkoDumpMem(pko_pkt_mem_io *cmd) {
int fd;
int total, len;
unsigned int offset;
unsigned int size;
char path[PKO_MAX_PATH];
int ret = 0;
size = ntohl(cmd->size);
offset = ntohl(cmd->offset);
scr_printf("dump mem from 0x%x, size %d\n",
ntohl(cmd->offset), ntohl(cmd->size)
);
memcpy(path, cmd->argv, PKO_MAX_PATH);
fd = fioOpen(path, O_WRONLY|O_CREAT);
total = 0;
len = 16*1024;
if ( fd > 0 ) {
while(total < size) {
if ( size < len) {
len = size;
} else if ((size - total) < len) {
len = size - total;
}
memcpy(dataBuffer, (void *)offset, len);
if ((ret = fioWrite(fd, (void *)dataBuffer, len)) > 0) {
} else {
printf("EE: pkoDumpMem() fioWrite failed\n");
return fd;
}
offset = offset + len;
total += len;
}
}
fioClose(fd);
return ret;
}
static int
pkoWriteMem(pko_pkt_mem_io *cmd) {
int fd, len, total;
unsigned int offset;
unsigned int size;
char path[PKO_MAX_PATH];
int ret = 0;
size = ntohl(cmd->size);
offset = ntohl(cmd->offset);
scr_printf("write mem to 0x%x, size %d\n",
ntohl(cmd->offset), ntohl(cmd->size)
);
memcpy(path, cmd->argv, PKO_MAX_PATH);
fd = fioOpen(path, O_RDONLY);
total = 0;
len = 16*1024;
if( fd > 0) {
while(total < size) {
if ( size < len) {
len = size;
} else if ((size - total) < len) {
len = size - total;
}
if ((ret = fioRead(fd, (void *)dataBuffer, len)) > 0) {
} else {
printf("EE: pkoDumpMem() fioWrite failed\n");
return fd;
}
memcpy((void *)offset, dataBuffer, len);
offset = offset + len;
total += len;
}
}
fioClose(fd);
return ret;
}
////////////////////////////////////////////////////////////////////////
// command to stop VU0/1 and VIF0/1
static int
pkoStopVU(pko_pkt_stop_vu *cmd) {
if ( ntohs(cmd->vpu) == 0 ) {
asm(
"ori $25, $0, 0x1;"
"ctc2 $25, $28;"
"sync.p;"
"vnop;"
);
VIF0_FBRST = 0x2;
} else if ( ntohs(cmd->vpu) == 1 ) {
asm(
"ori $25, $0, 0x100;"
"ctc2 $25, $28;"
"sync.p;"
"vnop;"
);
VIF1_FBRST = 0x2;
}
return 0;
}
////////////////////////////////////////////////////////////////////////
// command to reset VU0/1 VIF0/1
static int
pkoStartVU(pko_pkt_start_vu *cmd) {
if ( ntohs(cmd->vpu) == 0 ) {
asm(
"ori $25, $0, 0x2;"
"ctc2 $25, $28;"
"sync.p;"
"vnop;"
);
VIF0_FBRST = 0x8;
} else if ( ntohs(cmd->vpu) == 1 ) {
asm(
"ori $25, $0, 0x200;"
"ctc2 $25, $28;"
"sync.p;"
"vnop;"
);
VIF1_FBRST = 0x8;
}
return 0;
}
////////////////////////////////////////////////////////////////////////
void
pkoReset(void)
{
char *argv[1];
// Check if user thread is running, if so kill it
#if 1
#if HOOK_THREADS
KillActiveThreads();
#else
if (userThreadID) {
TerminateThread(userThreadID);
DeleteThread(userThreadID);
}
#endif
#endif
userThreadID = 0;
RemoveDmacHandler(5, sif0HandlerId);
sif0HandlerId = 0;
SifInitRpc(0);
//cdvdInit(CDVD_INIT_NOWAIT);
//cdvdInit(CDVD_EXIT);
SifIopReset(NULL, 0);
SifExitRpc();
while(SifIopSync());
#if 1
SifInitRpc(0);
//cdvdExit();
SifExitRpc();
#endif
FlushCache(0);
#ifdef USE_CACHED_CFG
argv[0] = elfName;
SifLoadFileExit();
ExecPS2(&_start, 0, 1, argv);
return;
#endif
if ((boot == B_MC) || (boot == B_HOST) || (boot == B_UNKN) || (boot == B_CC)) {
argv[0] = elfName;
SifLoadFileExit();
ExecPS2(&_start, 0, 1, argv);
}
else {
LoadExecPS2(elfName, 0, NULL);
}
}

View File

@ -1,170 +1,170 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include "stdio.h"
#include <tamtypes.h>
#include <kernel.h>
#include "excepHandler.h"
#include "debug.h"
extern int _gp;
int userThreadID;
int excepscrdump;
////////////////////////////////////////////////////////////////////////
typedef union
{
unsigned int uint128 __attribute__(( mode(TI) ));
unsigned long uint64[2];
} eeReg __attribute((packed));
////////////////////////////////////////////////////////////////////////
// Prototypes
void pkoDebug(int cause, int badvaddr, int status, int epc, eeReg *regs);
extern void pkoExceptionHandler(void);
////////////////////////////////////////////////////////////////////////
static const unsigned char regName[32][5] =
{
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
"t8", "t9", "s0", "s1", "s2", "s3", "s4", "s5",
"s6", "s7", "k0", "k1", "gp", "sp", "fp", "ra"
};
static char codeTxt[14][24] =
{
"Interrupt", "TLB modification", "TLB load/inst fetch", "TLB store",
"Address load/inst fetch", "Address store", "Bus error (instr)",
"Bus error (data)", "Syscall", "Breakpoint", "Reserved instruction",
"Coprocessor unusable", "Arithmetic overflow", "Trap"
};
char _exceptionStack[8*1024] __attribute__((aligned(16)));
eeReg _savedRegs[32+4] __attribute__((aligned(16)));
////////////////////////////////////////////////////////////////////////
// The 'ee exception handler', only dumps registers to console or screen atm
void
pkoDebug(int cause, int badvaddr, int status, int epc, eeReg *regs)
{
int i;
int code;
// extern void printf(char *, ...);
static void (* excpPrintf)(const char *, ...);
FlushCache(0);
FlushCache(2);
#if 1
if (userThreadID) {
TerminateThread(userThreadID);
DeleteThread(userThreadID);
}
#endif
code = cause & 0x7c;
if (excepscrdump)
{
init_scr();
excpPrintf = scr_printf;
}
else excpPrintf = (void*)printf;
excpPrintf("\n\n EE Exception handler: %s exception\n\n",
codeTxt[code>>2]);
excpPrintf(" Cause %08X BadVAddr %08X Status %08X EPC %08X\n\n",
cause, badvaddr, status, epc);
for(i = 0; i < 32/2; i++) {
excpPrintf("%4s: %016lX%016lX %4s: %016lX%016lX\n",
regName[i], regs[i].uint64[1], regs[i].uint64[0],
regName[i+16], regs[i+16].uint64[1], regs[i+16].uint64[0]);
}
excpPrintf("\n");
SleepThread();
}
////////////////////////////////////////////////////////////////////////
// The 'iop exception handler', only dumps registers to console or screen atm
void iopException(int cause, int badvaddr, int status, int epc, u32 *regs, int repc, char* name)
{
int i;
int code;
// extern void printf(char *, ...);
static void (* excpPrintf)(const char *, ...);
FlushCache(0);
FlushCache(2);
#if 1
if (userThreadID) {
TerminateThread(userThreadID);
DeleteThread(userThreadID);
}
#endif
code = cause & 0x7c;
if(excepscrdump)
{
init_scr();
excpPrintf = scr_printf;
}
else excpPrintf = (void*)printf;
excpPrintf("\n\n IOP Exception handler: %s exception\n\n",
codeTxt[code>>2]);
excpPrintf(" Module Name \"%s\" Relative EPC %08X\n\n",
name, repc);
excpPrintf(" Cause %08X BadVAddr %08X Status %08X EPC %08X\n\n",
cause, badvaddr, status, epc);
for(i = 0; i < 32/4; i++)
{
excpPrintf(" %4s: %08X %4s: %08X %4s: %08X %4s: %08X\n",
regName[i], regs[i], regName[i+8], regs[i+8],
regName[i+16], regs[i+16], regName[i+24], regs[i+24]);
}
excpPrintf("\n");
SleepThread();
}
////////////////////////////////////////////////////////////////////////
// Installs ee exception handlers for the 'usual' exceptions and iop
// exception callback
void
installExceptionHandlers(void)
{
int i;
// Skip exception #8 (syscall) & 9 (breakpoint)
for (i = 1; i < 4; i++) {
SetVTLBRefillHandler(i, pkoExceptionHandler);
}
for (i = 4; i < 8; i++) {
SetVCommonHandler(i, pkoExceptionHandler);
}
for (i = 10; i < 14; i++) {
SetVCommonHandler(i, pkoExceptionHandler);
}
}
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include "stdio.h"
#include <tamtypes.h>
#include <kernel.h>
#include "excepHandler.h"
#include "debug.h"
extern int _gp;
int userThreadID;
int excepscrdump;
////////////////////////////////////////////////////////////////////////
typedef union
{
unsigned int uint128 __attribute__(( mode(TI) ));
unsigned long uint64[2];
} eeReg __attribute((packed));
////////////////////////////////////////////////////////////////////////
// Prototypes
void pkoDebug(int cause, int badvaddr, int status, int epc, eeReg *regs);
extern void pkoExceptionHandler(void);
////////////////////////////////////////////////////////////////////////
static const unsigned char regName[32][5] =
{
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
"t8", "t9", "s0", "s1", "s2", "s3", "s4", "s5",
"s6", "s7", "k0", "k1", "gp", "sp", "fp", "ra"
};
static char codeTxt[14][24] =
{
"Interrupt", "TLB modification", "TLB load/inst fetch", "TLB store",
"Address load/inst fetch", "Address store", "Bus error (instr)",
"Bus error (data)", "Syscall", "Breakpoint", "Reserved instruction",
"Coprocessor unusable", "Arithmetic overflow", "Trap"
};
char _exceptionStack[8*1024] __attribute__((aligned(16)));
eeReg _savedRegs[32+4] __attribute__((aligned(16)));
////////////////////////////////////////////////////////////////////////
// The 'ee exception handler', only dumps registers to console or screen atm
void
pkoDebug(int cause, int badvaddr, int status, int epc, eeReg *regs)
{
int i;
int code;
// extern void printf(char *, ...);
static void (* excpPrintf)(const char *, ...);
FlushCache(0);
FlushCache(2);
#if 1
if (userThreadID) {
TerminateThread(userThreadID);
DeleteThread(userThreadID);
}
#endif
code = cause & 0x7c;
if (excepscrdump)
{
init_scr();
excpPrintf = scr_printf;
}
else excpPrintf = (void*)printf;
excpPrintf("\n\n EE Exception handler: %s exception\n\n",
codeTxt[code>>2]);
excpPrintf(" Cause %08X BadVAddr %08X Status %08X EPC %08X\n\n",
cause, badvaddr, status, epc);
for(i = 0; i < 32/2; i++) {
excpPrintf("%4s: %016lX%016lX %4s: %016lX%016lX\n",
regName[i], regs[i].uint64[1], regs[i].uint64[0],
regName[i+16], regs[i+16].uint64[1], regs[i+16].uint64[0]);
}
excpPrintf("\n");
SleepThread();
}
////////////////////////////////////////////////////////////////////////
// The 'iop exception handler', only dumps registers to console or screen atm
void iopException(int cause, int badvaddr, int status, int epc, u32 *regs, int repc, char* name)
{
int i;
int code;
// extern void printf(char *, ...);
static void (* excpPrintf)(const char *, ...);
FlushCache(0);
FlushCache(2);
#if 1
if (userThreadID) {
TerminateThread(userThreadID);
DeleteThread(userThreadID);
}
#endif
code = cause & 0x7c;
if(excepscrdump)
{
init_scr();
excpPrintf = scr_printf;
}
else excpPrintf = (void*)printf;
excpPrintf("\n\n IOP Exception handler: %s exception\n\n",
codeTxt[code>>2]);
excpPrintf(" Module Name \"%s\" Relative EPC %08X\n\n",
name, repc);
excpPrintf(" Cause %08X BadVAddr %08X Status %08X EPC %08X\n\n",
cause, badvaddr, status, epc);
for(i = 0; i < 32/4; i++)
{
excpPrintf(" %4s: %08X %4s: %08X %4s: %08X %4s: %08X\n",
regName[i], regs[i], regName[i+8], regs[i+8],
regName[i+16], regs[i+16], regName[i+24], regs[i+24]);
}
excpPrintf("\n");
SleepThread();
}
////////////////////////////////////////////////////////////////////////
// Installs ee exception handlers for the 'usual' exceptions and iop
// exception callback
void
installExceptionHandlers(void)
{
int i;
// Skip exception #8 (syscall) & 9 (breakpoint)
for (i = 1; i < 4; i++) {
SetVTLBRefillHandler(i, pkoExceptionHandler);
}
for (i = 4; i < 8; i++) {
SetVCommonHandler(i, pkoExceptionHandler);
}
for (i = 10; i < 14; i++) {
SetVCommonHandler(i, pkoExceptionHandler);
}
}

View File

@ -1,14 +1,14 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#ifndef _EXCEPTION_H_
#define _EXCEPTION_H_
void installExceptionHandlers(void);
void iopException(int cause, int badvaddr, int status, int epc, u32 *regs, int repc, char* name);
#endif
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#ifndef _EXCEPTION_H_
#define _EXCEPTION_H_
void installExceptionHandlers(void);
void iopException(int cause, int badvaddr, int status, int epc, u32 *regs, int repc, char* name);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,286 +1,286 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#ifndef PS2REGS_H
#define PS2REGS_H
/* TIMERS */
#define T0_COUNT *((volatile unsigned int *)0x10000000)
#define T0_MODE *((volatile unsigned short *)0x10000010)
#define T0_COMP *((volatile unsigned short *)0x10000020)
#define T0_HOLD *((volatile unsigned short *)0x10000030)
#define T1_COUNT *((volatile unsigned int *)0x10000800)
#define T1_MODE *((volatile unsigned short *)0x10000810)
#define T1_COMP *((volatile unsigned short *)0x10000820)
#define T1_HOLD *((volatile unsigned short *)0x10000830)
#define T2_COUNT *((volatile unsigned int *)0x10001000)
#define T2_MODE *((volatile unsigned short *)0x10001010)
#define T2_COMP *((volatile unsigned short *)0x10001020)
#define T3_COUNT *((volatile unsigned int *)0x10001800)
#define T3_MODE *((volatile unsigned short *)0x10001810)
#define T3_COMP *((volatile unsigned short *)0x10001820)
/* IPU */
#define IPU_CMD *((volatile unsigned long *)0x10002000)
#define IPU_CTRL *((volatile unsigned int *)0x10002010)
#define IPU_BP *((volatile unsigned int *)0x10002020)
#define IPU_TOP *((volatile unsigned long *)0x10002030)
/* GIF */
#define GIF_CTRL *((volatile unsigned int *)0x10003000)
#define GIF_MODE *((volatile unsigned int *)0x10003010)
#define GIF_STAT *((volatile unsigned int *)0x10003020)
#define GIF_TAG0 *((volatile unsigned int *)0x10003040)
#define GIF_TAG1 *((volatile unsigned int *)0x10003050)
#define GIF_TAG2 *((volatile unsigned int *)0x10003060)
#define GIF_TAG3 *((volatile unsigned int *)0x10003070)
#define GIF_CNT *((volatile unsigned int *)0x10003080)
#define GIF_P3CNT *((volatile unsigned int *)0x10003090)
#define GIF_P3TAG *((volatile unsigned int *)0x100030a0)
/* VIF */
#define VIF0_STAT *((volatile unsigned int *)0x10003800)
#define VIF0_FBRST *((volatile unsigned int *)0x10003810)
#define VIF0_ERR *((volatile unsigned int *)0x10003820)
#define VIF0_MARK *((volatile unsigned int *)0x10003830)
#define VIF0_CYCLE *((volatile unsigned int *)0x10003840)
#define VIF0_MODE *((volatile unsigned int *)0x10003850)
#define VIF0_NUM *((volatile unsigned int *)0x10003860)
#define VIF0_MASK *((volatile unsigned int *)0x10003870)
#define VIF0_CODE *((volatile unsigned int *)0x10003880)
#define VIF0_ITOPS *((volatile unsigned int *)0x10003890)
#define VIF0_ITOP *((volatile unsigned int *)0x100038d0)
#define VIF0_R0 *((volatile unsigned int *)0x10003900)
#define VIF0_R1 *((volatile unsigned int *)0x10003910)
#define VIF0_R2 *((volatile unsigned int *)0x10003920)
#define VIF0_R3 *((volatile unsigned int *)0x10003930)
#define VIF0_C0 *((volatile unsigned int *)0x10003940)
#define VIF0_C1 *((volatile unsigned int *)0x10003950)
#define VIF0_C2 *((volatile unsigned int *)0x10003960)
#define VIF0_C3 *((volatile unsigned int *)0x10003970)
#define VIF1_STAT *((volatile unsigned int *)0x10003c00)
#define VIF1_FBRST *((volatile unsigned int *)0x10003c10)
#define VIF1_ERR *((volatile unsigned int *)0x10003c20)
#define VIF1_MARK *((volatile unsigned int *)0x10003c30)
#define VIF1_CYCLE *((volatile unsigned int *)0x10003c40)
#define VIF1_MODE *((volatile unsigned int *)0x10003c50)
#define VIF1_NUM *((volatile unsigned int *)0x10003c60)
#define VIF1_MASK *((volatile unsigned int *)0x10003c70)
#define VIF1_CODE *((volatile unsigned int *)0x10003c80)
#define VIF1_ITOPS *((volatile unsigned int *)0x10003c90)
#define VIF1_BASE *((volatile unsigned int *)0x10003ca0)
#define VIF1_OFST *((volatile unsigned int *)0x10003cb0)
#define VIF1_TOPS *((volatile unsigned int *)0x10003cc0)
#define VIF1_ITOP *((volatile unsigned int *)0x10003cd0)
#define VIF1_TOP *((volatile unsigned int *)0x10003ce0)
#define VIF1_R0 *((volatile unsigned int *)0x10003d00)
#define VIF1_R1 *((volatile unsigned int *)0x10003d10)
#define VIF1_R2 *((volatile unsigned int *)0x10003d20)
#define VIF1_R3 *((volatile unsigned int *)0x10003d30)
#define VIF1_C0 *((volatile unsigned int *)0x10003d40)
#define VIF1_C1 *((volatile unsigned int *)0x10003d50)
#define VIF1_C2 *((volatile unsigned int *)0x10003d60)
#define VIF1_C3 *((volatile unsigned int *)0x10003d70)
/* FIFO */
//#define VIF0_FIFO(write) *((volatile unsigned int128 *)0x10004000)
//#define VIF1_FIFO(read/write) *((volatile unsigned int128 *)0x10005000)
//#define GIF_FIFO(write) *((volatile unsigned int128 *)0x10006000)
//#define IPU_out_FIFO(read) *((volatile unsigned int128 *)0x10007000)
//#define IPU_in_FIFO(write) *((volatile unsigned int128 *)0x10007010)
/* DMAC */
#define CHCR 0x00
#define MADR 0x04
#define QWC 0x08
#define TADR 0x0C
#define ASR0 0x10
#define ASR1 0x14
#define DMA0 ((volatile unsigned int *)0x10008000)
#define DMA1 ((volatile unsigned int *)0x10009000)
#define DMA2 ((volatile unsigned int *)0x1000a000)
#define DMA3 ((volatile unsigned int *)0x1000b000)
#define DMA4 ((volatile unsigned int *)0x1000b400)
#define DMA5 ((volatile unsigned int *)0x1000c000)
#define DMA6 ((volatile unsigned int *)0x1000c400)
#define DMA7 ((volatile unsigned int *)0x1000c800)
#define DMA8 ((volatile unsigned int *)0x1000d000)
#define DMA9 ((volatile unsigned int *)0x1000d400)
#define D0_CHCR *((volatile unsigned int *)0x10008000)
#define D0_MADR *((volatile unsigned int *)0x10008010)
#define D0_QWC *((volatile unsigned int *)0x10008020)
#define D0_TADR *((volatile unsigned int *)0x10008030)
#define D0_ASR0 *((volatile unsigned int *)0x10008040)
#define D0_ASR1 *((volatile unsigned int *)0x10008050)
#define D1_CHCR *((volatile unsigned int *)0x10009000)
#define D1_MADR *((volatile unsigned int *)0x10009010)
#define D1_QWC *((volatile unsigned int *)0x10009020)
#define D1_TADR *((volatile unsigned int *)0x10009030)
#define D1_ASR0 *((volatile unsigned int *)0x10009040)
#define D1_ASR1 *((volatile unsigned int *)0x10009050)
#define D2_CHCR *((volatile unsigned int *)0x1000a000)
#define D2_MADR *((volatile unsigned int *)0x1000a010)
#define D2_QWC *((volatile unsigned int *)0x1000a020)
#define D2_TADR *((volatile unsigned int *)0x1000a030)
#define D2_ASR0 *((volatile unsigned int *)0x1000a040)
#define D2_ASR1 *((volatile unsigned int *)0x1000a050)
#define D3_CHCR *((volatile unsigned int *)0x1000b000)
#define D3_MADR *((volatile unsigned int *)0x1000b010)
#define D3_QWC *((volatile unsigned int *)0x1000b020)
#define D4_CHCR *((volatile unsigned int *)0x1000b400)
#define D4_MADR *((volatile unsigned int *)0x1000b410)
#define D4_QWC *((volatile unsigned int *)0x1000b420)
#define D4_TADR *((volatile unsigned int *)0x1000b430)
#define D5_CHCR *((volatile unsigned int *)0x1000c000)
#define D5_MADR *((volatile unsigned int *)0x1000c010)
#define D5_QWC *((volatile unsigned int *)0x1000c020)
#define D6_CHCR *((volatile unsigned int *)0x1000c400)
#define D6_MADR *((volatile unsigned int *)0x1000c410)
#define D6_QWC *((volatile unsigned int *)0x1000c420)
#define D7_CHCR *((volatile unsigned int *)0x1000c800)
#define D7_MADR *((volatile unsigned int *)0x1000c810)
#define D7_QWC *((volatile unsigned int *)0x1000c820)
#define D8_CHCR *((volatile unsigned int *)0x1000d000)
#define D8_MADR *((volatile unsigned int *)0x1000d010)
#define D8_QWC *((volatile unsigned int *)0x1000d020)
#define D8_SADR *((volatile unsigned int *)0x1000d080)
#define D9_CHCR *((volatile unsigned int *)0x1000d400)
#define D9_MADR *((volatile unsigned int *)0x1000d410)
#define D9_QWC *((volatile unsigned int *)0x1000d420)
#define D9_TADR *((volatile unsigned int *)0x1000d430)
#define D9_SADR *((volatile unsigned int *)0x1000d480)
/* DMAC */
#define D_CTRL *((volatile unsigned int *)0x1000e000)
#define D_STAT *((volatile unsigned int *)0x1000e010)
#define D_PCR *((volatile unsigned int *)0x1000e020)
#define D_SQWC *((volatile unsigned int *)0x1000e030)
#define D_RBSR *((volatile unsigned int *)0x1000e040)
#define D_RBOR *((volatile unsigned int *)0x1000e050)
#define D_STADR *((volatile unsigned int *)0x1000e060)
/* INTC */
//#define I_STAT 0x1000f000
//#define I_MASK 0x1000f010
/* TOOL putchar */
// .byte KPUTCHAR (0x1000f180)
/* SIF */
// #define SB_SMFLG (0x1000f230)
/* DMAC */
#define D_ENABLER *((volatile unsigned int *)0x1000f520)
#define D_ENABLEW *((volatile unsigned int *)0x1000f590)
/* VU Mem */
#define VUMicroMem0 *((volatile unsigned int *)0x11000000)
#define VUMem0 *((volatile unsigned int *)0x11004000)
#define VUMicroMem1 *((volatile unsigned int *)0x11008000)
#define VUMem1 *((volatile unsigned int *)0x1100c000)
/* GS Privileged */
#define GS_PMODE *((volatile unsigned long *)0x12000000)
#define GS_SMODE1 *((volatile unsigned long *)0x12000010)
#define GS_SMODE2 *((volatile unsigned long *)0x12000020)
#define GS_SRFSH *((volatile unsigned long *)0x12000030)
#define GS_SYNCH1 *((volatile unsigned long *)0x12000040)
#define GS_SYNCH2 *((volatile unsigned long *)0x12000050)
#define GS_SYNCV *((volatile unsigned long *)0x12000060)
#define GS_DISPFB1 *((volatile unsigned long *)0x12000070)
#define GS_DISPLAY1 *((volatile unsigned long *)0x12000080)
#define GS_DISPFB2 *((volatile unsigned long *)0x12000090)
#define GS_DISPLAY2 *((volatile unsigned long *)0x120000a0)
#define GS_EXTBUF *((volatile unsigned long *)0x120000b0)
#define GS_EXTDATA *((volatile unsigned long *)0x120000c0)
#define GS_EXTWRITE *((volatile unsigned long *)0x120000d0)
#define GS_BGCOLOR *((volatile unsigned long *)0x120000e0)
#define GS_CSR *((volatile unsigned long *)0x12001000)
#define GS_IMR *((volatile unsigned long *)0x12001010)
#define GS_BUSDIR *((volatile unsigned long *)0x12001040)
#define GS_SIGLBLID *((volatile unsigned long *)0x12001080)
/* GS General */
#define GS_PRIM 0x00
#define GS_RGBAQ 0x01
#define GS_ST 0x02
#define GS_UV 0x03
#define GS_XYZF2 0x04
#define GS_XYZ2 0x05
#define GS_TEX0_1 0x06
#define GS_TEX0_2 0x07
#define GS_CLAMP_1 0x08
#define GS_CLAMP_2 0x09
#define GS_FOG 0x0a
#define GS_XYZF3 0x0c
#define GS_XYZ3 0x0d
#define GS_AD 0x0e
#define GS_TEX1_1 0x14
#define GS_TEX1_2 0x15
#define GS_TEX2_1 0x16
#define GS_TEX2_2 0x17
#define GS_XYOFFSET_1 0x18
#define GS_XYOFFSET_2 0x19
#define GS_PRMODECONT 0x1a
#define GS_PRMODE 0x1b
#define GS_TEXCLUT 0x1c
#define GS_SCANMSK 0x22
#define GS_MIPTBP1_1 0x34
#define GS_MIPTBP1_2 0x35
#define GS_MIPTBP2_1 0x36
#define GS_MIPTBP2_2 0x37
#define GS_TEXA 0x3b
#define GS_FOGCOL 0x3d
#define GS_TEXFLUSH 0x3f
#define GS_SCISSOR_1 0x40
#define GS_SCISSOR_2 0x41
#define GS_ALPHA_1 0x42
#define GS_ALPHA_2 0x43
#define GS_DIMX 0x44
#define GS_DTHE 0x45
#define GS_COLCLAMP 0x46
#define GS_TEST_1 0x47
#define GS_TEST_2 0x48
#define GS_PABE 0x49
#define GS_FBA_1 0x4a
#define GS_FBA_2 0x4b
#define GS_FRAME_1 0x4c
#define GS_FRAME_2 0x4d
#define GS_ZBUF_1 0x4e
#define GS_ZBUF_2 0x4f
#define GS_BITBLTBUF 0x50
#define GS_TRXPOS 0x51
#define GS_TRXREG 0x52
#define GS_TRXDIR 0x53
#define GS_HWREG 0x54
#define GS_SIGNAL 0x60
#define GS_FINISH 0x61
#define GS_LABEL 0x62
#endif
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#ifndef PS2REGS_H
#define PS2REGS_H
/* TIMERS */
#define T0_COUNT *((volatile unsigned int *)0x10000000)
#define T0_MODE *((volatile unsigned short *)0x10000010)
#define T0_COMP *((volatile unsigned short *)0x10000020)
#define T0_HOLD *((volatile unsigned short *)0x10000030)
#define T1_COUNT *((volatile unsigned int *)0x10000800)
#define T1_MODE *((volatile unsigned short *)0x10000810)
#define T1_COMP *((volatile unsigned short *)0x10000820)
#define T1_HOLD *((volatile unsigned short *)0x10000830)
#define T2_COUNT *((volatile unsigned int *)0x10001000)
#define T2_MODE *((volatile unsigned short *)0x10001010)
#define T2_COMP *((volatile unsigned short *)0x10001020)
#define T3_COUNT *((volatile unsigned int *)0x10001800)
#define T3_MODE *((volatile unsigned short *)0x10001810)
#define T3_COMP *((volatile unsigned short *)0x10001820)
/* IPU */
#define IPU_CMD *((volatile unsigned long *)0x10002000)
#define IPU_CTRL *((volatile unsigned int *)0x10002010)
#define IPU_BP *((volatile unsigned int *)0x10002020)
#define IPU_TOP *((volatile unsigned long *)0x10002030)
/* GIF */
#define GIF_CTRL *((volatile unsigned int *)0x10003000)
#define GIF_MODE *((volatile unsigned int *)0x10003010)
#define GIF_STAT *((volatile unsigned int *)0x10003020)
#define GIF_TAG0 *((volatile unsigned int *)0x10003040)
#define GIF_TAG1 *((volatile unsigned int *)0x10003050)
#define GIF_TAG2 *((volatile unsigned int *)0x10003060)
#define GIF_TAG3 *((volatile unsigned int *)0x10003070)
#define GIF_CNT *((volatile unsigned int *)0x10003080)
#define GIF_P3CNT *((volatile unsigned int *)0x10003090)
#define GIF_P3TAG *((volatile unsigned int *)0x100030a0)
/* VIF */
#define VIF0_STAT *((volatile unsigned int *)0x10003800)
#define VIF0_FBRST *((volatile unsigned int *)0x10003810)
#define VIF0_ERR *((volatile unsigned int *)0x10003820)
#define VIF0_MARK *((volatile unsigned int *)0x10003830)
#define VIF0_CYCLE *((volatile unsigned int *)0x10003840)
#define VIF0_MODE *((volatile unsigned int *)0x10003850)
#define VIF0_NUM *((volatile unsigned int *)0x10003860)
#define VIF0_MASK *((volatile unsigned int *)0x10003870)
#define VIF0_CODE *((volatile unsigned int *)0x10003880)
#define VIF0_ITOPS *((volatile unsigned int *)0x10003890)
#define VIF0_ITOP *((volatile unsigned int *)0x100038d0)
#define VIF0_R0 *((volatile unsigned int *)0x10003900)
#define VIF0_R1 *((volatile unsigned int *)0x10003910)
#define VIF0_R2 *((volatile unsigned int *)0x10003920)
#define VIF0_R3 *((volatile unsigned int *)0x10003930)
#define VIF0_C0 *((volatile unsigned int *)0x10003940)
#define VIF0_C1 *((volatile unsigned int *)0x10003950)
#define VIF0_C2 *((volatile unsigned int *)0x10003960)
#define VIF0_C3 *((volatile unsigned int *)0x10003970)
#define VIF1_STAT *((volatile unsigned int *)0x10003c00)
#define VIF1_FBRST *((volatile unsigned int *)0x10003c10)
#define VIF1_ERR *((volatile unsigned int *)0x10003c20)
#define VIF1_MARK *((volatile unsigned int *)0x10003c30)
#define VIF1_CYCLE *((volatile unsigned int *)0x10003c40)
#define VIF1_MODE *((volatile unsigned int *)0x10003c50)
#define VIF1_NUM *((volatile unsigned int *)0x10003c60)
#define VIF1_MASK *((volatile unsigned int *)0x10003c70)
#define VIF1_CODE *((volatile unsigned int *)0x10003c80)
#define VIF1_ITOPS *((volatile unsigned int *)0x10003c90)
#define VIF1_BASE *((volatile unsigned int *)0x10003ca0)
#define VIF1_OFST *((volatile unsigned int *)0x10003cb0)
#define VIF1_TOPS *((volatile unsigned int *)0x10003cc0)
#define VIF1_ITOP *((volatile unsigned int *)0x10003cd0)
#define VIF1_TOP *((volatile unsigned int *)0x10003ce0)
#define VIF1_R0 *((volatile unsigned int *)0x10003d00)
#define VIF1_R1 *((volatile unsigned int *)0x10003d10)
#define VIF1_R2 *((volatile unsigned int *)0x10003d20)
#define VIF1_R3 *((volatile unsigned int *)0x10003d30)
#define VIF1_C0 *((volatile unsigned int *)0x10003d40)
#define VIF1_C1 *((volatile unsigned int *)0x10003d50)
#define VIF1_C2 *((volatile unsigned int *)0x10003d60)
#define VIF1_C3 *((volatile unsigned int *)0x10003d70)
/* FIFO */
//#define VIF0_FIFO(write) *((volatile unsigned int128 *)0x10004000)
//#define VIF1_FIFO(read/write) *((volatile unsigned int128 *)0x10005000)
//#define GIF_FIFO(write) *((volatile unsigned int128 *)0x10006000)
//#define IPU_out_FIFO(read) *((volatile unsigned int128 *)0x10007000)
//#define IPU_in_FIFO(write) *((volatile unsigned int128 *)0x10007010)
/* DMAC */
#define CHCR 0x00
#define MADR 0x04
#define QWC 0x08
#define TADR 0x0C
#define ASR0 0x10
#define ASR1 0x14
#define DMA0 ((volatile unsigned int *)0x10008000)
#define DMA1 ((volatile unsigned int *)0x10009000)
#define DMA2 ((volatile unsigned int *)0x1000a000)
#define DMA3 ((volatile unsigned int *)0x1000b000)
#define DMA4 ((volatile unsigned int *)0x1000b400)
#define DMA5 ((volatile unsigned int *)0x1000c000)
#define DMA6 ((volatile unsigned int *)0x1000c400)
#define DMA7 ((volatile unsigned int *)0x1000c800)
#define DMA8 ((volatile unsigned int *)0x1000d000)
#define DMA9 ((volatile unsigned int *)0x1000d400)
#define D0_CHCR *((volatile unsigned int *)0x10008000)
#define D0_MADR *((volatile unsigned int *)0x10008010)
#define D0_QWC *((volatile unsigned int *)0x10008020)
#define D0_TADR *((volatile unsigned int *)0x10008030)
#define D0_ASR0 *((volatile unsigned int *)0x10008040)
#define D0_ASR1 *((volatile unsigned int *)0x10008050)
#define D1_CHCR *((volatile unsigned int *)0x10009000)
#define D1_MADR *((volatile unsigned int *)0x10009010)
#define D1_QWC *((volatile unsigned int *)0x10009020)
#define D1_TADR *((volatile unsigned int *)0x10009030)
#define D1_ASR0 *((volatile unsigned int *)0x10009040)
#define D1_ASR1 *((volatile unsigned int *)0x10009050)
#define D2_CHCR *((volatile unsigned int *)0x1000a000)
#define D2_MADR *((volatile unsigned int *)0x1000a010)
#define D2_QWC *((volatile unsigned int *)0x1000a020)
#define D2_TADR *((volatile unsigned int *)0x1000a030)
#define D2_ASR0 *((volatile unsigned int *)0x1000a040)
#define D2_ASR1 *((volatile unsigned int *)0x1000a050)
#define D3_CHCR *((volatile unsigned int *)0x1000b000)
#define D3_MADR *((volatile unsigned int *)0x1000b010)
#define D3_QWC *((volatile unsigned int *)0x1000b020)
#define D4_CHCR *((volatile unsigned int *)0x1000b400)
#define D4_MADR *((volatile unsigned int *)0x1000b410)
#define D4_QWC *((volatile unsigned int *)0x1000b420)
#define D4_TADR *((volatile unsigned int *)0x1000b430)
#define D5_CHCR *((volatile unsigned int *)0x1000c000)
#define D5_MADR *((volatile unsigned int *)0x1000c010)
#define D5_QWC *((volatile unsigned int *)0x1000c020)
#define D6_CHCR *((volatile unsigned int *)0x1000c400)
#define D6_MADR *((volatile unsigned int *)0x1000c410)
#define D6_QWC *((volatile unsigned int *)0x1000c420)
#define D7_CHCR *((volatile unsigned int *)0x1000c800)
#define D7_MADR *((volatile unsigned int *)0x1000c810)
#define D7_QWC *((volatile unsigned int *)0x1000c820)
#define D8_CHCR *((volatile unsigned int *)0x1000d000)
#define D8_MADR *((volatile unsigned int *)0x1000d010)
#define D8_QWC *((volatile unsigned int *)0x1000d020)
#define D8_SADR *((volatile unsigned int *)0x1000d080)
#define D9_CHCR *((volatile unsigned int *)0x1000d400)
#define D9_MADR *((volatile unsigned int *)0x1000d410)
#define D9_QWC *((volatile unsigned int *)0x1000d420)
#define D9_TADR *((volatile unsigned int *)0x1000d430)
#define D9_SADR *((volatile unsigned int *)0x1000d480)
/* DMAC */
#define D_CTRL *((volatile unsigned int *)0x1000e000)
#define D_STAT *((volatile unsigned int *)0x1000e010)
#define D_PCR *((volatile unsigned int *)0x1000e020)
#define D_SQWC *((volatile unsigned int *)0x1000e030)
#define D_RBSR *((volatile unsigned int *)0x1000e040)
#define D_RBOR *((volatile unsigned int *)0x1000e050)
#define D_STADR *((volatile unsigned int *)0x1000e060)
/* INTC */
//#define I_STAT 0x1000f000
//#define I_MASK 0x1000f010
/* TOOL putchar */
// .byte KPUTCHAR (0x1000f180)
/* SIF */
// #define SB_SMFLG (0x1000f230)
/* DMAC */
#define D_ENABLER *((volatile unsigned int *)0x1000f520)
#define D_ENABLEW *((volatile unsigned int *)0x1000f590)
/* VU Mem */
#define VUMicroMem0 *((volatile unsigned int *)0x11000000)
#define VUMem0 *((volatile unsigned int *)0x11004000)
#define VUMicroMem1 *((volatile unsigned int *)0x11008000)
#define VUMem1 *((volatile unsigned int *)0x1100c000)
/* GS Privileged */
#define GS_PMODE *((volatile unsigned long *)0x12000000)
#define GS_SMODE1 *((volatile unsigned long *)0x12000010)
#define GS_SMODE2 *((volatile unsigned long *)0x12000020)
#define GS_SRFSH *((volatile unsigned long *)0x12000030)
#define GS_SYNCH1 *((volatile unsigned long *)0x12000040)
#define GS_SYNCH2 *((volatile unsigned long *)0x12000050)
#define GS_SYNCV *((volatile unsigned long *)0x12000060)
#define GS_DISPFB1 *((volatile unsigned long *)0x12000070)
#define GS_DISPLAY1 *((volatile unsigned long *)0x12000080)
#define GS_DISPFB2 *((volatile unsigned long *)0x12000090)
#define GS_DISPLAY2 *((volatile unsigned long *)0x120000a0)
#define GS_EXTBUF *((volatile unsigned long *)0x120000b0)
#define GS_EXTDATA *((volatile unsigned long *)0x120000c0)
#define GS_EXTWRITE *((volatile unsigned long *)0x120000d0)
#define GS_BGCOLOR *((volatile unsigned long *)0x120000e0)
#define GS_CSR *((volatile unsigned long *)0x12001000)
#define GS_IMR *((volatile unsigned long *)0x12001010)
#define GS_BUSDIR *((volatile unsigned long *)0x12001040)
#define GS_SIGLBLID *((volatile unsigned long *)0x12001080)
/* GS General */
#define GS_PRIM 0x00
#define GS_RGBAQ 0x01
#define GS_ST 0x02
#define GS_UV 0x03
#define GS_XYZF2 0x04
#define GS_XYZ2 0x05
#define GS_TEX0_1 0x06
#define GS_TEX0_2 0x07
#define GS_CLAMP_1 0x08
#define GS_CLAMP_2 0x09
#define GS_FOG 0x0a
#define GS_XYZF3 0x0c
#define GS_XYZ3 0x0d
#define GS_AD 0x0e
#define GS_TEX1_1 0x14
#define GS_TEX1_2 0x15
#define GS_TEX2_1 0x16
#define GS_TEX2_2 0x17
#define GS_XYOFFSET_1 0x18
#define GS_XYOFFSET_2 0x19
#define GS_PRMODECONT 0x1a
#define GS_PRMODE 0x1b
#define GS_TEXCLUT 0x1c
#define GS_SCANMSK 0x22
#define GS_MIPTBP1_1 0x34
#define GS_MIPTBP1_2 0x35
#define GS_MIPTBP2_1 0x36
#define GS_MIPTBP2_2 0x37
#define GS_TEXA 0x3b
#define GS_FOGCOL 0x3d
#define GS_TEXFLUSH 0x3f
#define GS_SCISSOR_1 0x40
#define GS_SCISSOR_2 0x41
#define GS_ALPHA_1 0x42
#define GS_ALPHA_2 0x43
#define GS_DIMX 0x44
#define GS_DTHE 0x45
#define GS_COLCLAMP 0x46
#define GS_TEST_1 0x47
#define GS_TEST_2 0x48
#define GS_PABE 0x49
#define GS_FBA_1 0x4a
#define GS_FBA_2 0x4b
#define GS_FRAME_1 0x4c
#define GS_FRAME_2 0x4d
#define GS_ZBUF_1 0x4e
#define GS_ZBUF_2 0x4f
#define GS_BITBLTBUF 0x50
#define GS_TRXPOS 0x51
#define GS_TRXREG 0x52
#define GS_TRXDIR 0x53
#define GS_HWREG 0x54
#define GS_SIGNAL 0x60
#define GS_FINISH 0x61
#define GS_LABEL 0x62
#endif

View File

@ -1,73 +1,73 @@
//------------------------------------------------------------------------
// File: regs.h
// Author: Tony Saveski, t_saveski@yahoo.com
// Notes: Playstation 2 Register Definitions
//------------------------------------------------------------------------
#ifndef R5900_REGS_H
#define R5900_REGS_H
// MIPS CPU Registsers
#define zero $0 // Always 0
#define at $1 // Assembler temporary
#define v0 $2 // Function return
#define v1 $3 //
#define a0 $4 // Function arguments
#define a1 $5
#define a2 $6
#define a3 $7
#define t0 $8 // Temporaries. No need
#define t1 $9 // to preserve in your
#define t2 $10 // functions.
#define t3 $11
#define t4 $12
#define t5 $13
#define t6 $14
#define t7 $15
#define s0 $16 // Saved Temporaries.
#define s1 $17 // Make sure to restore
#define s2 $18 // to original value
#define s3 $19 // if your function
#define s4 $20 // changes their value.
#define s5 $21
#define s6 $22
#define s7 $23
#define t8 $24 // More Temporaries.
#define t9 $25
#define k0 $26 // Reserved for Kernel
#define k1 $27
#define gp $28 // Global Pointer
#define sp $29 // Stack Pointer
#define fp $30 // Frame Pointer
#define ra $31 // Function Return Address
// COP0
#define Index $0 // Index into the TLB array
#define Random $1 // Randomly generated index into the TLB array
#define EntryLo0 $2 // Low-order portion of the TLB entry for..
#define EntryLo1 $3 // Low-order portion of the TLB entry for
#define Context $4 // Pointer to page table entry in memory
#define PageMask $5 // Control for variable page size in TLB entries
#define Wired $6 // Controls the number of fixed ("wired") TLB entries
#define BadVAddr $8 // Address for the most recent address-related exception
#define Count $9 // Processor cycle count
#define EntryHi $10 // High-order portion of the TLB entry
#define Compare $11 // Timer interrupt control
#define Status $12 // Processor status and control
#define Cause $13 // Cause of last general exception
#define EPC $14 // Program counter at last exception
#define PRId $15 // Processor identification and revision
#define Config $16 // Configuration register
#define LLAddr $17 // Load linked address
#define WatchLo $18 // Watchpoint address Section 6.25 on
#define WatchHi $19 // Watchpoint control
#define Debug $23 // EJTAG Debug register
#define DEPC $24 // Program counter at last EJTAG debug exception
#define PerfCnt $25 // Performance counter interface
#define ErrCtl $26 // Parity/ECC error control and status
#define CacheErr $27 // Cache parity error control and status
#define TagLo $28 // Low-order portion of cache tag interface
#define TagHi $29 // High-order portion of cache tag interface
#define ErrorPC $30 // Program counter at last error
#define DEASVE $31 // EJTAG debug exception save register
#endif // R5900_REGS_H
//------------------------------------------------------------------------
// File: regs.h
// Author: Tony Saveski, t_saveski@yahoo.com
// Notes: Playstation 2 Register Definitions
//------------------------------------------------------------------------
#ifndef R5900_REGS_H
#define R5900_REGS_H
// MIPS CPU Registsers
#define zero $0 // Always 0
#define at $1 // Assembler temporary
#define v0 $2 // Function return
#define v1 $3 //
#define a0 $4 // Function arguments
#define a1 $5
#define a2 $6
#define a3 $7
#define t0 $8 // Temporaries. No need
#define t1 $9 // to preserve in your
#define t2 $10 // functions.
#define t3 $11
#define t4 $12
#define t5 $13
#define t6 $14
#define t7 $15
#define s0 $16 // Saved Temporaries.
#define s1 $17 // Make sure to restore
#define s2 $18 // to original value
#define s3 $19 // if your function
#define s4 $20 // changes their value.
#define s5 $21
#define s6 $22
#define s7 $23
#define t8 $24 // More Temporaries.
#define t9 $25
#define k0 $26 // Reserved for Kernel
#define k1 $27
#define gp $28 // Global Pointer
#define sp $29 // Stack Pointer
#define fp $30 // Frame Pointer
#define ra $31 // Function Return Address
// COP0
#define Index $0 // Index into the TLB array
#define Random $1 // Randomly generated index into the TLB array
#define EntryLo0 $2 // Low-order portion of the TLB entry for..
#define EntryLo1 $3 // Low-order portion of the TLB entry for
#define Context $4 // Pointer to page table entry in memory
#define PageMask $5 // Control for variable page size in TLB entries
#define Wired $6 // Controls the number of fixed ("wired") TLB entries
#define BadVAddr $8 // Address for the most recent address-related exception
#define Count $9 // Processor cycle count
#define EntryHi $10 // High-order portion of the TLB entry
#define Compare $11 // Timer interrupt control
#define Status $12 // Processor status and control
#define Cause $13 // Cause of last general exception
#define EPC $14 // Program counter at last exception
#define PRId $15 // Processor identification and revision
#define Config $16 // Configuration register
#define LLAddr $17 // Load linked address
#define WatchLo $18 // Watchpoint address Section 6.25 on
#define WatchHi $19 // Watchpoint control
#define Debug $23 // EJTAG Debug register
#define DEPC $24 // Program counter at last EJTAG debug exception
#define PerfCnt $25 // Performance counter interface
#define ErrCtl $26 // Parity/ECC error control and status
#define CacheErr $27 // Cache parity error control and status
#define TagLo $28 // Low-order portion of cache tag interface
#define TagHi $29 // High-order portion of cache tag interface
#define ErrorPC $30 // Program counter at last error
#define DEASVE $31 // EJTAG debug exception save register
#endif // R5900_REGS_H

View File

@ -1,42 +1,42 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#ifndef BYTEORDER_H
#define BYTEORDER_H
#include <tamtypes.h>
#ifdef BIG_ENDIAN
inline unsigned int ntohl(x) { return x; }
inline unsigned short ntohs(x) { return x; }
inline unsigned int ntohl(x) { return x; }
inline unsigned short ntohs(x) { return x; }
#else
// LITTLE_ENDIAN
inline unsigned int
htonl(unsigned int x)
{
return ((x & 0xff) << 24 ) |
((x & 0xff00) << 8 ) |
((x & 0xff0000) >> 8 ) |
((x & 0xff000000) >> 24 );
}
inline unsigned short
htons(unsigned short x)
{
return ((x & 0xff) << 8 ) | ((x & 0xff00) >> 8 );
}
#define ntohl htonl
#define ntohs htons
#endif
#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->s_addr = htonl(((u32)(a & 0xff) << 24) | ((u32)(b & 0xff) << 16 ) | ((u32)(c & 0xff) << 8) | (u32)(d & 0xff))
#endif /* BYTEORDER_H */
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#ifndef BYTEORDER_H
#define BYTEORDER_H
#include <tamtypes.h>
#ifdef BIG_ENDIAN
inline unsigned int ntohl(x) { return x; }
inline unsigned short ntohs(x) { return x; }
inline unsigned int ntohl(x) { return x; }
inline unsigned short ntohs(x) { return x; }
#else
// LITTLE_ENDIAN
inline unsigned int
htonl(unsigned int x)
{
return ((x & 0xff) << 24 ) |
((x & 0xff00) << 8 ) |
((x & 0xff0000) >> 8 ) |
((x & 0xff000000) >> 24 );
}
inline unsigned short
htons(unsigned short x)
{
return ((x & 0xff) << 8 ) | ((x & 0xff00) >> 8 );
}
#define ntohl htonl
#define ntohs htons
#endif
#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->s_addr = htonl(((u32)(a & 0xff) << 24) | ((u32)(b & 0xff) << 16 ) | ((u32)(c & 0xff) << 8) | (u32)(d & 0xff))
#endif /* BYTEORDER_H */

View File

@ -1,216 +1,216 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#define PS2E_FIO_OPEN_CMD 0xcc2e0101
#define PS2E_FIO_CLOSE_CMD 0xcc2e0102
#define PS2E_FIO_READ_CMD 0xcc2e0103
#define PS2E_FIO_WRITE_CMD 0xcc2e0104
#define PS2E_FIO_LSEEK_CMD 0xcc2e0105
#define PS2E_FIO_OPENDIR_CMD 0xcc2e0106
#define PS2E_FIO_CLOSEDIR_CMD 0xcc2e0107
#define PS2E_FIO_READDIR_CMD 0xcc2e0108
#define PS2E_FIO_REMOVE_CMD 0xcc2e0109
#define PS2E_FIO_MKDIR_CMD 0xcc2e010a
#define PS2E_FIO_RMDIR_CMD 0xcc2e010b
#define PS2E_FIO_PRINTF_CMD 0xcc2e0201
#define PS2E_FIO_MAX_PATH 256
#define PKO_MAX_PATH 256
// old stuff
typedef struct
{
unsigned int cmd;
unsigned short len;
} __attribute__((packed)) pko_pkt_hdr;
typedef struct
{
unsigned int cmd;
unsigned short len;
unsigned int retval;
} __attribute__((packed)) pko_pkt_file_rly;
typedef struct
{
unsigned int cmd;
unsigned short len;
int flags;
char path[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_open_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int fd;
} __attribute__((packed)) pko_pkt_close_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int fd;
int nbytes;
} __attribute__((packed)) pko_pkt_read_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int retval;
int nbytes;
} __attribute__((packed)) pko_pkt_read_rly;
typedef struct
{
unsigned int cmd;
unsigned short len;
int fd;
int nbytes;
} __attribute__((packed)) pko_pkt_write_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int fd;
int offset;
int whence;
} __attribute__((packed)) pko_pkt_lseek_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
char name[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_remove_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int mode;
char name[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_mkdir_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
char name[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_rmdir_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int fd;
} __attribute__((packed)) pko_pkt_dread_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int retval;
/* from io_common.h (fio_dirent_t) in ps2lib */
unsigned int mode;
unsigned int attr;
unsigned int size;
unsigned char ctime[8];
unsigned char atime[8];
unsigned char mtime[8];
unsigned int hisize;
char name[256];
} __attribute__((packed)) pko_pkt_dread_rly;
////
typedef struct
{
unsigned int cmd;
unsigned short len;
} __attribute__((packed)) pko_pkt_reset_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int argc;
char argv[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_execee_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int argc;
char argv[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_execiop_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
unsigned short size;
unsigned char file[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_gsexec_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
} __attribute__((packed)) pko_pkt_poweroff_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int vpu;
} __attribute__((packed)) pko_pkt_start_vu;
typedef struct
{
unsigned int cmd;
unsigned short len;
int vpu;
} __attribute__((packed)) pko_pkt_stop_vu;
typedef struct
{
unsigned int cmd;
unsigned short len;
unsigned int offset;
unsigned int size;
char argv[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_mem_io;
typedef struct {
unsigned int cmd;
unsigned short len;
int regs;
char argv[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_dump_regs;
typedef struct {
unsigned int cmd;
unsigned short len;
unsigned int regs[79];
} __attribute__((packed)) pko_pkt_send_regs;
typedef struct {
unsigned int cmd;
unsigned short len;
unsigned int base;
unsigned int width;
unsigned int height;
unsigned short psm;
} __attribute__((packed)) pko_pkt_screenshot;
#define PKO_MAX_WRITE_SEGMENT (1460 - sizeof(pko_pkt_write_req))
#define PKO_MAX_READ_SEGMENT (1460 - sizeof(pko_pkt_read_rly))
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#define PS2E_FIO_OPEN_CMD 0xcc2e0101
#define PS2E_FIO_CLOSE_CMD 0xcc2e0102
#define PS2E_FIO_READ_CMD 0xcc2e0103
#define PS2E_FIO_WRITE_CMD 0xcc2e0104
#define PS2E_FIO_LSEEK_CMD 0xcc2e0105
#define PS2E_FIO_OPENDIR_CMD 0xcc2e0106
#define PS2E_FIO_CLOSEDIR_CMD 0xcc2e0107
#define PS2E_FIO_READDIR_CMD 0xcc2e0108
#define PS2E_FIO_REMOVE_CMD 0xcc2e0109
#define PS2E_FIO_MKDIR_CMD 0xcc2e010a
#define PS2E_FIO_RMDIR_CMD 0xcc2e010b
#define PS2E_FIO_PRINTF_CMD 0xcc2e0201
#define PS2E_FIO_MAX_PATH 256
#define PKO_MAX_PATH 256
// old stuff
typedef struct
{
unsigned int cmd;
unsigned short len;
} __attribute__((packed)) pko_pkt_hdr;
typedef struct
{
unsigned int cmd;
unsigned short len;
unsigned int retval;
} __attribute__((packed)) pko_pkt_file_rly;
typedef struct
{
unsigned int cmd;
unsigned short len;
int flags;
char path[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_open_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int fd;
} __attribute__((packed)) pko_pkt_close_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int fd;
int nbytes;
} __attribute__((packed)) pko_pkt_read_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int retval;
int nbytes;
} __attribute__((packed)) pko_pkt_read_rly;
typedef struct
{
unsigned int cmd;
unsigned short len;
int fd;
int nbytes;
} __attribute__((packed)) pko_pkt_write_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int fd;
int offset;
int whence;
} __attribute__((packed)) pko_pkt_lseek_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
char name[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_remove_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int mode;
char name[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_mkdir_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
char name[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_rmdir_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int fd;
} __attribute__((packed)) pko_pkt_dread_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int retval;
/* from io_common.h (fio_dirent_t) in ps2lib */
unsigned int mode;
unsigned int attr;
unsigned int size;
unsigned char ctime[8];
unsigned char atime[8];
unsigned char mtime[8];
unsigned int hisize;
char name[256];
} __attribute__((packed)) pko_pkt_dread_rly;
////
typedef struct
{
unsigned int cmd;
unsigned short len;
} __attribute__((packed)) pko_pkt_reset_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int argc;
char argv[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_execee_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int argc;
char argv[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_execiop_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
unsigned short size;
unsigned char file[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_gsexec_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
} __attribute__((packed)) pko_pkt_poweroff_req;
typedef struct
{
unsigned int cmd;
unsigned short len;
int vpu;
} __attribute__((packed)) pko_pkt_start_vu;
typedef struct
{
unsigned int cmd;
unsigned short len;
int vpu;
} __attribute__((packed)) pko_pkt_stop_vu;
typedef struct
{
unsigned int cmd;
unsigned short len;
unsigned int offset;
unsigned int size;
char argv[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_mem_io;
typedef struct {
unsigned int cmd;
unsigned short len;
int regs;
char argv[PKO_MAX_PATH];
} __attribute__((packed)) pko_pkt_dump_regs;
typedef struct {
unsigned int cmd;
unsigned short len;
unsigned int regs[79];
} __attribute__((packed)) pko_pkt_send_regs;
typedef struct {
unsigned int cmd;
unsigned short len;
unsigned int base;
unsigned int width;
unsigned int height;
unsigned short psm;
} __attribute__((packed)) pko_pkt_screenshot;
#define PKO_MAX_WRITE_SEGMENT (1460 - sizeof(pko_pkt_write_req))
#define PKO_MAX_READ_SEGMENT (1460 - sizeof(pko_pkt_read_rly))

View File

@ -1,119 +1,119 @@
/*********************************************************************
* Copyright (C) 2004 Lukasz Bruun (mail@lukasz.dk)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include <tamtypes.h>
#include "irx_imports.h"
#include "hostlink.h"
#define BUFFER_SIZE sizeof(exception_frame_t)+4+4+128
u32 excep_buffer[BUFFER_SIZE/4] __attribute__ ((aligned(16)));
extern unsigned int pcsx2fioSendSifCmd(unsigned int cmd, void *src, unsigned int len); // lazy fix :)
extern int excepscrdump;
#define PKO_RPC_IOPEXCEP 12
// taken from smod by mrbrown, only use one function, didn't wanna include another irx.
/* Module info entry. */
typedef struct _smod_mod_info {
struct _smod_mod_info *next;
u8 *name;
u16 version;
u16 newflags; /* For modload shipped with games. */
u16 id;
u16 flags; /* I believe this is where flags are kept for BIOS versions. */
u32 entry; /* _start */
u32 gp;
u32 text_start;
u32 text_size;
u32 data_size;
u32 bss_size;
u32 unused1;
u32 unused2;
} smod_mod_info_t;
smod_mod_info_t *smod_get_next_mod(smod_mod_info_t *cur_mod)
{
/* If cur_mod is 0, return the head of the list (IOP address 0x800). */
if (!cur_mod) {
return (smod_mod_info_t *)0x800;
} else {
if (!cur_mod->next)
return 0;
else
return cur_mod->next;
}
return 0;
}
char* ExceptionGetModuleName(u32 epc, u32* r_epc)
{
smod_mod_info_t *mod_info = 0;
while((mod_info = smod_get_next_mod(mod_info)) != 0)
{
if((epc >= mod_info->text_start) && (epc <= (mod_info->text_start+mod_info->text_size)))
{
if(r_epc)
*r_epc = epc - mod_info->text_start;
return mod_info->name;
}
}
return 0;
}
static void excep_handler2(exception_frame_t *frame)
{
u32 r_epc; // relative epc
char *module_name;
u32 len;
u32* buffer = excep_buffer;
module_name = ExceptionGetModuleName(frame->epc, &r_epc);
len = strlen(module_name);
buffer[0] = 0x0d02beba; // reverse engineering..
buffer++;
memcpy(buffer, frame, BUFFER_SIZE);
buffer+= (sizeof(exception_frame_t)/4);
buffer[0] = r_epc;
buffer[1] = len;
buffer+=2;
memcpy(buffer, module_name, len+1);
//pcsx2fioSendSifCmd(PKO_RPC_IOPEXCEP, excep_buffer, BUFFER_SIZE);
}
static void excep_handler(exception_type_t type, exception_frame_t *frame)
{
excep_handler2(frame); // Don't know why this works, but keeps iop alive.
}
////////////////////////////////////////////////////////////////////////
// Installs iop exception handlers for the 'usual' exceptions..
void installExceptionHandlers(void)
{
s32 i;
for(i=1; i < 8; i++)
set_exception_handler(i, excep_handler);
for(i=10; i < 13; i++)
set_exception_handler(i, excep_handler);
}
/*********************************************************************
* Copyright (C) 2004 Lukasz Bruun (mail@lukasz.dk)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include <tamtypes.h>
#include "irx_imports.h"
#include "hostlink.h"
#define BUFFER_SIZE sizeof(exception_frame_t)+4+4+128
u32 excep_buffer[BUFFER_SIZE/4] __attribute__ ((aligned(16)));
extern unsigned int pcsx2fioSendSifCmd(unsigned int cmd, void *src, unsigned int len); // lazy fix :)
extern int excepscrdump;
#define PKO_RPC_IOPEXCEP 12
// taken from smod by mrbrown, only use one function, didn't wanna include another irx.
/* Module info entry. */
typedef struct _smod_mod_info {
struct _smod_mod_info *next;
u8 *name;
u16 version;
u16 newflags; /* For modload shipped with games. */
u16 id;
u16 flags; /* I believe this is where flags are kept for BIOS versions. */
u32 entry; /* _start */
u32 gp;
u32 text_start;
u32 text_size;
u32 data_size;
u32 bss_size;
u32 unused1;
u32 unused2;
} smod_mod_info_t;
smod_mod_info_t *smod_get_next_mod(smod_mod_info_t *cur_mod)
{
/* If cur_mod is 0, return the head of the list (IOP address 0x800). */
if (!cur_mod) {
return (smod_mod_info_t *)0x800;
} else {
if (!cur_mod->next)
return 0;
else
return cur_mod->next;
}
return 0;
}
char* ExceptionGetModuleName(u32 epc, u32* r_epc)
{
smod_mod_info_t *mod_info = 0;
while((mod_info = smod_get_next_mod(mod_info)) != 0)
{
if((epc >= mod_info->text_start) && (epc <= (mod_info->text_start+mod_info->text_size)))
{
if(r_epc)
*r_epc = epc - mod_info->text_start;
return mod_info->name;
}
}
return 0;
}
static void excep_handler2(exception_frame_t *frame)
{
u32 r_epc; // relative epc
char *module_name;
u32 len;
u32* buffer = excep_buffer;
module_name = ExceptionGetModuleName(frame->epc, &r_epc);
len = strlen(module_name);
buffer[0] = 0x0d02beba; // reverse engineering..
buffer++;
memcpy(buffer, frame, BUFFER_SIZE);
buffer+= (sizeof(exception_frame_t)/4);
buffer[0] = r_epc;
buffer[1] = len;
buffer+=2;
memcpy(buffer, module_name, len+1);
//pcsx2fioSendSifCmd(PKO_RPC_IOPEXCEP, excep_buffer, BUFFER_SIZE);
}
static void excep_handler(exception_type_t type, exception_frame_t *frame)
{
excep_handler2(frame); // Don't know why this works, but keeps iop alive.
}
////////////////////////////////////////////////////////////////////////
// Installs iop exception handlers for the 'usual' exceptions..
void installExceptionHandlers(void)
{
s32 i;
for(i=1; i < 8; i++)
set_exception_handler(i, excep_handler);
for(i=10; i < 13; i++)
set_exception_handler(i, excep_handler);
}

View File

@ -1,13 +1,13 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#ifndef _EXCEPTION_H_
#define _EXCEPTION_H_
void installExceptionHandlers(void);
#endif
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#ifndef _EXCEPTION_H_
#define _EXCEPTION_H_
void installExceptionHandlers(void);
#endif

View File

@ -1,28 +1,28 @@
/*
* irx_imports.h - Defines all IRX imports.
*
* Copyright (c) 2003 Marcus R. Brown <mrbrown@0xd6.org>
*
* See the file LICENSE included with this distribution for licensing terms.
*/
#ifndef IOP_IRX_IMPORTS_H
#define IOP_IRX_IMPORTS_H
#include "irx.h"
/* Please keep these in alphabetical order! */
#include "intrman.h"
#include "ioman.h"
#include "ioptrap.h"
#include "loadcore.h"
#include "modload.h"
#include "sifcmd.h"
#include "sifman.h"
#include "stdio.h"
#include "sysclib.h"
#include "thbase.h"
#include "thsemap.h"
#endif /* IOP_IRX_IMPORTS_H */
/*
* irx_imports.h - Defines all IRX imports.
*
* Copyright (c) 2003 Marcus R. Brown <mrbrown@0xd6.org>
*
* See the file LICENSE included with this distribution for licensing terms.
*/
#ifndef IOP_IRX_IMPORTS_H
#define IOP_IRX_IMPORTS_H
#include "irx.h"
/* Please keep these in alphabetical order! */
#include "intrman.h"
#include "ioman.h"
#include "ioptrap.h"
#include "loadcore.h"
#include "modload.h"
#include "sifcmd.h"
#include "sifman.h"
#include "stdio.h"
#include "sysclib.h"
#include "thbase.h"
#include "thsemap.h"
#endif /* IOP_IRX_IMPORTS_H */

View File

@ -1,230 +1,230 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
// Fu*k knows why net_fio & net_fsys are separated..
#include <types.h>
#include <ioman.h>
#include <sysclib.h>
#include <stdio.h>
#include <thbase.h>
#include <io_common.h>
#include "net_fio.h"
#include "hostlink.h"
#define PACKET_MAXSIZE 1024
static int send_packet[PACKET_MAXSIZE] __attribute__((aligned(16)));
#ifdef DEBUG
#define dbgprintf(args...) printf(args)
#else
#define dbgprintf(args...) do { } while(0)
#endif
//----------------------------------------------------------------------
//
#define PCSX2_FIO_BASE ((volatile unsigned int*)0x1d000800)
#define PCSX2_FIO_RDID (PCSX2_FIO_BASE + 0) // [f0] on read: returns the FIO magic number 'E2SP'
#define PCSX2_FIO_WCMD (PCSX2_FIO_BASE + 0) // [f0] on write: executes a command (usually "call function")
#define PCSX2_FIO_DLEN (PCSX2_FIO_BASE + 1) // [f4] write only: length of params data
#define PCSX2_FIO_DPTR (PCSX2_FIO_BASE + 2) // [f8] write only: mem address of params data
#define PCSX2_FIO_WFID (PCSX2_FIO_BASE + 3) // [fc] on write: function ID
#define PCSX2_FIO_RRET (PCSX2_FIO_BASE + 3) // [fc] on read: return value of the function
#define PCSX2_FIO_CMD_CALL 1
int pcsx2fio_device_exists()
{
return (*PCSX2_FIO_RDID == 'E2SP'); // PS2E
}
int pcsx2fio_set_call(unsigned int func_id, void* params, int params_length)
{
*PCSX2_FIO_DLEN = params_length;
*PCSX2_FIO_DPTR = (int)params;
*PCSX2_FIO_WFID = func_id;
*PCSX2_FIO_WCMD = PCSX2_FIO_CMD_CALL;
return *PCSX2_FIO_RRET;
}
char *strcpy(char *dest, const char *src)
{
while(*src)
{
*(dest++) = *(src++);
}
*(dest) = 0;
return dest;
}
//----------------------------------------------------------------------
//
void
pcsx2fio_close_fsys(void)
{
}
//----------------------------------------------------------------------
//
int pcsx2fio_open_file(char *path, int flags)
{
send_packet[0] = flags;
strcpy((char*)(send_packet+1),path);
int length = strlen(path) + 4;
int ret = pcsx2fio_set_call(PS2E_FIO_OPEN_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_close_file(int fd)
{
send_packet[0] = fd;
int length = 4;
int ret = pcsx2fio_set_call(PS2E_FIO_CLOSE_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_lseek_file(int fd, unsigned int offset, int whence)
{
send_packet[0] = fd;
send_packet[1] = offset;
send_packet[2] = whence;
send_packet[3] = 0;
int length = 12;
int ret = pcsx2fio_set_call(PS2E_FIO_LSEEK_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_write_file(int fd, char *buf, int _length)
{
send_packet[0] = fd;
send_packet[1] = (int)buf;
send_packet[2] = _length;
send_packet[3] = 0;
int length = 12;
int ret = pcsx2fio_set_call(PS2E_FIO_WRITE_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_read_file(int fd, char *buf, int _length)
{
send_packet[0] = fd;
send_packet[1] = (int)buf;
send_packet[2] = _length;
send_packet[3] = 0;
int length = 12;
int ret = pcsx2fio_set_call(PS2E_FIO_READ_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_remove(char *name)
{
strcpy((char*)(send_packet+0),name);
int length = strlen(name);
int ret = pcsx2fio_set_call(PS2E_FIO_REMOVE_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_mkdir(char *name, int mode)
{
send_packet[0] = mode;
strcpy((char*)(send_packet+1),name);
int length = strlen(name) + 4;
int ret = pcsx2fio_set_call(PS2E_FIO_MKDIR_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_rmdir(char *name)
{
strcpy((char*)(send_packet+0),name);
int length = strlen(name);
int ret = pcsx2fio_set_call(PS2E_FIO_RMDIR_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_open_dir(char *path)
{
strcpy((char*)(send_packet+0),path);
int length = strlen(path);
int ret = pcsx2fio_set_call(PS2E_FIO_OPENDIR_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_read_dir(int fd, void *buf)
{
send_packet[0] = fd;
send_packet[1] = (int)buf;
int length = 8;
int ret = pcsx2fio_set_call(PS2E_FIO_READDIR_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_close_dir(int fd)
{
send_packet[0] = fd;
int length = 4;
int ret = pcsx2fio_set_call(PS2E_FIO_CLOSEDIR_CMD, send_packet, length);
return ret;
}
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
// Fu*k knows why net_fio & net_fsys are separated..
#include <types.h>
#include <ioman.h>
#include <sysclib.h>
#include <stdio.h>
#include <thbase.h>
#include <io_common.h>
#include "net_fio.h"
#include "hostlink.h"
#define PACKET_MAXSIZE 1024
static int send_packet[PACKET_MAXSIZE] __attribute__((aligned(16)));
#ifdef DEBUG
#define dbgprintf(args...) printf(args)
#else
#define dbgprintf(args...) do { } while(0)
#endif
//----------------------------------------------------------------------
//
#define PCSX2_FIO_BASE ((volatile unsigned int*)0x1d000800)
#define PCSX2_FIO_RDID (PCSX2_FIO_BASE + 0) // [f0] on read: returns the FIO magic number 'E2SP'
#define PCSX2_FIO_WCMD (PCSX2_FIO_BASE + 0) // [f0] on write: executes a command (usually "call function")
#define PCSX2_FIO_DLEN (PCSX2_FIO_BASE + 1) // [f4] write only: length of params data
#define PCSX2_FIO_DPTR (PCSX2_FIO_BASE + 2) // [f8] write only: mem address of params data
#define PCSX2_FIO_WFID (PCSX2_FIO_BASE + 3) // [fc] on write: function ID
#define PCSX2_FIO_RRET (PCSX2_FIO_BASE + 3) // [fc] on read: return value of the function
#define PCSX2_FIO_CMD_CALL 1
int pcsx2fio_device_exists()
{
return (*PCSX2_FIO_RDID == 'E2SP'); // PS2E
}
int pcsx2fio_set_call(unsigned int func_id, void* params, int params_length)
{
*PCSX2_FIO_DLEN = params_length;
*PCSX2_FIO_DPTR = (int)params;
*PCSX2_FIO_WFID = func_id;
*PCSX2_FIO_WCMD = PCSX2_FIO_CMD_CALL;
return *PCSX2_FIO_RRET;
}
char *strcpy(char *dest, const char *src)
{
while(*src)
{
*(dest++) = *(src++);
}
*(dest) = 0;
return dest;
}
//----------------------------------------------------------------------
//
void
pcsx2fio_close_fsys(void)
{
}
//----------------------------------------------------------------------
//
int pcsx2fio_open_file(char *path, int flags)
{
send_packet[0] = flags;
strcpy((char*)(send_packet+1),path);
int length = strlen(path) + 4;
int ret = pcsx2fio_set_call(PS2E_FIO_OPEN_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_close_file(int fd)
{
send_packet[0] = fd;
int length = 4;
int ret = pcsx2fio_set_call(PS2E_FIO_CLOSE_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_lseek_file(int fd, unsigned int offset, int whence)
{
send_packet[0] = fd;
send_packet[1] = offset;
send_packet[2] = whence;
send_packet[3] = 0;
int length = 12;
int ret = pcsx2fio_set_call(PS2E_FIO_LSEEK_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_write_file(int fd, char *buf, int _length)
{
send_packet[0] = fd;
send_packet[1] = (int)buf;
send_packet[2] = _length;
send_packet[3] = 0;
int length = 12;
int ret = pcsx2fio_set_call(PS2E_FIO_WRITE_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_read_file(int fd, char *buf, int _length)
{
send_packet[0] = fd;
send_packet[1] = (int)buf;
send_packet[2] = _length;
send_packet[3] = 0;
int length = 12;
int ret = pcsx2fio_set_call(PS2E_FIO_READ_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_remove(char *name)
{
strcpy((char*)(send_packet+0),name);
int length = strlen(name);
int ret = pcsx2fio_set_call(PS2E_FIO_REMOVE_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_mkdir(char *name, int mode)
{
send_packet[0] = mode;
strcpy((char*)(send_packet+1),name);
int length = strlen(name) + 4;
int ret = pcsx2fio_set_call(PS2E_FIO_MKDIR_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_rmdir(char *name)
{
strcpy((char*)(send_packet+0),name);
int length = strlen(name);
int ret = pcsx2fio_set_call(PS2E_FIO_RMDIR_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_open_dir(char *path)
{
strcpy((char*)(send_packet+0),path);
int length = strlen(path);
int ret = pcsx2fio_set_call(PS2E_FIO_OPENDIR_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_read_dir(int fd, void *buf)
{
send_packet[0] = fd;
send_packet[1] = (int)buf;
int length = 8;
int ret = pcsx2fio_set_call(PS2E_FIO_READDIR_CMD, send_packet, length);
return ret;
}
//----------------------------------------------------------------------
//
int pcsx2fio_close_dir(int fd)
{
send_packet[0] = fd;
int length = 4;
int ret = pcsx2fio_set_call(PS2E_FIO_CLOSEDIR_CMD, send_packet, length);
return ret;
}

View File

@ -1,33 +1,33 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#ifndef _NETFIO_H_
#define _NETFIO_H_
int pcsx2fio_device_exists();
int pcsx2fio_set_call(unsigned int func_id, void* params, int params_length);
int pcsx2fio_file_serv(void *arg);
int pcsx2fio_recv_bytes(int fd, char *buf, int bytes);
int pcsx2fio_accept_pkt(int fd, char *buf, int len, int pkt_type);
int pcsx2fio_open_file(char *path, int flags);
int pcsx2fio_close_file(int fd);
int pcsx2fio_read_file(int fd, char *buf, int length);
int pcsx2fio_write_file(int fd, char *buf, int length);
int pcsx2fio_lseek_file(int fd, unsigned int offset, int whence);
void pcsx2fio_close_socket(void);
void pcsx2fio_close_fsys(void);
int pcsx2fio_remove(char *name);
int pcsx2fio_mkdir(char *name, int mode);
int pcsx2fio_rmdir(char *name);
int pcsx2fio_open_dir(char *path);
int pcsx2fio_read_dir(int fd, void *buf);
int pcsx2fio_close_dir(int fd);
#endif
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#ifndef _NETFIO_H_
#define _NETFIO_H_
int pcsx2fio_device_exists();
int pcsx2fio_set_call(unsigned int func_id, void* params, int params_length);
int pcsx2fio_file_serv(void *arg);
int pcsx2fio_recv_bytes(int fd, char *buf, int bytes);
int pcsx2fio_accept_pkt(int fd, char *buf, int len, int pkt_type);
int pcsx2fio_open_file(char *path, int flags);
int pcsx2fio_close_file(int fd);
int pcsx2fio_read_file(int fd, char *buf, int length);
int pcsx2fio_write_file(int fd, char *buf, int length);
int pcsx2fio_lseek_file(int fd, unsigned int offset, int whence);
void pcsx2fio_close_socket(void);
void pcsx2fio_close_fsys(void);
int pcsx2fio_remove(char *name);
int pcsx2fio_mkdir(char *name, int mode);
int pcsx2fio_rmdir(char *name);
int pcsx2fio_open_dir(char *path);
int pcsx2fio_read_dir(int fd, void *buf);
int pcsx2fio_close_dir(int fd);
#endif

View File

@ -1,306 +1,306 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include <types.h>
#include <thbase.h>
#include <ioman.h>
#include <sysclib.h>
#include <stdio.h>
#include <intrman.h>
#include <loadcore.h>
#include <thsemap.h>
#include "net_fio.h"
#ifdef DEBUG
#define dbgprintf(args...) printf(args)
#else
#define dbgprintf(args...) do { } while(0)
#endif
static char fsname[] = "host";
////////////////////////////////////////////////////////////////////////
//static iop_device_t fsys_driver;
/* File desc struct is probably larger than this, but we only
* need to access the word @ offset 0x0C (in which we put our identifier)
*/
struct filedesc_info
{
int unkn0;
int unkn4;
int device_id; // the X in hostX
int own_fd;
};
////////////////////////////////////////////////////////////////////////
/* We need(?) to protect the net access, so the server doesn't get
* confused if two processes calls a fsys func at the same time
*/
static int fsys_sema;
static int fsys_pid = 0;
//static iop_device_t fsys_driver;
////////////////////////////////////////////////////////////////////////
static int dummy5()
{
printf("dummy function called\n");
return -5;
}
////////////////////////////////////////////////////////////////////////
static void fsysInit(iop_device_t *driver)
{
}
////////////////////////////////////////////////////////////////////////
static int fsysDestroy(void)
{
WaitSema(fsys_sema);
pcsx2fio_close_fsys();
// ExitDeleteThread(fsys_pid);
SignalSema(fsys_sema);
DeleteSema(fsys_sema);
return 0;
}
////////////////////////////////////////////////////////////////////////
static int fsysOpen( int fd, char *name, int mode)
{
struct filedesc_info *fd_info;
int fsys_fd;
dbgprintf("fsysOpen..\n");
dbgprintf(" fd: %x, name: %s, mode: %d\n\n", fd, name, mode);
fd_info = (struct filedesc_info *)fd;
WaitSema(fsys_sema);
fsys_fd = pcsx2fio_open_file(name, mode);
SignalSema(fsys_sema);
fd_info->own_fd = fsys_fd;
return fsys_fd;
}
////////////////////////////////////////////////////////////////////////
static int fsysClose( int fd)
{
struct filedesc_info *fd_info;
int ret;
dbgprintf("fsys_close..\n"
" fd: %x\n\n", fd);
fd_info = (struct filedesc_info *)fd;
WaitSema(fsys_sema);
ret = pcsx2fio_close_file(fd_info->own_fd);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysRead( int fd, char *buf, int size)
{
struct filedesc_info *fd_info;
int ret;
fd_info = (struct filedesc_info *)fd;
dbgprintf("fsysRead..."
" fd: %x\n"
" bf: %x\n"
" sz: %d\n"
" ow: %d\n\n", fd, (int)buf, size, fd_info->own_fd);
WaitSema(fsys_sema);
ret = pcsx2fio_read_file(fd_info->own_fd, buf, size);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysWrite( int fd, char *buf, int size)
{
struct filedesc_info *fd_info;
int ret;
dbgprintf("fsysWrite..."
" fd: %x\n", fd);
fd_info = (struct filedesc_info *)fd;
WaitSema(fsys_sema);
ret = pcsx2fio_write_file(fd_info->own_fd, buf, size);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysLseek( int fd, unsigned int offset, int whence)
{
struct filedesc_info *fd_info;
int ret;
dbgprintf("fsysLseek..\n"
" fd: %x\n"
" of: %x\n"
" wh: %x\n\n", fd, offset, whence);
fd_info = (struct filedesc_info *)fd;
WaitSema(fsys_sema);
ret = pcsx2fio_lseek_file(fd_info->own_fd, offset, whence);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysRemove(iop_file_t* file, char *name)
{
int ret;
dbgprintf("fsysRemove..\n");
dbgprintf(" name: %s\n\n", name);
WaitSema(fsys_sema);
ret = pcsx2fio_remove(name);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysMkdir(iop_file_t* file, char *name, int mode)
{
int ret;
dbgprintf("fsysMkdir..\n");
dbgprintf(" name: '%s'\n\n", name);
WaitSema(fsys_sema);
ret = pcsx2fio_mkdir(name, mode);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysRmdir(iop_file_t* file, char *name)
{
int ret;
dbgprintf("fsysRmdir..\n");
dbgprintf(" name: %s\n\n", name);
WaitSema(fsys_sema);
ret = pcsx2fio_rmdir(name);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysDopen(int fd, char *name)
{
struct filedesc_info *fd_info;
int fsys_fd;
dbgprintf("fsysDopen..\n");
dbgprintf(" fd: %x, name: %s\n\n", fd, name);
fd_info = (struct filedesc_info *)fd;
WaitSema(fsys_sema);
fsys_fd = pcsx2fio_open_dir(name);
SignalSema(fsys_sema);
fd_info->own_fd = fsys_fd;
return fsys_fd;
}
////////////////////////////////////////////////////////////////////////
static int fsysDread(int fd, void *buf)
{
struct filedesc_info *fd_info;
int ret;
fd_info = (struct filedesc_info *)fd;
dbgprintf("fsysDread..."
" fd: %x\n"
" bf: %x\n"
" ow: %d\n\n", fd, (int)buf, fd_info->own_fd);
WaitSema(fsys_sema);
ret = pcsx2fio_read_dir(fd_info->own_fd, buf);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysDclose(int fd)
{
struct filedesc_info *fd_info;
int ret;
dbgprintf("fsys_dclose..\n"
" fd: %x\n\n", fd);
fd_info = (struct filedesc_info *)fd;
WaitSema(fsys_sema);
ret = pcsx2fio_close_dir(fd_info->own_fd);
SignalSema(fsys_sema);
return ret;
}
iop_device_ops_t fsys_functarray = { (void *)fsysInit, (void *)fsysDestroy, (void *)dummy5,
(void *)fsysOpen, (void *)fsysClose, (void *)fsysRead,
(void *)fsysWrite, (void *)fsysLseek, (void *)dummy5,
(void *)fsysRemove, (void *)fsysMkdir, (void *)fsysRmdir,
(void *)fsysDopen, (void *)fsysDclose, (void *)fsysDread,
(void *)dummy5, (void *)dummy5 };
iop_device_t fsys_driver = { fsname, 16, 1, "fsys driver",
&fsys_functarray };
////////////////////////////////////////////////////////////////////////
// Entry point for mounting the file system
int fsysMount(void)
{
iop_sema_t sema_info;
sema_info.attr = 1;
sema_info.option = 0;
sema_info.initial = 1;
sema_info.max = 1;
fsys_sema = CreateSema(&sema_info);
DelDrv(fsname);
AddDrv(&fsys_driver);
return 0;
}
int fsysUnmount(void)
{
DelDrv(fsname);
return 0;
}
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include <types.h>
#include <thbase.h>
#include <ioman.h>
#include <sysclib.h>
#include <stdio.h>
#include <intrman.h>
#include <loadcore.h>
#include <thsemap.h>
#include "net_fio.h"
#ifdef DEBUG
#define dbgprintf(args...) printf(args)
#else
#define dbgprintf(args...) do { } while(0)
#endif
static char fsname[] = "host";
////////////////////////////////////////////////////////////////////////
//static iop_device_t fsys_driver;
/* File desc struct is probably larger than this, but we only
* need to access the word @ offset 0x0C (in which we put our identifier)
*/
struct filedesc_info
{
int unkn0;
int unkn4;
int device_id; // the X in hostX
int own_fd;
};
////////////////////////////////////////////////////////////////////////
/* We need(?) to protect the net access, so the server doesn't get
* confused if two processes calls a fsys func at the same time
*/
static int fsys_sema;
static int fsys_pid = 0;
//static iop_device_t fsys_driver;
////////////////////////////////////////////////////////////////////////
static int dummy5()
{
printf("dummy function called\n");
return -5;
}
////////////////////////////////////////////////////////////////////////
static void fsysInit(iop_device_t *driver)
{
}
////////////////////////////////////////////////////////////////////////
static int fsysDestroy(void)
{
WaitSema(fsys_sema);
pcsx2fio_close_fsys();
// ExitDeleteThread(fsys_pid);
SignalSema(fsys_sema);
DeleteSema(fsys_sema);
return 0;
}
////////////////////////////////////////////////////////////////////////
static int fsysOpen( int fd, char *name, int mode)
{
struct filedesc_info *fd_info;
int fsys_fd;
dbgprintf("fsysOpen..\n");
dbgprintf(" fd: %x, name: %s, mode: %d\n\n", fd, name, mode);
fd_info = (struct filedesc_info *)fd;
WaitSema(fsys_sema);
fsys_fd = pcsx2fio_open_file(name, mode);
SignalSema(fsys_sema);
fd_info->own_fd = fsys_fd;
return fsys_fd;
}
////////////////////////////////////////////////////////////////////////
static int fsysClose( int fd)
{
struct filedesc_info *fd_info;
int ret;
dbgprintf("fsys_close..\n"
" fd: %x\n\n", fd);
fd_info = (struct filedesc_info *)fd;
WaitSema(fsys_sema);
ret = pcsx2fio_close_file(fd_info->own_fd);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysRead( int fd, char *buf, int size)
{
struct filedesc_info *fd_info;
int ret;
fd_info = (struct filedesc_info *)fd;
dbgprintf("fsysRead..."
" fd: %x\n"
" bf: %x\n"
" sz: %d\n"
" ow: %d\n\n", fd, (int)buf, size, fd_info->own_fd);
WaitSema(fsys_sema);
ret = pcsx2fio_read_file(fd_info->own_fd, buf, size);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysWrite( int fd, char *buf, int size)
{
struct filedesc_info *fd_info;
int ret;
dbgprintf("fsysWrite..."
" fd: %x\n", fd);
fd_info = (struct filedesc_info *)fd;
WaitSema(fsys_sema);
ret = pcsx2fio_write_file(fd_info->own_fd, buf, size);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysLseek( int fd, unsigned int offset, int whence)
{
struct filedesc_info *fd_info;
int ret;
dbgprintf("fsysLseek..\n"
" fd: %x\n"
" of: %x\n"
" wh: %x\n\n", fd, offset, whence);
fd_info = (struct filedesc_info *)fd;
WaitSema(fsys_sema);
ret = pcsx2fio_lseek_file(fd_info->own_fd, offset, whence);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysRemove(iop_file_t* file, char *name)
{
int ret;
dbgprintf("fsysRemove..\n");
dbgprintf(" name: %s\n\n", name);
WaitSema(fsys_sema);
ret = pcsx2fio_remove(name);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysMkdir(iop_file_t* file, char *name, int mode)
{
int ret;
dbgprintf("fsysMkdir..\n");
dbgprintf(" name: '%s'\n\n", name);
WaitSema(fsys_sema);
ret = pcsx2fio_mkdir(name, mode);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysRmdir(iop_file_t* file, char *name)
{
int ret;
dbgprintf("fsysRmdir..\n");
dbgprintf(" name: %s\n\n", name);
WaitSema(fsys_sema);
ret = pcsx2fio_rmdir(name);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysDopen(int fd, char *name)
{
struct filedesc_info *fd_info;
int fsys_fd;
dbgprintf("fsysDopen..\n");
dbgprintf(" fd: %x, name: %s\n\n", fd, name);
fd_info = (struct filedesc_info *)fd;
WaitSema(fsys_sema);
fsys_fd = pcsx2fio_open_dir(name);
SignalSema(fsys_sema);
fd_info->own_fd = fsys_fd;
return fsys_fd;
}
////////////////////////////////////////////////////////////////////////
static int fsysDread(int fd, void *buf)
{
struct filedesc_info *fd_info;
int ret;
fd_info = (struct filedesc_info *)fd;
dbgprintf("fsysDread..."
" fd: %x\n"
" bf: %x\n"
" ow: %d\n\n", fd, (int)buf, fd_info->own_fd);
WaitSema(fsys_sema);
ret = pcsx2fio_read_dir(fd_info->own_fd, buf);
SignalSema(fsys_sema);
return ret;
}
////////////////////////////////////////////////////////////////////////
static int fsysDclose(int fd)
{
struct filedesc_info *fd_info;
int ret;
dbgprintf("fsys_dclose..\n"
" fd: %x\n\n", fd);
fd_info = (struct filedesc_info *)fd;
WaitSema(fsys_sema);
ret = pcsx2fio_close_dir(fd_info->own_fd);
SignalSema(fsys_sema);
return ret;
}
iop_device_ops_t fsys_functarray = { (void *)fsysInit, (void *)fsysDestroy, (void *)dummy5,
(void *)fsysOpen, (void *)fsysClose, (void *)fsysRead,
(void *)fsysWrite, (void *)fsysLseek, (void *)dummy5,
(void *)fsysRemove, (void *)fsysMkdir, (void *)fsysRmdir,
(void *)fsysDopen, (void *)fsysDclose, (void *)fsysDread,
(void *)dummy5, (void *)dummy5 };
iop_device_t fsys_driver = { fsname, 16, 1, "fsys driver",
&fsys_functarray };
////////////////////////////////////////////////////////////////////////
// Entry point for mounting the file system
int fsysMount(void)
{
iop_sema_t sema_info;
sema_info.attr = 1;
sema_info.option = 0;
sema_info.initial = 1;
sema_info.max = 1;
fsys_sema = CreateSema(&sema_info);
DelDrv(fsname);
AddDrv(&fsys_driver);
return 0;
}
int fsysUnmount(void)
{
DelDrv(fsname);
return 0;
}

View File

@ -1,82 +1,82 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include <types.h>
#include <thbase.h>
#include <sifcmd.h>
#include <sysclib.h>
#include <stdio.h>
#include <ioman.h>
#include <intrman.h>
#include <loadcore.h>
////////////////////////////////////////////////////////////////////////
#define NPM_PUTS 0x01
#define RPC_NPM_USER 0x014d704e
////////////////////////////////////////////////////////////////////////
static void *
naplinkRpcHandler(int cmd, void *buffer, int size)
{
// Only supports npmPrintf of course
switch(cmd) {
case NPM_PUTS:
printf(buffer);
break;
default:
printf("unknown npm rpc call\n");
}
return buffer;
}
////////////////////////////////////////////////////////////////////////
static SifRpcServerData_t server __attribute((aligned(16)));
static SifRpcDataQueue_t queue __attribute((aligned(16)));
static unsigned char rpc_buffer[512] __attribute((aligned(16)));
static void
napThread(void *arg)
{
int pid;
SifInitRpc(0);
pid = GetThreadId();
SifSetRpcQueue(&queue, pid);
SifRegisterRpc(&server, RPC_NPM_USER, naplinkRpcHandler,
rpc_buffer, 0, 0, &queue);
SifRpcLoop(&queue); // Never exits
ExitDeleteThread();
}
////////////////////////////////////////////////////////////////////////
int
naplinkRpcInit(void)
{
struct _iop_thread th_attr;
int ret;
int pid;
th_attr.attr = 0x02000000;
th_attr.option = 0;
th_attr.thread = napThread;
th_attr.stacksize = 0x800;
th_attr.priority = 79;
pid = CreateThread(&th_attr);
if (pid < 0) {
printf("IOP: napRpc createThread failed %d\n", pid);
return -1;
}
ret = StartThread(pid, 0);
if (ret < 0) {
printf("IOP: napRpc startThread failed %d\n", ret);
DeleteThread(pid);
return -1;
}
return 0;
}
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include <types.h>
#include <thbase.h>
#include <sifcmd.h>
#include <sysclib.h>
#include <stdio.h>
#include <ioman.h>
#include <intrman.h>
#include <loadcore.h>
////////////////////////////////////////////////////////////////////////
#define NPM_PUTS 0x01
#define RPC_NPM_USER 0x014d704e
////////////////////////////////////////////////////////////////////////
static void *
naplinkRpcHandler(int cmd, void *buffer, int size)
{
// Only supports npmPrintf of course
switch(cmd) {
case NPM_PUTS:
printf(buffer);
break;
default:
printf("unknown npm rpc call\n");
}
return buffer;
}
////////////////////////////////////////////////////////////////////////
static SifRpcServerData_t server __attribute((aligned(16)));
static SifRpcDataQueue_t queue __attribute((aligned(16)));
static unsigned char rpc_buffer[512] __attribute((aligned(16)));
static void
napThread(void *arg)
{
int pid;
SifInitRpc(0);
pid = GetThreadId();
SifSetRpcQueue(&queue, pid);
SifRegisterRpc(&server, RPC_NPM_USER, naplinkRpcHandler,
rpc_buffer, 0, 0, &queue);
SifRpcLoop(&queue); // Never exits
ExitDeleteThread();
}
////////////////////////////////////////////////////////////////////////
int
naplinkRpcInit(void)
{
struct _iop_thread th_attr;
int ret;
int pid;
th_attr.attr = 0x02000000;
th_attr.option = 0;
th_attr.thread = napThread;
th_attr.stacksize = 0x800;
th_attr.priority = 79;
pid = CreateThread(&th_attr);
if (pid < 0) {
printf("IOP: napRpc createThread failed %d\n", pid);
return -1;
}
ret = StartThread(pid, 0);
if (ret < 0) {
printf("IOP: napRpc startThread failed %d\n", ret);
DeleteThread(pid);
return -1;
}
return 0;
}

View File

@ -1,55 +1,55 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include <stdio.h>
#include <sysclib.h>
#include <loadcore.h>
#include <intrman.h>
#include <types.h>
#include <sifrpc.h>
#include <cdvdman.h>
#include "excepHandler.h"
// Entry points
extern int fsysMount(void);
extern int cmdHandlerInit(void);
extern int ttyMount(void);
extern int naplinkRpcInit(void);
////////////////////////////////////////////////////////////////////////
// main
// start threads & init rpc & filesys
int
_start( int argc, char **argv)
{
ttyWrite(NULL,"TEST",4);
FlushDcache();
CpuEnableIntr(0);
SifInitRpc(0);
pcsx2fio_device_exists();
if ((argc < 2) || (strncmp(argv[1], "-notty", 6))) {
ttyMount();
// Oh well.. There's a bug in either smapif or lwip's etharp
// that thrashes udp msgs which are queued while waiting for arp
// request
// alas, this msg will probably not be displayed
printf("tty mounted\n");
}
fsysMount();
printf("host: mounted\n");
naplinkRpcInit();
printf("Naplink thread started\n");
installExceptionHandlers();
return 0;
}
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include <stdio.h>
#include <sysclib.h>
#include <loadcore.h>
#include <intrman.h>
#include <types.h>
#include <sifrpc.h>
#include <cdvdman.h>
#include "excepHandler.h"
// Entry points
extern int fsysMount(void);
extern int cmdHandlerInit(void);
extern int ttyMount(void);
extern int naplinkRpcInit(void);
////////////////////////////////////////////////////////////////////////
// main
// start threads & init rpc & filesys
int
_start( int argc, char **argv)
{
ttyWrite(NULL,"TEST",4);
FlushDcache();
CpuEnableIntr(0);
SifInitRpc(0);
pcsx2fio_device_exists();
if ((argc < 2) || (strncmp(argv[1], "-notty", 6))) {
ttyMount();
// Oh well.. There's a bug in either smapif or lwip's etharp
// that thrashes udp msgs which are queued while waiting for arp
// request
// alas, this msg will probably not be displayed
printf("tty mounted\n");
}
fsysMount();
printf("host: mounted\n");
naplinkRpcInit();
printf("Naplink thread started\n");
installExceptionHandlers();
return 0;
}

View File

@ -1,105 +1,105 @@
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include <types.h>
#include <thbase.h>
#include <thsemap.h>
#include <sysclib.h>
#include <stdio.h>
#include <ioman.h>
#include <intrman.h>
#include <loadcore.h>
#include "net_fio.h"
#include "hostlink.h"
////////////////////////////////////////////////////////////////////////
static int tty_socket = 0;
static int tty_sema = -1;
static char ttyname[] = "tty";
////////////////////////////////////////////////////////////////////////
static int dummy()
{
return -5;
}
////////////////////////////////////////////////////////////////////////
static int dummy0()
{
return 0;
}
////////////////////////////////////////////////////////////////////////
static int ttyInit(iop_device_t *driver)
{
iop_sema_t sema_info;
sema_info.attr = 0;
sema_info.initial = 1; /* Unlocked. */
sema_info.max = 1;
if ((tty_sema = CreateSema(&sema_info)) < 0)
return -1;
if(!pcsx2fio_device_exists())
return -1;
return 1;
}
////////////////////////////////////////////////////////////////////////
static int ttyOpen( int fd, char *name, int mode)
{
return 1;
}
////////////////////////////////////////////////////////////////////////
static int ttyClose( int fd)
{
return 1;
}
////////////////////////////////////////////////////////////////////////
int ttyWrite(iop_file_t *file, char *buf, int size)
{
int res;
WaitSema(tty_sema);
res = pcsx2fio_set_call(PS2E_FIO_PRINTF_CMD,buf,size);
SignalSema(tty_sema);
return res;
}
iop_device_ops_t tty_functarray = { ttyInit, dummy0, (void *)dummy,
(void *)ttyOpen, (void *)ttyClose, (void *)dummy,
(void *)ttyWrite, (void *)dummy, (void *)dummy,
(void *)dummy, (void *)dummy, (void *)dummy,
(void *)dummy, (void *)dummy, (void *)dummy,
(void *)dummy, (void *)dummy };
iop_device_t tty_driver = { ttyname, 3, 1, "Fast TTY for pcsx2",
&tty_functarray };
////////////////////////////////////////////////////////////////////////
// Entry point for mounting the file system
int ttyMount(void)
{
close(0);
close(1);
DelDrv(ttyname);
AddDrv(&tty_driver);
if(open("tty00:", O_RDONLY) != 0) while(1);
if(open("tty00:", O_WRONLY) != 1) while(1);
return 0;
}
/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
#include <types.h>
#include <thbase.h>
#include <thsemap.h>
#include <sysclib.h>
#include <stdio.h>
#include <ioman.h>
#include <intrman.h>
#include <loadcore.h>
#include "net_fio.h"
#include "hostlink.h"
////////////////////////////////////////////////////////////////////////
static int tty_socket = 0;
static int tty_sema = -1;
static char ttyname[] = "tty";
////////////////////////////////////////////////////////////////////////
static int dummy()
{
return -5;
}
////////////////////////////////////////////////////////////////////////
static int dummy0()
{
return 0;
}
////////////////////////////////////////////////////////////////////////
static int ttyInit(iop_device_t *driver)
{
iop_sema_t sema_info;
sema_info.attr = 0;
sema_info.initial = 1; /* Unlocked. */
sema_info.max = 1;
if ((tty_sema = CreateSema(&sema_info)) < 0)
return -1;
if(!pcsx2fio_device_exists())
return -1;
return 1;
}
////////////////////////////////////////////////////////////////////////
static int ttyOpen( int fd, char *name, int mode)
{
return 1;
}
////////////////////////////////////////////////////////////////////////
static int ttyClose( int fd)
{
return 1;
}
////////////////////////////////////////////////////////////////////////
int ttyWrite(iop_file_t *file, char *buf, int size)
{
int res;
WaitSema(tty_sema);
res = pcsx2fio_set_call(PS2E_FIO_PRINTF_CMD,buf,size);
SignalSema(tty_sema);
return res;
}
iop_device_ops_t tty_functarray = { ttyInit, dummy0, (void *)dummy,
(void *)ttyOpen, (void *)ttyClose, (void *)dummy,
(void *)ttyWrite, (void *)dummy, (void *)dummy,
(void *)dummy, (void *)dummy, (void *)dummy,
(void *)dummy, (void *)dummy, (void *)dummy,
(void *)dummy, (void *)dummy };
iop_device_t tty_driver = { ttyname, 3, 1, "Fast TTY for pcsx2",
&tty_functarray };
////////////////////////////////////////////////////////////////////////
// Entry point for mounting the file system
int ttyMount(void)
{
close(0);
close(1);
DelDrv(ttyname);
AddDrv(&tty_driver);
if(open("tty00:", O_RDONLY) != 0) while(1);
if(open("tty00:", O_WRONLY) != 1) while(1);
return 0;
}

0
plugins/CDVDiso/src/Linux/Config.cpp Executable file → Normal file
View File

0
plugins/CDVDiso/src/Linux/Linux.cpp Executable file → Normal file
View File

0
plugins/CDVDiso/src/Windows/Config.cpp Executable file → Normal file
View File

0
plugins/CDVDiso/src/Windows/Win32.cpp Executable file → Normal file
View File

0
plugins/CDVDiso/src/libiso.cpp Executable file → Normal file
View File

0
plugins/CDVDiso/src/mkiso/mkiso.cpp Executable file → Normal file
View File

File diff suppressed because it is too large Load Diff

View File

@ -1,368 +1,368 @@
/* CDVDlinuz.c
* Copyright (C) 2002-2005 CDVDlinuz 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 <errno.h> // errno
#include <fcntl.h> // open()
#include <stddef.h> // NULL
#include <stdio.h> // printf()
#include <stdlib.h> // getenv(), system()
#include <string.h> // strerror(), sprintf()
#include <sys/ioctl.h> // ioctl()
#include <sys/stat.h> // stat()
#include <sys/types.h> // stat()
#include <time.h> // time_t, time(), struct timeval
#include <unistd.h> // stat()
#ifndef __LINUX__
#ifdef __linux__
#define __LINUX__
#endif /* __linux__ */
#endif /* No __LINUX__ */
#define CDVDdefs
#include "PS2Edefs.h"
// #include "PS2Etypes.h"
#include "CDVDlinuz.h"
#include "buffer.h"
#include "conf.h"
#include "logfile.h"
#include "CD.h" // InitCDInfo()
#include "DVD.h" // InitDVDInfo()
#include "device.h"
#include "../version.h"
// Globals
time_t lasttime;
// Interface Functions
u32 CALLBACK PS2EgetLibType() {
return(PS2E_LT_CDVD); // Library Type CDVD
} // END PS2EgetLibType()
u32 CALLBACK PS2EgetLibVersion2(u32 type) {
return((version<<16)|(revision<<8)|build);
} // END PS2EgetLibVersion2()
char* CALLBACK PS2EgetLibName() {
return(libname);
} // END PS2EgetLibName()
s32 CALLBACK CDVDinit() {
errno = 0;
InitLog();
if(OpenLog() != 0) return(-1);
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDinit()");
#endif /* VERBOSE_FUNCTION */
InitConf();
devicehandle = -1;
devicecapability = 0;
lasttime = time(NULL);
// Initialize DVD.c and CD.c as well
InitDisc();
InitDVDInfo();
InitCDInfo();
return(0);
} // END CDVDinit()
void CALLBACK CDVDshutdown() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDshutdown()");
#endif /* VERBOSE_FUNCTION */
DeviceClose();
CloseLog();
} // END CDVDshutdown()
s32 CALLBACK CDVDopen(const char* pTitleFilename) {
s32 s32result;
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDopen()");
#endif /* VERBOSE_FUNCTION */
InitBuffer();
LoadConf();
errno = 0;
s32result = DeviceOpen();
if(s32result != 0) return(s32result);
if(errno != 0) return(-1);
return(0);
} // END CDVDopen();
void CALLBACK CDVDclose() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDclose()");
#endif /* VERBOSE_FUNCTION */
DeviceClose();
} // END CDVDclose()
s32 CALLBACK CDVDreadTrack(u32 lsn, int mode) {
s32 s32result;
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDreadTrack(%i)", lsn);
#endif /* VERBOSE_FUNCTION */
s32result = 0;
errno = 0;
if(DiscInserted() == -1) return(-1);
if(userbuffer < BUFFERMAX) {
if((bufferlist[userbuffer].lsn == lsn) &&
(bufferlist[userbuffer].mode == mode)) {
return(0);
} // ENDIF- And it's the right one?
} // ENDIF- Are we already pointing at the buffer?
userbuffer = FindListBuffer(lsn);
if(userbuffer < BUFFERMAX) {
if((bufferlist[userbuffer].lsn == lsn) &&
(bufferlist[userbuffer].mode == mode)) {
return(0);
} // ENDIF- And it was the right one?
} // ENDIF- Was a buffer found in the cache?
replacebuffer++;
if(replacebuffer >= BUFFERMAX) replacebuffer = 0;
userbuffer = replacebuffer;
if(bufferlist[replacebuffer].upsort != 0xffff) {
RemoveListBuffer(replacebuffer);
} // ENDIF- Reference already in place? Remove it.
s32result = DeviceReadTrack(lsn, mode, bufferlist[replacebuffer].buffer);
bufferlist[replacebuffer].lsn = lsn;
bufferlist[replacebuffer].mode = mode;
bufferlist[replacebuffer].offset = DeviceBufferOffset();
if((s32result != 0) || (errno != 0)) {
bufferlist[replacebuffer].mode = -1; // Error! flag buffer as such.
} else {
if((disctype != CDVD_TYPE_PS2DVD) && (disctype != CDVD_TYPE_DVDV)) {
if(mode == CDVD_MODE_2352) {
CDreadSubQ(lsn, &bufferlist[replacebuffer].subq);
errno = 0;
} // ENDIF- Read subq as well?
} // ENDIF- Read a DVD buffer or a CD buffer?
} // ENDIF-Read ok? Fill out rest of buffer info.
AddListBuffer(replacebuffer);
return(s32result);
} // END CDVDreadTrack()
u8* CALLBACK CDVDgetBuffer() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetBuffer()");
#endif /* VERBOSE_FUNCTION */
if(DiscInserted() == -1) return(NULL);
if(userbuffer == 0xffff) {
#ifdef VERBOSE_WARNINGS
PrintLog("CDVD interface: Not pointing to a buffer!");
#endif /* VERBOSE_WARNINGS */
return(NULL); // No buffer reference?
} // ENDIF- user buffer not pointing at anything? Abort
if(bufferlist[userbuffer].mode < 0) {
#ifdef VERBOSE_WARNINGS
PrintLog("CDVD interface: Error in buffer!");
#endif /* VERBOSE_WARNINGS */
return(NULL); // Bad Sector?
} // ENDIF- Trouble reading physical sector? Tell them.
return(bufferlist[userbuffer].buffer + bufferlist[userbuffer].offset);
} // END CDVDgetBuffer()
// Note: without the lsn, I could pull the SubQ data directly from
// the stored buffer (in buffer.h). Oh, well.
s32 CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ *subq) {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDreadSubQ(%i)", lsn);
#endif /* VERBOSE_FUNCTION */
if(DiscInserted() == -1) return(-1);
// DVDs don't have SubQ data
if(disctype == CDVD_TYPE_PS2DVD) return(-1);
if(disctype == CDVD_TYPE_DVDV) return(-1);
return(CDreadSubQ(lsn, subq));
} // END CDVDreadSubQ()
s32 CALLBACK CDVDgetTN(cdvdTN *cdvdtn) {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetTN()");
#endif /* VERBOSE_FUNCTION */
if(DiscInserted() == -1) return(-1);
if((disctype == CDVD_TYPE_PS2DVD) || (disctype == CDVD_TYPE_DVDV)) {
return(DVDgetTN(cdvdtn));
} else {
return(CDgetTN(cdvdtn));
} // ENDIF- Are we looking at a DVD?
} // END CDVDgetTN()
s32 CALLBACK CDVDgetTD(u8 newtrack, cdvdTD *cdvdtd) {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetTD()");
#endif /* VERBOSE_FUNCTION */
if(DiscInserted() == -1) return(-1);
if((disctype == CDVD_TYPE_PS2DVD) || (disctype == CDVD_TYPE_DVDV)) {
return(DVDgetTD(newtrack, cdvdtd));
} else {
return(CDgetTD(newtrack, cdvdtd));
} // ENDIF- Are we looking at a DVD?
} // END CDVDgetTD()
s32 CALLBACK CDVDgetTOC(void *toc) {
// A structure to fill in, or at least some documentation on what
// the PS2 expects from this call would be more helpful than a
// "void *".
union {
void *voidptr;
u8 *u8ptr;
} tocptr;
s32 i;
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetTOC()");
#endif /* VERBOSE_FUNCTION */
if(toc == NULL) return(-1);
if(DiscInserted() == -1) return(-1);
tocptr.voidptr = toc;
for(i = 0; i < 1024; i++) *(tocptr.u8ptr + i) = tocbuffer[i];
tocptr.voidptr = NULL;
return(0);
} // END CDVDgetTOC()
s32 CALLBACK CDVDgetDiskType() {
#ifdef VERBOSE_FUNCTION
// Called way too often in boot part of bios to be left in.
// PrintLog("CDVD interface: CDVDgetDiskType()");
#endif /* VERBOSE_FUNCTION */
if(lasttime != time(NULL)) {
lasttime = time(NULL);
DeviceTrayStatus();
} // ENDIF- Has enough time passed between calls?
return(disctype);
} // END CDVDgetDiskType()
s32 CALLBACK CDVDgetTrayStatus() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetTrayStatus()");
#endif /* VERBOSE_FUNCTION */
if(lasttime != time(NULL)) {
lasttime = time(NULL);
DeviceTrayStatus();
} // ENDIF- Has enough time passed between calls?
return(traystatus);
} // END CDVDgetTrayStatus()
s32 CALLBACK CDVDctrlTrayOpen() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDctrlTrayOpen()");
#endif /* VERBOSE_FUNCTION */
return(DeviceTrayOpen());
} // END CDVDctrlTrayOpen()
s32 CALLBACK CDVDctrlTrayClose() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDctrlTrayClose()");
#endif /* VERBOSE_FUNCTION */
return(DeviceTrayClose());
} // END CDVDctrlTrayClose()
void CALLBACK CDVDconfigure() {
ExecCfg("configure");
} // END CDVDconfigure()
void CALLBACK CDVDabout() {
ExecCfg("about");
} // END CDVDabout()
s32 CALLBACK CDVDtest() {
s32 s32result;
errno = 0;
if(devicehandle != -1) {
#ifdef VERBOSE_WARNINGS
PrintLog("CDVD interface: Device already open");
#endif /* VERBOSE_WARNINGS */
return(0);
} // ENDIF- Is the CD/DVD already in use? That's fine.
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD driver: CDVDtest()");
#endif /* VERBOSE_FUNCTION */
s32result = DeviceOpen();
DeviceClose();
return(s32result);
} // END CDVDtest()
/* CDVDlinuz.c
* Copyright (C) 2002-2005 CDVDlinuz 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 <errno.h> // errno
#include <fcntl.h> // open()
#include <stddef.h> // NULL
#include <stdio.h> // printf()
#include <stdlib.h> // getenv(), system()
#include <string.h> // strerror(), sprintf()
#include <sys/ioctl.h> // ioctl()
#include <sys/stat.h> // stat()
#include <sys/types.h> // stat()
#include <time.h> // time_t, time(), struct timeval
#include <unistd.h> // stat()
#ifndef __LINUX__
#ifdef __linux__
#define __LINUX__
#endif /* __linux__ */
#endif /* No __LINUX__ */
#define CDVDdefs
#include "PS2Edefs.h"
// #include "PS2Etypes.h"
#include "CDVDlinuz.h"
#include "buffer.h"
#include "conf.h"
#include "logfile.h"
#include "CD.h" // InitCDInfo()
#include "DVD.h" // InitDVDInfo()
#include "device.h"
#include "../version.h"
// Globals
time_t lasttime;
// Interface Functions
u32 CALLBACK PS2EgetLibType() {
return(PS2E_LT_CDVD); // Library Type CDVD
} // END PS2EgetLibType()
u32 CALLBACK PS2EgetLibVersion2(u32 type) {
return((version<<16)|(revision<<8)|build);
} // END PS2EgetLibVersion2()
char* CALLBACK PS2EgetLibName() {
return(libname);
} // END PS2EgetLibName()
s32 CALLBACK CDVDinit() {
errno = 0;
InitLog();
if(OpenLog() != 0) return(-1);
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDinit()");
#endif /* VERBOSE_FUNCTION */
InitConf();
devicehandle = -1;
devicecapability = 0;
lasttime = time(NULL);
// Initialize DVD.c and CD.c as well
InitDisc();
InitDVDInfo();
InitCDInfo();
return(0);
} // END CDVDinit()
void CALLBACK CDVDshutdown() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDshutdown()");
#endif /* VERBOSE_FUNCTION */
DeviceClose();
CloseLog();
} // END CDVDshutdown()
s32 CALLBACK CDVDopen(const char* pTitleFilename) {
s32 s32result;
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDopen()");
#endif /* VERBOSE_FUNCTION */
InitBuffer();
LoadConf();
errno = 0;
s32result = DeviceOpen();
if(s32result != 0) return(s32result);
if(errno != 0) return(-1);
return(0);
} // END CDVDopen();
void CALLBACK CDVDclose() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDclose()");
#endif /* VERBOSE_FUNCTION */
DeviceClose();
} // END CDVDclose()
s32 CALLBACK CDVDreadTrack(u32 lsn, int mode) {
s32 s32result;
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDreadTrack(%i)", lsn);
#endif /* VERBOSE_FUNCTION */
s32result = 0;
errno = 0;
if(DiscInserted() == -1) return(-1);
if(userbuffer < BUFFERMAX) {
if((bufferlist[userbuffer].lsn == lsn) &&
(bufferlist[userbuffer].mode == mode)) {
return(0);
} // ENDIF- And it's the right one?
} // ENDIF- Are we already pointing at the buffer?
userbuffer = FindListBuffer(lsn);
if(userbuffer < BUFFERMAX) {
if((bufferlist[userbuffer].lsn == lsn) &&
(bufferlist[userbuffer].mode == mode)) {
return(0);
} // ENDIF- And it was the right one?
} // ENDIF- Was a buffer found in the cache?
replacebuffer++;
if(replacebuffer >= BUFFERMAX) replacebuffer = 0;
userbuffer = replacebuffer;
if(bufferlist[replacebuffer].upsort != 0xffff) {
RemoveListBuffer(replacebuffer);
} // ENDIF- Reference already in place? Remove it.
s32result = DeviceReadTrack(lsn, mode, bufferlist[replacebuffer].buffer);
bufferlist[replacebuffer].lsn = lsn;
bufferlist[replacebuffer].mode = mode;
bufferlist[replacebuffer].offset = DeviceBufferOffset();
if((s32result != 0) || (errno != 0)) {
bufferlist[replacebuffer].mode = -1; // Error! flag buffer as such.
} else {
if((disctype != CDVD_TYPE_PS2DVD) && (disctype != CDVD_TYPE_DVDV)) {
if(mode == CDVD_MODE_2352) {
CDreadSubQ(lsn, &bufferlist[replacebuffer].subq);
errno = 0;
} // ENDIF- Read subq as well?
} // ENDIF- Read a DVD buffer or a CD buffer?
} // ENDIF-Read ok? Fill out rest of buffer info.
AddListBuffer(replacebuffer);
return(s32result);
} // END CDVDreadTrack()
u8* CALLBACK CDVDgetBuffer() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetBuffer()");
#endif /* VERBOSE_FUNCTION */
if(DiscInserted() == -1) return(NULL);
if(userbuffer == 0xffff) {
#ifdef VERBOSE_WARNINGS
PrintLog("CDVD interface: Not pointing to a buffer!");
#endif /* VERBOSE_WARNINGS */
return(NULL); // No buffer reference?
} // ENDIF- user buffer not pointing at anything? Abort
if(bufferlist[userbuffer].mode < 0) {
#ifdef VERBOSE_WARNINGS
PrintLog("CDVD interface: Error in buffer!");
#endif /* VERBOSE_WARNINGS */
return(NULL); // Bad Sector?
} // ENDIF- Trouble reading physical sector? Tell them.
return(bufferlist[userbuffer].buffer + bufferlist[userbuffer].offset);
} // END CDVDgetBuffer()
// Note: without the lsn, I could pull the SubQ data directly from
// the stored buffer (in buffer.h). Oh, well.
s32 CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ *subq) {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDreadSubQ(%i)", lsn);
#endif /* VERBOSE_FUNCTION */
if(DiscInserted() == -1) return(-1);
// DVDs don't have SubQ data
if(disctype == CDVD_TYPE_PS2DVD) return(-1);
if(disctype == CDVD_TYPE_DVDV) return(-1);
return(CDreadSubQ(lsn, subq));
} // END CDVDreadSubQ()
s32 CALLBACK CDVDgetTN(cdvdTN *cdvdtn) {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetTN()");
#endif /* VERBOSE_FUNCTION */
if(DiscInserted() == -1) return(-1);
if((disctype == CDVD_TYPE_PS2DVD) || (disctype == CDVD_TYPE_DVDV)) {
return(DVDgetTN(cdvdtn));
} else {
return(CDgetTN(cdvdtn));
} // ENDIF- Are we looking at a DVD?
} // END CDVDgetTN()
s32 CALLBACK CDVDgetTD(u8 newtrack, cdvdTD *cdvdtd) {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetTD()");
#endif /* VERBOSE_FUNCTION */
if(DiscInserted() == -1) return(-1);
if((disctype == CDVD_TYPE_PS2DVD) || (disctype == CDVD_TYPE_DVDV)) {
return(DVDgetTD(newtrack, cdvdtd));
} else {
return(CDgetTD(newtrack, cdvdtd));
} // ENDIF- Are we looking at a DVD?
} // END CDVDgetTD()
s32 CALLBACK CDVDgetTOC(void *toc) {
// A structure to fill in, or at least some documentation on what
// the PS2 expects from this call would be more helpful than a
// "void *".
union {
void *voidptr;
u8 *u8ptr;
} tocptr;
s32 i;
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetTOC()");
#endif /* VERBOSE_FUNCTION */
if(toc == NULL) return(-1);
if(DiscInserted() == -1) return(-1);
tocptr.voidptr = toc;
for(i = 0; i < 1024; i++) *(tocptr.u8ptr + i) = tocbuffer[i];
tocptr.voidptr = NULL;
return(0);
} // END CDVDgetTOC()
s32 CALLBACK CDVDgetDiskType() {
#ifdef VERBOSE_FUNCTION
// Called way too often in boot part of bios to be left in.
// PrintLog("CDVD interface: CDVDgetDiskType()");
#endif /* VERBOSE_FUNCTION */
if(lasttime != time(NULL)) {
lasttime = time(NULL);
DeviceTrayStatus();
} // ENDIF- Has enough time passed between calls?
return(disctype);
} // END CDVDgetDiskType()
s32 CALLBACK CDVDgetTrayStatus() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetTrayStatus()");
#endif /* VERBOSE_FUNCTION */
if(lasttime != time(NULL)) {
lasttime = time(NULL);
DeviceTrayStatus();
} // ENDIF- Has enough time passed between calls?
return(traystatus);
} // END CDVDgetTrayStatus()
s32 CALLBACK CDVDctrlTrayOpen() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDctrlTrayOpen()");
#endif /* VERBOSE_FUNCTION */
return(DeviceTrayOpen());
} // END CDVDctrlTrayOpen()
s32 CALLBACK CDVDctrlTrayClose() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDctrlTrayClose()");
#endif /* VERBOSE_FUNCTION */
return(DeviceTrayClose());
} // END CDVDctrlTrayClose()
void CALLBACK CDVDconfigure() {
ExecCfg("configure");
} // END CDVDconfigure()
void CALLBACK CDVDabout() {
ExecCfg("about");
} // END CDVDabout()
s32 CALLBACK CDVDtest() {
s32 s32result;
errno = 0;
if(devicehandle != -1) {
#ifdef VERBOSE_WARNINGS
PrintLog("CDVD interface: Device already open");
#endif /* VERBOSE_WARNINGS */
return(0);
} // ENDIF- Is the CD/DVD already in use? That's fine.
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD driver: CDVDtest()");
#endif /* VERBOSE_FUNCTION */
s32result = DeviceOpen();
DeviceClose();
return(s32result);
} // END CDVDtest()

View File

@ -1,212 +1,212 @@
/* aboutbox.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <stddef.h> // NULL
#include <stdio.h> // sprintf()
#include <gtk/gtkbutton.h> // gtk_button_new_with_label()
#include <gtk/gtkcontainer.h> // gtk_container_add()
#include <gtk/gtkhbbox.h> // gtk_hbutton_box_new()
#include <gtk/gtklabel.h> // gtk_label_new()
#include <gtk/gtkmain.h> // gtk_init(), gtk_main(), gtk_main_quit()
#include <gtk/gtkvbox.h> // gtk_vbox_new()
#include <gtk/gtkwindow.h> // gtk_window_new()
#include "version.h"
#include "aboutbox.h"
struct AboutBoxData aboutbox;
gint AboutBoxCancelEvent(GtkWidget *widget, GdkEvent event, gpointer data) {
if(aboutbox.window != NULL) {
gtk_widget_destroy(aboutbox.window);
aboutbox.window = NULL;
} // ENDIF- Do we have an About Box still?
gtk_main_quit();
return(TRUE);
} // END AboutBoxCancelEvent()
void AboutBoxDisplay() {
GtkWidget *item;
GtkWidget *container;
GtkWidget *vbox1;
char templine[256];
aboutbox.window = NULL;
aboutbox.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width(GTK_CONTAINER(aboutbox.window), 5);
gtk_window_set_title(GTK_WINDOW(aboutbox.window), "About CDVDlinuz");
gtk_window_set_position(GTK_WINDOW(aboutbox.window), GTK_WIN_POS_CENTER);
gtk_window_set_modal(GTK_WINDOW(aboutbox.window), TRUE);
gtk_window_set_resizable(GTK_WINDOW(aboutbox.window), FALSE);
g_signal_connect(G_OBJECT(aboutbox.window), "delete_event",
G_CALLBACK(AboutBoxCancelEvent), NULL);
vbox1 = gtk_vbox_new(FALSE, 5);
gtk_container_add(GTK_CONTAINER(aboutbox.window), vbox1);
gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5);
gtk_widget_show(vbox1);
sprintf(templine, "%s v%i.%i", libname, revision, build);
item = gtk_label_new(templine);
gtk_box_pack_start(GTK_BOX(vbox1), item, FALSE, FALSE, 0);
gtk_widget_show(item);
item = NULL;
item = gtk_label_new("Current Author: efp");
gtk_box_pack_start(GTK_BOX(vbox1), item, FALSE, FALSE, 0);
gtk_widget_show(item);
item = NULL;
item = gtk_label_new("Original code by: linuzappz & shadow");
gtk_box_pack_start(GTK_BOX(vbox1), item, FALSE, FALSE, 0);
gtk_widget_show(item);
item = NULL;
container = gtk_hbutton_box_new();
gtk_box_pack_start(GTK_BOX(vbox1), container, TRUE, TRUE, 0);
gtk_widget_show(container);
item = gtk_button_new_with_label("Ok");
gtk_container_add(GTK_CONTAINER(container), item);
GTK_WIDGET_SET_FLAGS(item, GTK_CAN_DEFAULT);
gtk_widget_show(item);
g_signal_connect(G_OBJECT(item), "clicked",
G_CALLBACK(AboutBoxCancelEvent), NULL);
item = NULL;
container = NULL;
vbox1 = NULL;
gtk_widget_show(aboutbox.window);
gtk_main();
} // END AboutDisplay()
/* aboutbox.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <stddef.h> // NULL
#include <stdio.h> // sprintf()
#include <gtk/gtkbutton.h> // gtk_button_new_with_label()
#include <gtk/gtkcontainer.h> // gtk_container_add()
#include <gtk/gtkhbbox.h> // gtk_hbutton_box_new()
#include <gtk/gtklabel.h> // gtk_label_new()
#include <gtk/gtkmain.h> // gtk_init(), gtk_main(), gtk_main_quit()
#include <gtk/gtkvbox.h> // gtk_vbox_new()
#include <gtk/gtkwindow.h> // gtk_window_new()
#include "version.h"
#include "aboutbox.h"
struct AboutBoxData aboutbox;
gint AboutBoxCancelEvent(GtkWidget *widget, GdkEvent event, gpointer data) {
if(aboutbox.window != NULL) {
gtk_widget_destroy(aboutbox.window);
aboutbox.window = NULL;
} // ENDIF- Do we have an About Box still?
gtk_main_quit();
return(TRUE);
} // END AboutBoxCancelEvent()
void AboutBoxDisplay() {
GtkWidget *item;
GtkWidget *container;
GtkWidget *vbox1;
char templine[256];
aboutbox.window = NULL;
aboutbox.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width(GTK_CONTAINER(aboutbox.window), 5);
gtk_window_set_title(GTK_WINDOW(aboutbox.window), "About CDVDlinuz");
gtk_window_set_position(GTK_WINDOW(aboutbox.window), GTK_WIN_POS_CENTER);
gtk_window_set_modal(GTK_WINDOW(aboutbox.window), TRUE);
gtk_window_set_resizable(GTK_WINDOW(aboutbox.window), FALSE);
g_signal_connect(G_OBJECT(aboutbox.window), "delete_event",
G_CALLBACK(AboutBoxCancelEvent), NULL);
vbox1 = gtk_vbox_new(FALSE, 5);
gtk_container_add(GTK_CONTAINER(aboutbox.window), vbox1);
gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5);
gtk_widget_show(vbox1);
sprintf(templine, "%s v%i.%i", libname, revision, build);
item = gtk_label_new(templine);
gtk_box_pack_start(GTK_BOX(vbox1), item, FALSE, FALSE, 0);
gtk_widget_show(item);
item = NULL;
item = gtk_label_new("Current Author: efp");
gtk_box_pack_start(GTK_BOX(vbox1), item, FALSE, FALSE, 0);
gtk_widget_show(item);
item = NULL;
item = gtk_label_new("Original code by: linuzappz & shadow");
gtk_box_pack_start(GTK_BOX(vbox1), item, FALSE, FALSE, 0);
gtk_widget_show(item);
item = NULL;
container = gtk_hbutton_box_new();
gtk_box_pack_start(GTK_BOX(vbox1), container, TRUE, TRUE, 0);
gtk_widget_show(container);
item = gtk_button_new_with_label("Ok");
gtk_container_add(GTK_CONTAINER(container), item);
GTK_WIDGET_SET_FLAGS(item, GTK_CAN_DEFAULT);
gtk_widget_show(item);
g_signal_connect(G_OBJECT(item), "clicked",
G_CALLBACK(AboutBoxCancelEvent), NULL);
item = NULL;
container = NULL;
vbox1 = NULL;
gtk_widget_show(aboutbox.window);
gtk_main();
} // END AboutDisplay()

View File

@ -1,78 +1,78 @@
/* aboutbox.h
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#ifndef ABOUTBOX_H
#define ABOUTBOX_H
#include <gtk/gtkwidget.h>
struct AboutBoxData {
GtkWidget *window; // GtkWindow - About Box
};
extern struct AboutBoxData aboutbox;
extern void AboutBoxDisplay();
#endif /* ABOUTBOX_H */
/* aboutbox.h
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#ifndef ABOUTBOX_H
#define ABOUTBOX_H
#include <gtk/gtkwidget.h>
struct AboutBoxData {
GtkWidget *window; // GtkWindow - About Box
};
extern struct AboutBoxData aboutbox;
extern void AboutBoxDisplay();
#endif /* ABOUTBOX_H */

View File

@ -1,444 +1,444 @@
/* actualfile.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <errno.h> // errno
#include <fcntl.h> // open()
#include <stdio.h> // rename()
#include <string.h> // strerror()
#include <sys/stat.h> // stat64(), open(), fstat()
#include <sys/types.h> // stat64(), open(), fstat(), lseek64()
#include <unistd.h> // stat64(), fstat(), lseek64(), read(), close(), write()
// unlink()
#include "logfile.h"
#include "actualfile.h"
int IsActualFile(const char *filename) {
int retval;
struct stat64 filestat;
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: IsActualFile(%s)", filename);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
retval = stat64(filename, &filestat);
if((retval < 0) || (errno != 0)) {
#ifdef VERBOSE_WARNING_ACTUALFILE
PrintLog("CDVDiso file: Error retrieving stats on %s", filename);
PrintLog("CDVDiso file: %i:%s\n", errno, strerror(errno));
#endif /* VERBOSE_WARNING_ACTUALFILE */
return(-1); // Name doesn't exist.
} // ENDIF- Trouble getting stat on a file?
if(S_ISREG(filestat.st_mode) == 0) return(-2); // Not a regular file.
return(0); // Yep, that's a file.
} // END IsActualFile()
void ActualFileDelete(const char *filename) {
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileDelete(%s)", filename);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
unlink(filename);
} // END ActualFileDelete()
void ActualFileRename(const char *origname, const char *newname) {
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileRename(%s->%s)", origname, newname);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
rename(origname, newname);
return;
} // END ActualFileRename()
ACTUALHANDLE ActualFileOpenForRead(const char *filename) {
int newhandle;
if(filename == NULL) return(-1);
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileOpenForRead(%s)", filename);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
newhandle = open(filename, O_RDONLY | O_LARGEFILE);
if((newhandle < 0) || (errno != 0)) {
#ifdef VERBOSE_WARNING_ACTUALFILE
PrintLog("CDVDiso file: Error opening file %s\n", filename);
PrintLog("CDVDiso file: (%i) %i:%s\n", newhandle, errno, strerror(errno));
#endif /* VERBOSE_WARNING_ACTUALFILE */
return(-1);
} // ENDIF- Error? Abort
return(newhandle);
} // END ActualFileOpenForRead()
off64_t ActualFileSize(ACTUALHANDLE handle) {
int retval;
struct stat64 filestat;
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileSize()\n");
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
retval = fstat64(handle, &filestat);
if((retval < 0) || (errno != 0)) return(-1); // Name doesn't exist.
return(filestat.st_size);
} // END ActualFileSize()
int ActualFileSeek(ACTUALHANDLE handle, off64_t position) {
off64_t moved;
if(handle < 0) return(-1);
if(position < 0) return(-1); // Maybe... position = 0?
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileSeek(%lli)", position);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
moved = lseek64(handle, position, SEEK_SET);
if(errno != 0) {
#ifdef VERBOSE_WARNING_ACTUALFILE
PrintLog("CDVDiso file: Error on seek (%lli)", position);
PrintLog("CDVDiso file: %i:%s\n", errno, strerror(errno));
#endif /* VERBOSE_WARNING_ACTUALFILE */
return(-1);
} // ENDIF- Error? Abort
return(0);
} // END ActualFileSeek()
int ActualFileRead(ACTUALHANDLE handle, int bytes, char *buffer) {
int retval;
if(handle == ACTUALHANDLENULL) return(-1);
if(bytes < 1) return(-1);
if(buffer == NULL) return(-1);
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileRead(%i)", bytes);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
retval = read(handle, buffer, bytes);
if((retval < 0) || (errno != 0)) {
#ifdef VERBOSE_WARNING_ACTUALFILE
PrintLog("CDVDiso file: Error reading from file!");
PrintLog("CDVDiso file: %i:%s", errno, strerror(errno));
#endif /* VERBOSE_WARNING_ACTUALFILE */
// return(-1);
} // ENDIF- Error? Abort
return(retval); // Send back how many bytes read
} // END ActualFileRead()
void ActualFileClose(ACTUALHANDLE handle) {
if(handle < 0) return;
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileClose()");
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
close(handle);
return;
} // END ActualFileClose()
ACTUALHANDLE ActualFileOpenForWrite(const char *filename) {
int newhandle;
if(filename == NULL) return(-1);
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileOpenForWrite(%s)", filename);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
newhandle = open(filename, O_WRONLY | O_CREAT | O_LARGEFILE, 0644);
if((newhandle < 0) || (errno != 0)) {
#ifdef VERBOSE_WARNING_ACTUALFILE
PrintLog("CDVDiso file: Error opening file %s", filename);
PrintLog("CDVDiso file: (%i) %i:%s", newhandle, errno, strerror(errno));
#endif /* VERBOSE_WARNING_ACTUALFILE */
return(-1);
} // ENDIF- Error? Abort
return(newhandle);
} // END ActualFileOpenForWrite()
int ActualFileWrite(ACTUALHANDLE handle, int bytes, char *buffer) {
int retval;
if(handle < 0) return(-1);
if(bytes < 1) return(-1);
if(buffer == NULL) return(-1);
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileWrite(%i)", bytes);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
retval = write(handle, buffer, bytes);
if((retval < 0) || (errno != 0)) {
#ifdef VERBOSE_WARNING_ACTUALFILE
PrintLog("CDVDiso file: Error writing to file!");
PrintLog("CDVDiso file: %i:%s", errno, strerror(errno));
#endif /* VERBOSE_WARNING_ACTUALFILE */
// return(-1);
} // ENDIF- Error? Abort
return(retval); // Send back how many bytes written
} // END ActualFileWrite()
/* actualfile.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <errno.h> // errno
#include <fcntl.h> // open()
#include <stdio.h> // rename()
#include <string.h> // strerror()
#include <sys/stat.h> // stat64(), open(), fstat()
#include <sys/types.h> // stat64(), open(), fstat(), lseek64()
#include <unistd.h> // stat64(), fstat(), lseek64(), read(), close(), write()
// unlink()
#include "logfile.h"
#include "actualfile.h"
int IsActualFile(const char *filename) {
int retval;
struct stat64 filestat;
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: IsActualFile(%s)", filename);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
retval = stat64(filename, &filestat);
if((retval < 0) || (errno != 0)) {
#ifdef VERBOSE_WARNING_ACTUALFILE
PrintLog("CDVDiso file: Error retrieving stats on %s", filename);
PrintLog("CDVDiso file: %i:%s\n", errno, strerror(errno));
#endif /* VERBOSE_WARNING_ACTUALFILE */
return(-1); // Name doesn't exist.
} // ENDIF- Trouble getting stat on a file?
if(S_ISREG(filestat.st_mode) == 0) return(-2); // Not a regular file.
return(0); // Yep, that's a file.
} // END IsActualFile()
void ActualFileDelete(const char *filename) {
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileDelete(%s)", filename);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
unlink(filename);
} // END ActualFileDelete()
void ActualFileRename(const char *origname, const char *newname) {
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileRename(%s->%s)", origname, newname);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
rename(origname, newname);
return;
} // END ActualFileRename()
ACTUALHANDLE ActualFileOpenForRead(const char *filename) {
int newhandle;
if(filename == NULL) return(-1);
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileOpenForRead(%s)", filename);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
newhandle = open(filename, O_RDONLY | O_LARGEFILE);
if((newhandle < 0) || (errno != 0)) {
#ifdef VERBOSE_WARNING_ACTUALFILE
PrintLog("CDVDiso file: Error opening file %s\n", filename);
PrintLog("CDVDiso file: (%i) %i:%s\n", newhandle, errno, strerror(errno));
#endif /* VERBOSE_WARNING_ACTUALFILE */
return(-1);
} // ENDIF- Error? Abort
return(newhandle);
} // END ActualFileOpenForRead()
off64_t ActualFileSize(ACTUALHANDLE handle) {
int retval;
struct stat64 filestat;
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileSize()\n");
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
retval = fstat64(handle, &filestat);
if((retval < 0) || (errno != 0)) return(-1); // Name doesn't exist.
return(filestat.st_size);
} // END ActualFileSize()
int ActualFileSeek(ACTUALHANDLE handle, off64_t position) {
off64_t moved;
if(handle < 0) return(-1);
if(position < 0) return(-1); // Maybe... position = 0?
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileSeek(%lli)", position);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
moved = lseek64(handle, position, SEEK_SET);
if(errno != 0) {
#ifdef VERBOSE_WARNING_ACTUALFILE
PrintLog("CDVDiso file: Error on seek (%lli)", position);
PrintLog("CDVDiso file: %i:%s\n", errno, strerror(errno));
#endif /* VERBOSE_WARNING_ACTUALFILE */
return(-1);
} // ENDIF- Error? Abort
return(0);
} // END ActualFileSeek()
int ActualFileRead(ACTUALHANDLE handle, int bytes, char *buffer) {
int retval;
if(handle == ACTUALHANDLENULL) return(-1);
if(bytes < 1) return(-1);
if(buffer == NULL) return(-1);
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileRead(%i)", bytes);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
retval = read(handle, buffer, bytes);
if((retval < 0) || (errno != 0)) {
#ifdef VERBOSE_WARNING_ACTUALFILE
PrintLog("CDVDiso file: Error reading from file!");
PrintLog("CDVDiso file: %i:%s", errno, strerror(errno));
#endif /* VERBOSE_WARNING_ACTUALFILE */
// return(-1);
} // ENDIF- Error? Abort
return(retval); // Send back how many bytes read
} // END ActualFileRead()
void ActualFileClose(ACTUALHANDLE handle) {
if(handle < 0) return;
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileClose()");
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
close(handle);
return;
} // END ActualFileClose()
ACTUALHANDLE ActualFileOpenForWrite(const char *filename) {
int newhandle;
if(filename == NULL) return(-1);
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileOpenForWrite(%s)", filename);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
newhandle = open(filename, O_WRONLY | O_CREAT | O_LARGEFILE, 0644);
if((newhandle < 0) || (errno != 0)) {
#ifdef VERBOSE_WARNING_ACTUALFILE
PrintLog("CDVDiso file: Error opening file %s", filename);
PrintLog("CDVDiso file: (%i) %i:%s", newhandle, errno, strerror(errno));
#endif /* VERBOSE_WARNING_ACTUALFILE */
return(-1);
} // ENDIF- Error? Abort
return(newhandle);
} // END ActualFileOpenForWrite()
int ActualFileWrite(ACTUALHANDLE handle, int bytes, char *buffer) {
int retval;
if(handle < 0) return(-1);
if(bytes < 1) return(-1);
if(buffer == NULL) return(-1);
#ifdef VERBOSE_FUNCTION_ACTUALFILE
PrintLog("CDVDiso file: ActualFileWrite(%i)", bytes);
#endif /* VERBOSE_FUNCTION_ACTUALFILE */
errno = 0;
retval = write(handle, buffer, bytes);
if((retval < 0) || (errno != 0)) {
#ifdef VERBOSE_WARNING_ACTUALFILE
PrintLog("CDVDiso file: Error writing to file!");
PrintLog("CDVDiso file: %i:%s", errno, strerror(errno));
#endif /* VERBOSE_WARNING_ACTUALFILE */
// return(-1);
} // ENDIF- Error? Abort
return(retval); // Send back how many bytes written
} // END ActualFileWrite()

View File

@ -1,184 +1,184 @@
/* conf.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <errno.h> // errno
#include <stddef.h> // NULL
#include <stdio.h> // sprintf()
#include <stdlib.h> // getenv()
#include <string.h> // strerror()
#include <sys/stat.h> // mkdir(), stat()
#include <sys/types.h> // mkdir(), stat()
#include <unistd.h> // stat()
// #define CDVDdefs
// #include "../PS2Edefs.h"
#include "logfile.h"
#include "../ini.h"
#include "conf.h"
const char *cfgname[] = { \
"./cfg/cfgCDVDlinuz", \
"../cfg/cfgCDVDlinuz", \
"./plugins/cfgCDVDlinuz", \
"../plugins/cfgCDVDlinuz", \
"./cfgCDVDlinuz", \
"../cfgCDVDlinuz", \
NULL };
const char *confnames[] = { "Device", NULL };
const u8 defaultdevice[] = DEFAULT_DEVICE;
const char defaulthome[] = "../inis";
const char defaultdirectory[] = ".PS2E";
const char defaultfile[] = "CDVDlinuz.ini";
char confdirname[256];
char conffilename[256];
CDVDconf conf;
void ExecCfg(char *arg) {
int nameptr;
struct stat filestat;
char templine[256];
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVDiso interface: ExecCfg(%s)", arg);
#endif /* VERBOSE FUNCTION_CONF */
errno = 0;
nameptr = 0;
while((cfgname[nameptr] != NULL) &&
(stat(cfgname[nameptr], &filestat) == -1)) nameptr++;
errno = 0;
if(cfgname[nameptr] == NULL) {
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVDiso interface: Couldn't find configuration program!");
#endif /* VERBOSE_FUNCTION_CONF */
return;
} // ENDIF- Did not find the executable?
sprintf(templine, "%s %s", cfgname[nameptr], arg);
system(templine);
} // END ExecCfg()
void InitConf() {
int i;
int pos;
char *envptr;
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: InitConf()");
#endif /* VERBOSE_FUNCTION_CONF */
i = 0;
while((i < 255) && defaultdevice[i] != 0) {
conf.devicename[i] = defaultdevice[i];
i++;
} // ENDWHILE- copying the default CD/DVD name in
conf.devicename[i] = 0; // 0-terminate the device name
// Locating directory and file positions
pos = 0;
envptr = getenv("HOME");
if(envptr == NULL) {
// = <Default Home>
i = 0;
while((pos < 253) && (defaulthome[i] != 0)) {
confdirname[pos] = defaulthome[i];
conffilename[pos] = defaulthome[i];
pos++;
i++;
} // NEXT- putting a default place to store configuration data
} else {
// = <Env Home>/<Default Directory>
i = 0;
while((pos < 253) && (*(envptr + i) != 0)) {
confdirname[pos] = *(envptr + i);
conffilename[pos] = *(envptr + i);
pos++;
i++;
} // ENDWHILE- copying home directory info in
if(confdirname[pos-1] != '/') {
confdirname[pos] = '/';
conffilename[pos] = '/';
pos++;
} // ENDIF- No directory separator here? Add one.
i = 0;
while((pos < 253) && (defaultdirectory[i] != 0)) {
confdirname[pos] = defaultdirectory[i];
conffilename[pos] = defaultdirectory[i];
pos++;
i++;
} // NEXT- putting a default place to store configuration data
} // ENDIF- No Home directory?
confdirname[pos] = 0; // Directory reference finished
// += /<Config File Name>
if(conffilename[pos-1] != '/') {
conffilename[pos] = '/';
pos++;
} // ENDIF- No directory separator here? Add one.
i = 0;
while((pos < 253) && (defaultfile[i] != 0)) {
conffilename[pos] = defaultfile[i];
pos++;
i++;
} // NEXT- putting a default place to store configuration data
conffilename[pos] = 0; // File reference finished
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: Directory: %s\n", confdirname);
PrintLog("CDVD config: File: %s\n", conffilename);
#endif /* VERBOSE_FUNCTION_CONF */
} // END InitConf()
void LoadConf() {
int retval;
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: LoadConf()\n");
#endif /* VERBOSE_FUNCTION_CONF */
retval = INILoadString(conffilename, "Settings", "Device", conf.devicename);
if(retval < 0) {
sprintf(conf.devicename, "/dev/dvd");
} // ENDIF- Couldn't find keyword? Fill in a default
} // END LoadConf()
void SaveConf() {
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: SaveConf()\n");
#endif /* VERBOSE_FUNCTION_CONF */
mkdir(confdirname, 0755);
INISaveString(conffilename, "Settings", "Device", conf.devicename);
} // END SaveConf()
/* conf.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <errno.h> // errno
#include <stddef.h> // NULL
#include <stdio.h> // sprintf()
#include <stdlib.h> // getenv()
#include <string.h> // strerror()
#include <sys/stat.h> // mkdir(), stat()
#include <sys/types.h> // mkdir(), stat()
#include <unistd.h> // stat()
// #define CDVDdefs
// #include "../PS2Edefs.h"
#include "logfile.h"
#include "../ini.h"
#include "conf.h"
const char *cfgname[] = { \
"./cfg/cfgCDVDlinuz", \
"../cfg/cfgCDVDlinuz", \
"./plugins/cfgCDVDlinuz", \
"../plugins/cfgCDVDlinuz", \
"./cfgCDVDlinuz", \
"../cfgCDVDlinuz", \
NULL };
const char *confnames[] = { "Device", NULL };
const u8 defaultdevice[] = DEFAULT_DEVICE;
const char defaulthome[] = "../inis";
const char defaultdirectory[] = ".PS2E";
const char defaultfile[] = "CDVDlinuz.ini";
char confdirname[256];
char conffilename[256];
CDVDconf conf;
void ExecCfg(char *arg) {
int nameptr;
struct stat filestat;
char templine[256];
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVDiso interface: ExecCfg(%s)", arg);
#endif /* VERBOSE FUNCTION_CONF */
errno = 0;
nameptr = 0;
while((cfgname[nameptr] != NULL) &&
(stat(cfgname[nameptr], &filestat) == -1)) nameptr++;
errno = 0;
if(cfgname[nameptr] == NULL) {
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVDiso interface: Couldn't find configuration program!");
#endif /* VERBOSE_FUNCTION_CONF */
return;
} // ENDIF- Did not find the executable?
sprintf(templine, "%s %s", cfgname[nameptr], arg);
system(templine);
} // END ExecCfg()
void InitConf() {
int i;
int pos;
char *envptr;
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: InitConf()");
#endif /* VERBOSE_FUNCTION_CONF */
i = 0;
while((i < 255) && defaultdevice[i] != 0) {
conf.devicename[i] = defaultdevice[i];
i++;
} // ENDWHILE- copying the default CD/DVD name in
conf.devicename[i] = 0; // 0-terminate the device name
// Locating directory and file positions
pos = 0;
envptr = getenv("HOME");
if(envptr == NULL) {
// = <Default Home>
i = 0;
while((pos < 253) && (defaulthome[i] != 0)) {
confdirname[pos] = defaulthome[i];
conffilename[pos] = defaulthome[i];
pos++;
i++;
} // NEXT- putting a default place to store configuration data
} else {
// = <Env Home>/<Default Directory>
i = 0;
while((pos < 253) && (*(envptr + i) != 0)) {
confdirname[pos] = *(envptr + i);
conffilename[pos] = *(envptr + i);
pos++;
i++;
} // ENDWHILE- copying home directory info in
if(confdirname[pos-1] != '/') {
confdirname[pos] = '/';
conffilename[pos] = '/';
pos++;
} // ENDIF- No directory separator here? Add one.
i = 0;
while((pos < 253) && (defaultdirectory[i] != 0)) {
confdirname[pos] = defaultdirectory[i];
conffilename[pos] = defaultdirectory[i];
pos++;
i++;
} // NEXT- putting a default place to store configuration data
} // ENDIF- No Home directory?
confdirname[pos] = 0; // Directory reference finished
// += /<Config File Name>
if(conffilename[pos-1] != '/') {
conffilename[pos] = '/';
pos++;
} // ENDIF- No directory separator here? Add one.
i = 0;
while((pos < 253) && (defaultfile[i] != 0)) {
conffilename[pos] = defaultfile[i];
pos++;
i++;
} // NEXT- putting a default place to store configuration data
conffilename[pos] = 0; // File reference finished
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: Directory: %s\n", confdirname);
PrintLog("CDVD config: File: %s\n", conffilename);
#endif /* VERBOSE_FUNCTION_CONF */
} // END InitConf()
void LoadConf() {
int retval;
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: LoadConf()\n");
#endif /* VERBOSE_FUNCTION_CONF */
retval = INILoadString(conffilename, "Settings", "Device", conf.devicename);
if(retval < 0) {
sprintf(conf.devicename, "/dev/dvd");
} // ENDIF- Couldn't find keyword? Fill in a default
} // END LoadConf()
void SaveConf() {
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: SaveConf()\n");
#endif /* VERBOSE_FUNCTION_CONF */
mkdir(confdirname, 0755);
INISaveString(conffilename, "Settings", "Device", conf.devicename);
} // END SaveConf()

View File

@ -1,114 +1,114 @@
/* interface.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <stddef.h> // NULL
#include <stdio.h> // sprintf()
#include <string.h> // strcmp()
#include <gtk/gtkmain.h> // gtk_init(), gtk_main(), gtk_main_quit()
#include <gtk/gtkwidget.h> // gtk_widget_show_all()
#include "logfile.h"
#include "conf.h"
#include "aboutbox.h"
#include "mainbox.h"
int main(int argc, char *argv[]) {
if(argc != 2) return(1);
gtk_init(NULL, NULL);
if(!strcmp(argv[1], "about")) {
AboutBoxDisplay();
return(0);
} else if (!strcmp(argv[1], "configure")) {
OpenLog();
InitConf();
LoadConf();
MainBoxDisplay();
gtk_widget_show_all(mainbox.window);
gtk_main();
CloseLog();
return(0);
} // ENDLONGIF- Which display would you like to see?
return(1); // No Displays chosen? Abort!
} // END main()
/* interface.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <stddef.h> // NULL
#include <stdio.h> // sprintf()
#include <string.h> // strcmp()
#include <gtk/gtkmain.h> // gtk_init(), gtk_main(), gtk_main_quit()
#include <gtk/gtkwidget.h> // gtk_widget_show_all()
#include "logfile.h"
#include "conf.h"
#include "aboutbox.h"
#include "mainbox.h"
int main(int argc, char *argv[]) {
if(argc != 2) return(1);
gtk_init(NULL, NULL);
if(!strcmp(argv[1], "about")) {
AboutBoxDisplay();
return(0);
} else if (!strcmp(argv[1], "configure")) {
OpenLog();
InitConf();
LoadConf();
MainBoxDisplay();
gtk_widget_show_all(mainbox.window);
gtk_main();
CloseLog();
return(0);
} // ENDLONGIF- Which display would you like to see?
return(1); // No Displays chosen? Abort!
} // END main()

View File

@ -1,180 +1,180 @@
/* logfile.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <fcntl.h> // open
#include <stdio.h> // vsprintf()
#include <stdarg.h> // va_start(), va_end(), vsprintf()
#include <sys/stat.h> // mkdir(), open()
#include <sys/types.h> // mkdir(), open()
#include <unistd.h> // close(), write(), unlink()
#include "logfile.h"
int logfile;
char logfiletemp[2048];
void InitLog() {
// Token comment line
#ifdef VERBOSE_LOGFILE
mkdir("./logs", 0755);
unlink("./logs/CDVDlog.txt");
#endif /* VERBOSE LOGFILE */
} // END InitLog();
int OpenLog() {
// Token comment line
#ifdef VERBOSE_LOGFILE
logfile = -1;
logfile = open("./logs/CDVDlog.txt", O_WRONLY | O_CREAT | O_APPEND, 0755);
if(logfile == -1) return(-1);
#endif /* VERBOSE LOGFILE */
return(0);
} // END OpenLog();
void CloseLog() {
// Token comment line
#ifdef VERBOSE_LOGFILE
if(logfile != -1) {
close(logfile);
logfile = -1;
} // ENDIF- Is the log file actually open? Close it.
#endif /* VERBOSE LOGFILE */
} // END CloseLog()
void PrintLog(const char *fmt, ...) {
// Token comment line
#ifdef VERBOSE_LOGFILE
va_list list;
int len;
if(logfile == -1) return; // Log file not open.
va_start(list, fmt);
vsprintf(logfiletemp, fmt, list);
va_end(list);
len = 0;
while((len < 2048) && (logfiletemp[len] != 0)) len++;
if((len > 0) && (logfiletemp[len-1] == '\n')) len--;
if((len > 0) && (logfiletemp[len-1] == '\r')) len--;
logfiletemp[len] = 0; // Slice off the last "\r\n"...
write(logfile, logfiletemp, len);
write(logfile, "\r\n", 2); // ... and write out your own.
#endif /* VERBOSE LOGFILE */
} // END PrintLog()
/* logfile.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <fcntl.h> // open
#include <stdio.h> // vsprintf()
#include <stdarg.h> // va_start(), va_end(), vsprintf()
#include <sys/stat.h> // mkdir(), open()
#include <sys/types.h> // mkdir(), open()
#include <unistd.h> // close(), write(), unlink()
#include "logfile.h"
int logfile;
char logfiletemp[2048];
void InitLog() {
// Token comment line
#ifdef VERBOSE_LOGFILE
mkdir("./logs", 0755);
unlink("./logs/CDVDlog.txt");
#endif /* VERBOSE LOGFILE */
} // END InitLog();
int OpenLog() {
// Token comment line
#ifdef VERBOSE_LOGFILE
logfile = -1;
logfile = open("./logs/CDVDlog.txt", O_WRONLY | O_CREAT | O_APPEND, 0755);
if(logfile == -1) return(-1);
#endif /* VERBOSE LOGFILE */
return(0);
} // END OpenLog();
void CloseLog() {
// Token comment line
#ifdef VERBOSE_LOGFILE
if(logfile != -1) {
close(logfile);
logfile = -1;
} // ENDIF- Is the log file actually open? Close it.
#endif /* VERBOSE LOGFILE */
} // END CloseLog()
void PrintLog(const char *fmt, ...) {
// Token comment line
#ifdef VERBOSE_LOGFILE
va_list list;
int len;
if(logfile == -1) return; // Log file not open.
va_start(list, fmt);
vsprintf(logfiletemp, fmt, list);
va_end(list);
len = 0;
while((len < 2048) && (logfiletemp[len] != 0)) len++;
if((len > 0) && (logfiletemp[len-1] == '\n')) len--;
if((len > 0) && (logfiletemp[len-1] == '\r')) len--;
logfiletemp[len] = 0; // Slice off the last "\r\n"...
write(logfile, logfiletemp, len);
write(logfile, "\r\n", 2); // ... and write out your own.
#endif /* VERBOSE LOGFILE */
} // END PrintLog()

View File

@ -1,374 +1,374 @@
/* mainbox.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <stddef.h> // NULL
#include <stdio.h> // sprintf()
#include <string.h> // strcpy()
#include <sys/stat.h> // stat()
#include <sys/types.h> // stat()
#include <unistd.h> // stat()
#include <gtk/gtkbutton.h> // gtk_button_new_with_label()
#include <gtk/gtkcontainer.h> // gtk_container_add()
#include <gtk/gtkentry.h> // gtk_entry_new()
#include <gtk/gtkhbbox.h> // gtk_hbutton_box_new()
#include <gtk/gtkhbox.h> // gtk_hbox_new()
#include <gtk/gtklabel.h> // gtk_label_new()
#include <gtk/gtkmain.h> // gtk_init(), gtk_main(), gtk_main_quit()
#include <gtk/gtkvbox.h> // gtk_vbox_new()
#include <gtk/gtkwindow.h> // gtk_window_new()
#include "conf.h"
// #include "logfile.h"
#include "device.h" // DeviceOpen(), DeviceClose()
#include "mainbox.h"
struct MainBoxData mainbox;
void MainBoxDestroy() {
if(mainbox.window != NULL) {
gtk_widget_destroy(mainbox.window);
mainbox.window = NULL;
mainbox.device = NULL;
mainbox.desc = NULL;
} // ENDIF- Do we have a Main Window still?
} // END MainBoxDestroy()
void MainBoxUnfocus() {
gtk_widget_set_sensitive(mainbox.device, FALSE);
gtk_window_iconify(GTK_WINDOW(mainbox.window));
} // END MainBoxUnfocus()
gint MainBoxDeviceEvent(GtkWidget *widget, GdkEvent event, gpointer data) {
struct stat filestat;
int retval;
retval = stat(gtk_entry_get_text(GTK_ENTRY(mainbox.device)), &filestat);
if(retval == -1) {
gtk_label_set_text(GTK_LABEL(mainbox.desc), "Device Type: ---");
return(TRUE);
} // ENDIF- Not a name of any sort?
if(S_ISDIR(filestat.st_mode) != 0) {
gtk_label_set_text(GTK_LABEL(mainbox.desc), "Device Type: Not a device");
return(TRUE);
} // ENDIF- Not a regular file?
gtk_label_set_text(GTK_LABEL(mainbox.desc), "Device Type: Device Likely");
return(TRUE);
} // END MainBoxFileEvent()
void MainBoxRefocus() {
GdkEvent event;
MainBoxDeviceEvent(NULL, event, NULL);
gtk_widget_set_sensitive(mainbox.device, TRUE);
gtk_window_set_focus(GTK_WINDOW(mainbox.window), mainbox.device);
gtk_window_deiconify(GTK_WINDOW(mainbox.window));
} // END MainBoxRefocus()
gint MainBoxCancelEvent(GtkWidget *widget, GdkEvent event, gpointer data) {
MainBoxDestroy();
gtk_main_quit();
return(TRUE);
} // END MainBoxCancelEvent()
gint MainBoxOKEvent(GtkWidget *widget, GdkEvent event, gpointer data) {
const char *tempdevice;
int retval;
MainBoxUnfocus();
tempdevice = gtk_entry_get_text(GTK_ENTRY(mainbox.device));
strcpy(conf.devicename, tempdevice); // Temporarily put in new device name
tempdevice = NULL;
if(*(conf.devicename) != 0) {
retval = DeviceOpen(); // Test by opening the device.
DeviceClose(); // Failed or not, close it.
if(retval != 0) {
MainBoxRefocus();
return(TRUE);
} // ENDIF- Not an ISO file? Message and Stop here.
} // ENDIF- Is there an ISO file to check out?
SaveConf();
MainBoxCancelEvent(widget, event, data);
return(TRUE);
} // END MainBoxOKEvent()
void MainBoxDisplay() {
GtkWidget *item;
GtkWidget *hbox1;
GtkWidget *vbox1;
mainbox.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width(GTK_CONTAINER(mainbox.window), 5);
gtk_window_set_title(GTK_WINDOW(mainbox.window), "CDVDlinuz Configuration");
gtk_window_set_position(GTK_WINDOW(mainbox.window), GTK_WIN_POS_CENTER);
g_signal_connect(G_OBJECT(mainbox.window), "delete_event",
G_CALLBACK(MainBoxCancelEvent), NULL);
vbox1 = gtk_vbox_new(FALSE, 5);
gtk_container_add(GTK_CONTAINER(mainbox.window), vbox1);
gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5);
gtk_widget_show(vbox1);
hbox1 = gtk_hbox_new(FALSE, 10);
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, TRUE, TRUE, 0);
gtk_widget_show(hbox1);
item = gtk_label_new("CD/DVD Device:");
gtk_box_pack_start(GTK_BOX(hbox1), item, FALSE, FALSE, 0);
gtk_widget_show(item);
item = NULL;
mainbox.device = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(hbox1), mainbox.device, TRUE, TRUE, 0);
gtk_widget_show(mainbox.device);
g_signal_connect(G_OBJECT(mainbox.device), "changed",
G_CALLBACK(MainBoxDeviceEvent), NULL);
hbox1 = NULL;
mainbox.desc = gtk_label_new("File Type: ---");
gtk_box_pack_start(GTK_BOX(vbox1), mainbox.desc, FALSE, FALSE, 0);
gtk_widget_show(mainbox.desc);
hbox1 = gtk_hbutton_box_new();
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, TRUE, TRUE, 0);
gtk_widget_show(hbox1);
item = gtk_button_new_with_label("Ok");
gtk_box_pack_start(GTK_BOX(hbox1), item, TRUE, TRUE, 0);
gtk_widget_show(item);
g_signal_connect(G_OBJECT(item), "clicked",
G_CALLBACK(MainBoxOKEvent), NULL);
item = gtk_button_new_with_label("Cancel");
gtk_box_pack_start(GTK_BOX(hbox1), item, TRUE, TRUE, 0);
gtk_widget_show(item);
g_signal_connect(G_OBJECT(item), "clicked",
G_CALLBACK(MainBoxCancelEvent), NULL);
item = NULL;
hbox1 = NULL;
vbox1 = NULL;
// We held off setting the name until now... so description would show.
gtk_entry_set_text(GTK_ENTRY(mainbox.device), conf.devicename);
} // END MainBoxDisplay()
/* mainbox.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <stddef.h> // NULL
#include <stdio.h> // sprintf()
#include <string.h> // strcpy()
#include <sys/stat.h> // stat()
#include <sys/types.h> // stat()
#include <unistd.h> // stat()
#include <gtk/gtkbutton.h> // gtk_button_new_with_label()
#include <gtk/gtkcontainer.h> // gtk_container_add()
#include <gtk/gtkentry.h> // gtk_entry_new()
#include <gtk/gtkhbbox.h> // gtk_hbutton_box_new()
#include <gtk/gtkhbox.h> // gtk_hbox_new()
#include <gtk/gtklabel.h> // gtk_label_new()
#include <gtk/gtkmain.h> // gtk_init(), gtk_main(), gtk_main_quit()
#include <gtk/gtkvbox.h> // gtk_vbox_new()
#include <gtk/gtkwindow.h> // gtk_window_new()
#include "conf.h"
// #include "logfile.h"
#include "device.h" // DeviceOpen(), DeviceClose()
#include "mainbox.h"
struct MainBoxData mainbox;
void MainBoxDestroy() {
if(mainbox.window != NULL) {
gtk_widget_destroy(mainbox.window);
mainbox.window = NULL;
mainbox.device = NULL;
mainbox.desc = NULL;
} // ENDIF- Do we have a Main Window still?
} // END MainBoxDestroy()
void MainBoxUnfocus() {
gtk_widget_set_sensitive(mainbox.device, FALSE);
gtk_window_iconify(GTK_WINDOW(mainbox.window));
} // END MainBoxUnfocus()
gint MainBoxDeviceEvent(GtkWidget *widget, GdkEvent event, gpointer data) {
struct stat filestat;
int retval;
retval = stat(gtk_entry_get_text(GTK_ENTRY(mainbox.device)), &filestat);
if(retval == -1) {
gtk_label_set_text(GTK_LABEL(mainbox.desc), "Device Type: ---");
return(TRUE);
} // ENDIF- Not a name of any sort?
if(S_ISDIR(filestat.st_mode) != 0) {
gtk_label_set_text(GTK_LABEL(mainbox.desc), "Device Type: Not a device");
return(TRUE);
} // ENDIF- Not a regular file?
gtk_label_set_text(GTK_LABEL(mainbox.desc), "Device Type: Device Likely");
return(TRUE);
} // END MainBoxFileEvent()
void MainBoxRefocus() {
GdkEvent event;
MainBoxDeviceEvent(NULL, event, NULL);
gtk_widget_set_sensitive(mainbox.device, TRUE);
gtk_window_set_focus(GTK_WINDOW(mainbox.window), mainbox.device);
gtk_window_deiconify(GTK_WINDOW(mainbox.window));
} // END MainBoxRefocus()
gint MainBoxCancelEvent(GtkWidget *widget, GdkEvent event, gpointer data) {
MainBoxDestroy();
gtk_main_quit();
return(TRUE);
} // END MainBoxCancelEvent()
gint MainBoxOKEvent(GtkWidget *widget, GdkEvent event, gpointer data) {
const char *tempdevice;
int retval;
MainBoxUnfocus();
tempdevice = gtk_entry_get_text(GTK_ENTRY(mainbox.device));
strcpy(conf.devicename, tempdevice); // Temporarily put in new device name
tempdevice = NULL;
if(*(conf.devicename) != 0) {
retval = DeviceOpen(); // Test by opening the device.
DeviceClose(); // Failed or not, close it.
if(retval != 0) {
MainBoxRefocus();
return(TRUE);
} // ENDIF- Not an ISO file? Message and Stop here.
} // ENDIF- Is there an ISO file to check out?
SaveConf();
MainBoxCancelEvent(widget, event, data);
return(TRUE);
} // END MainBoxOKEvent()
void MainBoxDisplay() {
GtkWidget *item;
GtkWidget *hbox1;
GtkWidget *vbox1;
mainbox.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width(GTK_CONTAINER(mainbox.window), 5);
gtk_window_set_title(GTK_WINDOW(mainbox.window), "CDVDlinuz Configuration");
gtk_window_set_position(GTK_WINDOW(mainbox.window), GTK_WIN_POS_CENTER);
g_signal_connect(G_OBJECT(mainbox.window), "delete_event",
G_CALLBACK(MainBoxCancelEvent), NULL);
vbox1 = gtk_vbox_new(FALSE, 5);
gtk_container_add(GTK_CONTAINER(mainbox.window), vbox1);
gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5);
gtk_widget_show(vbox1);
hbox1 = gtk_hbox_new(FALSE, 10);
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, TRUE, TRUE, 0);
gtk_widget_show(hbox1);
item = gtk_label_new("CD/DVD Device:");
gtk_box_pack_start(GTK_BOX(hbox1), item, FALSE, FALSE, 0);
gtk_widget_show(item);
item = NULL;
mainbox.device = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(hbox1), mainbox.device, TRUE, TRUE, 0);
gtk_widget_show(mainbox.device);
g_signal_connect(G_OBJECT(mainbox.device), "changed",
G_CALLBACK(MainBoxDeviceEvent), NULL);
hbox1 = NULL;
mainbox.desc = gtk_label_new("File Type: ---");
gtk_box_pack_start(GTK_BOX(vbox1), mainbox.desc, FALSE, FALSE, 0);
gtk_widget_show(mainbox.desc);
hbox1 = gtk_hbutton_box_new();
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, TRUE, TRUE, 0);
gtk_widget_show(hbox1);
item = gtk_button_new_with_label("Ok");
gtk_box_pack_start(GTK_BOX(hbox1), item, TRUE, TRUE, 0);
gtk_widget_show(item);
g_signal_connect(G_OBJECT(item), "clicked",
G_CALLBACK(MainBoxOKEvent), NULL);
item = gtk_button_new_with_label("Cancel");
gtk_box_pack_start(GTK_BOX(hbox1), item, TRUE, TRUE, 0);
gtk_widget_show(item);
g_signal_connect(G_OBJECT(item), "clicked",
G_CALLBACK(MainBoxCancelEvent), NULL);
item = NULL;
hbox1 = NULL;
vbox1 = NULL;
// We held off setting the name until now... so description would show.
gtk_entry_set_text(GTK_ENTRY(mainbox.device), conf.devicename);
} // END MainBoxDisplay()

File diff suppressed because it is too large Load Diff

View File

@ -1,88 +1,88 @@
/* CD.h
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#ifndef CD_H
#define CD_H
#include <windows.h> // DWORD
#define CDVDdefs
#include "PS2Edefs.h"
extern DWORD cdblocksize;
extern void InitCDInfo();
extern s32 CDreadTrack(u32 lsn, int mode, u8 *buffer);
extern s32 CDgetBufferOffset();
extern s32 CDreadSubQ();
extern s32 CDgetTN(cdvdTN *cdvdtn);
extern s32 CDgetTD(u8 newtrack, cdvdTD *cdvdtd);
extern s32 CDgetDiskType();
#endif /* CD_H */
/* CD.h
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#ifndef CD_H
#define CD_H
#include <windows.h> // DWORD
#define CDVDdefs
#include "PS2Edefs.h"
extern DWORD cdblocksize;
extern void InitCDInfo();
extern s32 CDreadTrack(u32 lsn, int mode, u8 *buffer);
extern s32 CDgetBufferOffset();
extern s32 CDreadSubQ();
extern s32 CDgetTN(cdvdTN *cdvdtn);
extern s32 CDgetTD(u8 newtrack, cdvdTD *cdvdtd);
extern s32 CDgetDiskType();
#endif /* CD_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,80 +1,80 @@
/* CDVDlinuz.h
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#ifndef CDVDLINUZ_H
#define CDVDLINUZ_H
#include <windows.h> // HINSTANCE
// #define VERBOSE_WARNINGS
// #define VERBOSE_FUNCTION_INTERFACE
#define VERBOSE_DISC_INFO
#define VERBOSE_DISC_TYPE
#define READ_AHEAD_BUFFERS 32
extern HINSTANCE progmodule;
#endif /* CDVDLINUZ_H */
/* CDVDlinuz.h
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#ifndef CDVDLINUZ_H
#define CDVDLINUZ_H
#include <windows.h> // HINSTANCE
// #define VERBOSE_WARNINGS
// #define VERBOSE_FUNCTION_INTERFACE
#define VERBOSE_DISC_INFO
#define VERBOSE_DISC_TYPE
#define READ_AHEAD_BUFFERS 32
extern HINSTANCE progmodule;
#endif /* CDVDLINUZ_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,104 +1,104 @@
/* actualfile.h
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#ifndef ACTUALFILE_H
#define ACTUALFILE_H
#include <windows.h>
#include <sys/types.h> // off64_t
#define ACTUALHANDLE HANDLE
#define ACTUALHANDLENULL NULL
// #define VERBOSE_FUNCTION_ACTUALFILE
// #define VERBOSE_WARNING_ACTUALFILE
extern int IsActualFile(const char *filename);
extern void ActualFileDelete(const char *filename);
extern void ActualFileRename(const char *origname, const char *newname);
extern ACTUALHANDLE ActualFileOpenForRead(const char *filename);
extern off64_t ActualFileSize(ACTUALHANDLE handle);
extern int ActualFileSeek(ACTUALHANDLE handle, off64_t position);
extern int ActualFileRead(ACTUALHANDLE handle, int bytes, char *buffer);
extern void ActualFileClose(ACTUALHANDLE handle);
extern ACTUALHANDLE ActualFileOpenForWrite(const char *filename);
extern int ActualFileWrite(ACTUALHANDLE handle, int bytes, char *buffer);
#endif /* ACTUALFILE_H */
/* actualfile.h
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#ifndef ACTUALFILE_H
#define ACTUALFILE_H
#include <windows.h>
#include <sys/types.h> // off64_t
#define ACTUALHANDLE HANDLE
#define ACTUALHANDLENULL NULL
// #define VERBOSE_FUNCTION_ACTUALFILE
// #define VERBOSE_WARNING_ACTUALFILE
extern int IsActualFile(const char *filename);
extern void ActualFileDelete(const char *filename);
extern void ActualFileRename(const char *origname, const char *newname);
extern ACTUALHANDLE ActualFileOpenForRead(const char *filename);
extern off64_t ActualFileSize(ACTUALHANDLE handle);
extern int ActualFileSeek(ACTUALHANDLE handle, off64_t position);
extern int ActualFileRead(ACTUALHANDLE handle, int bytes, char *buffer);
extern void ActualFileClose(ACTUALHANDLE handle);
extern ACTUALHANDLE ActualFileOpenForWrite(const char *filename);
extern int ActualFileWrite(ACTUALHANDLE handle, int bytes, char *buffer);
#endif /* ACTUALFILE_H */

View File

@ -1,350 +1,350 @@
/* conf.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <errno.h> // errno
#include <stddef.h> // NULL
#include <stdio.h> // sprintf()
#include <stdlib.h> // getenv()
#include <string.h> // strerror()
#include <sys/stat.h> // mkdir(), stat()
#include <sys/types.h> // mkdir(), stat(), fork()
#include <unistd.h> // stat(), fork(), execlp()
#include <windows.h> // CreateProcess()
// #define CDVDdefs
// #include "../PS2Edefs.h"
#include "../PS2Etypes.h" // u8
#include "logfile.h"
#include "../ini.h"
#include "conf.h"
const char *confnames[] = { "Device", NULL };
const u8 defaultdevice[] = DEFAULT_DEVICE;
const char defaulthome[] = "inis";
const char defaultdirectory[] = "HideMe.PS2E";
const char defaultfile[] = "CDVDlinuz.ini";
char confdirname[256];
char conffilename[256];
CDVDconf conf;
void InitConf() {
DWORD retval;
int i;
int pos;
char *envptr;
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: InitConf()");
#endif /* VERBOSE_FUNCTION_CONF */
i = 0;
while((i < 255) && defaultdevice[i] != 0) {
conf.devicename[i] = defaultdevice[i];
i++;
} // ENDWHILE- copying the default CD/DVD name in
conf.devicename[i] = 0; // 0-terminate the device name
// Locating directory and file positions
pos = 0;
envptr = NULL;
// envptr = getenv("HOME");
if(envptr == NULL) {
// = <Default Home>
retval = GetCurrentDirectory(253, confdirname);
if(retval > 0) {
pos = retval;
} else {
pos = 2;
confdirname[0] = '.';
confdirname[1] = '\\';
} // ENDIF- Did we retrieve a directory reference?
i = 0;
while(i < pos) {
conffilename[i] = confdirname[i];
i++;
} // ENDWHILE- Copying dir info (so far) into file info
if(confdirname[pos-1] != '\\') {
confdirname[pos] = '\\';
conffilename[pos] = '\\';
pos++;
} // ENDIF- No directory separator here? Add one.
i = 0;
while((pos < 253) && (defaulthome[i] != 0)) {
confdirname[pos] = defaulthome[i];
conffilename[pos] = defaulthome[i];
pos++;
i++;
} // ENDWHILE- putting an offset where to store ini data
} else {
// = <Env Home>/<Default Directory>
i = 0;
while((pos < 253) && (*(envptr + i) != 0)) {
confdirname[pos] = *(envptr + i);
conffilename[pos] = *(envptr + i);
pos++;
i++;
} // ENDWHILE- copying home directory info in
if(confdirname[pos-1] != '\\') {
confdirname[pos] = '\\';
conffilename[pos] = '\\';
pos++;
} // ENDIF- No directory separator here? Add one.
i = 0;
while((pos < 253) && (defaultdirectory[i] != 0)) {
confdirname[pos] = defaultdirectory[i];
conffilename[pos] = defaultdirectory[i];
pos++;
i++;
} // NEXT- putting a default place to store configuration data
} // ENDIF- No Home directory?
confdirname[pos] = 0; // Directory reference finished
// += /<Config File Name>
if(conffilename[pos-1] != '\\') {
conffilename[pos] = '\\';
pos++;
} // ENDIF- No directory separator here? Add one.
i = 0;
while((pos < 253) && (defaultfile[i] != 0)) {
conffilename[pos] = defaultfile[i];
pos++;
i++;
} // NEXT- putting a default place to store configuration data
conffilename[pos] = 0; // File reference finished
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: Directory: %s", confdirname);
PrintLog("CDVD config: File: %s", conffilename);
#endif /* VERBOSE_FUNCTION_CONF */
} // END InitConf()
void LoadConf() {
int retval;
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: LoadConf()");
#endif /* VERBOSE_FUNCTION_CONF */
retval = INILoadString(conffilename, "Settings", "Device", conf.devicename);
if(retval < 0) {
sprintf(conf.devicename, "D:");
} // ENDIF- Couldn't find keyword? Fill in a default
} // END LoadConf()
void SaveConf() {
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: SaveConf()");
#endif /* VERBOSE_FUNCTION_CONF */
mkdir(confdirname);
INISaveString(conffilename, "Settings", "Device", conf.devicename);
} // END SaveConf()
/* conf.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <errno.h> // errno
#include <stddef.h> // NULL
#include <stdio.h> // sprintf()
#include <stdlib.h> // getenv()
#include <string.h> // strerror()
#include <sys/stat.h> // mkdir(), stat()
#include <sys/types.h> // mkdir(), stat(), fork()
#include <unistd.h> // stat(), fork(), execlp()
#include <windows.h> // CreateProcess()
// #define CDVDdefs
// #include "../PS2Edefs.h"
#include "../PS2Etypes.h" // u8
#include "logfile.h"
#include "../ini.h"
#include "conf.h"
const char *confnames[] = { "Device", NULL };
const u8 defaultdevice[] = DEFAULT_DEVICE;
const char defaulthome[] = "inis";
const char defaultdirectory[] = "HideMe.PS2E";
const char defaultfile[] = "CDVDlinuz.ini";
char confdirname[256];
char conffilename[256];
CDVDconf conf;
void InitConf() {
DWORD retval;
int i;
int pos;
char *envptr;
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: InitConf()");
#endif /* VERBOSE_FUNCTION_CONF */
i = 0;
while((i < 255) && defaultdevice[i] != 0) {
conf.devicename[i] = defaultdevice[i];
i++;
} // ENDWHILE- copying the default CD/DVD name in
conf.devicename[i] = 0; // 0-terminate the device name
// Locating directory and file positions
pos = 0;
envptr = NULL;
// envptr = getenv("HOME");
if(envptr == NULL) {
// = <Default Home>
retval = GetCurrentDirectory(253, confdirname);
if(retval > 0) {
pos = retval;
} else {
pos = 2;
confdirname[0] = '.';
confdirname[1] = '\\';
} // ENDIF- Did we retrieve a directory reference?
i = 0;
while(i < pos) {
conffilename[i] = confdirname[i];
i++;
} // ENDWHILE- Copying dir info (so far) into file info
if(confdirname[pos-1] != '\\') {
confdirname[pos] = '\\';
conffilename[pos] = '\\';
pos++;
} // ENDIF- No directory separator here? Add one.
i = 0;
while((pos < 253) && (defaulthome[i] != 0)) {
confdirname[pos] = defaulthome[i];
conffilename[pos] = defaulthome[i];
pos++;
i++;
} // ENDWHILE- putting an offset where to store ini data
} else {
// = <Env Home>/<Default Directory>
i = 0;
while((pos < 253) && (*(envptr + i) != 0)) {
confdirname[pos] = *(envptr + i);
conffilename[pos] = *(envptr + i);
pos++;
i++;
} // ENDWHILE- copying home directory info in
if(confdirname[pos-1] != '\\') {
confdirname[pos] = '\\';
conffilename[pos] = '\\';
pos++;
} // ENDIF- No directory separator here? Add one.
i = 0;
while((pos < 253) && (defaultdirectory[i] != 0)) {
confdirname[pos] = defaultdirectory[i];
conffilename[pos] = defaultdirectory[i];
pos++;
i++;
} // NEXT- putting a default place to store configuration data
} // ENDIF- No Home directory?
confdirname[pos] = 0; // Directory reference finished
// += /<Config File Name>
if(conffilename[pos-1] != '\\') {
conffilename[pos] = '\\';
pos++;
} // ENDIF- No directory separator here? Add one.
i = 0;
while((pos < 253) && (defaultfile[i] != 0)) {
conffilename[pos] = defaultfile[i];
pos++;
i++;
} // NEXT- putting a default place to store configuration data
conffilename[pos] = 0; // File reference finished
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: Directory: %s", confdirname);
PrintLog("CDVD config: File: %s", conffilename);
#endif /* VERBOSE_FUNCTION_CONF */
} // END InitConf()
void LoadConf() {
int retval;
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: LoadConf()");
#endif /* VERBOSE_FUNCTION_CONF */
retval = INILoadString(conffilename, "Settings", "Device", conf.devicename);
if(retval < 0) {
sprintf(conf.devicename, "D:");
} // ENDIF- Couldn't find keyword? Fill in a default
} // END LoadConf()
void SaveConf() {
#ifdef VERBOSE_FUNCTION_CONF
PrintLog("CDVD config: SaveConf()");
#endif /* VERBOSE_FUNCTION_CONF */
mkdir(confdirname);
INISaveString(conffilename, "Settings", "Device", conf.devicename);
} // END SaveConf()

File diff suppressed because it is too large Load Diff

View File

@ -1,238 +1,238 @@
/* logfile.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <windows.h>
// #include <fcntl.h> // open()
// #include <io.h> // mkdir()
#include <stddef.h> // NULL
#include <stdio.h> // vsprintf()
#include <stdarg.h> // va_start(), va_end(), vsprintf()
// #include <sys/stat.h> // open()
// #include <sys/types.h> // open()
#include "logfile.h"
HANDLE logfile;
char logfiletemp[2048];
void InitLog() {
// Token comment line
#ifdef VERBOSE_LOGFILE
CreateDirectory("logs", NULL);
DeleteFile("logs\\CDVDlog.txt");
logfile = NULL;
#endif /* VERBOSE LOGFILE */
} // END InitLog();
int OpenLog() {
// Token comment line
#ifdef VERBOSE_LOGFILE
logfile = CreateFile("logs\\CDVDlog.txt",
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if(logfile == INVALID_HANDLE_VALUE) {
logfile = NULL;
return(-1);
} // ENDIF- Failed to open? Say so.
#endif /* VERBOSE LOGFILE */
return(0);
} // END OpenLog();
void CloseLog() {
// Token comment line
#ifdef VERBOSE_LOGFILE
if(logfile != NULL) {
CloseHandle(logfile);
logfile = NULL;
} // ENDIF- Is the log file actually open? Close it.
#endif /* VERBOSE LOGFILE */
} // END CloseLog()
void PrintLog(const char *fmt, ...) {
DWORD byteswritten;
// Token comment line
#ifdef VERBOSE_LOGFILE
va_list list;
int len;
if(logfile == NULL) return; // Log file not open... yet.
va_start(list, fmt);
vsprintf(logfiletemp, fmt, list);
va_end(list);
len = 0;
while((len < 2048) && (logfiletemp[len] != 0)) len++;
if((len > 0) && (logfiletemp[len-1] == '\n')) len--;
if((len > 0) && (logfiletemp[len-1] == '\r')) len--;
logfiletemp[len] = 0; // Slice off the last "\r\n"...
WriteFile(logfile, logfiletemp, len, &byteswritten, NULL);
WriteFile(logfile, "\r\n", 2, &byteswritten, NULL);
#endif /* VERBOSE LOGFILE */
} // END PrintLog()
void PrintError(const char *header, DWORD errcode) {
#ifdef VERBOSE_LOGFILE
TCHAR errmsg[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | 80,
NULL,
errcode,
0,
errmsg,
256,
NULL);
PrintLog("%s: (%u) %s", header, errcode, errmsg);
#endif /* VERBOSE_WARNING_DEVICE */
} // END PrintError()
/* logfile.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <windows.h>
// #include <fcntl.h> // open()
// #include <io.h> // mkdir()
#include <stddef.h> // NULL
#include <stdio.h> // vsprintf()
#include <stdarg.h> // va_start(), va_end(), vsprintf()
// #include <sys/stat.h> // open()
// #include <sys/types.h> // open()
#include "logfile.h"
HANDLE logfile;
char logfiletemp[2048];
void InitLog() {
// Token comment line
#ifdef VERBOSE_LOGFILE
CreateDirectory("logs", NULL);
DeleteFile("logs\\CDVDlog.txt");
logfile = NULL;
#endif /* VERBOSE LOGFILE */
} // END InitLog();
int OpenLog() {
// Token comment line
#ifdef VERBOSE_LOGFILE
logfile = CreateFile("logs\\CDVDlog.txt",
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if(logfile == INVALID_HANDLE_VALUE) {
logfile = NULL;
return(-1);
} // ENDIF- Failed to open? Say so.
#endif /* VERBOSE LOGFILE */
return(0);
} // END OpenLog();
void CloseLog() {
// Token comment line
#ifdef VERBOSE_LOGFILE
if(logfile != NULL) {
CloseHandle(logfile);
logfile = NULL;
} // ENDIF- Is the log file actually open? Close it.
#endif /* VERBOSE LOGFILE */
} // END CloseLog()
void PrintLog(const char *fmt, ...) {
DWORD byteswritten;
// Token comment line
#ifdef VERBOSE_LOGFILE
va_list list;
int len;
if(logfile == NULL) return; // Log file not open... yet.
va_start(list, fmt);
vsprintf(logfiletemp, fmt, list);
va_end(list);
len = 0;
while((len < 2048) && (logfiletemp[len] != 0)) len++;
if((len > 0) && (logfiletemp[len-1] == '\n')) len--;
if((len > 0) && (logfiletemp[len-1] == '\r')) len--;
logfiletemp[len] = 0; // Slice off the last "\r\n"...
WriteFile(logfile, logfiletemp, len, &byteswritten, NULL);
WriteFile(logfile, "\r\n", 2, &byteswritten, NULL);
#endif /* VERBOSE LOGFILE */
} // END PrintLog()
void PrintError(const char *header, DWORD errcode) {
#ifdef VERBOSE_LOGFILE
TCHAR errmsg[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | 80,
NULL,
errcode,
0,
errmsg,
256,
NULL);
PrintLog("%s: (%u) %s", header, errcode, errmsg);
#endif /* VERBOSE_WARNING_DEVICE */
} // END PrintError()

View File

@ -1,346 +1,346 @@
/* mainbox.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <windows.h>
// #include <windowsx.h> // Button_
#include <windef.h> // NULL
#include <stdio.h> // sprintf()
#include <string.h> // strcpy()
#include <sys/stat.h> // stat()
#include <sys/types.h> // stat()
#include <unistd.h> // stat()
#include "conf.h"
#include "device.h"
// #include "imagetype.h" // imagedata[].name
#include "screens.h" // DLG_, IDC_
#include "CDVDlinuz.h" // progmodule
#include "mainbox.h"
HWND mainboxwindow;
void MainBoxDestroy() {
if(mainboxwindow != NULL) {
EndDialog(mainboxwindow, FALSE);
mainboxwindow = NULL;
} // ENDIF- Do we have a Main Window still?
} // END MainBoxDestroy()
void MainBoxUnfocus() {
// EnableWindow(?)
// gtk_widget_set_sensitive(mainbox.device, FALSE);
ShowWindow(mainboxwindow, SW_HIDE);
} // END MainBoxUnfocus()
void MainBoxDeviceEvent() {
char tempdevice[256];
struct stat filestat;
int returnval;
GetDlgItemText(mainboxwindow, IDC_0202, tempdevice, 256);
returnval = stat(tempdevice, &filestat);
if(returnval == -1) {
SetDlgItemText(mainboxwindow, IDC_0203, "Device Type: ---");
return;
} // ENDIF- Not a name of any sort?
if(S_ISDIR(filestat.st_mode) != 0) {
SetDlgItemText(mainboxwindow, IDC_0203, "Device Type: Not a device");
return;
} // ENDIF- Not a regular file?
SetDlgItemText(mainboxwindow, IDC_0203, "Device Type: Device Likely");
return;
} // END MainBoxFileEvent()
void MainBoxRefocus() {
MainBoxDeviceEvent();
// gtk_widget_set_sensitive(mainbox.device, TRUE);
// gtk_window_set_focus(GTK_WINDOW(mainbox.window), mainbox.device);
// ShowWindow(mainboxwindow, SW_RESTORE); // and/or, SW_SHOW? SW_SHOWNORMAL?
ShowWindow(mainboxwindow, SW_SHOW);
SetActiveWindow(mainboxwindow);
} // END MainBoxRefocus()
void MainBoxCancelEvent() {
MainBoxDestroy();
return;
} // END MainBoxCancelEvent()
void MainBoxOKEvent() {
int retval;
MainBoxUnfocus();
GetDlgItemText(mainboxwindow, IDC_0202, conf.devicename, 256);
retval = DeviceOpen();
DeviceClose();
if(retval != 0) {
MainBoxRefocus();
MessageBox(mainboxwindow,
"Could not open the device",
"CDVDlinuz Message",
MB_OK | MB_ICONWARNING | MB_SETFOREGROUND);
return;
} // ENDIF- Trouble opening device? Abort here.
SaveConf();
MainBoxCancelEvent();
return;
} // END MainBoxOKEvent()
void MainBoxDisplay() {
InitConf(); // Man, am I boiling mad! CDVDinit() should have been called first!
LoadConf();
// Adjust window position?
// We held off setting the name until now... so description would show.
SetDlgItemText(mainboxwindow, IDC_0202, conf.devicename);
// First Time - Show the window
ShowWindow(mainboxwindow, SW_SHOWNORMAL);
} // END MainBoxDisplay()
BOOL CALLBACK MainBoxCallback(HWND window,
UINT msg,
WPARAM param,
LPARAM param2) {
switch(msg) {
case WM_INITDIALOG:
mainboxwindow = window;
MainBoxDisplay(); // In this case, final touches to this window.
return(FALSE); // And let Windows display this window.
break;
case WM_CLOSE: // The "X" in the upper right corner was hit.
MainBoxCancelEvent();
return(TRUE);
break;
case WM_COMMAND:
// Do we wish to capture 'ENTER/RETURN' and/or 'ESC' here?
switch(LOWORD(param)) {
case IDC_0202: // Devicename Edit Box
MainBoxDeviceEvent(); // Describe the File's type...
return(FALSE); // Let Windows handle the actual 'edit' processing...
break;
case IDC_0204: // "Ok" Button
MainBoxOKEvent();
return(TRUE);
break;
case IDC_0205: // "Cancel" Button
MainBoxCancelEvent();
return(TRUE);
break;
} // ENDSWITCH param- Which object got the message?
} // ENDSWITCH msg- what message has been sent to this window?
return(FALSE); // Not a recognized message? Tell Windows to handle it.
} // END MainBoxEventLoop()
/* mainbox.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <windows.h>
// #include <windowsx.h> // Button_
#include <windef.h> // NULL
#include <stdio.h> // sprintf()
#include <string.h> // strcpy()
#include <sys/stat.h> // stat()
#include <sys/types.h> // stat()
#include <unistd.h> // stat()
#include "conf.h"
#include "device.h"
// #include "imagetype.h" // imagedata[].name
#include "screens.h" // DLG_, IDC_
#include "CDVDlinuz.h" // progmodule
#include "mainbox.h"
HWND mainboxwindow;
void MainBoxDestroy() {
if(mainboxwindow != NULL) {
EndDialog(mainboxwindow, FALSE);
mainboxwindow = NULL;
} // ENDIF- Do we have a Main Window still?
} // END MainBoxDestroy()
void MainBoxUnfocus() {
// EnableWindow(?)
// gtk_widget_set_sensitive(mainbox.device, FALSE);
ShowWindow(mainboxwindow, SW_HIDE);
} // END MainBoxUnfocus()
void MainBoxDeviceEvent() {
char tempdevice[256];
struct stat filestat;
int returnval;
GetDlgItemText(mainboxwindow, IDC_0202, tempdevice, 256);
returnval = stat(tempdevice, &filestat);
if(returnval == -1) {
SetDlgItemText(mainboxwindow, IDC_0203, "Device Type: ---");
return;
} // ENDIF- Not a name of any sort?
if(S_ISDIR(filestat.st_mode) != 0) {
SetDlgItemText(mainboxwindow, IDC_0203, "Device Type: Not a device");
return;
} // ENDIF- Not a regular file?
SetDlgItemText(mainboxwindow, IDC_0203, "Device Type: Device Likely");
return;
} // END MainBoxFileEvent()
void MainBoxRefocus() {
MainBoxDeviceEvent();
// gtk_widget_set_sensitive(mainbox.device, TRUE);
// gtk_window_set_focus(GTK_WINDOW(mainbox.window), mainbox.device);
// ShowWindow(mainboxwindow, SW_RESTORE); // and/or, SW_SHOW? SW_SHOWNORMAL?
ShowWindow(mainboxwindow, SW_SHOW);
SetActiveWindow(mainboxwindow);
} // END MainBoxRefocus()
void MainBoxCancelEvent() {
MainBoxDestroy();
return;
} // END MainBoxCancelEvent()
void MainBoxOKEvent() {
int retval;
MainBoxUnfocus();
GetDlgItemText(mainboxwindow, IDC_0202, conf.devicename, 256);
retval = DeviceOpen();
DeviceClose();
if(retval != 0) {
MainBoxRefocus();
MessageBox(mainboxwindow,
"Could not open the device",
"CDVDlinuz Message",
MB_OK | MB_ICONWARNING | MB_SETFOREGROUND);
return;
} // ENDIF- Trouble opening device? Abort here.
SaveConf();
MainBoxCancelEvent();
return;
} // END MainBoxOKEvent()
void MainBoxDisplay() {
InitConf(); // Man, am I boiling mad! CDVDinit() should have been called first!
LoadConf();
// Adjust window position?
// We held off setting the name until now... so description would show.
SetDlgItemText(mainboxwindow, IDC_0202, conf.devicename);
// First Time - Show the window
ShowWindow(mainboxwindow, SW_SHOWNORMAL);
} // END MainBoxDisplay()
BOOL CALLBACK MainBoxCallback(HWND window,
UINT msg,
WPARAM param,
LPARAM param2) {
switch(msg) {
case WM_INITDIALOG:
mainboxwindow = window;
MainBoxDisplay(); // In this case, final touches to this window.
return(FALSE); // And let Windows display this window.
break;
case WM_CLOSE: // The "X" in the upper right corner was hit.
MainBoxCancelEvent();
return(TRUE);
break;
case WM_COMMAND:
// Do we wish to capture 'ENTER/RETURN' and/or 'ESC' here?
switch(LOWORD(param)) {
case IDC_0202: // Devicename Edit Box
MainBoxDeviceEvent(); // Describe the File's type...
return(FALSE); // Let Windows handle the actual 'edit' processing...
break;
case IDC_0204: // "Ok" Button
MainBoxOKEvent();
return(TRUE);
break;
case IDC_0205: // "Cancel" Button
MainBoxCancelEvent();
return(TRUE);
break;
} // ENDSWITCH param- Which object got the message?
} // ENDSWITCH msg- what message has been sent to this window?
return(FALSE); // Not a recognized message? Tell Windows to handle it.
} // END MainBoxEventLoop()

View File

@ -1,18 +1,18 @@
/* Weditres generated include file. Do NOT edit */
#include <windows.h>
#define DLG_0100 100
#define IDC_0104 104
#define DLG_0200 200
#define IDC_0202 202
#define IDC_0203 203
#define IDC_0204 204
#define IDC_0205 205
/* Weditres generated include file. Do NOT edit */
#include <windows.h>
#define DLG_0100 100
#define IDC_0104 104
#define DLG_0200 200
#define IDC_0202 202
#define IDC_0203 203
#define IDC_0204 204
#define IDC_0205 205

File diff suppressed because it is too large Load Diff

View File

@ -1,134 +1,134 @@
/* buffer.h
* Copyright (C) 2002-2005 CDVDlinuz 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 __BUFFER_H__
#define __BUFFER_H__
#define CDVDdefs
#include "PS2Edefs.h"
// #define VERBOSE_FUNCTION_BUFFER
// #define VERBOSE_WARNINGS_BUFFER
// Remember, each buffer set is about 5k (packed. might be 4x that in-memory)
// Minimum: 16 Maximum: 32760
#define BUFFERMAX 256
// Buffer Structures
struct BufferList {
u16 upsort; // Don't alter this variable
u16 uppos; // Don't alter this variable
u32 lsn;
int mode; // -1 means error
u8 buffer[2368];
u8 offset;
cdvdSubQ subq;
};
// Exported Variables
extern struct BufferList bufferlist[];
extern u16 userbuffer;
extern u16 replacebuffer;
// Exported Functions
extern void InitBuffer();
extern u16 FindListBuffer(u32 lsn);
extern void RemoveListBuffer(u16 oldbuffer);
extern void AddListBuffer(u16 newbuffer);
#ifdef VERBOSE_WARNINGS_BUFFER
extern void PrintSortBuffers();
#endif /* VERBOSE_WARNINGS_BUFFER */
#endif /* __BUFFER_H__ */
/* buffer.h
* Copyright (C) 2002-2005 CDVDlinuz 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 __BUFFER_H__
#define __BUFFER_H__
#define CDVDdefs
#include "PS2Edefs.h"
// #define VERBOSE_FUNCTION_BUFFER
// #define VERBOSE_WARNINGS_BUFFER
// Remember, each buffer set is about 5k (packed. might be 4x that in-memory)
// Minimum: 16 Maximum: 32760
#define BUFFERMAX 256
// Buffer Structures
struct BufferList {
u16 upsort; // Don't alter this variable
u16 uppos; // Don't alter this variable
u32 lsn;
int mode; // -1 means error
u8 buffer[2368];
u8 offset;
cdvdSubQ subq;
};
// Exported Variables
extern struct BufferList bufferlist[];
extern u16 userbuffer;
extern u16 replacebuffer;
// Exported Functions
extern void InitBuffer();
extern u16 FindListBuffer(u32 lsn);
extern void RemoveListBuffer(u16 oldbuffer);
extern void AddListBuffer(u16 newbuffer);
#ifdef VERBOSE_WARNINGS_BUFFER
extern void PrintSortBuffers();
#endif /* VERBOSE_WARNINGS_BUFFER */
#endif /* __BUFFER_H__ */

View File

@ -1,236 +1,236 @@
/* convert.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <stddef.h>
#include <sys/types.h>
#include "convert.h"
off64_t ConvertEndianOffset(off64_t number) {
#ifndef CONVERTLITTLEENDIAN
union {
off64_t n;
char c[sizeof(off64_t)];
} oldnumber, newnumber;
int i;
oldnumber.n = number;
for(i = 0; i < sizeof(off64_t); i++)
newnumber.c[i] = oldnumber.c[sizeof(off64_t) - 1 - i];
return(newnumber.n);
#else
return(number);
#endif /* CONVERTLITTLEENDIAN */
} // END ConvertEndianOffset()
unsigned int ConvertEndianUInt(unsigned int number) {
#ifndef CONVERTLITTLEENDIAN
union {
unsigned int n;
char c[sizeof(unsigned int)];
} oldnumber, newnumber;
int i;
oldnumber.n = number;
for(i = 0; i < sizeof(unsigned int); i++)
newnumber.c[i] = oldnumber.c[sizeof(unsigned int) - 1 - i];
return(newnumber.n);
#else
return(number);
#endif /* CONVERTLITTLEENDIAN */
} // END ConvertEndianUInt()
unsigned short ConvertEndianUShort(unsigned short number) {
#ifndef CONVERTLITTLEENDIAN
union {
unsigned short n;
char c[sizeof(unsigned short)];
} oldnumber, newnumber;
int i;
oldnumber.n = number;
for(i = 0; i < sizeof(unsigned short); i++)
newnumber.c[i] = oldnumber.c[sizeof(unsigned short) - 1 - i];
return(newnumber.n);
#else
return(number);
#endif /* CONVERTLITTLEENDIAN */
} // END ConvertEndianUShort()
// Note: deposits M/S/F data in buffer[0]/[1]/[2] respectively.
void LBAtoMSF(unsigned long lsn, char *buffer) {
unsigned long templsn;
if(lsn >= 0xFFFFFFFF - 150) {
*(buffer + 2) = 75-1;
*(buffer + 1) = 60-1;
*(buffer) = 100-1;
} // ENDIF- Out of range?
templsn = lsn;
templsn += 150; // 2 second offset (75 Frames * 2 Seconds)
*(buffer + 2) = templsn % 75; // Remainder in frames
templsn -= *(buffer + 2);
templsn /= 75;
*(buffer + 1) = templsn % 60; // Remainder in seconds
templsn -= *(buffer + 1);
templsn /= 60;
*(buffer) = templsn; // Leftover quotient in minutes
} // END LBAtoMSF()
unsigned long MSFtoLBA(char *buffer) {
unsigned long templsn;
if(buffer == NULL) return(0xFFFFFFFF);
templsn = *(buffer); // Minutes
templsn *= 60;
templsn += *(buffer + 1); // Seconds
templsn *= 75;
templsn += *(buffer + 2); // Frames
if(templsn < 150) return(0xFFFFFFFF);
templsn -= 150; // Offset
return(templsn);
} // END MSFtoLBA()
/* convert.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#include <stddef.h>
#include <sys/types.h>
#include "convert.h"
off64_t ConvertEndianOffset(off64_t number) {
#ifndef CONVERTLITTLEENDIAN
union {
off64_t n;
char c[sizeof(off64_t)];
} oldnumber, newnumber;
int i;
oldnumber.n = number;
for(i = 0; i < sizeof(off64_t); i++)
newnumber.c[i] = oldnumber.c[sizeof(off64_t) - 1 - i];
return(newnumber.n);
#else
return(number);
#endif /* CONVERTLITTLEENDIAN */
} // END ConvertEndianOffset()
unsigned int ConvertEndianUInt(unsigned int number) {
#ifndef CONVERTLITTLEENDIAN
union {
unsigned int n;
char c[sizeof(unsigned int)];
} oldnumber, newnumber;
int i;
oldnumber.n = number;
for(i = 0; i < sizeof(unsigned int); i++)
newnumber.c[i] = oldnumber.c[sizeof(unsigned int) - 1 - i];
return(newnumber.n);
#else
return(number);
#endif /* CONVERTLITTLEENDIAN */
} // END ConvertEndianUInt()
unsigned short ConvertEndianUShort(unsigned short number) {
#ifndef CONVERTLITTLEENDIAN
union {
unsigned short n;
char c[sizeof(unsigned short)];
} oldnumber, newnumber;
int i;
oldnumber.n = number;
for(i = 0; i < sizeof(unsigned short); i++)
newnumber.c[i] = oldnumber.c[sizeof(unsigned short) - 1 - i];
return(newnumber.n);
#else
return(number);
#endif /* CONVERTLITTLEENDIAN */
} // END ConvertEndianUShort()
// Note: deposits M/S/F data in buffer[0]/[1]/[2] respectively.
void LBAtoMSF(unsigned long lsn, char *buffer) {
unsigned long templsn;
if(lsn >= 0xFFFFFFFF - 150) {
*(buffer + 2) = 75-1;
*(buffer + 1) = 60-1;
*(buffer) = 100-1;
} // ENDIF- Out of range?
templsn = lsn;
templsn += 150; // 2 second offset (75 Frames * 2 Seconds)
*(buffer + 2) = templsn % 75; // Remainder in frames
templsn -= *(buffer + 2);
templsn /= 75;
*(buffer + 1) = templsn % 60; // Remainder in seconds
templsn -= *(buffer + 1);
templsn /= 60;
*(buffer) = templsn; // Leftover quotient in minutes
} // END LBAtoMSF()
unsigned long MSFtoLBA(char *buffer) {
unsigned long templsn;
if(buffer == NULL) return(0xFFFFFFFF);
templsn = *(buffer); // Minutes
templsn *= 60;
templsn += *(buffer + 1); // Seconds
templsn *= 75;
templsn += *(buffer + 2); // Frames
if(templsn < 150) return(0xFFFFFFFF);
templsn -= 150; // Offset
return(templsn);
} // END MSFtoLBA()

File diff suppressed because it is too large Load Diff

View File

@ -1,72 +1,72 @@
/* version.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#ifndef __LINUX__
#ifdef __linux__
#define __LINUX__
#endif /* __linux__ */
#endif /* No __LINUX__ */
#define CDVDdefs
#include "PS2Edefs.h"
char *libname = "EFP polling CDVD Driver";
const unsigned char version = PS2E_CDVD_VERSION;
const unsigned char revision = 0;
const unsigned char build = 4;
/* version.c
* Copyright (C) 2002-2005 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
*
* PCSX2 members can be contacted through their website at www.pcsx2.net.
*/
#ifndef __LINUX__
#ifdef __linux__
#define __LINUX__
#endif /* __linux__ */
#endif /* No __LINUX__ */
#define CDVDdefs
#include "PS2Edefs.h"
char *libname = "EFP polling CDVD Driver";
const unsigned char version = PS2E_CDVD_VERSION;
const unsigned char revision = 0;
const unsigned char build = 4;

View File

@ -1,177 +1,177 @@
/*
* 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 "CDVD.h"
#include "CDVDDialog.h"
CDVDDialog::CDVDDialog(UINT id)
: m_id(id)
, m_hWnd(NULL)
{
}
INT_PTR CDVDDialog::DoModal()
{
return DialogBoxParam(theApp.GetModuleHandle(), MAKEINTRESOURCE(m_id), NULL, DialogProc, (LPARAM)this);
}
INT_PTR CALLBACK CDVDDialog::DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
CDVDDialog* dlg = NULL;
if(message == WM_INITDIALOG)
{
dlg = (CDVDDialog*)lParam;
SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)dlg);
dlg->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;
}
/*
* 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 "CDVD.h"
#include "CDVDDialog.h"
CDVDDialog::CDVDDialog(UINT id)
: m_id(id)
, m_hWnd(NULL)
{
}
INT_PTR CDVDDialog::DoModal()
{
return DialogBoxParam(theApp.GetModuleHandle(), MAKEINTRESOURCE(m_id), NULL, DialogProc, (LPARAM)this);
}
INT_PTR CALLBACK CDVDDialog::DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
CDVDDialog* dlg = NULL;
if(message == WM_INITDIALOG)
{
dlg = (CDVDDialog*)lParam;
SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)dlg);
dlg->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;
}

View File

@ -1,59 +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);
};
/*
* 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);
};

View File

@ -1,59 +1,59 @@
#ifndef __LIBISO_H__
#define __LIBISO_H__
#ifdef __MSCW32__
#pragma warning(disable:4018)
#endif
#define CDVDdefs
#include "PS2Etypes.h"
#include "PS2Edefs.h"
#define ISOTYPE_ILLEGAL 0
#define ISOTYPE_CD 1
#define ISOTYPE_DVD 2
#define ISOTYPE_AUDIO 3
#define ISOFLAGS_Z 0x1
#define ISOFLAGS_Z2 0x2
#define ISOFLAGS_BLOCKDUMP 0x4
#define CD_FRAMESIZE_RAW 2352
#define DATA_SIZE (CD_FRAMESIZE_RAW-12)
#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */
#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */
typedef struct {
char filename[256];
u32 type;
u32 flags;
u32 offset;
u32 blockofs;
u32 blocksize;
u32 blocks;
void *handle;
void *htable;
char *Ztable;
u32 *dtable;
int dtablesize;
char buffer[CD_FRAMESIZE_RAW * 10];
} isoFile;
isoFile *isoOpen(const char *filename);
isoFile *isoCreate(const char *filename, int mode);
int isoSetFormat(isoFile *iso, int blockofs, int blocksize, int blocks);
int isoDetect(isoFile *iso);
int isoReadBlock(isoFile *iso, char *dst, int lsn);
int isoWriteBlock(isoFile *iso, char *src, int lsn);
void isoClose(isoFile *iso);
void *_openfile(const char *filename, int flags);
u64 _tellfile(void *handle);
int _seekfile(void *handle, u64 offset, int whence);
int _readfile(void *handle, void *dst, int size);
int _writefile(void *handle, void *src, int size);
void _closefile(void *handle);
#endif /* __LIBISO_H__ */
#ifndef __LIBISO_H__
#define __LIBISO_H__
#ifdef __MSCW32__
#pragma warning(disable:4018)
#endif
#define CDVDdefs
#include "PS2Etypes.h"
#include "PS2Edefs.h"
#define ISOTYPE_ILLEGAL 0
#define ISOTYPE_CD 1
#define ISOTYPE_DVD 2
#define ISOTYPE_AUDIO 3
#define ISOFLAGS_Z 0x1
#define ISOFLAGS_Z2 0x2
#define ISOFLAGS_BLOCKDUMP 0x4
#define CD_FRAMESIZE_RAW 2352
#define DATA_SIZE (CD_FRAMESIZE_RAW-12)
#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */
#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */
typedef struct {
char filename[256];
u32 type;
u32 flags;
u32 offset;
u32 blockofs;
u32 blocksize;
u32 blocks;
void *handle;
void *htable;
char *Ztable;
u32 *dtable;
int dtablesize;
char buffer[CD_FRAMESIZE_RAW * 10];
} isoFile;
isoFile *isoOpen(const char *filename);
isoFile *isoCreate(const char *filename, int mode);
int isoSetFormat(isoFile *iso, int blockofs, int blocksize, int blocks);
int isoDetect(isoFile *iso);
int isoReadBlock(isoFile *iso, char *dst, int lsn);
int isoWriteBlock(isoFile *iso, char *src, int lsn);
void isoClose(isoFile *iso);
void *_openfile(const char *filename, int flags);
u64 _tellfile(void *handle);
int _seekfile(void *handle, u64 offset, int whence);
int _readfile(void *handle, void *dst, int size);
int _writefile(void *handle, void *src, int size);
void _closefile(void *handle);
#endif /* __LIBISO_H__ */

View File

@ -1,51 +1,51 @@
#include <stdlib.h>
#include "../FW.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 ;
}
#include <stdlib.h>
#include "../FW.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 ;
}

View File

@ -1,81 +1,81 @@
#include <stdio.h>
#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#include "../FW.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(GetActiveWindow(), tmp, "FW Plugin Msg", MB_SETFOREGROUND | MB_OK);
}
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;
}
void CALLBACK FWconfigure() {
DialogBox(hInst,
MAKEINTRESOURCE(IDD_CONFIG),
GetActiveWindow(),
(DLGPROC)ConfigureDlgProc);
}
void CALLBACK FWabout() {
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 :)
}
#include <stdio.h>
#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#include "../FW.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(GetActiveWindow(), tmp, "FW Plugin Msg", MB_SETFOREGROUND | MB_OK);
}
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;
}
void CALLBACK FWconfigure() {
DialogBox(hInst,
MAKEINTRESOURCE(IDD_CONFIG),
GetActiveWindow(),
(DLGPROC)ConfigureDlgProc);
}
void CALLBACK FWabout() {
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 :)
}

View File

@ -1,71 +1,71 @@
/*
* 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 "GSCodeBuffer.h"
GSCodeBuffer::GSCodeBuffer(size_t blocksize)
: m_ptr(NULL)
, m_blocksize(blocksize)
, m_pos(0)
, m_reserved(0)
{
}
GSCodeBuffer::~GSCodeBuffer()
{
for(list<void*>::iterator i = m_buffers.begin(); i != m_buffers.end(); i++)
{
VirtualFree(*i, 0, MEM_RELEASE);
}
}
void* GSCodeBuffer::GetBuffer(size_t size)
{
ASSERT(size < m_blocksize);
ASSERT(m_reserved == 0);
size = (size + 15) & ~15;
if(m_ptr == NULL || m_pos + size > m_blocksize)
{
m_ptr = (uint8*)VirtualAlloc(NULL, m_blocksize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
m_pos = 0;
m_buffers.push_back(m_ptr);
}
uint8* ptr = &m_ptr[m_pos];
m_reserved = size;
return ptr;
}
void GSCodeBuffer::ReleaseBuffer(size_t size)
{
ASSERT(size <= m_reserved);
m_pos = ((m_pos + size) + 15) & ~15;
m_reserved = 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 "GSCodeBuffer.h"
GSCodeBuffer::GSCodeBuffer(size_t blocksize)
: m_ptr(NULL)
, m_blocksize(blocksize)
, m_pos(0)
, m_reserved(0)
{
}
GSCodeBuffer::~GSCodeBuffer()
{
for(list<void*>::iterator i = m_buffers.begin(); i != m_buffers.end(); i++)
{
VirtualFree(*i, 0, MEM_RELEASE);
}
}
void* GSCodeBuffer::GetBuffer(size_t size)
{
ASSERT(size < m_blocksize);
ASSERT(m_reserved == 0);
size = (size + 15) & ~15;
if(m_ptr == NULL || m_pos + size > m_blocksize)
{
m_ptr = (uint8*)VirtualAlloc(NULL, m_blocksize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
m_pos = 0;
m_buffers.push_back(m_ptr);
}
uint8* ptr = &m_ptr[m_pos];
m_reserved = size;
return ptr;
}
void GSCodeBuffer::ReleaseBuffer(size_t size)
{
ASSERT(size <= m_reserved);
m_pos = ((m_pos + size) + 15) & ~15;
m_reserved = 0;
}

View File

@ -1,37 +1,37 @@
/*
* 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 GSCodeBuffer
{
list<void*> m_buffers;
size_t m_blocksize;
size_t m_pos, m_reserved;
uint8* m_ptr;
public:
GSCodeBuffer(size_t blocksize = 4096 * 64); // 256k
virtual ~GSCodeBuffer();
void* GetBuffer(size_t size);
void ReleaseBuffer(size_t size);
/*
* 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 GSCodeBuffer
{
list<void*> m_buffers;
size_t m_blocksize;
size_t m_pos, m_reserved;
uint8* m_ptr;
public:
GSCodeBuffer(size_t blocksize = 4096 * 64); // 256k
virtual ~GSCodeBuffer();
void* GetBuffer(size_t size);
void ReleaseBuffer(size_t size);
};

View File

@ -1,180 +1,180 @@
/*
* 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 "GSDeviceDX.h"
#include "GSTexture11.h"
struct GSVertexShader11
{
CComPtr<ID3D11VertexShader> vs;
CComPtr<ID3D11InputLayout> il;
};
class GSDevice11 : public GSDeviceDX
{
GSTexture* Create(int type, int w, int h, bool msaa, 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<ID3D11Device> m_dev;
CComPtr<ID3D11DeviceContext> m_ctx;
CComPtr<IDXGISwapChain> m_swapchain;
CComPtr<ID3D11Buffer> m_vb;
CComPtr<ID3D11Buffer> m_vb_old;
struct
{
ID3D11Buffer* vb;
size_t vb_stride;
ID3D11InputLayout* layout;
D3D11_PRIMITIVE_TOPOLOGY topology;
ID3D11VertexShader* vs;
ID3D11Buffer* vs_cb;
ID3D11GeometryShader* gs;
ID3D11ShaderResourceView* ps_srv[2];
ID3D11PixelShader* ps;
ID3D11Buffer* ps_cb;
ID3D11SamplerState* ps_ss[2];
GSVector2i viewport;
GSVector4i scissor;
ID3D11DepthStencilState* dss;
uint8 sref;
ID3D11BlendState* bs;
float bf;
ID3D11RenderTargetView* rtv;
ID3D11DepthStencilView* dsv;
} m_state;
public: // TODO
CComPtr<ID3D11RasterizerState> m_rs;
struct
{
CComPtr<ID3D11InputLayout> il;
CComPtr<ID3D11VertexShader> vs;
CComPtr<ID3D11PixelShader> ps[7];
CComPtr<ID3D11SamplerState> ln;
CComPtr<ID3D11SamplerState> pt;
CComPtr<ID3D11DepthStencilState> dss;
CComPtr<ID3D11BlendState> bs;
} m_convert;
struct
{
CComPtr<ID3D11PixelShader> ps[2];
CComPtr<ID3D11Buffer> cb;
CComPtr<ID3D11BlendState> bs;
} m_merge;
struct
{
CComPtr<ID3D11PixelShader> ps[4];
CComPtr<ID3D11Buffer> cb;
} m_interlace;
struct
{
CComPtr<ID3D11DepthStencilState> dss;
CComPtr<ID3D11BlendState> bs;
} m_date;
void SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1 (&iaVertices)[4], bool datm);
// Shaders...
hash_map<uint32, GSVertexShader11 > m_vs;
CComPtr<ID3D11Buffer> m_vs_cb;
hash_map<uint32, CComPtr<ID3D11GeometryShader> > m_gs;
hash_map<uint32, CComPtr<ID3D11PixelShader> > m_ps;
CComPtr<ID3D11Buffer> m_ps_cb;
hash_map<uint32, CComPtr<ID3D11SamplerState> > m_ps_ss;
CComPtr<ID3D11SamplerState> m_palette_ss;
hash_map<uint32, CComPtr<ID3D11DepthStencilState> > m_om_dss;
hash_map<uint32, CComPtr<ID3D11BlendState> > m_om_bs;
VSConstantBuffer m_vs_cb_cache;
PSConstantBuffer m_ps_cb_cache;
public:
GSDevice11();
virtual ~GSDevice11();
bool Create(GSWnd* wnd);
bool CreateTextureFX();
bool Reset(int w, int h);
void Flip();
void SetExclusive(bool isExcl);
void DrawPrimitive();
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, bool msaa, int format = 0);
GSTexture* CreateDepthStencil(int w, int h, bool msaa, int format = 0);
GSTexture* CreateTexture(int w, int h, int format = 0);
GSTexture* CreateOffscreen(int w, int h, int format = 0);
GSTexture* Resolve(GSTexture* t);
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);
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 OMSetDepthStencilState(ID3D11DepthStencilState* dss, uint8 sref);
void OMSetBlendState(ID3D11BlendState* bs, float bf);
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
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);
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
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);
};
/*
* 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 "GSDeviceDX.h"
#include "GSTexture11.h"
struct GSVertexShader11
{
CComPtr<ID3D11VertexShader> vs;
CComPtr<ID3D11InputLayout> il;
};
class GSDevice11 : public GSDeviceDX
{
GSTexture* Create(int type, int w, int h, bool msaa, 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<ID3D11Device> m_dev;
CComPtr<ID3D11DeviceContext> m_ctx;
CComPtr<IDXGISwapChain> m_swapchain;
CComPtr<ID3D11Buffer> m_vb;
CComPtr<ID3D11Buffer> m_vb_old;
struct
{
ID3D11Buffer* vb;
size_t vb_stride;
ID3D11InputLayout* layout;
D3D11_PRIMITIVE_TOPOLOGY topology;
ID3D11VertexShader* vs;
ID3D11Buffer* vs_cb;
ID3D11GeometryShader* gs;
ID3D11ShaderResourceView* ps_srv[2];
ID3D11PixelShader* ps;
ID3D11Buffer* ps_cb;
ID3D11SamplerState* ps_ss[2];
GSVector2i viewport;
GSVector4i scissor;
ID3D11DepthStencilState* dss;
uint8 sref;
ID3D11BlendState* bs;
float bf;
ID3D11RenderTargetView* rtv;
ID3D11DepthStencilView* dsv;
} m_state;
public: // TODO
CComPtr<ID3D11RasterizerState> m_rs;
struct
{
CComPtr<ID3D11InputLayout> il;
CComPtr<ID3D11VertexShader> vs;
CComPtr<ID3D11PixelShader> ps[7];
CComPtr<ID3D11SamplerState> ln;
CComPtr<ID3D11SamplerState> pt;
CComPtr<ID3D11DepthStencilState> dss;
CComPtr<ID3D11BlendState> bs;
} m_convert;
struct
{
CComPtr<ID3D11PixelShader> ps[2];
CComPtr<ID3D11Buffer> cb;
CComPtr<ID3D11BlendState> bs;
} m_merge;
struct
{
CComPtr<ID3D11PixelShader> ps[4];
CComPtr<ID3D11Buffer> cb;
} m_interlace;
struct
{
CComPtr<ID3D11DepthStencilState> dss;
CComPtr<ID3D11BlendState> bs;
} m_date;
void SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1 (&iaVertices)[4], bool datm);
// Shaders...
hash_map<uint32, GSVertexShader11 > m_vs;
CComPtr<ID3D11Buffer> m_vs_cb;
hash_map<uint32, CComPtr<ID3D11GeometryShader> > m_gs;
hash_map<uint32, CComPtr<ID3D11PixelShader> > m_ps;
CComPtr<ID3D11Buffer> m_ps_cb;
hash_map<uint32, CComPtr<ID3D11SamplerState> > m_ps_ss;
CComPtr<ID3D11SamplerState> m_palette_ss;
hash_map<uint32, CComPtr<ID3D11DepthStencilState> > m_om_dss;
hash_map<uint32, CComPtr<ID3D11BlendState> > m_om_bs;
VSConstantBuffer m_vs_cb_cache;
PSConstantBuffer m_ps_cb_cache;
public:
GSDevice11();
virtual ~GSDevice11();
bool Create(GSWnd* wnd);
bool CreateTextureFX();
bool Reset(int w, int h);
void Flip();
void SetExclusive(bool isExcl);
void DrawPrimitive();
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, bool msaa, int format = 0);
GSTexture* CreateDepthStencil(int w, int h, bool msaa, int format = 0);
GSTexture* CreateTexture(int w, int h, int format = 0);
GSTexture* CreateOffscreen(int w, int h, int format = 0);
GSTexture* Resolve(GSTexture* t);
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);
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 OMSetDepthStencilState(ID3D11DepthStencilState* dss, uint8 sref);
void OMSetBlendState(ID3D11BlendState* bs, float bf);
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
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);
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
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);
};

View File

@ -1,178 +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), GetActiveWindow(), 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;
}
/*
* 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), GetActiveWindow(), 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;
}

View File

@ -1,54 +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);
};
/*
* 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);
};

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More