diff --git a/OpenAL/Win32/EFX-Util.lib b/OpenAL/Win32/EFX-Util.lib new file mode 100644 index 0000000000..94ab9c817a Binary files /dev/null and b/OpenAL/Win32/EFX-Util.lib differ diff --git a/OpenAL/Win32/OpenAL32.lib b/OpenAL/Win32/OpenAL32.lib new file mode 100644 index 0000000000..d635de97ef Binary files /dev/null and b/OpenAL/Win32/OpenAL32.lib differ diff --git a/OpenAL/Win64/EFX-Util.lib b/OpenAL/Win64/EFX-Util.lib new file mode 100644 index 0000000000..5c5e98177a Binary files /dev/null and b/OpenAL/Win64/EFX-Util.lib differ diff --git a/OpenAL/Win64/OpenAL32.lib b/OpenAL/Win64/OpenAL32.lib new file mode 100644 index 0000000000..17663e0a38 Binary files /dev/null and b/OpenAL/Win64/OpenAL32.lib differ diff --git a/OpenAL/include/EFX-Util.h b/OpenAL/include/EFX-Util.h new file mode 100644 index 0000000000..b4a6b4e2d8 --- /dev/null +++ b/OpenAL/include/EFX-Util.h @@ -0,0 +1,422 @@ +/*******************************************************************\ +* * +* EFX-UTIL.H - EFX Utilities functions and Reverb Presets * +* * +* File revision 1.0 * +* * +\*******************************************************************/ + +#ifndef EAXVECTOR_DEFINED +#define EAXVECTOR_DEFINED +typedef struct _EAXVECTOR { + float x; + float y; + float z; +} EAXVECTOR; +#endif + +#ifndef EAXREVERBPROPERTIES_DEFINED +#define EAXREVERBPROPERTIES_DEFINED +typedef struct _EAXREVERBPROPERTIES +{ + unsigned long ulEnvironment; + float flEnvironmentSize; + float flEnvironmentDiffusion; + long lRoom; + long lRoomHF; + long lRoomLF; + float flDecayTime; + float flDecayHFRatio; + float flDecayLFRatio; + long lReflections; + float flReflectionsDelay; + EAXVECTOR vReflectionsPan; + long lReverb; + float flReverbDelay; + EAXVECTOR vReverbPan; + float flEchoTime; + float flEchoDepth; + float flModulationTime; + float flModulationDepth; + float flAirAbsorptionHF; + float flHFReference; + float flLFReference; + float flRoomRolloffFactor; + unsigned long ulFlags; +} EAXREVERBPROPERTIES, *LPEAXREVERBPROPERTIES; +#endif + +#ifndef EFXEAXREVERBPROPERTIES_DEFINED +#define EFXEAXREVERBPROPERTIES_DEFINED +typedef struct +{ + float flDensity; + float flDiffusion; + float flGain; + float flGainHF; + float flGainLF; + float flDecayTime; + float flDecayHFRatio; + float flDecayLFRatio; + float flReflectionsGain; + float flReflectionsDelay; + float flReflectionsPan[3]; + float flLateReverbGain; + float flLateReverbDelay; + float flLateReverbPan[3]; + float flEchoTime; + float flEchoDepth; + float flModulationTime; + float flModulationDepth; + float flAirAbsorptionGainHF; + float flHFReference; + float flLFReference; + float flRoomRolloffFactor; + int iDecayHFLimit; +} EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES; +#endif + +#ifndef EAXOBSTRUCTIONPROPERTIES_DEFINED +#define EAXOBSTRUCTIONPROPERTIES_DEFINED +typedef struct _EAXOBSTRUCTIONPROPERTIES +{ + long lObstruction; + float flObstructionLFRatio; +} EAXOBSTRUCTIONPROPERTIES, *LPEAXOBSTRUCTIONPROPERTIES; +#endif + +#ifndef EAXOCCLUSIONPROPERTIES_DEFINED +#define EAXOCCLUSIONPROPERTIES_DEFINED +typedef struct _EAXOCCLUSIONPROPERTIES +{ + long lOcclusion; + float flOcclusionLFRatio; + float flOcclusionRoomRatio; + float flOcclusionDirectRatio; +} EAXOCCLUSIONPROPERTIES, *LPEAXOCCLUSIONPROPERTIES; +#endif + +#ifndef EAXEXCLUSIONPROPERTIES_DEFINED +#define EAXEXCLUSIONPROPERTIES_DEFINED +typedef struct _EAXEXCLUSIONPROPERTIES +{ + long lExclusion; + float flExclusionLFRatio; +} EAXEXCLUSIONPROPERTIES, *LPEAXEXCLUSIONPROPERTIES; +#endif + +#ifndef EFXLOWPASSFILTER_DEFINED +#define EFXLOWPASSFILTER_DEFINED +typedef struct _EFXLOWPASSFILTER +{ + float flGain; + float flGainHF; +} EFXLOWPASSFILTER, *LPEFXLOWPASSFILTER; +#endif + +void ConvertReverbParameters(EAXREVERBPROPERTIES *pEAXProp, EFXEAXREVERBPROPERTIES *pEFXEAXReverb); +void ConvertObstructionParameters(EAXOBSTRUCTIONPROPERTIES *pObProp, EFXLOWPASSFILTER *pDirectLowPassFilter); +void ConvertExclusionParameters(EAXEXCLUSIONPROPERTIES *pExProp, EFXLOWPASSFILTER *pSendLowPassFilter); +void ConvertOcclusionParameters(EAXOCCLUSIONPROPERTIES *pOcProp, EFXLOWPASSFILTER *pDirectLowPassFilter, EFXLOWPASSFILTER *pSendLowPassFilter); + + +/***********************************************************************************************\ +* +* EAX Reverb Presets in legacy format - use ConvertReverbParameters() to convert to +* EFX EAX Reverb Presets for use with the OpenAL Effects Extension. +* +************************************************************************************************/ + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_GENERIC \ + {0, 7.5f, 1.000f, -1000, -100, 0, 1.49f, 0.83f, 1.00f, -2602, 0.007f, 0.00f,0.00f,0.00f, 200, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_PADDEDCELL \ + {1, 1.4f, 1.000f, -1000, -6000, 0, 0.17f, 0.10f, 1.00f, -1204, 0.001f, 0.00f,0.00f,0.00f, 207, 0.002f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_ROOM \ + {2, 1.9f, 1.000f, -1000, -454, 0, 0.40f, 0.83f, 1.00f, -1646, 0.002f, 0.00f,0.00f,0.00f, 53, 0.003f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_BATHROOM \ + {3, 1.4f, 1.000f, -1000, -1200, 0, 1.49f, 0.54f, 1.00f, -370, 0.007f, 0.00f,0.00f,0.00f, 1030, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_LIVINGROOM \ + {4, 2.5f, 1.000f, -1000, -6000, 0, 0.50f, 0.10f, 1.00f, -1376, 0.003f, 0.00f,0.00f,0.00f, -1104, 0.004f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_STONEROOM \ + {5, 11.6f, 1.000f, -1000, -300, 0, 2.31f, 0.64f, 1.00f, -711, 0.012f, 0.00f,0.00f,0.00f, 83, 0.017f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_AUDITORIUM \ + {6, 21.6f, 1.000f, -1000, -476, 0, 4.32f, 0.59f, 1.00f, -789, 0.020f, 0.00f,0.00f,0.00f, -289, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_CONCERTHALL \ + {7, 19.6f, 1.000f, -1000, -500, 0, 3.92f, 0.70f, 1.00f, -1230, 0.020f, 0.00f,0.00f,0.00f, -02, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_CAVE \ + {8, 14.6f, 1.000f, -1000, 0, 0, 2.91f, 1.30f, 1.00f, -602, 0.015f, 0.00f,0.00f,0.00f, -302, 0.022f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } +#define REVERB_PRESET_ARENA \ + {9, 36.2f, 1.000f, -1000, -698, 0, 7.24f, 0.33f, 1.00f, -1166, 0.020f, 0.00f,0.00f,0.00f, 16, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_HANGAR \ + {10, 50.3f, 1.000f, -1000, -1000, 0, 10.05f, 0.23f, 1.00f, -602, 0.020f, 0.00f,0.00f,0.00f, 198, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_CARPETTEDHALLWAY \ + {11, 1.9f, 1.000f, -1000, -4000, 0, 0.30f, 0.10f, 1.00f, -1831, 0.002f, 0.00f,0.00f,0.00f, -1630, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_HALLWAY \ + {12, 1.8f, 1.000f, -1000, -300, 0, 1.49f, 0.59f, 1.00f, -1219, 0.007f, 0.00f,0.00f,0.00f, 441, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_STONECORRIDOR \ + {13, 13.5f, 1.000f, -1000, -237, 0, 2.70f, 0.79f, 1.00f, -1214, 0.013f, 0.00f,0.00f,0.00f, 395, 0.020f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_ALLEY \ + {14, 7.5f, 0.300f, -1000, -270, 0, 1.49f, 0.86f, 1.00f, -1204, 0.007f, 0.00f,0.00f,0.00f, -4, 0.011f, 0.00f,0.00f,0.00f, 0.125f, 0.950f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_FOREST \ + {15, 38.0f, 0.300f, -1000, -3300, 0, 1.49f, 0.54f, 1.00f, -2560, 0.162f, 0.00f,0.00f,0.00f, -229, 0.088f, 0.00f,0.00f,0.00f, 0.125f, 1.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_CITY \ + {16, 7.5f, 0.500f, -1000, -800, 0, 1.49f, 0.67f, 1.00f, -2273, 0.007f, 0.00f,0.00f,0.00f, -1691, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_MOUNTAINS \ + {17, 100.0f, 0.270f, -1000, -2500, 0, 1.49f, 0.21f, 1.00f, -2780, 0.300f, 0.00f,0.00f,0.00f, -1434, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } +#define REVERB_PRESET_QUARRY \ + {18, 17.5f, 1.000f, -1000, -1000, 0, 1.49f, 0.83f, 1.00f, -10000, 0.061f, 0.00f,0.00f,0.00f, 500, 0.025f, 0.00f,0.00f,0.00f, 0.125f, 0.700f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_PLAIN \ + {19, 42.5f, 0.210f, -1000, -2000, 0, 1.49f, 0.50f, 1.00f, -2466, 0.179f, 0.00f,0.00f,0.00f, -1926, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_PARKINGLOT \ + {20, 8.3f, 1.000f, -1000, 0, 0, 1.65f, 1.50f, 1.00f, -1363, 0.008f, 0.00f,0.00f,0.00f, -1153, 0.012f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } +#define REVERB_PRESET_SEWERPIPE \ + {21, 1.7f, 0.800f, -1000, -1000, 0, 2.81f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_UNDERWATER \ + {22, 1.8f, 1.000f, -1000, -4000, 0, 1.49f, 0.10f, 1.00f, -449, 0.007f, 0.00f,0.00f,0.00f, 1700, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 1.180f, 0.348f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_DRUGGED \ + {23, 1.9f, 0.500f, -1000, 0, 0, 8.39f, 1.39f, 1.00f, -115, 0.002f, 0.00f,0.00f,0.00f, 985, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 1.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } +#define REVERB_PRESET_DIZZY \ + {24, 1.8f, 0.600f, -1000, -400, 0, 17.23f, 0.56f, 1.00f, -1713, 0.020f, 0.00f,0.00f,0.00f, -613, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.810f, 0.310f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } +#define REVERB_PRESET_PSYCHOTIC \ + {25, 1.0f, 0.500f, -1000, -151, 0, 7.56f, 0.91f, 1.00f, -626, 0.020f, 0.00f,0.00f,0.00f, 774, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 4.000f, 1.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } + + +// CASTLE PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_CASTLE_SMALLROOM \ + { 26, 8.3f, 0.890f, -1000, -800, -2000, 1.22f, 0.83f, 0.31f, -100, 0.022f, 0.00f,0.00f,0.00f, 600, 0.011f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define REVERB_PRESET_CASTLE_SHORTPASSAGE \ + { 26, 8.3f, 0.890f, -1000, -1000, -2000, 2.32f, 0.83f, 0.31f, -100, 0.007f, 0.00f,0.00f,0.00f, 200, 0.023f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define REVERB_PRESET_CASTLE_MEDIUMROOM \ + { 26, 8.3f, 0.930f, -1000, -1100, -2000, 2.04f, 0.83f, 0.46f, -400, 0.022f, 0.00f,0.00f,0.00f, 400, 0.011f, 0.00f,0.00f,0.00f, 0.155f, 0.030f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define REVERB_PRESET_CASTLE_LONGPASSAGE \ + { 26, 8.3f, 0.890f, -1000, -800, -2000, 3.42f, 0.83f, 0.31f, -100, 0.007f, 0.00f,0.00f,0.00f, 300, 0.023f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define REVERB_PRESET_CASTLE_LARGEROOM \ + { 26, 8.3f, 0.820f, -1000, -1100, -1800, 2.53f, 0.83f, 0.50f, -700, 0.034f, 0.00f,0.00f,0.00f, 200, 0.016f, 0.00f,0.00f,0.00f, 0.185f, 0.070f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define REVERB_PRESET_CASTLE_HALL \ + { 26, 8.3f, 0.810f, -1000, -1100, -1500, 3.14f, 0.79f, 0.62f, -1500, 0.056f, 0.00f,0.00f,0.00f, 100, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define REVERB_PRESET_CASTLE_CUPBOARD \ + { 26, 8.3f, 0.890f, -1000, -1100, -2000, 0.67f, 0.87f, 0.31f, 300, 0.010f, 0.00f,0.00f,0.00f, 1100, 0.007f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define REVERB_PRESET_CASTLE_COURTYARD \ + { 26, 8.3f, 0.420f, -1000, -700, -1400, 2.13f, 0.61f, 0.23f, -1300, 0.160f, 0.00f,0.00f,0.00f, -300, 0.036f, 0.00f,0.00f,0.00f, 0.250f, 0.370f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } +#define REVERB_PRESET_CASTLE_ALCOVE \ + { 26, 8.3f, 0.890f, -1000, -600, -2000, 1.64f, 0.87f, 0.31f, 00, 0.007f, 0.00f,0.00f,0.00f, 300, 0.034f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } + + +// FACTORY PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_FACTORY_ALCOVE \ + { 26, 1.8f, 0.590f, -1200, -200, -600, 3.14f, 0.65f, 1.31f, 300, 0.010f, 0.00f,0.00f,0.00f, 000, 0.038f, 0.00f,0.00f,0.00f, 0.114f, 0.100f, 0.250f, 0.000f, -5.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define REVERB_PRESET_FACTORY_SHORTPASSAGE \ + { 26, 1.8f, 0.640f, -1200, -200, -600, 2.53f, 0.65f, 1.31f, 0, 0.010f, 0.00f,0.00f,0.00f, 200, 0.038f, 0.00f,0.00f,0.00f, 0.135f, 0.230f, 0.250f, 0.000f, -5.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define REVERB_PRESET_FACTORY_MEDIUMROOM \ + { 26, 1.9f, 0.820f, -1200, -200, -600, 2.76f, 0.65f, 1.31f, -1100, 0.022f, 0.00f,0.00f,0.00f, 300, 0.023f, 0.00f,0.00f,0.00f, 0.174f, 0.070f, 0.250f, 0.000f, -5.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define REVERB_PRESET_FACTORY_LONGPASSAGE \ + { 26, 1.8f, 0.640f, -1200, -200, -600, 4.06f, 0.65f, 1.31f, 0, 0.020f, 0.00f,0.00f,0.00f, 200, 0.037f, 0.00f,0.00f,0.00f, 0.135f, 0.230f, 0.250f, 0.000f, -5.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define REVERB_PRESET_FACTORY_LARGEROOM \ + { 26, 1.9f, 0.750f, -1200, -300, -400, 4.24f, 0.51f, 1.31f, -1500, 0.039f, 0.00f,0.00f,0.00f, 100, 0.023f, 0.00f,0.00f,0.00f, 0.231f, 0.070f, 0.250f, 0.000f, -5.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define REVERB_PRESET_FACTORY_HALL \ + { 26, 1.9f, 0.750f, -1000, -300, -400, 7.43f, 0.51f, 1.31f, -2400, 0.073f, 0.00f,0.00f,0.00f, -100, 0.027f, 0.00f,0.00f,0.00f, 0.250f, 0.070f, 0.250f, 0.000f, -5.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define REVERB_PRESET_FACTORY_CUPBOARD \ + { 26, 1.7f, 0.630f, -1200, -200, -600, 0.49f, 0.65f, 1.31f, 200, 0.010f, 0.00f,0.00f,0.00f, 600, 0.032f, 0.00f,0.00f,0.00f, 0.107f, 0.070f, 0.250f, 0.000f, -5.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define REVERB_PRESET_FACTORY_COURTYARD \ + { 26, 1.7f, 0.570f, -1000, -1000, -400, 2.32f, 0.29f, 0.56f, -1300, 0.140f, 0.00f,0.00f,0.00f, -800, 0.039f, 0.00f,0.00f,0.00f, 0.250f, 0.290f, 0.250f, 0.000f, -5.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define REVERB_PRESET_FACTORY_SMALLROOM \ + { 26, 1.8f, 0.820f, -1000, -200, -600, 1.72f, 0.65f, 1.31f, -300, 0.010f, 0.00f,0.00f,0.00f, 500, 0.024f, 0.00f,0.00f,0.00f, 0.119f, 0.070f, 0.250f, 0.000f, -5.0f, 3762.6f, 362.5f, 0.00f, 0x20 } + + +// ICE PALACE PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_ICEPALACE_ALCOVE \ + { 26, 2.7f, 0.840f, -1000, -500, -1100, 2.76f, 1.46f, 0.28f, 100, 0.010f, 0.00f,0.00f,0.00f, -100, 0.030f, 0.00f,0.00f,0.00f, 0.161f, 0.090f, 0.250f, 0.000f, -5.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define REVERB_PRESET_ICEPALACE_SHORTPASSAGE \ + { 26, 2.7f, 0.750f, -1000, -500, -1100, 1.79f, 1.46f, 0.28f, -600, 0.010f, 0.00f,0.00f,0.00f, 100, 0.019f, 0.00f,0.00f,0.00f, 0.177f, 0.090f, 0.250f, 0.000f, -5.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define REVERB_PRESET_ICEPALACE_MEDIUMROOM \ + { 26, 2.7f, 0.870f, -1000, -500, -700, 2.22f, 1.53f, 0.32f, -800, 0.039f, 0.00f,0.00f,0.00f, 100, 0.027f, 0.00f,0.00f,0.00f, 0.186f, 0.120f, 0.250f, 0.000f, -5.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define REVERB_PRESET_ICEPALACE_LONGPASSAGE \ + { 26, 2.7f, 0.770f, -1000, -500, -800, 3.01f, 1.46f, 0.28f, -200, 0.012f, 0.00f,0.00f,0.00f, 200, 0.025f, 0.00f,0.00f,0.00f, 0.186f, 0.040f, 0.250f, 0.000f, -5.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define REVERB_PRESET_ICEPALACE_LARGEROOM \ + { 26, 2.9f, 0.810f, -1000, -500, -700, 3.14f, 1.53f, 0.32f, -1200, 0.039f, 0.00f,0.00f,0.00f, 000, 0.027f, 0.00f,0.00f,0.00f, 0.214f, 0.110f, 0.250f, 0.000f, -5.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define REVERB_PRESET_ICEPALACE_HALL \ + { 26, 2.9f, 0.760f, -1000, -700, -500, 5.49f, 1.53f, 0.38f, -1900, 0.054f, 0.00f,0.00f,0.00f, -400, 0.052f, 0.00f,0.00f,0.00f, 0.226f, 0.110f, 0.250f, 0.000f, -5.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define REVERB_PRESET_ICEPALACE_CUPBOARD \ + { 26, 2.7f, 0.830f, -1000, -600, -1300, 0.76f, 1.53f, 0.26f, 100, 0.012f, 0.00f,0.00f,0.00f, 600, 0.016f, 0.00f,0.00f,0.00f, 0.143f, 0.080f, 0.250f, 0.000f, -5.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define REVERB_PRESET_ICEPALACE_COURTYARD \ + { 26, 2.9f, 0.590f, -1000, -1100, -1000, 2.04f, 1.20f, 0.38f, -1000, 0.173f, 0.00f,0.00f,0.00f, -1000, 0.043f, 0.00f,0.00f,0.00f, 0.235f, 0.480f, 0.250f, 0.000f, -5.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define REVERB_PRESET_ICEPALACE_SMALLROOM \ + { 26, 2.7f, 0.840f, -1000, -500, -1100, 1.51f, 1.53f, 0.27f, -100, 0.010f, 0.00f,0.00f,0.00f, 300, 0.011f, 0.00f,0.00f,0.00f, 0.164f, 0.140f, 0.250f, 0.000f, -5.0f, 12428.5f, 99.6f, 0.00f, 0x20 } + + +// SPACE STATION PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_SPACESTATION_ALCOVE \ + { 26, 1.5f, 0.780f, -1000, -300, -100, 1.16f, 0.81f, 0.55f, 300, 0.007f, 0.00f,0.00f,0.00f, 000, 0.018f, 0.00f,0.00f,0.00f, 0.192f, 0.210f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define REVERB_PRESET_SPACESTATION_MEDIUMROOM \ + { 26, 1.5f, 0.750f, -1000, -400, -100, 3.01f, 0.50f, 0.55f, -800, 0.034f, 0.00f,0.00f,0.00f, 100, 0.035f, 0.00f,0.00f,0.00f, 0.209f, 0.310f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define REVERB_PRESET_SPACESTATION_SHORTPASSAGE \ + { 26, 1.5f, 0.870f, -1000, -400, -100, 3.57f, 0.50f, 0.55f, 0, 0.012f, 0.00f,0.00f,0.00f, 100, 0.016f, 0.00f,0.00f,0.00f, 0.172f, 0.200f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define REVERB_PRESET_SPACESTATION_LONGPASSAGE \ + { 26, 1.9f, 0.820f, -1000, -400, -100, 4.62f, 0.62f, 0.55f, 0, 0.012f, 0.00f,0.00f,0.00f, 200, 0.031f, 0.00f,0.00f,0.00f, 0.250f, 0.230f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define REVERB_PRESET_SPACESTATION_LARGEROOM \ + { 26, 1.8f, 0.810f, -1000, -400, -100, 3.89f, 0.38f, 0.61f, -1000, 0.056f, 0.00f,0.00f,0.00f, -100, 0.035f, 0.00f,0.00f,0.00f, 0.233f, 0.280f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define REVERB_PRESET_SPACESTATION_HALL \ + { 26, 1.9f, 0.870f, -1000, -400, -100, 7.11f, 0.38f, 0.61f, -1500, 0.100f, 0.00f,0.00f,0.00f, -400, 0.047f, 0.00f,0.00f,0.00f, 0.250f, 0.250f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define REVERB_PRESET_SPACESTATION_CUPBOARD \ + { 26, 1.4f, 0.560f, -1000, -300, -100, 0.79f, 0.81f, 0.55f, 300, 0.007f, 0.00f,0.00f,0.00f, 500, 0.018f, 0.00f,0.00f,0.00f, 0.181f, 0.310f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define REVERB_PRESET_SPACESTATION_SMALLROOM \ + { 26, 1.5f, 0.700f, -1000, -300, -100, 1.72f, 0.82f, 0.55f, -200, 0.007f, 0.00f,0.00f,0.00f, 300, 0.013f, 0.00f,0.00f,0.00f, 0.188f, 0.260f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } + + +// WOODEN GALLEON PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_WOODEN_ALCOVE \ + { 26, 7.5f, 1.000f, -1000, -1800, -1000, 1.22f, 0.62f, 0.91f, 100, 0.012f, 0.00f,0.00f,0.00f, -300, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define REVERB_PRESET_WOODEN_SHORTPASSAGE \ + { 26, 7.5f, 1.000f, -1000, -1800, -1000, 1.75f, 0.50f, 0.87f, -100, 0.012f, 0.00f,0.00f,0.00f, -400, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define REVERB_PRESET_WOODEN_MEDIUMROOM \ + { 26, 7.5f, 1.000f, -1000, -2000, -1100, 1.47f, 0.42f, 0.82f, -100, 0.049f, 0.00f,0.00f,0.00f, -100, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define REVERB_PRESET_WOODEN_LONGPASSAGE \ + { 26, 7.5f, 1.000f, -1000, -2000, -1000, 1.99f, 0.40f, 0.79f, 000, 0.020f, 0.00f,0.00f,0.00f, -700, 0.036f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define REVERB_PRESET_WOODEN_LARGEROOM \ + { 26, 7.5f, 1.000f, -1000, -2100, -1100, 2.65f, 0.33f, 0.82f, -100, 0.066f, 0.00f,0.00f,0.00f, -200, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define REVERB_PRESET_WOODEN_HALL \ + { 26, 7.5f, 1.000f, -1000, -2200, -1100, 3.45f, 0.30f, 0.82f, -100, 0.088f, 0.00f,0.00f,0.00f, -200, 0.063f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define REVERB_PRESET_WOODEN_CUPBOARD \ + { 26, 7.5f, 1.000f, -1000, -1700, -1000, 0.56f, 0.46f, 0.91f, 100, 0.012f, 0.00f,0.00f,0.00f, 100, 0.028f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define REVERB_PRESET_WOODEN_SMALLROOM \ + { 26, 7.5f, 1.000f, -1000, -1900, -1000, 0.79f, 0.32f, 0.87f, 00, 0.032f, 0.00f,0.00f,0.00f, -100, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define REVERB_PRESET_WOODEN_COURTYARD \ + { 26, 7.5f, 0.650f, -1000, -2200, -1000, 1.79f, 0.35f, 0.79f, -500, 0.123f, 0.00f,0.00f,0.00f, -2000, 0.032f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } + + +// SPORTS PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_SPORT_EMPTYSTADIUM \ + { 26, 7.2f, 1.000f, -1000, -700, -200, 6.26f, 0.51f, 1.10f, -2400, 0.183f, 0.00f,0.00f,0.00f, -800, 0.038f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x20 } +#define REVERB_PRESET_SPORT_SQUASHCOURT \ + { 26, 7.5f, 0.750f, -1000, -1000, -200, 2.22f, 0.91f, 1.16f, -700, 0.007f, 0.00f,0.00f,0.00f, -200, 0.011f, 0.00f,0.00f,0.00f, 0.126f, 0.190f, 0.250f, 0.000f, -5.0f, 7176.9f, 211.2f, 0.00f, 0x20 } +#define REVERB_PRESET_SPORT_SMALLSWIMMINGPOOL \ + { 26, 36.2f, 0.700f, -1000, -200, -100, 2.76f, 1.25f, 1.14f, -400, 0.020f, 0.00f,0.00f,0.00f, -200, 0.030f, 0.00f,0.00f,0.00f, 0.179f, 0.150f, 0.895f, 0.190f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } +#define REVERB_PRESET_SPORT_LARGESWIMMINGPOOL\ + { 26, 36.2f, 0.820f, -1000, -200, 0, 5.49f, 1.31f, 1.14f, -700, 0.039f, 0.00f,0.00f,0.00f, -600, 0.049f, 0.00f,0.00f,0.00f, 0.222f, 0.550f, 1.159f, 0.210f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } +#define REVERB_PRESET_SPORT_GYMNASIUM \ + { 26, 7.5f, 0.810f, -1000, -700, -100, 3.14f, 1.06f, 1.35f, -800, 0.029f, 0.00f,0.00f,0.00f, -500, 0.045f, 0.00f,0.00f,0.00f, 0.146f, 0.140f, 0.250f, 0.000f, -5.0f, 7176.9f, 211.2f, 0.00f, 0x20 } +#define REVERB_PRESET_SPORT_FULLSTADIUM \ + { 26, 7.2f, 1.000f, -1000, -2300, -200, 5.25f, 0.17f, 0.80f, -2000, 0.188f, 0.00f,0.00f,0.00f, -1100, 0.038f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x20 } +#define REVERB_PRESET_SPORT_STADIUMTANNOY \ + { 26, 3.0f, 0.780f, -1000, -500, -600, 2.53f, 0.88f, 0.68f, -1100, 0.230f, 0.00f,0.00f,0.00f, -600, 0.063f, 0.00f,0.00f,0.00f, 0.250f, 0.200f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x20 } + + +// PREFAB PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_PREFAB_WORKSHOP \ + { 26, 1.9f, 1.000f, -1000, -1700, -800, 0.76f, 1.00f, 1.00f, 0, 0.012f, 0.00f,0.00f,0.00f, 100, 0.012f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } +#define REVERB_PRESET_PREFAB_SCHOOLROOM \ + { 26, 1.86f, 0.690f, -1000, -400, -600, 0.98f, 0.45f, 0.18f, 300, 0.017f, 0.00f,0.00f,0.00f, 300, 0.015f, 0.00f,0.00f,0.00f, 0.095f, 0.140f, 0.250f, 0.000f, -5.0f, 7176.9f, 211.2f, 0.00f, 0x20 } +#define REVERB_PRESET_PREFAB_PRACTISEROOM \ + { 26, 1.86f, 0.870f, -1000, -800, -600, 1.12f, 0.56f, 0.18f, 200, 0.010f, 0.00f,0.00f,0.00f, 300, 0.011f, 0.00f,0.00f,0.00f, 0.095f, 0.140f, 0.250f, 0.000f, -5.0f, 7176.9f, 211.2f, 0.00f, 0x20 } +#define REVERB_PRESET_PREFAB_OUTHOUSE \ + { 26, 80.3f, 0.820f, -1000, -1900, -1600, 1.38f, 0.38f, 0.35f, -100, 0.024f, 0.00f,0.00f,-0.00f, -400, 0.044f, 0.00f,0.00f,0.00f, 0.121f, 0.170f, 0.250f, 0.000f, -5.0f, 2854.4f, 107.5f, 0.00f, 0x0 } +#define REVERB_PRESET_PREFAB_CARAVAN \ + { 26, 8.3f, 1.000f, -1000, -2100, -1800, 0.43f, 1.50f, 1.00f, 0, 0.012f, 0.00f,0.00f,0.00f, 600, 0.012f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } + // for US developers, a caravan is the same as a trailer =o) + + +// DOME AND PIPE PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_DOME_TOMB \ + { 26, 51.8f, 0.790f, -1000, -900, -1300, 4.18f, 0.21f, 0.10f, -825, 0.030f, 0.00f,0.00f,0.00f, 450, 0.022f, 0.00f,0.00f,0.00f, 0.177f, 0.190f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x0 } +#define REVERB_PRESET_PIPE_SMALL \ + { 26, 50.3f, 1.000f, -1000, -900, -1300, 5.04f, 0.10f, 0.10f, -600, 0.032f, 0.00f,0.00f,0.00f, 800, 0.015f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x3f } +#define REVERB_PRESET_DOME_SAINTPAULS \ + { 26, 50.3f, 0.870f, -1000, -900, -1300, 10.48f, 0.19f, 0.10f, -1500, 0.090f, 0.00f,0.00f,0.00f, 200, 0.042f, 0.00f,0.00f,0.00f, 0.250f, 0.120f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x3f } +#define REVERB_PRESET_PIPE_LONGTHIN \ + { 26, 1.6f, 0.910f, -1000, -700, -1100, 9.21f, 0.18f, 0.10f, -300, 0.010f, 0.00f,0.00f,0.00f, -300, 0.022f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x0 } +#define REVERB_PRESET_PIPE_LARGE \ + { 26, 50.3f, 1.000f, -1000, -900, -1300, 8.45f, 0.10f, 0.10f, -800, 0.046f, 0.00f,0.00f,0.00f, 400, 0.032f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x3f } +#define REVERB_PRESET_PIPE_RESONANT \ + { 26, 1.3f, 0.910f, -1000, -700, -1100, 6.81f, 0.18f, 0.10f, -300, 0.010f, 0.00f,0.00f,0.00f, 00, 0.022f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x0 } + + +// OUTDOORS PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_OUTDOORS_BACKYARD \ + { 26, 80.3f, 0.450f, -1000, -1200, -600, 1.12f, 0.34f, 0.46f, -700, 0.069f, 0.00f,0.00f,-0.00f, -300, 0.023f, 0.00f,0.00f,0.00f, 0.218f, 0.340f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 } +#define REVERB_PRESET_OUTDOORS_ROLLINGPLAINS \ + { 26, 80.3f, 0.000f, -1000, -3900, -400, 2.13f, 0.21f, 0.46f, -1500, 0.300f, 0.00f,0.00f,-0.00f, -700, 0.019f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 } +#define REVERB_PRESET_OUTDOORS_DEEPCANYON \ + { 26, 80.3f, 0.740f, -1000, -1500, -400, 3.89f, 0.21f, 0.46f, -1000, 0.223f, 0.00f,0.00f,-0.00f, -900, 0.019f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 } +#define REVERB_PRESET_OUTDOORS_CREEK \ + { 26, 80.3f, 0.350f, -1000, -1500, -600, 2.13f, 0.21f, 0.46f, -800, 0.115f, 0.00f,0.00f,-0.00f, -1400, 0.031f, 0.00f,0.00f,0.00f, 0.218f, 0.340f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 } +#define REVERB_PRESET_OUTDOORS_VALLEY \ + { 26, 80.3f, 0.280f, -1000, -3100, -1600, 2.88f, 0.26f, 0.35f, -1700, 0.263f, 0.00f,0.00f,-0.00f, -800, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 0.340f, 0.250f, 0.000f, -5.0f, 2854.4f, 107.5f, 0.00f, 0x0 } + + +// MOOD PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_MOOD_HEAVEN \ + { 26, 19.6f, 0.940f, -1000, -200, -700, 5.04f, 1.12f, 0.56f, -1230, 0.020f, 0.00f,0.00f,0.00f, 200, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.080f, 2.742f, 0.050f, -2.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_MOOD_HELL \ + { 26, 100.0f, 0.570f, -1000, -900, -700, 3.57f, 0.49f, 2.00f, -10000, 0.020f, 0.00f,0.00f,0.00f, 300, 0.030f, 0.00f,0.00f,0.00f, 0.110f, 0.040f, 2.109f, 0.520f, -5.0f, 5000.0f, 139.5f, 0.00f, 0x40 } +#define REVERB_PRESET_MOOD_MEMORY \ + { 26, 8.0f, 0.850f, -1000, -400, -900, 4.06f, 0.82f, 0.56f, -2800, 0.000f, 0.00f,0.00f,0.00f, 100, 0.000f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.474f, 0.450f, -10.0f, 5000.0f, 250.0f, 0.00f, 0x0 } + + +// DRIVING SIMULATION PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_DRIVING_COMMENTATOR \ + { 26, 3.0f, 0.000f, 1000, -500, -600, 2.42f, 0.88f, 0.68f, -1400, 0.093f, 0.00f,0.00f,0.00f, -1200, 0.017f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -10.0f, 5000.0f, 250.0f, 0.00f, 0x20 } +#define REVERB_PRESET_DRIVING_PITGARAGE \ + { 26, 1.9f, 0.590f, -1000, -300, -500, 1.72f, 0.93f, 0.87f, -500, 0.000f, 0.00f,0.00f,0.00f, 200, 0.016f, 0.00f,0.00f,0.00f, 0.250f, 0.110f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } +#define REVERB_PRESET_DRIVING_INCAR_RACER \ + { 26, 1.1f, 0.800f, -1000, 0, -200, 0.17f, 2.00f, 0.41f, 500, 0.007f, 0.00f,0.00f,0.00f, -300, 0.015f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 10268.2f, 251.0f, 0.00f, 0x20 } +#define REVERB_PRESET_DRIVING_INCAR_SPORTS \ + { 26, 1.1f, 0.800f, -1000, -400, 0, 0.17f, 0.75f, 0.41f, 0, 0.010f, 0.00f,0.00f,0.00f, -500, 0.000f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 10268.2f, 251.0f, 0.00f, 0x20 } +#define REVERB_PRESET_DRIVING_INCAR_LUXURY \ + { 26, 1.6f, 1.000f, -1000, -2000, -600, 0.13f, 0.41f, 0.46f, -200, 0.010f, 0.00f,0.00f,0.00f, 400, 0.010f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 10268.2f, 251.0f, 0.00f, 0x20 } +#define REVERB_PRESET_DRIVING_FULLGRANDSTAND \ + { 26, 8.3f, 1.000f, -1000, -1100, -400, 3.01f, 1.37f, 1.28f, -900, 0.090f, 0.00f,0.00f,0.00f, -1500, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 10420.2f, 250.0f, 0.00f, 0x1f } +#define REVERB_PRESET_DRIVING_EMPTYGRANDSTAND \ + { 26, 8.3f, 1.000f, -1000, 0, -200, 4.62f, 1.75f, 1.40f, -1363, 0.090f, 0.00f,0.00f,0.00f, -1200, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 10420.2f, 250.0f, 0.00f, 0x1f } +#define REVERB_PRESET_DRIVING_TUNNEL \ + { 26, 3.1f, 0.810f, -1000, -800, -100, 3.42f, 0.94f, 1.31f, -300, 0.051f, 0.00f,0.00f,0.00f, -300, 0.047f, 0.00f,0.00f,0.00f, 0.214f, 0.050f, 0.250f, 0.000f, -5.0f, 5000.0f, 155.3f, 0.00f, 0x20 } + + +// CITY PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_CITY_STREETS \ + { 26, 3.0f, 0.780f, -1000, -300, -100, 1.79f, 1.12f, 0.91f, -1100, 0.046f, 0.00f,0.00f,0.00f, -1400, 0.028f, 0.00f,0.00f,0.00f, 0.250f, 0.200f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x20 } +#define REVERB_PRESET_CITY_SUBWAY \ + { 26, 3.0f, 0.740f, -1000, -300, -100, 3.01f, 1.23f, 0.91f, -300, 0.046f, 0.00f,0.00f,0.00f, 200, 0.028f, 0.00f,0.00f,0.00f, 0.125f, 0.210f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x20 } +#define REVERB_PRESET_CITY_MUSEUM \ + { 26, 80.3f, 0.820f, -1000, -1500, -1500, 3.28f, 1.40f, 0.57f, -1200, 0.039f, 0.00f,0.00f,-0.00f, -100, 0.034f, 0.00f,0.00f,0.00f, 0.130f, 0.170f, 0.250f, 0.000f, -5.0f, 2854.4f, 107.5f, 0.00f, 0x0 } +#define REVERB_PRESET_CITY_LIBRARY \ + { 26, 80.3f, 0.820f, -1000, -1100, -2100, 2.76f, 0.89f, 0.41f, -900, 0.029f, 0.00f,0.00f,-0.00f, -100, 0.020f, 0.00f,0.00f,0.00f, 0.130f, 0.170f, 0.250f, 0.000f, -5.0f, 2854.4f, 107.5f, 0.00f, 0x0 } +#define REVERB_PRESET_CITY_UNDERPASS \ + { 26, 3.0f, 0.820f, -1000, -700, -100, 3.57f, 1.12f, 0.91f, -800, 0.059f, 0.00f,0.00f,0.00f, -100, 0.037f, 0.00f,0.00f,0.00f, 0.250f, 0.140f, 0.250f, 0.000f, -7.0f, 5000.0f, 250.0f, 0.00f, 0x20 } +#define REVERB_PRESET_CITY_ABANDONED \ + { 26, 3.0f, 0.690f, -1000, -200, -100, 3.28f, 1.17f, 0.91f, -700, 0.044f, 0.00f,0.00f,0.00f, -1100, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.200f, 0.250f, 0.000f, -3.0f, 5000.0f, 250.0f, 0.00f, 0x20 } + + +// MISC ROOMS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define REVERB_PRESET_DUSTYROOM \ + { 26, 1.8f, 0.560f, -1000, -200, -300, 1.79f, 0.38f, 0.21f, -600, 0.002f, 0.00f,0.00f,0.00f, 200, 0.006f, 0.00f,0.00f,0.00f, 0.202f, 0.050f, 0.250f, 0.000f, -10.0f, 13046.0f, 163.3f, 0.00f, 0x20 } +#define REVERB_PRESET_CHAPEL \ + { 26, 19.6f, 0.840f, -1000, -500, 0, 4.62f, 0.64f, 1.23f, -700, 0.032f, 0.00f,0.00f,0.00f, -200, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.110f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define REVERB_PRESET_SMALLWATERROOM \ + { 26, 36.2f, 0.700f, -1000, -698, 0, 1.51f, 1.25f, 1.14f, -100, 0.020f, 0.00f,0.00f,0.00f, 300, 0.030f, 0.00f,0.00f,0.00f, 0.179f, 0.150f, 0.895f, 0.190f, -7.0f, 5000.0f, 250.0f, 0.00f, 0x0 } diff --git a/OpenAL/include/al.h b/OpenAL/include/al.h new file mode 100644 index 0000000000..1c2f95b318 --- /dev/null +++ b/OpenAL/include/al.h @@ -0,0 +1,732 @@ +#ifndef AL_AL_H +#define AL_AL_H + + + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(_WIN32) && !defined(_XBOX) + /* _OPENAL32LIB is deprecated */ + #if defined(AL_BUILD_LIBRARY) || defined (_OPENAL32LIB) + #define AL_API __declspec(dllexport) + #else + #define AL_API __declspec(dllimport) + #endif +#else + #define AL_API extern +#endif + +#if defined(_WIN32) + #define AL_APIENTRY __cdecl +#else + #define AL_APIENTRY +#endif + +#if TARGET_OS_MAC + #pragma export on +#endif + +/* The OPENAL, ALAPI, and ALAPIENTRY macros are deprecated, but are included for applications porting code + from AL 1.0 */ +#define OPENAL +#define ALAPI AL_API +#define ALAPIENTRY AL_APIENTRY + +#define AL_VERSION_1_0 +#define AL_VERSION_1_1 + + +/** 8-bit boolean */ +typedef char ALboolean; + +/** character */ +typedef char ALchar; + +/** signed 8-bit 2's complement integer */ +typedef char ALbyte; + +/** unsigned 8-bit integer */ +typedef unsigned char ALubyte; + +/** signed 16-bit 2's complement integer */ +typedef short ALshort; + +/** unsigned 16-bit integer */ +typedef unsigned short ALushort; + +/** signed 32-bit 2's complement integer */ +typedef int ALint; + +/** unsigned 32-bit integer */ +typedef unsigned int ALuint; + +/** non-negative 32-bit binary integer size */ +typedef int ALsizei; + +/** enumerated 32-bit value */ +typedef int ALenum; + +/** 32-bit IEEE754 floating-point */ +typedef float ALfloat; + +/** 64-bit IEEE754 floating-point */ +typedef double ALdouble; + +/** void type (for opaque pointers only) */ +typedef void ALvoid; + + +/* Enumerant values begin at column 50. No tabs. */ + +/* bad value */ +#define AL_INVALID -1 + +#define AL_NONE 0 + +/* Boolean False. */ +#define AL_FALSE 0 + +/** Boolean True. */ +#define AL_TRUE 1 + +/** Indicate Source has relative coordinates. */ +#define AL_SOURCE_RELATIVE 0x202 + + + +/** + * Directional source, inner cone angle, in degrees. + * Range: [0-360] + * Default: 360 + */ +#define AL_CONE_INNER_ANGLE 0x1001 + +/** + * Directional source, outer cone angle, in degrees. + * Range: [0-360] + * Default: 360 + */ +#define AL_CONE_OUTER_ANGLE 0x1002 + +/** + * Specify the pitch to be applied, either at source, + * or on mixer results, at listener. + * Range: [0.5-2.0] + * Default: 1.0 + */ +#define AL_PITCH 0x1003 + +/** + * Specify the current location in three dimensional space. + * OpenAL, like OpenGL, uses a right handed coordinate system, + * where in a frontal default view X (thumb) points right, + * Y points up (index finger), and Z points towards the + * viewer/camera (middle finger). + * To switch from a left handed coordinate system, flip the + * sign on the Z coordinate. + * Listener position is always in the world coordinate system. + */ +#define AL_POSITION 0x1004 + +/** Specify the current direction. */ +#define AL_DIRECTION 0x1005 + +/** Specify the current velocity in three dimensional space. */ +#define AL_VELOCITY 0x1006 + +/** + * Indicate whether source is looping. + * Type: ALboolean? + * Range: [AL_TRUE, AL_FALSE] + * Default: FALSE. + */ +#define AL_LOOPING 0x1007 + +/** + * Indicate the buffer to provide sound samples. + * Type: ALuint. + * Range: any valid Buffer id. + */ +#define AL_BUFFER 0x1009 + +/** + * Indicate the gain (volume amplification) applied. + * Type: ALfloat. + * Range: ]0.0- ] + * A value of 1.0 means un-attenuated/unchanged. + * Each division by 2 equals an attenuation of -6dB. + * Each multiplicaton with 2 equals an amplification of +6dB. + * A value of 0.0 is meaningless with respect to a logarithmic + * scale; it is interpreted as zero volume - the channel + * is effectively disabled. + */ +#define AL_GAIN 0x100A + +/* + * Indicate minimum source attenuation + * Type: ALfloat + * Range: [0.0 - 1.0] + * + * Logarthmic + */ +#define AL_MIN_GAIN 0x100D + +/** + * Indicate maximum source attenuation + * Type: ALfloat + * Range: [0.0 - 1.0] + * + * Logarthmic + */ +#define AL_MAX_GAIN 0x100E + +/** + * Indicate listener orientation. + * + * at/up + */ +#define AL_ORIENTATION 0x100F + +/** + * Specify the channel mask. (Creative) + * Type: ALuint + * Range: [0 - 255] + */ +#define AL_CHANNEL_MASK 0x3000 + + +/** + * Source state information. + */ +#define AL_SOURCE_STATE 0x1010 +#define AL_INITIAL 0x1011 +#define AL_PLAYING 0x1012 +#define AL_PAUSED 0x1013 +#define AL_STOPPED 0x1014 + +/** + * Buffer Queue params + */ +#define AL_BUFFERS_QUEUED 0x1015 +#define AL_BUFFERS_PROCESSED 0x1016 + +/** + * Source buffer position information + */ +#define AL_SEC_OFFSET 0x1024 +#define AL_SAMPLE_OFFSET 0x1025 +#define AL_BYTE_OFFSET 0x1026 + +/* + * Source type (Static, Streaming or undetermined) + * Source is Static if a Buffer has been attached using AL_BUFFER + * Source is Streaming if one or more Buffers have been attached using alSourceQueueBuffers + * Source is undetermined when it has the NULL buffer attached + */ +#define AL_SOURCE_TYPE 0x1027 +#define AL_STATIC 0x1028 +#define AL_STREAMING 0x1029 +#define AL_UNDETERMINED 0x1030 + +/** Sound samples: format specifier. */ +#define AL_FORMAT_MONO8 0x1100 +#define AL_FORMAT_MONO16 0x1101 +#define AL_FORMAT_STEREO8 0x1102 +#define AL_FORMAT_STEREO16 0x1103 + +/** + * source specific reference distance + * Type: ALfloat + * Range: 0.0 - +inf + * + * At 0.0, no distance attenuation occurs. Default is + * 1.0. + */ +#define AL_REFERENCE_DISTANCE 0x1020 + +/** + * source specific rolloff factor + * Type: ALfloat + * Range: 0.0 - +inf + * + */ +#define AL_ROLLOFF_FACTOR 0x1021 + +/** + * Directional source, outer cone gain. + * + * Default: 0.0 + * Range: [0.0 - 1.0] + * Logarithmic + */ +#define AL_CONE_OUTER_GAIN 0x1022 + +/** + * Indicate distance above which sources are not + * attenuated using the inverse clamped distance model. + * + * Default: +inf + * Type: ALfloat + * Range: 0.0 - +inf + */ +#define AL_MAX_DISTANCE 0x1023 + +/** + * Sound samples: frequency, in units of Hertz [Hz]. + * This is the number of samples per second. Half of the + * sample frequency marks the maximum significant + * frequency component. + */ +#define AL_FREQUENCY 0x2001 +#define AL_BITS 0x2002 +#define AL_CHANNELS 0x2003 +#define AL_SIZE 0x2004 + +/** + * Buffer state. + * + * Not supported for public use (yet). + */ +#define AL_UNUSED 0x2010 +#define AL_PENDING 0x2011 +#define AL_PROCESSED 0x2012 + + +/** Errors: No Error. */ +#define AL_NO_ERROR AL_FALSE + +/** + * Invalid Name paramater passed to AL call. + */ +#define AL_INVALID_NAME 0xA001 + +/** + * Invalid parameter passed to AL call. + */ +#define AL_ILLEGAL_ENUM 0xA002 +#define AL_INVALID_ENUM 0xA002 + +/** + * Invalid enum parameter value. + */ +#define AL_INVALID_VALUE 0xA003 + +/** + * Illegal call. + */ +#define AL_ILLEGAL_COMMAND 0xA004 +#define AL_INVALID_OPERATION 0xA004 + + +/** + * No mojo. + */ +#define AL_OUT_OF_MEMORY 0xA005 + + +/** Context strings: Vendor Name. */ +#define AL_VENDOR 0xB001 +#define AL_VERSION 0xB002 +#define AL_RENDERER 0xB003 +#define AL_EXTENSIONS 0xB004 + +/** Global tweakage. */ + +/** + * Doppler scale. Default 1.0 + */ +#define AL_DOPPLER_FACTOR 0xC000 + +/** + * Tweaks speed of propagation. + */ +#define AL_DOPPLER_VELOCITY 0xC001 + +/** + * Speed of Sound in units per second + */ +#define AL_SPEED_OF_SOUND 0xC003 + +/** + * Distance models + * + * used in conjunction with DistanceModel + * + * implicit: NONE, which disances distance attenuation. + */ +#define AL_DISTANCE_MODEL 0xD000 +#define AL_INVERSE_DISTANCE 0xD001 +#define AL_INVERSE_DISTANCE_CLAMPED 0xD002 +#define AL_LINEAR_DISTANCE 0xD003 +#define AL_LINEAR_DISTANCE_CLAMPED 0xD004 +#define AL_EXPONENT_DISTANCE 0xD005 +#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006 + + +#if !defined(AL_NO_PROTOTYPES) + +/* + * Renderer State management + */ +AL_API void AL_APIENTRY alEnable( ALenum capability ); + +AL_API void AL_APIENTRY alDisable( ALenum capability ); + +AL_API ALboolean AL_APIENTRY alIsEnabled( ALenum capability ); + + +/* + * State retrieval + */ +AL_API const ALchar* AL_APIENTRY alGetString( ALenum param ); + +AL_API void AL_APIENTRY alGetBooleanv( ALenum param, ALboolean* data ); + +AL_API void AL_APIENTRY alGetIntegerv( ALenum param, ALint* data ); + +AL_API void AL_APIENTRY alGetFloatv( ALenum param, ALfloat* data ); + +AL_API void AL_APIENTRY alGetDoublev( ALenum param, ALdouble* data ); + +AL_API ALboolean AL_APIENTRY alGetBoolean( ALenum param ); + +AL_API ALint AL_APIENTRY alGetInteger( ALenum param ); + +AL_API ALfloat AL_APIENTRY alGetFloat( ALenum param ); + +AL_API ALdouble AL_APIENTRY alGetDouble( ALenum param ); + + +/* + * Error support. + * Obtain the most recent error generated in the AL state machine. + */ +AL_API ALenum AL_APIENTRY alGetError( void ); + + +/* + * Extension support. + * Query for the presence of an extension, and obtain any appropriate + * function pointers and enum values. + */ +AL_API ALboolean AL_APIENTRY alIsExtensionPresent( const ALchar* extname ); + +AL_API void* AL_APIENTRY alGetProcAddress( const ALchar* fname ); + +AL_API ALenum AL_APIENTRY alGetEnumValue( const ALchar* ename ); + + +/* + * LISTENER + * Listener represents the location and orientation of the + * 'user' in 3D-space. + * + * Properties include: - + * + * Gain AL_GAIN ALfloat + * Position AL_POSITION ALfloat[3] + * Velocity AL_VELOCITY ALfloat[3] + * Orientation AL_ORIENTATION ALfloat[6] (Forward then Up vectors) +*/ + +/* + * Set Listener parameters + */ +AL_API void AL_APIENTRY alListenerf( ALenum param, ALfloat value ); + +AL_API void AL_APIENTRY alListener3f( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); + +AL_API void AL_APIENTRY alListenerfv( ALenum param, const ALfloat* values ); + +AL_API void AL_APIENTRY alListeneri( ALenum param, ALint value ); + +AL_API void AL_APIENTRY alListener3i( ALenum param, ALint value1, ALint value2, ALint value3 ); + +AL_API void AL_APIENTRY alListeneriv( ALenum param, const ALint* values ); + +/* + * Get Listener parameters + */ +AL_API void AL_APIENTRY alGetListenerf( ALenum param, ALfloat* value ); + +AL_API void AL_APIENTRY alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ); + +AL_API void AL_APIENTRY alGetListenerfv( ALenum param, ALfloat* values ); + +AL_API void AL_APIENTRY alGetListeneri( ALenum param, ALint* value ); + +AL_API void AL_APIENTRY alGetListener3i( ALenum param, ALint *value1, ALint *value2, ALint *value3 ); + +AL_API void AL_APIENTRY alGetListeneriv( ALenum param, ALint* values ); + + +/** + * SOURCE + * Sources represent individual sound objects in 3D-space. + * Sources take the PCM data provided in the specified Buffer, + * apply Source-specific modifications, and then + * submit them to be mixed according to spatial arrangement etc. + * + * Properties include: - + * + * Gain AL_GAIN ALfloat + * Min Gain AL_MIN_GAIN ALfloat + * Max Gain AL_MAX_GAIN ALfloat + * Position AL_POSITION ALfloat[3] + * Velocity AL_VELOCITY ALfloat[3] + * Direction AL_DIRECTION ALfloat[3] + * Head Relative Mode AL_SOURCE_RELATIVE ALint (AL_TRUE or AL_FALSE) + * Reference Distance AL_REFERENCE_DISTANCE ALfloat + * Max Distance AL_MAX_DISTANCE ALfloat + * RollOff Factor AL_ROLLOFF_FACTOR ALfloat + * Inner Angle AL_CONE_INNER_ANGLE ALint or ALfloat + * Outer Angle AL_CONE_OUTER_ANGLE ALint or ALfloat + * Cone Outer Gain AL_CONE_OUTER_GAIN ALint or ALfloat + * Pitch AL_PITCH ALfloat + * Looping AL_LOOPING ALint (AL_TRUE or AL_FALSE) + * MS Offset AL_MSEC_OFFSET ALint or ALfloat + * Byte Offset AL_BYTE_OFFSET ALint or ALfloat + * Sample Offset AL_SAMPLE_OFFSET ALint or ALfloat + * Attached Buffer AL_BUFFER ALint + * State (Query only) AL_SOURCE_STATE ALint + * Buffers Queued (Query only) AL_BUFFERS_QUEUED ALint + * Buffers Processed (Query only) AL_BUFFERS_PROCESSED ALint + */ + +/* Create Source objects */ +AL_API void AL_APIENTRY alGenSources( ALsizei n, ALuint* sources ); + +/* Delete Source objects */ +AL_API void AL_APIENTRY alDeleteSources( ALsizei n, const ALuint* sources ); + +/* Verify a handle is a valid Source */ +AL_API ALboolean AL_APIENTRY alIsSource( ALuint sid ); + +/* + * Set Source parameters + */ +AL_API void AL_APIENTRY alSourcef( ALuint sid, ALenum param, ALfloat value ); + +AL_API void AL_APIENTRY alSource3f( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); + +AL_API void AL_APIENTRY alSourcefv( ALuint sid, ALenum param, const ALfloat* values ); + +AL_API void AL_APIENTRY alSourcei( ALuint sid, ALenum param, ALint value ); + +AL_API void AL_APIENTRY alSource3i( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ); + +AL_API void AL_APIENTRY alSourceiv( ALuint sid, ALenum param, const ALint* values ); + +/* + * Get Source parameters + */ +AL_API void AL_APIENTRY alGetSourcef( ALuint sid, ALenum param, ALfloat* value ); + +AL_API void AL_APIENTRY alGetSource3f( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3); + +AL_API void AL_APIENTRY alGetSourcefv( ALuint sid, ALenum param, ALfloat* values ); + +AL_API void AL_APIENTRY alGetSourcei( ALuint sid, ALenum param, ALint* value ); + +AL_API void AL_APIENTRY alGetSource3i( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3); + +AL_API void AL_APIENTRY alGetSourceiv( ALuint sid, ALenum param, ALint* values ); + + +/* + * Source vector based playback calls + */ + +/* Play, replay, or resume (if paused) a list of Sources */ +AL_API void AL_APIENTRY alSourcePlayv( ALsizei ns, const ALuint *sids ); + +/* Stop a list of Sources */ +AL_API void AL_APIENTRY alSourceStopv( ALsizei ns, const ALuint *sids ); + +/* Rewind a list of Sources */ +AL_API void AL_APIENTRY alSourceRewindv( ALsizei ns, const ALuint *sids ); + +/* Pause a list of Sources */ +AL_API void AL_APIENTRY alSourcePausev( ALsizei ns, const ALuint *sids ); + +/* + * Source based playback calls + */ + +/* Play, replay, or resume a Source */ +AL_API void AL_APIENTRY alSourcePlay( ALuint sid ); + +/* Stop a Source */ +AL_API void AL_APIENTRY alSourceStop( ALuint sid ); + +/* Rewind a Source (set playback postiton to beginning) */ +AL_API void AL_APIENTRY alSourceRewind( ALuint sid ); + +/* Pause a Source */ +AL_API void AL_APIENTRY alSourcePause( ALuint sid ); + +/* + * Source Queuing + */ +AL_API void AL_APIENTRY alSourceQueueBuffers( ALuint sid, ALsizei numEntries, const ALuint *bids ); + +AL_API void AL_APIENTRY alSourceUnqueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids ); + + +/** + * BUFFER + * Buffer objects are storage space for sample data. + * Buffers are referred to by Sources. One Buffer can be used + * by multiple Sources. + * + * Properties include: - + * + * Frequency (Query only) AL_FREQUENCY ALint + * Size (Query only) AL_SIZE ALint + * Bits (Query only) AL_BITS ALint + * Channels (Query only) AL_CHANNELS ALint + */ + +/* Create Buffer objects */ +AL_API void AL_APIENTRY alGenBuffers( ALsizei n, ALuint* buffers ); + +/* Delete Buffer objects */ +AL_API void AL_APIENTRY alDeleteBuffers( ALsizei n, const ALuint* buffers ); + +/* Verify a handle is a valid Buffer */ +AL_API ALboolean AL_APIENTRY alIsBuffer( ALuint bid ); + +/* Specify the data to be copied into a buffer */ +AL_API void AL_APIENTRY alBufferData( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq ); + +/* + * Set Buffer parameters + */ +AL_API void AL_APIENTRY alBufferf( ALuint bid, ALenum param, ALfloat value ); + +AL_API void AL_APIENTRY alBuffer3f( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); + +AL_API void AL_APIENTRY alBufferfv( ALuint bid, ALenum param, const ALfloat* values ); + +AL_API void AL_APIENTRY alBufferi( ALuint bid, ALenum param, ALint value ); + +AL_API void AL_APIENTRY alBuffer3i( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ); + +AL_API void AL_APIENTRY alBufferiv( ALuint bid, ALenum param, const ALint* values ); + +/* + * Get Buffer parameters + */ +AL_API void AL_APIENTRY alGetBufferf( ALuint bid, ALenum param, ALfloat* value ); + +AL_API void AL_APIENTRY alGetBuffer3f( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3); + +AL_API void AL_APIENTRY alGetBufferfv( ALuint bid, ALenum param, ALfloat* values ); + +AL_API void AL_APIENTRY alGetBufferi( ALuint bid, ALenum param, ALint* value ); + +AL_API void AL_APIENTRY alGetBuffer3i( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3); + +AL_API void AL_APIENTRY alGetBufferiv( ALuint bid, ALenum param, ALint* values ); + + +/* + * Global Parameters + */ +AL_API void AL_APIENTRY alDopplerFactor( ALfloat value ); + +AL_API void AL_APIENTRY alDopplerVelocity( ALfloat value ); + +AL_API void AL_APIENTRY alSpeedOfSound( ALfloat value ); + +AL_API void AL_APIENTRY alDistanceModel( ALenum distanceModel ); + +#else /* AL_NO_PROTOTYPES */ + +typedef void (AL_APIENTRY *LPALENABLE)( ALenum capability ); +typedef void (AL_APIENTRY *LPALDISABLE)( ALenum capability ); +typedef ALboolean (AL_APIENTRY *LPALISENABLED)( ALenum capability ); +typedef const ALchar* (AL_APIENTRY *LPALGETSTRING)( ALenum param ); +typedef void (AL_APIENTRY *LPALGETBOOLEANV)( ALenum param, ALboolean* data ); +typedef void (AL_APIENTRY *LPALGETINTEGERV)( ALenum param, ALint* data ); +typedef void (AL_APIENTRY *LPALGETFLOATV)( ALenum param, ALfloat* data ); +typedef void (AL_APIENTRY *LPALGETDOUBLEV)( ALenum param, ALdouble* data ); +typedef ALboolean (AL_APIENTRY *LPALGETBOOLEAN)( ALenum param ); +typedef ALint (AL_APIENTRY *LPALGETINTEGER)( ALenum param ); +typedef ALfloat (AL_APIENTRY *LPALGETFLOAT)( ALenum param ); +typedef ALdouble (AL_APIENTRY *LPALGETDOUBLE)( ALenum param ); +typedef ALenum (AL_APIENTRY *LPALGETERROR)( void ); +typedef ALboolean (AL_APIENTRY *LPALISEXTENSIONPRESENT)(const ALchar* extname ); +typedef void* (AL_APIENTRY *LPALGETPROCADDRESS)( const ALchar* fname ); +typedef ALenum (AL_APIENTRY *LPALGETENUMVALUE)( const ALchar* ename ); +typedef void (AL_APIENTRY *LPALLISTENERF)( ALenum param, ALfloat value ); +typedef void (AL_APIENTRY *LPALLISTENER3F)( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); +typedef void (AL_APIENTRY *LPALLISTENERFV)( ALenum param, const ALfloat* values ); +typedef void (AL_APIENTRY *LPALLISTENERI)( ALenum param, ALint value ); +typedef void (AL_APIENTRY *LPALLISTENER3I)( ALenum param, ALint value1, ALint value2, ALint value3 ); +typedef void (AL_APIENTRY *LPALLISTENERIV)( ALenum param, const ALint* values ); +typedef void (AL_APIENTRY *LPALGETLISTENERF)( ALenum param, ALfloat* value ); +typedef void (AL_APIENTRY *LPALGETLISTENER3F)( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ); +typedef void (AL_APIENTRY *LPALGETLISTENERFV)( ALenum param, ALfloat* values ); +typedef void (AL_APIENTRY *LPALGETLISTENERI)( ALenum param, ALint* value ); +typedef void (AL_APIENTRY *LPALGETLISTENER3I)( ALenum param, ALint *value1, ALint *value2, ALint *value3 ); +typedef void (AL_APIENTRY *LPALGETLISTENERIV)( ALenum param, ALint* values ); +typedef void (AL_APIENTRY *LPALGENSOURCES)( ALsizei n, ALuint* sources ); +typedef void (AL_APIENTRY *LPALDELETESOURCES)( ALsizei n, const ALuint* sources ); +typedef ALboolean (AL_APIENTRY *LPALISSOURCE)( ALuint sid ); +typedef void (AL_APIENTRY *LPALSOURCEF)( ALuint sid, ALenum param, ALfloat value); +typedef void (AL_APIENTRY *LPALSOURCE3F)( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); +typedef void (AL_APIENTRY *LPALSOURCEFV)( ALuint sid, ALenum param, const ALfloat* values ); +typedef void (AL_APIENTRY *LPALSOURCEI)( ALuint sid, ALenum param, ALint value); +typedef void (AL_APIENTRY *LPALSOURCE3I)( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ); +typedef void (AL_APIENTRY *LPALSOURCEIV)( ALuint sid, ALenum param, const ALint* values ); +typedef void (AL_APIENTRY *LPALGETSOURCEF)( ALuint sid, ALenum param, ALfloat* value ); +typedef void (AL_APIENTRY *LPALGETSOURCE3F)( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3); +typedef void (AL_APIENTRY *LPALGETSOURCEFV)( ALuint sid, ALenum param, ALfloat* values ); +typedef void (AL_APIENTRY *LPALGETSOURCEI)( ALuint sid, ALenum param, ALint* value ); +typedef void (AL_APIENTRY *LPALGETSOURCE3I)( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3); +typedef void (AL_APIENTRY *LPALGETSOURCEIV)( ALuint sid, ALenum param, ALint* values ); +typedef void (AL_APIENTRY *LPALSOURCEPLAYV)( ALsizei ns, const ALuint *sids ); +typedef void (AL_APIENTRY *LPALSOURCESTOPV)( ALsizei ns, const ALuint *sids ); +typedef void (AL_APIENTRY *LPALSOURCEREWINDV)( ALsizei ns, const ALuint *sids ); +typedef void (AL_APIENTRY *LPALSOURCEPAUSEV)( ALsizei ns, const ALuint *sids ); +typedef void (AL_APIENTRY *LPALSOURCEPLAY)( ALuint sid ); +typedef void (AL_APIENTRY *LPALSOURCESTOP)( ALuint sid ); +typedef void (AL_APIENTRY *LPALSOURCEREWIND)( ALuint sid ); +typedef void (AL_APIENTRY *LPALSOURCEPAUSE)( ALuint sid ); +typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, const ALuint *bids ); +typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, ALuint *bids ); +typedef void (AL_APIENTRY *LPALGENBUFFERS)( ALsizei n, ALuint* buffers ); +typedef void (AL_APIENTRY *LPALDELETEBUFFERS)( ALsizei n, const ALuint* buffers ); +typedef ALboolean (AL_APIENTRY *LPALISBUFFER)( ALuint bid ); +typedef void (AL_APIENTRY *LPALBUFFERDATA)( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq ); +typedef void (AL_APIENTRY *LPALBUFFERF)( ALuint bid, ALenum param, ALfloat value); +typedef void (AL_APIENTRY *LPALBUFFER3F)( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); +typedef void (AL_APIENTRY *LPALBUFFERFV)( ALuint bid, ALenum param, const ALfloat* values ); +typedef void (AL_APIENTRY *LPALBUFFERI)( ALuint bid, ALenum param, ALint value); +typedef void (AL_APIENTRY *LPALBUFFER3I)( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ); +typedef void (AL_APIENTRY *LPALBUFFERIV)( ALuint bid, ALenum param, const ALint* values ); +typedef void (AL_APIENTRY *LPALGETBUFFERF)( ALuint bid, ALenum param, ALfloat* value ); +typedef void (AL_APIENTRY *LPALGETBUFFER3F)( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3); +typedef void (AL_APIENTRY *LPALGETBUFFERFV)( ALuint bid, ALenum param, ALfloat* values ); +typedef void (AL_APIENTRY *LPALGETBUFFERI)( ALuint bid, ALenum param, ALint* value ); +typedef void (AL_APIENTRY *LPALGETBUFFER3I)( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3); +typedef void (AL_APIENTRY *LPALGETBUFFERIV)( ALuint bid, ALenum param, ALint* values ); +typedef void (AL_APIENTRY *LPALDOPPLERFACTOR)( ALfloat value ); +typedef void (AL_APIENTRY *LPALDOPPLERVELOCITY)( ALfloat value ); +typedef void (AL_APIENTRY *LPALSPEEDOFSOUND)( ALfloat value ); +typedef void (AL_APIENTRY *LPALDISTANCEMODEL)( ALenum distanceModel ); + +#endif /* AL_NO_PROTOTYPES */ + +#if TARGET_OS_MAC + #pragma export off +#endif + +#if defined(__cplusplus) +} /* extern "C" */ +#endif + +#endif /* AL_AL_H */ diff --git a/OpenAL/include/alc.h b/OpenAL/include/alc.h new file mode 100644 index 0000000000..b0bbfbe7de --- /dev/null +++ b/OpenAL/include/alc.h @@ -0,0 +1,281 @@ +#ifndef AL_ALC_H +#define AL_ALC_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(_WIN32) && !defined(_XBOX) + /* _OPENAL32LIB is deprecated */ + #if defined(AL_BUILD_LIBRARY) || defined (_OPENAL32LIB) + #define ALC_API __declspec(dllexport) + #else + #define ALC_API __declspec(dllimport) + #endif +#else + #if defined(AL_BUILD_LIBRARY) && defined(HAVE_GCC_VISIBILITY) + #define ALC_API __attribute__((visibility("default"))) + #else + #define ALC_API extern + #endif +#endif + +#if defined(_WIN32) + #define ALC_APIENTRY __cdecl +#else + #define ALC_APIENTRY +#endif + +#if defined(TARGET_OS_MAC) && TARGET_OS_MAC + #pragma export on +#endif + +/* + * The ALCAPI, ALCAPIENTRY, and ALC_INVALID macros are deprecated, but are + * included for applications porting code from AL 1.0 + */ +#define ALCAPI ALC_API +#define ALCAPIENTRY ALC_APIENTRY +#define ALC_INVALID 0 + + +#define ALC_VERSION_0_1 1 + +typedef struct ALCdevice_struct ALCdevice; +typedef struct ALCcontext_struct ALCcontext; + + +/** 8-bit boolean */ +typedef char ALCboolean; + +/** character */ +typedef char ALCchar; + +/** signed 8-bit 2's complement integer */ +typedef char ALCbyte; + +/** unsigned 8-bit integer */ +typedef unsigned char ALCubyte; + +/** signed 16-bit 2's complement integer */ +typedef short ALCshort; + +/** unsigned 16-bit integer */ +typedef unsigned short ALCushort; + +/** signed 32-bit 2's complement integer */ +typedef int ALCint; + +/** unsigned 32-bit integer */ +typedef unsigned int ALCuint; + +/** non-negative 32-bit binary integer size */ +typedef int ALCsizei; + +/** enumerated 32-bit value */ +typedef int ALCenum; + +/** 32-bit IEEE754 floating-point */ +typedef float ALCfloat; + +/** 64-bit IEEE754 floating-point */ +typedef double ALCdouble; + +/** void type (for opaque pointers only) */ +typedef void ALCvoid; + + +/* Enumerant values begin at column 50. No tabs. */ + +/* Boolean False. */ +#define ALC_FALSE 0 + +/* Boolean True. */ +#define ALC_TRUE 1 + +/** + * followed by Hz + */ +#define ALC_FREQUENCY 0x1007 + +/** + * followed by Hz + */ +#define ALC_REFRESH 0x1008 + +/** + * followed by AL_TRUE, AL_FALSE + */ +#define ALC_SYNC 0x1009 + +/** + * followed by Num of requested Mono (3D) Sources + */ +#define ALC_MONO_SOURCES 0x1010 + +/** + * followed by Num of requested Stereo Sources + */ +#define ALC_STEREO_SOURCES 0x1011 + +/** + * errors + */ + +/** + * No error + */ +#define ALC_NO_ERROR ALC_FALSE + +/** + * No device + */ +#define ALC_INVALID_DEVICE 0xA001 + +/** + * invalid context ID + */ +#define ALC_INVALID_CONTEXT 0xA002 + +/** + * bad enum + */ +#define ALC_INVALID_ENUM 0xA003 + +/** + * bad value + */ +#define ALC_INVALID_VALUE 0xA004 + +/** + * Out of memory. + */ +#define ALC_OUT_OF_MEMORY 0xA005 + + +/** + * The Specifier string for default device + */ +#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004 +#define ALC_DEVICE_SPECIFIER 0x1005 +#define ALC_EXTENSIONS 0x1006 + +#define ALC_MAJOR_VERSION 0x1000 +#define ALC_MINOR_VERSION 0x1001 + +#define ALC_ATTRIBUTES_SIZE 0x1002 +#define ALC_ALL_ATTRIBUTES 0x1003 + +/** + * ALC_ENUMERATE_ALL_EXT enums + */ +#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012 +#define ALC_ALL_DEVICES_SPECIFIER 0x1013 + +/** + * Capture extension + */ +#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310 +#define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311 +#define ALC_CAPTURE_SAMPLES 0x312 + + +/* + * Context Management + */ +ALC_API ALCcontext * ALC_APIENTRY alcCreateContext( ALCdevice *device, const ALCint* attrlist ); + +ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent( ALCcontext *context ); + +ALC_API void ALC_APIENTRY alcProcessContext( ALCcontext *context ); + +ALC_API void ALC_APIENTRY alcSuspendContext( ALCcontext *context ); + +ALC_API void ALC_APIENTRY alcDestroyContext( ALCcontext *context ); + +ALC_API ALCcontext * ALC_APIENTRY alcGetCurrentContext( void ); + +ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice( ALCcontext *context ); + + +/* + * Device Management + */ +ALC_API ALCdevice * ALC_APIENTRY alcOpenDevice( const ALCchar *devicename ); + +ALC_API ALCboolean ALC_APIENTRY alcCloseDevice( ALCdevice *device ); + + +/* + * Error support. + * Obtain the most recent Context error + */ +ALC_API ALCenum ALC_APIENTRY alcGetError( ALCdevice *device ); + + +/* + * Extension support. + * Query for the presence of an extension, and obtain any appropriate + * function pointers and enum values. + */ +ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent( ALCdevice *device, const ALCchar *extname ); + +ALC_API void * ALC_APIENTRY alcGetProcAddress( ALCdevice *device, const ALCchar *funcname ); + +ALC_API ALCenum ALC_APIENTRY alcGetEnumValue( ALCdevice *device, const ALCchar *enumname ); + + +/* + * Query functions + */ +ALC_API const ALCchar * ALC_APIENTRY alcGetString( ALCdevice *device, ALCenum param ); + +ALC_API void ALC_APIENTRY alcGetIntegerv( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data ); + + +/* + * Capture functions + */ +ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ); + +ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice( ALCdevice *device ); + +ALC_API void ALC_APIENTRY alcCaptureStart( ALCdevice *device ); + +ALC_API void ALC_APIENTRY alcCaptureStop( ALCdevice *device ); + +ALC_API void ALC_APIENTRY alcCaptureSamples( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ); + +/* + * Pointer-to-function types, useful for dynamically getting ALC entry points. + */ +typedef ALCcontext * (ALC_APIENTRY *LPALCCREATECONTEXT) (ALCdevice *device, const ALCint *attrlist); +typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)( ALCcontext *context ); +typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)( ALCcontext *context ); +typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)( ALCcontext *context ); +typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)( ALCcontext *context ); +typedef ALCcontext * (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)( void ); +typedef ALCdevice * (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)( ALCcontext *context ); +typedef ALCdevice * (ALC_APIENTRY *LPALCOPENDEVICE)( const ALCchar *devicename ); +typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)( ALCdevice *device ); +typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)( ALCdevice *device ); +typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)( ALCdevice *device, const ALCchar *extname ); +typedef void * (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname ); +typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname ); +typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param ); +typedef void (ALC_APIENTRY *LPALCGETINTEGERV)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *dest ); +typedef ALCdevice * (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ); +typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)( ALCdevice *device ); +typedef void (ALC_APIENTRY *LPALCCAPTURESTART)( ALCdevice *device ); +typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)( ALCdevice *device ); +typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ); + +#if defined(TARGET_OS_MAC) && TARGET_OS_MAC + #pragma export off +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* AL_ALC_H */ diff --git a/OpenAL/include/efx-creative.h b/OpenAL/include/efx-creative.h new file mode 100644 index 0000000000..4ea9da6b72 --- /dev/null +++ b/OpenAL/include/efx-creative.h @@ -0,0 +1,151 @@ +#ifndef __efxcreative_h_ +#define __efxcreative_h_ + +/** + * efx-creative.h - Environmental Audio Extensions + * for OpenAL Effects Extension. + * + */ +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Effect object definitions to be used with alEffect functions. + * + * Effect parameter value definitions, ranges, and defaults + * appear farther down in this file. + */ + +/* AL EAXReverb effect parameters. */ +#define AL_EAXREVERB_DENSITY 0x0001 +#define AL_EAXREVERB_DIFFUSION 0x0002 +#define AL_EAXREVERB_GAIN 0x0003 +#define AL_EAXREVERB_GAINHF 0x0004 +#define AL_EAXREVERB_GAINLF 0x0005 +#define AL_EAXREVERB_DECAY_TIME 0x0006 +#define AL_EAXREVERB_DECAY_HFRATIO 0x0007 +#define AL_EAXREVERB_DECAY_LFRATIO 0x0008 +#define AL_EAXREVERB_REFLECTIONS_GAIN 0x0009 +#define AL_EAXREVERB_REFLECTIONS_DELAY 0x000A +#define AL_EAXREVERB_REFLECTIONS_PAN 0x000B +#define AL_EAXREVERB_LATE_REVERB_GAIN 0x000C +#define AL_EAXREVERB_LATE_REVERB_DELAY 0x000D +#define AL_EAXREVERB_LATE_REVERB_PAN 0x000E +#define AL_EAXREVERB_ECHO_TIME 0x000F +#define AL_EAXREVERB_ECHO_DEPTH 0x0010 +#define AL_EAXREVERB_MODULATION_TIME 0x0011 +#define AL_EAXREVERB_MODULATION_DEPTH 0x0012 +#define AL_EAXREVERB_AIR_ABSORPTION_GAINHF 0x0013 +#define AL_EAXREVERB_HFREFERENCE 0x0014 +#define AL_EAXREVERB_LFREFERENCE 0x0015 +#define AL_EAXREVERB_ROOM_ROLLOFF_FACTOR 0x0016 +#define AL_EAXREVERB_DECAY_HFLIMIT 0x0017 + +/* Effect type definitions to be used with AL_EFFECT_TYPE. */ +#define AL_EFFECT_EAXREVERB 0x8000 + + + + /********************************************************** + * Effect parameter structures, value definitions, ranges and defaults. + */ + +/** + * AL reverb effect parameter ranges and defaults + */ +#define AL_EAXREVERB_MIN_DENSITY 0.0f +#define AL_EAXREVERB_MAX_DENSITY 1.0f +#define AL_EAXREVERB_DEFAULT_DENSITY 1.0f + +#define AL_EAXREVERB_MIN_DIFFUSION 0.0f +#define AL_EAXREVERB_MAX_DIFFUSION 1.0f +#define AL_EAXREVERB_DEFAULT_DIFFUSION 1.0f + +#define AL_EAXREVERB_MIN_GAIN 0.0f +#define AL_EAXREVERB_MAX_GAIN 1.0f +#define AL_EAXREVERB_DEFAULT_GAIN 0.32f + +#define AL_EAXREVERB_MIN_GAINHF 0.0f +#define AL_EAXREVERB_MAX_GAINHF 1.0f +#define AL_EAXREVERB_DEFAULT_GAINHF 0.89f + +#define AL_EAXREVERB_MIN_GAINLF 0.0f +#define AL_EAXREVERB_MAX_GAINLF 1.0f +#define AL_EAXREVERB_DEFAULT_GAINLF 1.0f + +#define AL_EAXREVERB_MIN_DECAY_TIME 0.1f +#define AL_EAXREVERB_MAX_DECAY_TIME 20.0f +#define AL_EAXREVERB_DEFAULT_DECAY_TIME 1.49f + +#define AL_EAXREVERB_MIN_DECAY_HFRATIO 0.1f +#define AL_EAXREVERB_MAX_DECAY_HFRATIO 2.0f +#define AL_EAXREVERB_DEFAULT_DECAY_HFRATIO 0.83f + +#define AL_EAXREVERB_MIN_DECAY_LFRATIO 0.1f +#define AL_EAXREVERB_MAX_DECAY_LFRATIO 2.0f +#define AL_EAXREVERB_DEFAULT_DECAY_LFRATIO 1.0f + +#define AL_EAXREVERB_MIN_REFLECTIONS_GAIN 0.0f +#define AL_EAXREVERB_MAX_REFLECTIONS_GAIN 3.16f +#define AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN 0.05f + +#define AL_EAXREVERB_MIN_REFLECTIONS_DELAY 0.0f +#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY 0.3f +#define AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY 0.007f + +#define AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN {0.0f, 0.0f, 0.0f} + +#define AL_EAXREVERB_MIN_LATE_REVERB_GAIN 0.0f +#define AL_EAXREVERB_MAX_LATE_REVERB_GAIN 10.0f +#define AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN 1.26f + +#define AL_EAXREVERB_MIN_LATE_REVERB_DELAY 0.0f +#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY 0.1f +#define AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY 0.011f + +#define AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN {0.0f, 0.0f, 0.0f} + +#define AL_EAXREVERB_MIN_ECHO_TIME 0.075f +#define AL_EAXREVERB_MAX_ECHO_TIME 0.25f +#define AL_EAXREVERB_DEFAULT_ECHO_TIME 0.25f + +#define AL_EAXREVERB_MIN_ECHO_DEPTH 0.0f +#define AL_EAXREVERB_MAX_ECHO_DEPTH 1.0f +#define AL_EAXREVERB_DEFAULT_ECHO_DEPTH 0.0f + +#define AL_EAXREVERB_MIN_MODULATION_TIME 0.04f +#define AL_EAXREVERB_MAX_MODULATION_TIME 4.0f +#define AL_EAXREVERB_DEFAULT_MODULATION_TIME 0.25f + +#define AL_EAXREVERB_MIN_MODULATION_DEPTH 0.0f +#define AL_EAXREVERB_MAX_MODULATION_DEPTH 1.0f +#define AL_EAXREVERB_DEFAULT_MODULATION_DEPTH 0.0f + +#define AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF 0.892f +#define AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF 1.0f +#define AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF 0.994f + +#define AL_EAXREVERB_MIN_HFREFERENCE 1000.0f +#define AL_EAXREVERB_MAX_HFREFERENCE 20000.0f +#define AL_EAXREVERB_DEFAULT_HFREFERENCE 5000.0f + +#define AL_EAXREVERB_MIN_LFREFERENCE 20.0f +#define AL_EAXREVERB_MAX_LFREFERENCE 1000.0f +#define AL_EAXREVERB_DEFAULT_LFREFERENCE 250.0f + +#define AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR 0.0f +#define AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR 10.0f +#define AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR 0.0f + +#define AL_EAXREVERB_MIN_DECAY_HFLIMIT AL_FALSE +#define AL_EAXREVERB_MAX_DECAY_HFLIMIT AL_TRUE +#define AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __efxcreative_h_ */ diff --git a/OpenAL/include/efx.h b/OpenAL/include/efx.h new file mode 100644 index 0000000000..fece1608de --- /dev/null +++ b/OpenAL/include/efx.h @@ -0,0 +1,737 @@ +#ifndef __efx_h_ +#define __efx_h_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#define ALC_EXT_EFX_NAME "ALC_EXT_EFX" + +/** + * Context definitions to be used with alcCreateContext. + * These values must be unique and not conflict with other + * al context values. + */ +#define ALC_EFX_MAJOR_VERSION 0x20001 +#define ALC_EFX_MINOR_VERSION 0x20002 +#define ALC_MAX_AUXILIARY_SENDS 0x20003 + + + + +/** + * Listener definitions to be used with alListener functions. + * These values must be unique and not conflict with other + * al listener values. + */ +#define AL_METERS_PER_UNIT 0x20004 + + + + +/** + * Source definitions to be used with alSource functions. + * These values must be unique and not conflict with other + * al source values. + */ +#define AL_DIRECT_FILTER 0x20005 +#define AL_AUXILIARY_SEND_FILTER 0x20006 +#define AL_AIR_ABSORPTION_FACTOR 0x20007 +#define AL_ROOM_ROLLOFF_FACTOR 0x20008 +#define AL_CONE_OUTER_GAINHF 0x20009 +#define AL_DIRECT_FILTER_GAINHF_AUTO 0x2000A +#define AL_AUXILIARY_SEND_FILTER_GAIN_AUTO 0x2000B +#define AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO 0x2000C + + + + +/** + * Effect object definitions to be used with alEffect functions. + * + * Effect parameter value definitions, ranges, and defaults + * appear farther down in this file. + */ + +/* Reverb Parameters */ +#define AL_REVERB_DENSITY 0x0001 +#define AL_REVERB_DIFFUSION 0x0002 +#define AL_REVERB_GAIN 0x0003 +#define AL_REVERB_GAINHF 0x0004 +#define AL_REVERB_DECAY_TIME 0x0005 +#define AL_REVERB_DECAY_HFRATIO 0x0006 +#define AL_REVERB_REFLECTIONS_GAIN 0x0007 +#define AL_REVERB_REFLECTIONS_DELAY 0x0008 +#define AL_REVERB_LATE_REVERB_GAIN 0x0009 +#define AL_REVERB_LATE_REVERB_DELAY 0x000A +#define AL_REVERB_AIR_ABSORPTION_GAINHF 0x000B +#define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C +#define AL_REVERB_DECAY_HFLIMIT 0x000D + +/* Chorus Parameters */ +#define AL_CHORUS_WAVEFORM 0x0001 +#define AL_CHORUS_PHASE 0x0002 +#define AL_CHORUS_RATE 0x0003 +#define AL_CHORUS_DEPTH 0x0004 +#define AL_CHORUS_FEEDBACK 0x0005 +#define AL_CHORUS_DELAY 0x0006 + +/* Distortion Parameters */ +#define AL_DISTORTION_EDGE 0x0001 +#define AL_DISTORTION_GAIN 0x0002 +#define AL_DISTORTION_LOWPASS_CUTOFF 0x0003 +#define AL_DISTORTION_EQCENTER 0x0004 +#define AL_DISTORTION_EQBANDWIDTH 0x0005 + +/* Echo Parameters */ +#define AL_ECHO_DELAY 0x0001 +#define AL_ECHO_LRDELAY 0x0002 +#define AL_ECHO_DAMPING 0x0003 +#define AL_ECHO_FEEDBACK 0x0004 +#define AL_ECHO_SPREAD 0x0005 + +/* Flanger Parameters */ +#define AL_FLANGER_WAVEFORM 0x0001 +#define AL_FLANGER_PHASE 0x0002 +#define AL_FLANGER_RATE 0x0003 +#define AL_FLANGER_DEPTH 0x0004 +#define AL_FLANGER_FEEDBACK 0x0005 +#define AL_FLANGER_DELAY 0x0006 + +/* Frequencyshifter Parameters */ +#define AL_FREQUENCY_SHIFTER_FREQUENCY 0x0001 +#define AL_FREQUENCY_SHIFTER_LEFT_DIRECTION 0x0002 +#define AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION 0x0003 + +/* Vocalmorpher Parameters */ +#define AL_VOCAL_MORPHER_PHONEMEA 0x0001 +#define AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING 0x0002 +#define AL_VOCAL_MORPHER_PHONEMEB 0x0003 +#define AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING 0x0004 +#define AL_VOCAL_MORPHER_WAVEFORM 0x0005 +#define AL_VOCAL_MORPHER_RATE 0x0006 + +/* Pitchshifter Parameters */ +#define AL_PITCH_SHIFTER_COARSE_TUNE 0x0001 +#define AL_PITCH_SHIFTER_FINE_TUNE 0x0002 + +/* Ringmodulator Parameters */ +#define AL_RING_MODULATOR_FREQUENCY 0x0001 +#define AL_RING_MODULATOR_HIGHPASS_CUTOFF 0x0002 +#define AL_RING_MODULATOR_WAVEFORM 0x0003 + +/* Autowah Parameters */ +#define AL_AUTOWAH_ATTACK_TIME 0x0001 +#define AL_AUTOWAH_RELEASE_TIME 0x0002 +#define AL_AUTOWAH_RESONANCE 0x0003 +#define AL_AUTOWAH_PEAK_GAIN 0x0004 + +/* Compressor Parameters */ +#define AL_COMPRESSOR_ONOFF 0x0001 + +/* Equalizer Parameters */ +#define AL_EQUALIZER_LOW_GAIN 0x0001 +#define AL_EQUALIZER_LOW_CUTOFF 0x0002 +#define AL_EQUALIZER_MID1_GAIN 0x0003 +#define AL_EQUALIZER_MID1_CENTER 0x0004 +#define AL_EQUALIZER_MID1_WIDTH 0x0005 +#define AL_EQUALIZER_MID2_GAIN 0x0006 +#define AL_EQUALIZER_MID2_CENTER 0x0007 +#define AL_EQUALIZER_MID2_WIDTH 0x0008 +#define AL_EQUALIZER_HIGH_GAIN 0x0009 +#define AL_EQUALIZER_HIGH_CUTOFF 0x000A + +/* Effect type */ +#define AL_EFFECT_FIRST_PARAMETER 0x0000 +#define AL_EFFECT_LAST_PARAMETER 0x8000 +#define AL_EFFECT_TYPE 0x8001 + +/* Effect type definitions to be used with AL_EFFECT_TYPE. */ +#define AL_EFFECT_NULL 0x0000 /* Can also be used as an Effect Object ID */ +#define AL_EFFECT_REVERB 0x0001 +#define AL_EFFECT_CHORUS 0x0002 +#define AL_EFFECT_DISTORTION 0x0003 +#define AL_EFFECT_ECHO 0x0004 +#define AL_EFFECT_FLANGER 0x0005 +#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006 +#define AL_EFFECT_VOCAL_MORPHER 0x0007 +#define AL_EFFECT_PITCH_SHIFTER 0x0008 +#define AL_EFFECT_RING_MODULATOR 0x0009 +#define AL_EFFECT_AUTOWAH 0x000A +#define AL_EFFECT_COMPRESSOR 0x000B +#define AL_EFFECT_EQUALIZER 0x000C + +/** + * Auxiliary Slot object definitions to be used with alAuxiliaryEffectSlot functions. + */ +#define AL_EFFECTSLOT_EFFECT 0x0001 +#define AL_EFFECTSLOT_GAIN 0x0002 +#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO 0x0003 + +/** + * Value to be used as an Auxiliary Slot ID to disable a source send.. + */ +#define AL_EFFECTSLOT_NULL 0x0000 + + + +/** + * Filter object definitions to be used with alFilter functions. + */ + +/* Lowpass parameters. */ +#define AL_LOWPASS_GAIN 0x0001 +#define AL_LOWPASS_GAINHF 0x0002 + +/* Highpass Parameters */ +#define AL_HIGHPASS_GAIN 0x0001 +#define AL_HIGHPASS_GAINLF 0x0002 + +/* Bandpass Parameters */ +#define AL_BANDPASS_GAIN 0x0001 +#define AL_BANDPASS_GAINLF 0x0002 +#define AL_BANDPASS_GAINHF 0x0003 + +/* Filter type */ +#define AL_FILTER_FIRST_PARAMETER 0x0000 +#define AL_FILTER_LAST_PARAMETER 0x8000 +#define AL_FILTER_TYPE 0x8001 + +/* Filter type definitions to be used with AL_FILTER_TYPE. */ +#define AL_FILTER_NULL 0x0000 /* Can also be used as a Filter Object ID */ +#define AL_FILTER_LOWPASS 0x0001 +#define AL_FILTER_HIGHPASS 0x0002 +#define AL_FILTER_BANDPASS 0x0003 + + +/** + * Effect object functions. + */ + +/* Create Effect objects. */ +typedef void (__cdecl *LPALGENEFFECTS)( ALsizei n, ALuint* effects ); + +/* Delete Effect objects. */ +typedef void (__cdecl *LPALDELETEEFFECTS)( ALsizei n, ALuint* effects ); + +/* Verify a handle is a valid Effect. */ +typedef ALboolean (__cdecl *LPALISEFFECT)( ALuint eid ); + +/* Set an integer parameter for an Effect object. */ +typedef void (__cdecl *LPALEFFECTI)( ALuint eid, ALenum param, ALint value); +typedef void (__cdecl *LPALEFFECTIV)( ALuint eid, ALenum param, ALint* values ); + +/* Set a floating point parameter for an Effect object. */ +typedef void (__cdecl *LPALEFFECTF)( ALuint eid, ALenum param, ALfloat value); +typedef void (__cdecl *LPALEFFECTFV)( ALuint eid, ALenum param, ALfloat* values ); + +/* Get an integer parameter for an Effect object. */ +typedef void (__cdecl *LPALGETEFFECTI)( ALuint eid, ALenum pname, ALint* value ); +typedef void (__cdecl *LPALGETEFFECTIV)( ALuint eid, ALenum pname, ALint* values ); + +/* Get a floating point parameter for an Effect object. */ +typedef void (__cdecl *LPALGETEFFECTF)( ALuint eid, ALenum pname, ALfloat* value ); +typedef void (__cdecl *LPALGETEFFECTFV)( ALuint eid, ALenum pname, ALfloat* values ); + + +/** + * Filter object functions + */ + +/* Create Filter objects. */ +typedef void (__cdecl *LPALGENFILTERS)( ALsizei n, ALuint* filters ); + +/* Delete Filter objects. */ +typedef void (__cdecl *LPALDELETEFILTERS)( ALsizei n, ALuint* filters ); + +/* Verify a handle is a valid Filter. */ +typedef ALboolean (__cdecl *LPALISFILTER)( ALuint fid ); + +/* Set an integer parameter for a Filter object. */ +typedef void (__cdecl *LPALFILTERI)( ALuint fid, ALenum param, ALint value ); +typedef void (__cdecl *LPALFILTERIV)( ALuint fid, ALenum param, ALint* values ); + +/* Set a floating point parameter for an Filter object. */ +typedef void (__cdecl *LPALFILTERF)( ALuint fid, ALenum param, ALfloat value); +typedef void (__cdecl *LPALFILTERFV)( ALuint fid, ALenum param, ALfloat* values ); + +/* Get an integer parameter for a Filter object. */ +typedef void (__cdecl *LPALGETFILTERI)( ALuint fid, ALenum pname, ALint* value ); +typedef void (__cdecl *LPALGETFILTERIV)( ALuint fid, ALenum pname, ALint* values ); + +/* Get a floating point parameter for a Filter object. */ +typedef void (__cdecl *LPALGETFILTERF)( ALuint fid, ALenum pname, ALfloat* value ); +typedef void (__cdecl *LPALGETFILTERFV)( ALuint fid, ALenum pname, ALfloat* values ); + + +/** + * Auxiliary Slot object functions + */ + +/* Create Auxiliary Slot objects. */ +typedef void (__cdecl *LPALGENAUXILIARYEFFECTSLOTS)( ALsizei n, ALuint* slots ); + +/* Delete Auxiliary Slot objects. */ +typedef void (__cdecl *LPALDELETEAUXILIARYEFFECTSLOTS)( ALsizei n, ALuint* slots ); + +/* Verify a handle is a valid Auxiliary Slot. */ +typedef ALboolean (__cdecl *LPALISAUXILIARYEFFECTSLOT)( ALuint slot ); + +/* Set an integer parameter for a Auxiliary Slot object. */ +typedef void (__cdecl *LPALAUXILIARYEFFECTSLOTI)( ALuint asid, ALenum param, ALint value ); +typedef void (__cdecl *LPALAUXILIARYEFFECTSLOTIV)( ALuint asid, ALenum param, ALint* values ); + +/* Set a floating point parameter for an Auxiliary Slot object. */ +typedef void (__cdecl *LPALAUXILIARYEFFECTSLOTF)( ALuint asid, ALenum param, ALfloat value ); +typedef void (__cdecl *LPALAUXILIARYEFFECTSLOTFV)( ALuint asid, ALenum param, ALfloat* values ); + +/* Get an integer parameter for a Auxiliary Slot object. */ +typedef void (__cdecl *LPALGETAUXILIARYEFFECTSLOTI)( ALuint asid, ALenum pname, ALint* value ); +typedef void (__cdecl *LPALGETAUXILIARYEFFECTSLOTIV)( ALuint asid, ALenum pname, ALint* values ); + +/* Get a floating point parameter for a Auxiliary Slot object. */ +typedef void (__cdecl *LPALGETAUXILIARYEFFECTSLOTF)( ALuint asid, ALenum pname, ALfloat* value ); +typedef void (__cdecl *LPALGETAUXILIARYEFFECTSLOTFV)( ALuint asid, ALenum pname, ALfloat* values ); + + + + +/********************************************************** + * Filter ranges and defaults. + */ + +/** + * Lowpass filter + */ + +#define LOWPASS_MIN_GAIN 0.0f +#define LOWPASS_MAX_GAIN 1.0f +#define LOWPASS_DEFAULT_GAIN 1.0f + +#define LOWPASS_MIN_GAINHF 0.0f +#define LOWPASS_MAX_GAINHF 1.0f +#define LOWPASS_DEFAULT_GAINHF 1.0f + +/** + * Highpass filter + */ + +#define HIGHPASS_MIN_GAIN 0.0f +#define HIGHPASS_MAX_GAIN 1.0f +#define HIGHPASS_DEFAULT_GAIN 1.0f + +#define HIGHPASS_MIN_GAINLF 0.0f +#define HIGHPASS_MAX_GAINLF 1.0f +#define HIGHPASS_DEFAULT_GAINLF 1.0f + +/** + * Bandpass filter + */ + +#define BANDPASS_MIN_GAIN 0.0f +#define BANDPASS_MAX_GAIN 1.0f +#define BANDPASS_DEFAULT_GAIN 1.0f + +#define BANDPASS_MIN_GAINHF 0.0f +#define BANDPASS_MAX_GAINHF 1.0f +#define BANDPASS_DEFAULT_GAINHF 1.0f + +#define BANDPASS_MIN_GAINLF 0.0f +#define BANDPASS_MAX_GAINLF 1.0f +#define BANDPASS_DEFAULT_GAINLF 1.0f + + + + + /********************************************************** + * Effect parameter structures, value definitions, ranges and defaults. + */ + +/** + * AL reverb effect parameter ranges and defaults + */ +#define AL_REVERB_MIN_DENSITY 0.0f +#define AL_REVERB_MAX_DENSITY 1.0f +#define AL_REVERB_DEFAULT_DENSITY 1.0f + +#define AL_REVERB_MIN_DIFFUSION 0.0f +#define AL_REVERB_MAX_DIFFUSION 1.0f +#define AL_REVERB_DEFAULT_DIFFUSION 1.0f + +#define AL_REVERB_MIN_GAIN 0.0f +#define AL_REVERB_MAX_GAIN 1.0f +#define AL_REVERB_DEFAULT_GAIN 0.32f + +#define AL_REVERB_MIN_GAINHF 0.0f +#define AL_REVERB_MAX_GAINHF 1.0f +#define AL_REVERB_DEFAULT_GAINHF 0.89f + +#define AL_REVERB_MIN_DECAY_TIME 0.1f +#define AL_REVERB_MAX_DECAY_TIME 20.0f +#define AL_REVERB_DEFAULT_DECAY_TIME 1.49f + +#define AL_REVERB_MIN_DECAY_HFRATIO 0.1f +#define AL_REVERB_MAX_DECAY_HFRATIO 2.0f +#define AL_REVERB_DEFAULT_DECAY_HFRATIO 0.83f + +#define AL_REVERB_MIN_REFLECTIONS_GAIN 0.0f +#define AL_REVERB_MAX_REFLECTIONS_GAIN 3.16f +#define AL_REVERB_DEFAULT_REFLECTIONS_GAIN 0.05f + +#define AL_REVERB_MIN_REFLECTIONS_DELAY 0.0f +#define AL_REVERB_MAX_REFLECTIONS_DELAY 0.3f +#define AL_REVERB_DEFAULT_REFLECTIONS_DELAY 0.007f + +#define AL_REVERB_MIN_LATE_REVERB_GAIN 0.0f +#define AL_REVERB_MAX_LATE_REVERB_GAIN 10.0f +#define AL_REVERB_DEFAULT_LATE_REVERB_GAIN 1.26f + +#define AL_REVERB_MIN_LATE_REVERB_DELAY 0.0f +#define AL_REVERB_MAX_LATE_REVERB_DELAY 0.1f +#define AL_REVERB_DEFAULT_LATE_REVERB_DELAY 0.011f + +#define AL_REVERB_MIN_AIR_ABSORPTION_GAINHF 0.892f +#define AL_REVERB_MAX_AIR_ABSORPTION_GAINHF 1.0f +#define AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF 0.994f + +#define AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR 0.0f +#define AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR 10.0f +#define AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR 0.0f + +#define AL_REVERB_MIN_DECAY_HFLIMIT AL_FALSE +#define AL_REVERB_MAX_DECAY_HFLIMIT AL_TRUE +#define AL_REVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE + +/** + * AL chorus effect parameter ranges and defaults + */ +#define AL_CHORUS_MIN_WAVEFORM 0 +#define AL_CHORUS_MAX_WAVEFORM 1 +#define AL_CHORUS_DEFAULT_WAVEFORM 1 + +#define AL_CHORUS_WAVEFORM_SINUSOID 0 +#define AL_CHORUS_WAVEFORM_TRIANGLE 1 + +#define AL_CHORUS_MIN_PHASE (-180) +#define AL_CHORUS_MAX_PHASE 180 +#define AL_CHORUS_DEFAULT_PHASE 90 + +#define AL_CHORUS_MIN_RATE 0.0f +#define AL_CHORUS_MAX_RATE 10.0f +#define AL_CHORUS_DEFAULT_RATE 1.1f + +#define AL_CHORUS_MIN_DEPTH 0.0f +#define AL_CHORUS_MAX_DEPTH 1.0f +#define AL_CHORUS_DEFAULT_DEPTH 0.1f + +#define AL_CHORUS_MIN_FEEDBACK (-1.0f) +#define AL_CHORUS_MAX_FEEDBACK 1.0f +#define AL_CHORUS_DEFAULT_FEEDBACK 0.25f + +#define AL_CHORUS_MIN_DELAY 0.0f +#define AL_CHORUS_MAX_DELAY 0.016f +#define AL_CHORUS_DEFAULT_DELAY 0.016f + +/** + * AL distortion effect parameter ranges and defaults + */ +#define AL_DISTORTION_MIN_EDGE 0.0f +#define AL_DISTORTION_MAX_EDGE 1.0f +#define AL_DISTORTION_DEFAULT_EDGE 0.2f + +#define AL_DISTORTION_MIN_GAIN 0.01f +#define AL_DISTORTION_MAX_GAIN 1.0f +#define AL_DISTORTION_DEFAULT_GAIN 0.05f + +#define AL_DISTORTION_MIN_LOWPASS_CUTOFF 80.0f +#define AL_DISTORTION_MAX_LOWPASS_CUTOFF 24000.0f +#define AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF 8000.0f + +#define AL_DISTORTION_MIN_EQCENTER 80.0f +#define AL_DISTORTION_MAX_EQCENTER 24000.0f +#define AL_DISTORTION_DEFAULT_EQCENTER 3600.0f + +#define AL_DISTORTION_MIN_EQBANDWIDTH 80.0f +#define AL_DISTORTION_MAX_EQBANDWIDTH 24000.0f +#define AL_DISTORTION_DEFAULT_EQBANDWIDTH 3600.0f + +/** + * AL echo effect parameter ranges and defaults + */ +#define AL_ECHO_MIN_DELAY 0.0f +#define AL_ECHO_MAX_DELAY 0.207f +#define AL_ECHO_DEFAULT_DELAY 0.1f + +#define AL_ECHO_MIN_LRDELAY 0.0f +#define AL_ECHO_MAX_LRDELAY 0.404f +#define AL_ECHO_DEFAULT_LRDELAY 0.1f + +#define AL_ECHO_MIN_DAMPING 0.0f +#define AL_ECHO_MAX_DAMPING 0.99f +#define AL_ECHO_DEFAULT_DAMPING 0.5f + +#define AL_ECHO_MIN_FEEDBACK 0.0f +#define AL_ECHO_MAX_FEEDBACK 1.0f +#define AL_ECHO_DEFAULT_FEEDBACK 0.5f + +#define AL_ECHO_MIN_SPREAD (-1.0f) +#define AL_ECHO_MAX_SPREAD 1.0f +#define AL_ECHO_DEFAULT_SPREAD (-1.0f) + +/** + * AL flanger effect parameter ranges and defaults + */ +#define AL_FLANGER_MIN_WAVEFORM 0 +#define AL_FLANGER_MAX_WAVEFORM 1 +#define AL_FLANGER_DEFAULT_WAVEFORM 1 + +#define AL_FLANGER_WAVEFORM_SINUSOID 0 +#define AL_FLANGER_WAVEFORM_TRIANGLE 1 + +#define AL_FLANGER_MIN_PHASE (-180) +#define AL_FLANGER_MAX_PHASE 180 +#define AL_FLANGER_DEFAULT_PHASE 0 + +#define AL_FLANGER_MIN_RATE 0.0f +#define AL_FLANGER_MAX_RATE 10.0f +#define AL_FLANGER_DEFAULT_RATE 0.27f + +#define AL_FLANGER_MIN_DEPTH 0.0f +#define AL_FLANGER_MAX_DEPTH 1.0f +#define AL_FLANGER_DEFAULT_DEPTH 1.0f + +#define AL_FLANGER_MIN_FEEDBACK (-1.0f) +#define AL_FLANGER_MAX_FEEDBACK 1.0f +#define AL_FLANGER_DEFAULT_FEEDBACK (-0.5f) + +#define AL_FLANGER_MIN_DELAY 0.0f +#define AL_FLANGER_MAX_DELAY 0.004f +#define AL_FLANGER_DEFAULT_DELAY 0.002f + +/** + * AL frequency shifter effect parameter ranges and defaults + */ +#define AL_FREQUENCY_SHIFTER_MIN_FREQUENCY 0.0f +#define AL_FREQUENCY_SHIFTER_MAX_FREQUENCY 24000.0f +#define AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY 0.0f + +#define AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION 0 +#define AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION 2 +#define AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION 0 + +#define AL_FREQUENCY_SHIFTER_MIN_RIGHT_DIRECTION 0 +#define AL_FREQUENCY_SHIFTER_MAX_RIGHT_DIRECTION 2 +#define AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION 0 + +#define AL_FREQUENCY_SHIFTER_DIRECTION_DOWN 0 +#define AL_FREQUENCY_SHIFTER_DIRECTION_UP 1 +#define AL_FREQUENCY_SHIFTER_DIRECTION_OFF 2 + +/** + * AL vocal morpher effect parameter ranges and defaults + */ +#define AL_VOCAL_MORPHER_MIN_PHONEMEA 0 +#define AL_VOCAL_MORPHER_MAX_PHONEMEA 29 +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA 0 + +#define AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING (-24) +#define AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING 24 +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING 0 + +#define AL_VOCAL_MORPHER_MIN_PHONEMEB 0 +#define AL_VOCAL_MORPHER_MAX_PHONEMEB 29 +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB 10 + +#define AL_VOCAL_MORPHER_PHONEME_A 0 +#define AL_VOCAL_MORPHER_PHONEME_E 1 +#define AL_VOCAL_MORPHER_PHONEME_I 2 +#define AL_VOCAL_MORPHER_PHONEME_O 3 +#define AL_VOCAL_MORPHER_PHONEME_U 4 +#define AL_VOCAL_MORPHER_PHONEME_AA 5 +#define AL_VOCAL_MORPHER_PHONEME_AE 6 +#define AL_VOCAL_MORPHER_PHONEME_AH 7 +#define AL_VOCAL_MORPHER_PHONEME_AO 8 +#define AL_VOCAL_MORPHER_PHONEME_EH 9 +#define AL_VOCAL_MORPHER_PHONEME_ER 10 +#define AL_VOCAL_MORPHER_PHONEME_IH 11 +#define AL_VOCAL_MORPHER_PHONEME_IY 12 +#define AL_VOCAL_MORPHER_PHONEME_UH 13 +#define AL_VOCAL_MORPHER_PHONEME_UW 14 +#define AL_VOCAL_MORPHER_PHONEME_B 15 +#define AL_VOCAL_MORPHER_PHONEME_D 16 +#define AL_VOCAL_MORPHER_PHONEME_F 17 +#define AL_VOCAL_MORPHER_PHONEME_G 18 +#define AL_VOCAL_MORPHER_PHONEME_J 19 +#define AL_VOCAL_MORPHER_PHONEME_K 20 +#define AL_VOCAL_MORPHER_PHONEME_L 21 +#define AL_VOCAL_MORPHER_PHONEME_M 22 +#define AL_VOCAL_MORPHER_PHONEME_N 23 +#define AL_VOCAL_MORPHER_PHONEME_P 24 +#define AL_VOCAL_MORPHER_PHONEME_R 25 +#define AL_VOCAL_MORPHER_PHONEME_S 26 +#define AL_VOCAL_MORPHER_PHONEME_T 27 +#define AL_VOCAL_MORPHER_PHONEME_V 28 +#define AL_VOCAL_MORPHER_PHONEME_Z 29 + +#define AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING (-24) +#define AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING 24 +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING 0 + +#define AL_VOCAL_MORPHER_MIN_WAVEFORM 0 +#define AL_VOCAL_MORPHER_MAX_WAVEFORM 2 +#define AL_VOCAL_MORPHER_DEFAULT_WAVEFORM 0 + +#define AL_VOCAL_MORPHER_WAVEFORM_SINUSOID 0 +#define AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE 1 +#define AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH 2 + +#define AL_VOCAL_MORPHER_MIN_RATE 0.0f +#define AL_VOCAL_MORPHER_MAX_RATE 10.0f +#define AL_VOCAL_MORPHER_DEFAULT_RATE 1.41f + +/** + * AL pitch shifter effect parameter ranges and defaults + */ +#define AL_PITCH_SHIFTER_MIN_COARSE_TUNE (-12) +#define AL_PITCH_SHIFTER_MAX_COARSE_TUNE 12 +#define AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE 12 + +#define AL_PITCH_SHIFTER_MIN_FINE_TUNE (-50) +#define AL_PITCH_SHIFTER_MAX_FINE_TUNE 50 +#define AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE 0 + +/** + * AL ring modulator effect parameter ranges and defaults + */ +#define AL_RING_MODULATOR_MIN_FREQUENCY 0.0f +#define AL_RING_MODULATOR_MAX_FREQUENCY 8000.0f +#define AL_RING_MODULATOR_DEFAULT_FREQUENCY 440.0f + +#define AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF 0.0f +#define AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF 24000.0f +#define AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF 800.0f + +#define AL_RING_MODULATOR_MIN_WAVEFORM 0 +#define AL_RING_MODULATOR_MAX_WAVEFORM 2 +#define AL_RING_MODULATOR_DEFAULT_WAVEFORM 0 + +#define AL_RING_MODULATOR_SINUSOID 0 +#define AL_RING_MODULATOR_SAWTOOTH 1 +#define AL_RING_MODULATOR_SQUARE 2 + +/** + * AL autowah effect parameter ranges and defaults + */ +#define AL_AUTOWAH_MIN_ATTACK_TIME 0.0001f +#define AL_AUTOWAH_MAX_ATTACK_TIME 1.0f +#define AL_AUTOWAH_DEFAULT_ATTACK_TIME 0.06f + +#define AL_AUTOWAH_MIN_RELEASE_TIME 0.0001f +#define AL_AUTOWAH_MAX_RELEASE_TIME 1.0f +#define AL_AUTOWAH_DEFAULT_RELEASE_TIME 0.06f + +#define AL_AUTOWAH_MIN_RESONANCE 2.0f +#define AL_AUTOWAH_MAX_RESONANCE 1000.0f +#define AL_AUTOWAH_DEFAULT_RESONANCE 1000.0f + +#define AL_AUTOWAH_MIN_PEAK_GAIN 0.00003f +#define AL_AUTOWAH_MAX_PEAK_GAIN 31621.0f +#define AL_AUTOWAH_DEFAULT_PEAK_GAIN 11.22f + +/** + * AL compressor effect parameter ranges and defaults + */ +#define AL_COMPRESSOR_MIN_ONOFF 0 +#define AL_COMPRESSOR_MAX_ONOFF 1 +#define AL_COMPRESSOR_DEFAULT_ONOFF 1 + +/** + * AL equalizer effect parameter ranges and defaults + */ +#define AL_EQUALIZER_MIN_LOW_GAIN 0.126f +#define AL_EQUALIZER_MAX_LOW_GAIN 7.943f +#define AL_EQUALIZER_DEFAULT_LOW_GAIN 1.0f + +#define AL_EQUALIZER_MIN_LOW_CUTOFF 50.0f +#define AL_EQUALIZER_MAX_LOW_CUTOFF 800.0f +#define AL_EQUALIZER_DEFAULT_LOW_CUTOFF 200.0f + +#define AL_EQUALIZER_MIN_MID1_GAIN 0.126f +#define AL_EQUALIZER_MAX_MID1_GAIN 7.943f +#define AL_EQUALIZER_DEFAULT_MID1_GAIN 1.0f + +#define AL_EQUALIZER_MIN_MID1_CENTER 200.0f +#define AL_EQUALIZER_MAX_MID1_CENTER 3000.0f +#define AL_EQUALIZER_DEFAULT_MID1_CENTER 500.0f + +#define AL_EQUALIZER_MIN_MID1_WIDTH 0.01f +#define AL_EQUALIZER_MAX_MID1_WIDTH 1.0f +#define AL_EQUALIZER_DEFAULT_MID1_WIDTH 1.0f + +#define AL_EQUALIZER_MIN_MID2_GAIN 0.126f +#define AL_EQUALIZER_MAX_MID2_GAIN 7.943f +#define AL_EQUALIZER_DEFAULT_MID2_GAIN 1.0f + +#define AL_EQUALIZER_MIN_MID2_CENTER 1000.0f +#define AL_EQUALIZER_MAX_MID2_CENTER 8000.0f +#define AL_EQUALIZER_DEFAULT_MID2_CENTER 3000.0f + +#define AL_EQUALIZER_MIN_MID2_WIDTH 0.01f +#define AL_EQUALIZER_MAX_MID2_WIDTH 1.0f +#define AL_EQUALIZER_DEFAULT_MID2_WIDTH 1.0f + +#define AL_EQUALIZER_MIN_HIGH_GAIN 0.126f +#define AL_EQUALIZER_MAX_HIGH_GAIN 7.943f +#define AL_EQUALIZER_DEFAULT_HIGH_GAIN 1.0f + +#define AL_EQUALIZER_MIN_HIGH_CUTOFF 4000.0f +#define AL_EQUALIZER_MAX_HIGH_CUTOFF 16000.0f +#define AL_EQUALIZER_DEFAULT_HIGH_CUTOFF 6000.0f + + + + +/********************************************************** + * Source parameter value definitions, ranges and defaults. + */ +#define AL_MIN_AIR_ABSORPTION_FACTOR 0.0f +#define AL_MAX_AIR_ABSORPTION_FACTOR 10.0f +#define AL_DEFAULT_AIR_ABSORPTION_FACTOR 0.0f + +#define AL_MIN_ROOM_ROLLOFF_FACTOR 0.0f +#define AL_MAX_ROOM_ROLLOFF_FACTOR 10.0f +#define AL_DEFAULT_ROOM_ROLLOFF_FACTOR 0.0f + +#define AL_MIN_CONE_OUTER_GAINHF 0.0f +#define AL_MAX_CONE_OUTER_GAINHF 1.0f +#define AL_DEFAULT_CONE_OUTER_GAINHF 1.0f + +#define AL_MIN_DIRECT_FILTER_GAINHF_AUTO AL_FALSE +#define AL_MAX_DIRECT_FILTER_GAINHF_AUTO AL_TRUE +#define AL_DEFAULT_DIRECT_FILTER_GAINHF_AUTO AL_TRUE + +#define AL_MIN_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_FALSE +#define AL_MAX_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE +#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE + +#define AL_MIN_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_FALSE +#define AL_MAX_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE +#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE + + + + +/********************************************************** + * Listener parameter value definitions, ranges and defaults. + */ +#define AL_MIN_METERS_PER_UNIT FLT_MIN +#define AL_MAX_METERS_PER_UNIT FLT_MAX +#define AL_DEFAULT_METERS_PER_UNIT 1.0f + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __efx_h_ */ diff --git a/OpenAL/include/xram.h b/OpenAL/include/xram.h new file mode 100644 index 0000000000..5d83662424 --- /dev/null +++ b/OpenAL/include/xram.h @@ -0,0 +1,94 @@ +#include + +// X-RAM Function pointer definitions +typedef ALboolean (__cdecl *EAXSetBufferMode)(ALsizei n, ALuint *buffers, ALint value); +typedef ALenum (__cdecl *EAXGetBufferMode)(ALuint buffer, ALint *value); + +////////////////////////////////////////////////////////////////////////////// +// Query for X-RAM extension +// +// if (alIsExtensionPresent("EAX-RAM") == AL_TRUE) +// X-RAM Extension found +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// X-RAM enum names +// +// "AL_EAX_RAM_SIZE" +// "AL_EAX_RAM_FREE" +// "AL_STORAGE_AUTOMATIC" +// "AL_STORAGE_HARDWARE" +// "AL_STORAGE_ACCESSIBLE" +// +// Query enum values using alGetEnumValue, for example +// +// long lRamSizeEnum = alGetEnumValue("AL_EAX_RAM_SIZE") +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// Query total amount of X-RAM +// +// long lTotalSize = alGetInteger(alGetEnumValue("AL_EAX_RAM_SIZE") +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// Query free X-RAM available +// +// long lFreeSize = alGetInteger(alGetEnumValue("AL_EAX_RAM_FREE") +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// Query X-RAM Function pointers +// +// Use typedefs defined above to get the X-RAM function pointers using +// alGetProcAddress +// +// EAXSetBufferMode eaxSetBufferMode; +// EAXGetBufferMode eaxGetBufferMode; +// +// eaxSetBufferMode = (EAXSetBufferMode)alGetProcAddress("EAXSetBufferMode"); +// eaxGetBufferMode = (EAXGetBufferMode)alGetProcAddress("EAXGetBufferMode"); +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// Force an Open AL Buffer into X-RAM (good for non-streaming buffers) +// +// ALuint uiBuffer; +// alGenBuffers(1, &uiBuffer); +// eaxSetBufferMode(1, &uiBuffer, alGetEnumValue("AL_STORAGE_HARDWARE")); +// alBufferData(...); +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// Force an Open AL Buffer into 'accessible' (currently host) RAM (good for streaming buffers) +// +// ALuint uiBuffer; +// alGenBuffers(1, &uiBuffer); +// eaxSetBufferMode(1, &uiBuffer, alGetEnumValue("AL_STORAGE_ACCESSIBLE")); +// alBufferData(...); +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// Put an Open AL Buffer into X-RAM if memory is available, otherwise use +// host RAM. This is the default mode. +// +// ALuint uiBuffer; +// alGenBuffers(1, &uiBuffer); +// eaxSetBufferMode(1, &uiBuffer, alGetEnumValue("AL_STORAGE_AUTOMATIC")); +// alBufferData(...); +// +////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/Utilities/SMutex.h b/Utilities/SMutex.h index b92d67e614..5aa9a98f07 100644 --- a/Utilities/SMutex.h +++ b/Utilities/SMutex.h @@ -145,15 +145,19 @@ public: { if (!tid) { - ConLog.Error("SMutexLockerBase: thread id == 0"); - Emu.Pause(); + if (!Emu.IsStopped()) + { + ConLog.Error("SMutexLockerBase: thread id == 0"); + Emu.Pause(); + } + return; } sm.lock(tid); } ~SMutexLockerBase() { - sm.unlock(tid); + if (tid) sm.unlock(tid); } }; diff --git a/Utilities/SQueue.h b/Utilities/SQueue.h index a7021365e1..8c0201d257 100644 --- a/Utilities/SQueue.h +++ b/Utilities/SQueue.h @@ -19,11 +19,6 @@ public: { while (true) { - if (Emu.IsStopped()) - { - return false; - } - if (m_mutex.GetOwner() == m_mutex.GetDeadValue()) { return false; @@ -31,6 +26,10 @@ public: if (m_count >= SQSize) { + if (Emu.IsStopped()) + { + return false; + } Sleep(1); continue; } @@ -51,11 +50,6 @@ public: { while (true) { - if (Emu.IsStopped()) - { - return false; - } - if (m_mutex.GetOwner() == m_mutex.GetDeadValue()) { return false; @@ -63,6 +57,10 @@ public: if (!m_count) { + if (Emu.IsStopped()) + { + return false; + } Sleep(1); continue; } @@ -96,4 +94,10 @@ public: SMutexLocker lock(m_mutex); m_count = 0; } + + T& Peek(u32 pos = 0) + { + SMutexLocker lock(m_mutex); + return m_data[(m_pos + pos) % SQSize]; + } }; diff --git a/rpcs3/Emu/Audio/AL/OpenALThread.cpp b/rpcs3/Emu/Audio/AL/OpenALThread.cpp new file mode 100644 index 0000000000..4517f527c0 --- /dev/null +++ b/rpcs3/Emu/Audio/AL/OpenALThread.cpp @@ -0,0 +1,144 @@ +#include "stdafx.h" +#include "OpenALThread.h" + +ALenum g_last_al_error = AL_NO_ERROR; +ALCenum g_last_alc_error = ALC_NO_ERROR; + +ALCdevice* pDevice; +ALCcontext* pContext; + +void printAlError(ALenum err, const char* situation) +{ + if(err != AL_NO_ERROR) + { + ConLog.Error("%s: OpenAL error 0x%04x", wxString(situation).wx_str(), err); + Emu.Pause(); + } +} + +void printAlcError(ALCenum err, const char* situation) +{ + if(err != ALC_NO_ERROR) + { + ConLog.Error("%s: OpenALC error 0x%04x", wxString(situation).wx_str(), err); + Emu.Pause(); + } +} + +void OpenALThread::Init() +{ + pDevice = alcOpenDevice(NULL); + checkForAlcError("alcOpenDevice"); + + pContext = alcCreateContext(pDevice, NULL); + checkForAlcError("alcCreateContext"); + + alcMakeContextCurrent(pContext); + checkForAlcError("alcMakeContextCurrent"); +} + +void OpenALThread::Quit() +{ + for (SampleBuffer::iterator i = mBuffers.begin(); i != mBuffers.end(); i++) + alDeleteBuffers(1, &i->second.mBufferID); + + alcMakeContextCurrent(NULL); + alcDestroyContext(pContext); + alcCloseDevice(pDevice); +} + +void OpenALThread::Play() +{ + alSourcePlay(mSource); + checkForAlError("alSourcePlay"); +} + +void OpenALThread::Close() +{ + alSourceStop(mSource); + checkForAlError("alSourceStop"); + if (alIsSource(mSource)) + alDeleteSources(1, &mSource); +} + +void OpenALThread::Stop() +{ + alSourceStop(mSource); + checkForAlError("alSourceStop"); +} + +void OpenALThread::Open(const void* src, ALsizei size) +{ + alGenSources(1, &mSource); // WARNING: Memory leaks! + checkForAlError("alGenSources"); + + alSourcei(mSource, AL_LOOPING, AL_FALSE); + checkForAlError("alSourcei"); + + mProcessed = 0; + mBuffer.mFreq = 48000; + mBuffer.mFormat = AL_FORMAT_STEREO16; + + for (int i = 0; i < NUM_OF_BUFFERS; i++) + { + AddData(src, size); + } +} + +void OpenALThread::AddData(const void* src, ALsizei size) +{ + alGenBuffers(1, &mBuffer.mBufferID); + checkForAlError("alGenBuffers"); + + mBuffers[mBuffer.mBufferID] = mBuffer; + + AddBlock(mBuffer.mBufferID, size, src); + + alSourceQueueBuffers(mSource, 1, &mBuffer.mBufferID); + checkForAlError("alSourceQueueBuffers"); + + alGetSourcei(mSource, AL_BUFFERS_PROCESSED, &mProcessed); + + while (mProcessed--) + { + alSourceUnqueueBuffers(mSource, 1, &mBuffer.mBufferID); + checkForAlError("alSourceUnqueueBuffers"); + + alDeleteBuffers(1, &mBuffer.mBufferID); + checkForAlError("alDeleteBuffers"); + } +} + +bool OpenALThread::AddBlock(ALuint bufferID, ALsizei size, const void* src) +{ + memset(&mTempBuffer, 0, sizeof(mTempBuffer)); + memcpy(mTempBuffer, src, size); + + long TotalRet = 0, ret; + + if (size < 1) return false; + + while (TotalRet < size) + { + ret = size; + + // if buffer is empty + if (ret == 0) break; + else if (ret < 0) + { + ConLog.Error("Error in bitstream!"); + } + else + { + TotalRet += ret; + } + } + if (TotalRet > 0) + { + alBufferData(bufferID, mBuffers[bufferID].mFormat, mTempBuffer, + TotalRet, mBuffers[bufferID].mFreq); + checkForAlError("alBufferData"); + } + + return (ret > 0); +} \ No newline at end of file diff --git a/rpcs3/Emu/Audio/AL/OpenALThread.h b/rpcs3/Emu/Audio/AL/OpenALThread.h new file mode 100644 index 0000000000..62a16c42f6 --- /dev/null +++ b/rpcs3/Emu/Audio/AL/OpenALThread.h @@ -0,0 +1,50 @@ +#pragma once + +#include "OpenAL/include/al.h" +#include "OpenAL/include/alc.h" +#include + +extern ALenum g_last_al_error; +extern ALCenum g_last_alc_error; + +void printAlError(ALenum err, const char* situation); +void printAlcError(ALCenum err, const char* situation); + +#define checkForAlError(sit) if((g_last_al_error = alGetError()) != AL_NO_ERROR) printAlError(g_last_al_error, sit) +#define checkForAlcError(sit) if((g_last_alc_error = alcGetError(pDevice)) != ALC_NO_ERROR) printAlcError(g_last_alc_error, sit) + +struct SampleInfo +{ + uint mBufferID; + uint mFreq; + uint mFormat; +}; + +typedef std::map SampleBuffer; + +#define NUM_OF_BUFFERS 16 + + +extern ALCdevice* pDevice; +extern ALCcontext* pContext; + +class OpenALThread +{ +private: + ALuint mSource; + SampleBuffer mBuffers; + SampleInfo mBuffer; + ALint mProcessed; + u16 mTempBuffer[512]; + +public: + void Init(); + void Quit(); + void Play(); + void Open(const void* src, ALsizei size); + void Close(); + void Stop(); + bool AddBlock(ALuint bufferID, ALsizei size, const void* src); + void AddData(const void* src, ALsizei size); +}; + diff --git a/rpcs3/Emu/Audio/AudioDumper.cpp b/rpcs3/Emu/Audio/AudioDumper.cpp new file mode 100644 index 0000000000..95b83272c0 --- /dev/null +++ b/rpcs3/Emu/Audio/AudioDumper.cpp @@ -0,0 +1,43 @@ +#include "stdafx.h" +#include "AudioDumper.h" + +AudioDumper::AudioDumper(u8 ch) : m_header(ch) +{ +} + +AudioDumper::~AudioDumper() +{ +} + +bool AudioDumper::Init() +{ + if(m_output.Open("audio.wav", wxFile::write)) + return true; + return false; +} + +void AudioDumper::WriteHeader() +{ + m_output.Write(&m_header, sizeof(m_header)); // write file header +} + +size_t AudioDumper::WriteData(const void* buffer, size_t size) +{ + size_t ret = m_output.Write(buffer, size); + + + return ret; +} + +void AudioDumper::UpdateHeader(size_t size) +{ + m_header.Size += size; + m_header.RIFF.Size += size; +} + +void AudioDumper::Finalize() +{ + m_output.Seek(0); + m_output.Write(&m_header, sizeof(m_header)); // write fixed file header + m_output.Close(); +} \ No newline at end of file diff --git a/rpcs3/Emu/Audio/AudioDumper.h b/rpcs3/Emu/Audio/AudioDumper.h new file mode 100644 index 0000000000..6d1d8568e1 --- /dev/null +++ b/rpcs3/Emu/Audio/AudioDumper.h @@ -0,0 +1,69 @@ +#pragma once + +struct WAVHeader +{ + struct RIFFHeader + { + u32 ID; // "RIFF" + u32 Size; // FileSize - 8 + u32 WAVE; // "WAVE" + + RIFFHeader(u32 size) + : ID(*(u32*)"RIFF") + , WAVE(*(u32*)"WAVE") + , Size(size) + { + } + } RIFF; + struct FMTHeader + { + u32 ID; // "fmt " + u32 Size; // 16 + u16 AudioFormat; // 1 for PCM, 3 for IEEE Floating Point + u16 NumChannels; // 1, 2, 6, 8 + u32 SampleRate; // 48000 + u32 ByteRate; // SampleRate * NumChannels * BitsPerSample/8 + u16 BlockAlign; // NumChannels * BitsPerSample/8 + u16 BitsPerSample; // sizeof(float) * 8 + + FMTHeader(u8 ch) + : ID(*(u32*)"fmt ") + , Size(16) + , AudioFormat(3) + , NumChannels(ch) + , SampleRate(48000) + , ByteRate(SampleRate * ch * sizeof(float)) + , BlockAlign(ch * sizeof(float)) + , BitsPerSample(sizeof(float) * 8) + { + } + } FMT; + u32 ID; // "data" + u32 Size; // size of data (256 * NumChannels * sizeof(float)) + + WAVHeader(u8 ch) + : ID(*(u32*)"data") + , Size(0) + , FMT(ch) + , RIFF(sizeof(RIFFHeader) + sizeof(FMTHeader)) + { + } +}; + + +class AudioDumper +{ +private: + WAVHeader m_header; + wxFile m_output; + +public: + AudioDumper(u8 ch); + ~AudioDumper(); + + bool Init(); + void WriteHeader(); + size_t WriteData(const void* buffer, size_t size); + void UpdateHeader(size_t size); + void Finalize(); +}; diff --git a/rpcs3/Emu/Audio/AudioManager.cpp b/rpcs3/Emu/Audio/AudioManager.cpp index 94d7bbda1e..eb0e094cc2 100644 --- a/rpcs3/Emu/Audio/AudioManager.cpp +++ b/rpcs3/Emu/Audio/AudioManager.cpp @@ -1,16 +1,33 @@ #include "stdafx.h" #include "AudioManager.h" +OpenALThread* m_audio_out; + AudioManager::AudioManager() { } void AudioManager::Init() { + if(m_audio_out) return; + + m_audio_info.Init(); + + switch(Ini.AudioOutMode.GetValue()) + { + default: + case 0: m_audio_out = nullptr; break; + case 1: m_audio_out = new OpenALThread(); break; + } } void AudioManager::Close() { + if(m_audio_out) + { + delete m_audio_out; + m_audio_out = nullptr; + } } u8 AudioManager::GetState() diff --git a/rpcs3/Emu/Audio/AudioManager.h b/rpcs3/Emu/Audio/AudioManager.h index 4fe6080864..dc448b7ced 100644 --- a/rpcs3/Emu/Audio/AudioManager.h +++ b/rpcs3/Emu/Audio/AudioManager.h @@ -1,5 +1,6 @@ #pragma once #include "sysutil_audio.h" +#include "AL/OpenALThread.h" struct AudioInfo { @@ -31,7 +32,6 @@ struct AudioInfo class AudioManager { AudioInfo m_audio_info; - public: AudioManager(); @@ -41,4 +41,7 @@ public: AudioInfo& GetInfo() { return m_audio_info; } u8 GetState(); -}; \ No newline at end of file +}; + +extern OpenALThread* m_audio_out; + diff --git a/rpcs3/Emu/Audio/cellAudio.h b/rpcs3/Emu/Audio/cellAudio.h index 73804b2dfd..e5ea8545fe 100644 --- a/rpcs3/Emu/Audio/cellAudio.h +++ b/rpcs3/Emu/Audio/cellAudio.h @@ -1,5 +1,60 @@ #pragma once +// Error codes +enum +{ + //libaudio Error Codes + CELL_AUDIO_ERROR_ALREADY_INIT = 0x80310701, + CELL_AUDIO_ERROR_AUDIOSYSTEM = 0x80310702, + CELL_AUDIO_ERROR_NOT_INIT = 0x80310703, + CELL_AUDIO_ERROR_PARAM = 0x80310704, + CELL_AUDIO_ERROR_PORT_FULL = 0x80310705, + CELL_AUDIO_ERROR_PORT_ALREADY_RUN = 0x80310706, + CELL_AUDIO_ERROR_PORT_NOT_OPEN = 0x80310707, + CELL_AUDIO_ERROR_PORT_NOT_RUN = 0x80310708, + CELL_AUDIO_ERROR_TRANS_EVENT = 0x80310709, + CELL_AUDIO_ERROR_PORT_OPEN = 0x8031070a, + CELL_AUDIO_ERROR_SHAREDMEMORY = 0x8031070b, + CELL_AUDIO_ERROR_MUTEX = 0x8031070c, + CELL_AUDIO_ERROR_EVENT_QUEUE = 0x8031070d, + CELL_AUDIO_ERROR_AUDIOSYSTEM_NOT_FOUND = 0x8031070e, + CELL_AUDIO_ERROR_TAG_NOT_FOUND = 0x8031070f, + + //libmixer Error Codes + CELL_LIBMIXER_ERROR_NOT_INITIALIZED = 0x80310002, + CELL_LIBMIXER_ERROR_INVALID_PARAMATER = 0x80310003, + CELL_LIBMIXER_ERROR_NO_MEMORY = 0x80310005, + CELL_LIBMIXER_ERROR_ALREADY_EXIST = 0x80310006, + CELL_LIBMIXER_ERROR_FULL = 0x80310007, + CELL_LIBMIXER_ERROR_NOT_EXIST = 0x80310008, + CELL_LIBMIXER_ERROR_TYPE_MISMATCH = 0x80310009, + CELL_LIBMIXER_ERROR_NOT_FOUND = 0x8031000a, + + //libsnd3 Error Codes + CELL_SND3_ERROR_PARAM = 0x80310301, + CELL_SND3_ERROR_CREATE_MUTEX = 0x80310302, + CELL_SND3_ERROR_SYNTH = 0x80310303, + CELL_SND3_ERROR_ALREADY = 0x80310304, + CELL_SND3_ERROR_NOTINIT = 0x80310305, + CELL_SND3_ERROR_SMFFULL = 0x80310306, + CELL_SND3_ERROR_HD3ID = 0x80310307, + CELL_SND3_ERROR_SMF = 0x80310308, + CELL_SND3_ERROR_SMFCTX = 0x80310309, + CELL_SND3_ERROR_FORMAT = 0x8031030a, + CELL_SND3_ERROR_SMFID = 0x8031030b, + CELL_SND3_ERROR_SOUNDDATAFULL = 0x8031030c, + CELL_SND3_ERROR_VOICENUM = 0x8031030d, + CELL_SND3_ERROR_RESERVEDVOICE = 0x8031030e, + CELL_SND3_ERROR_REQUESTQUEFULL = 0x8031030f, + CELL_SND3_ERROR_OUTPUTMODE = 0x80310310, + + //libsynt2 Error Codes + CELL_SOUND_SYNTH2_ERROR_FATAL = 0x80310201, + CELL_SOUND_SYNTH2_ERROR_INVALID_PARAMETER = 0x80310202, + CELL_SOUND_SYNTH2_ERROR_ALREADY_INITIALIZED = 0x80310203, +}; + +// constants enum { CELL_AUDIO_BLOCK_16 = 16, @@ -31,3 +86,111 @@ enum CELL_AUDIO_STATUS_READY = 1, CELL_AUDIO_STATUS_RUN = 2, }; + +//libaudio datatypes +struct CellAudioPortParam +{ + be_t nChannel; + be_t nBlock; + be_t attr; + be_t level; +}; + +struct CellAudioPortConfig +{ + be_t readIndexAddr; + be_t status; + be_t nChannel; + be_t nBlock; + be_t portSize; + be_t portAddr; +}; + +struct AudioPortConfig +{ + SMutexGeneral m_mutex; + bool m_is_audio_port_opened; + bool m_is_audio_port_started; + u8 channel; + u8 block; + float level; + u64 attr; + u64 tag; + u64 counter; // copy of global counter +}; + +struct AudioConfig //custom structure +{ + enum + { + AUDIO_PORT_COUNT = 8, + }; + AudioPortConfig m_ports[AUDIO_PORT_COUNT]; + u32 m_buffer; // 1 MB memory for audio ports + u32 m_indexes; // current block indexes and other info + bool m_is_audio_initialized; + bool m_is_audio_finalized; + u32 m_port_in_use; + u64 event_key; + u64 counter; + u64 start_time; + + AudioConfig() + : m_is_audio_initialized(false) + , m_is_audio_finalized(false) + , m_port_in_use(0) + , event_key(0) + , counter(0) + { + memset(&m_ports, 0, sizeof(AudioPortConfig) * AUDIO_PORT_COUNT); + } + + void Clear() + { + memset(&m_ports, 0, sizeof(AudioPortConfig) * AUDIO_PORT_COUNT); + m_port_in_use = 0; + } +} m_config; + +//libsnd3 datatypes +struct CellSnd3DataCtx +{ + s8 system; //[CELL_SND3_DATA_CTX_SIZE], unknown identifier +}; + +struct CellSnd3SmfCtx +{ + s8 system; //[CELL_SND3_SMF_CTX_SIZE], unknown identifier +}; + +struct CellSnd3KeyOnParam +{ + u8 vel; + u8 pan; + u8 panEx; + be_t addPitch; +}; + +struct CellSnd3VoiceBitCtx +{ + be_t core; //[CELL_SND3_MAX_CORE], unknown identifier +}; + +struct CellSnd3RequestQueueCtx +{ + void *frontQueue; + be_t frontQueueSize; + void *rearQueue; + be_t rearQueueSize; +}; + +//libsynt2 datatypes +struct CellSoundSynth2EffectAttr +{ + be_t core; + be_t mode; + be_t depth_L; + be_t depth_R; + be_t delay; + be_t feedback; +}; diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 2d98e28e4b..1ec31434b2 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -360,3 +360,44 @@ void CPUThread::Task() if (Ini.HLELogging.GetValue()) ConLog.Write("%s leave", CPUThread::GetFName().wx_str()); } + +s64 CPUThread::ExecAsCallback(u64 pc, bool wait, u64 a1, u64 a2, u64 a3, u64 a4) // not multithread-safe +{ + while (m_alive) + { + if (Emu.IsStopped()) + { + ConLog.Warning("ExecAsCallback() aborted"); + return CELL_ECANCELED; // doesn't mean anything + } + Sleep(1); + } + + Stop(); + Reset(); + + SetEntry(pc); + SetPrio(1001); + SetStackSize(0x10000); + SetExitStatus(CELL_OK); + + SetArg(0, a1); + SetArg(1, a2); + SetArg(2, a3); + SetArg(3, a4); + Run(); + + Exec(); + + while (wait && m_alive) + { + if (Emu.IsStopped()) + { + ConLog.Warning("ExecAsCallback() aborted"); + return CELL_EABORT; // doesn't mean anything + } + Sleep(1); + } + + return wait * m_exit_status; +} \ No newline at end of file diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index 88470283bc..3c2bbafd3e 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -57,7 +57,7 @@ protected: u64 m_stack_size; u64 m_stack_point; - u32 m_exit_status; + u64 m_exit_status; CPUDecoder* m_dec; @@ -80,10 +80,10 @@ public: void SetName(const std::string& name); void SetPrio(const u64 prio) { m_prio = prio; } void SetOffset(const u64 offset) { m_offset = offset; } - void SetExitStatus(const u32 status) { m_exit_status = status; } + void SetExitStatus(const u64 status) { m_exit_status = status; } u64 GetOffset() const { return m_offset; } - u32 GetExitStatus() const { return m_exit_status; } + u64 GetExitStatus() const { return m_exit_status; } u64 GetPrio() const { return m_prio; } std::string GetName() const { return NamedThreadBase::GetThreadName(); } @@ -234,6 +234,8 @@ public: return pc + 4; } + s64 ExecAsCallback(u64 pc, bool wait, u64 a1 = 0, u64 a2 = 0, u64 a3 = 0, u64 a4 = 0); + protected: virtual void DoReset()=0; virtual void DoRun()=0; diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index 2a0090c251..ea916d43b1 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -71,10 +71,16 @@ private: if(Ini.HLELogging.GetValue()) { - ConLog.Warning("SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC); + ConLog.Warning("SysCall[0x%llx] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC); if(CPU.GPR[11] > 1024) SysCalls::DoFunc(CPU.GPR[11]); } + /*else if ((s64)CPU.GPR[3] < 0) // probably, error code + { + ConLog.Error("SysCall[0x%llx] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC); + if(CPU.GPR[11] > 1024) + SysCalls::DoFunc(CPU.GPR[11]); + }*/ #ifdef HLE_CALL_DEBUG ConLog.Write("SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC); #endif @@ -2088,6 +2094,14 @@ private: { case 0x1: UNK(wxString::Format("HyperCall %d", CPU.GPR[0])); break; case 0x2: SysCall(); break; + case 0x3: + StaticExecute(CPU.GPR[11]); + if (Ini.HLELogging.GetValue()) + { + ConLog.Write("'%s' done with code[0x%llx]! #pc: 0x%llx", + wxString(g_static_funcs_list[CPU.GPR[11]].name).wx_str(), CPU.GPR[3], CPU.PC); + } + break; case 0x22: UNK("HyperCall LV1"); break; default: UNK(wxString::Format("Unknown sc: %x", sc_code)); } diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 91dce7d6a8..bd6c6570e5 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -17,6 +17,7 @@ PPUThread& GetCurrentPPUThread() PPUThread::PPUThread() : PPCThread(CPU_THREAD_PPU) { + owned_mutexes = 0; Reset(); } @@ -118,14 +119,11 @@ void PPUThread::InitRegs() GPR[6] = m_args[3]; } - u32 prx_mem = Memory.PRXMem.AllocAlign(0x10000); - Memory.Write64(prx_mem, 0xDEADBEEFABADCAFE); - GPR[0] = pc; GPR[8] = entry; GPR[11] = 0x80; GPR[12] = Emu.GetMallocPageSize(); - GPR[13] = prx_mem + 0x7060; + GPR[13] = Memory.PRXMem.GetStartAddr() + 0x7060; GPR[28] = GPR[4]; GPR[29] = GPR[3]; GPR[31] = GPR[5]; diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index b4a12efedf..fbb53bf1ae 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -525,6 +525,9 @@ static const s32 MAX_INT_VALUE = 0x7fffffff; class PPUThread : public PPCThread { +public: + std::atomic owned_mutexes; + public: PPCdouble FPR[32]; //Floating Point Register FPSCRhdr FPSCR; //Floating Point Status and Control Register diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index ea670cb846..a7468cb161 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -513,6 +513,8 @@ public: __forceinline AT GetAddr() const { return m_addr; } + __forceinline void SetAddr(AT addr) { m_addr = addr; } + __forceinline bool IsGood() const { return Memory.IsGoodAddr(m_addr, sizeof(T)); diff --git a/rpcs3/Emu/SysCalls/Callback.cpp b/rpcs3/Emu/SysCalls/Callback.cpp index f64851b6c3..73e7896744 100644 --- a/rpcs3/Emu/SysCalls/Callback.cpp +++ b/rpcs3/Emu/SysCalls/Callback.cpp @@ -53,7 +53,7 @@ void Callback::Branch(bool wait) { m_has_data = false; - static SMutexGeneral cb_mutex; + static std::mutex cb_mutex; CPUThread& thr = Emu.GetCallbackThread(); @@ -69,7 +69,7 @@ again: Sleep(1); } - SMutexGeneralLocker lock(cb_mutex); + std::lock_guard lock(cb_mutex); if (thr.IsAlive()) { diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index bdecfc62b8..370ad88004 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -8,6 +8,7 @@ uint g_max_module_id = 0; uint g_module_2_count = 0; ArrayF g_modules_funcs_list; std::mutex g_funcs_lock; +ArrayF g_static_funcs_list; struct ModuleInfo { @@ -62,7 +63,7 @@ static const g_module_list[] = {0x002e, "cellLv2dbg"}, {0x0030, "cellUsbpspcm"}, {0x0031, "cellAvconfExt"}, - {0x0032, "cellSysutilUserinfo"}, + {0x0032, "cellUserInfo"}, {0x0033, "cellSysutilSavedata"}, {0x0034, "cellSubdisplay"}, {0x0035, "cellSysutilRec"}, diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index faef27d9b7..165f59a49d 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -25,6 +25,21 @@ struct ModuleFunc } }; +struct SFuncOp +{ + u32 crc; + u32 mask; +}; + +struct SFunc +{ + func_caller* func; + char* name; + Array ops; +}; + +extern ArrayF g_static_funcs_list; + class Module { std::string m_name; @@ -94,6 +109,8 @@ public: } template __forceinline void AddFunc(u32 id, T func); + + template __forceinline void AddFuncSub(const u64 ops[], char* name, T func); }; template @@ -102,6 +119,29 @@ __forceinline void Module::AddFunc(u32 id, T func) m_funcs_list.Move(new ModuleFunc(id, bind_func(func))); } +template +__forceinline void Module::AddFuncSub(const u64 ops[], char* name, T func) +{ + if (!ops[0]) return; + + SFunc* sf = new SFunc; + sf->func = bind_func(func); + sf->name = name; + + // TODO: check for self-inclusions, use CRC + + for (u32 i = 0; ops[i]; i++) + { + SFuncOp op; + op.mask = ops[i] >> 32; + op.crc = ops[i] & op.mask; + op.mask = re(op.mask); + op.crc = re(op.crc); + sf->ops.AddCpy(op); + } + g_static_funcs_list.Add(sf); +} + bool IsLoadedFunc(u32 id); bool CallFunc(u32 num); bool UnloadFunc(u32 id); diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index 5829ac0e29..94a754d8e4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -1,64 +1,586 @@ #include "stdafx.h" #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" +#include "cellPamf.h" + +extern SMutexGeneral g_mutex_avcodec_open2; + +extern "C" +{ +#include "libavcodec/avcodec.h" +#include "libavformat/avformat.h" +} + #include "cellAdec.h" void cellAdec_init(); Module cellAdec(0x0006, cellAdec_init); +int adecRead(void* opaque, u8* buf, int buf_size) +{ + AudioDecoder& adec = *(AudioDecoder*)opaque; + + if (adec.reader.size < (u32)buf_size) + { + buf_size = adec.reader.size; + } + + if (!buf_size) + { + return 0; + } + else if (!Memory.CopyToReal(buf, adec.reader.addr, buf_size)) + { + ConLog.Error("adecRead: data reading failed (buf_size=0x%x)", buf_size); + Emu.Pause(); + return 0; + } + else + { + adec.reader.addr += buf_size; + adec.reader.size -= buf_size; + return 0 + buf_size; + } +} + +u32 adecOpen(AudioDecoder* data) +{ + AudioDecoder& adec = *data; + + adec.adecCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU); + + u32 adec_id = cellAdec.GetNewId(data); + + adec.id = adec_id; + + adec.adecCb->SetName("Audio Decoder[" + std::to_string(adec_id) + "] Callback"); + + thread t("Audio Decoder[" + std::to_string(adec_id) + "] Thread", [&]() + { + ConLog.Write("Audio Decoder enter()"); + + AdecTask task; + + while (true) + { + if (Emu.IsStopped()) + { + break; + } + + if (adec.job.IsEmpty() && adec.is_running) + { + Sleep(1); + continue; + } + + /*if (adec.frames.GetCount() >= 50) + { + Sleep(1); + continue; + }*/ + + if (!adec.job.Pop(task)) + { + break; + } + + switch (task.type) + { + case adecStartSeq: + { + // TODO: reset data + ConLog.Warning("adecStartSeq:"); + + adec.reader.addr = 0; + adec.reader.size = 0; + adec.is_running = true; + adec.just_started = true; + } + break; + + case adecEndSeq: + { + // TODO: finalize + ConLog.Warning("adecEndSeq:"); + + /*Callback cb; + cb.SetAddr(adec.cbFunc); + cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg); + cb.Branch(true); // ???*/ + adec.adecCb->ExecAsCallback(adec.cbFunc, true, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg); + + avcodec_close(adec.ctx); + avformat_close_input(&adec.fmt); + + adec.is_running = false; + } + break; + + case adecDecodeAu: + { + int err; + + adec.reader.addr = task.au.addr; + adec.reader.size = task.au.size; + + u64 last_pts = task.au.pts; + + struct AVPacketHolder : AVPacket + { + AVPacketHolder(u32 size) + { + av_init_packet(this); + + if (size) + { + data = (u8*)av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + this->size = size + FF_INPUT_BUFFER_PADDING_SIZE; + } + else + { + data = NULL; + size = 0; + } + } + + ~AVPacketHolder() + { + av_free(data); + //av_free_packet(this); + } + + } au(0); + + /*{ + wxFile dump; + dump.Open(wxString::Format("audio pts-0x%llx.dump", task.au.pts), wxFile::write); + u8* buf = (u8*)malloc(task.au.size); + if (Memory.CopyToReal(buf, task.au.addr, task.au.size)) dump.Write(buf, task.au.size); + free(buf); + dump.Close(); + } + + if (adec.just_started) // deferred initialization + { + err = avformat_open_input(&adec.fmt, NULL, NULL, NULL); + if (err) + { + ConLog.Error("adecDecodeAu: avformat_open_input() failed"); + Emu.Pause(); + break; + } + err = avformat_find_stream_info(adec.fmt, NULL); + if (err) + { + ConLog.Error("adecDecodeAu: avformat_find_stream_info() failed"); + Emu.Pause(); + break; + } + if (!adec.fmt->nb_streams) + { + ConLog.Error("adecDecodeAu: no stream found"); + Emu.Pause(); + break; + } + adec.ctx = adec.fmt->streams[0]->codec; // TODO: check data + + AVCodec* codec = avcodec_find_decoder(adec.ctx->codec_id); // ??? + if (!codec) + { + ConLog.Error("adecDecodeAu: avcodec_find_decoder() failed"); + Emu.Pause(); + break; + } + + AVDictionary* opts; + av_dict_set(&opts, "refcounted_frames", "1", 0); + { + SMutexGeneralLocker lock(g_mutex_avcodec_open2); + // not multithread-safe + err = avcodec_open2(adec.ctx, codec, &opts); + } + if (err) + { + ConLog.Error("adecDecodeAu: avcodec_open2() failed"); + Emu.Pause(); + break; + } + adec.just_started = false; + } + + while (av_read_frame(adec.fmt, &au) >= 0)*/ while (true) + { + if (!adec.ctx) // fake + { + AdecFrame frame; + frame.pts = task.au.pts; + frame.auAddr = task.au.addr; + frame.auSize = task.au.size; + frame.userdata = task.au.userdata; + frame.size = 4096; + frame.data = nullptr; + adec.frames.Push(frame); + + /*Callback cb; + cb.SetAddr(adec.cbFunc); + cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); + cb.Branch(false);*/ + adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); + + break; + } + + struct VdecFrameHolder : AdecFrame + { + VdecFrameHolder() + { + data = av_frame_alloc(); + } + + ~VdecFrameHolder() + { + if (data) + { + av_frame_unref(data); + av_frame_free(&data); + } + } + + } frame; + + if (!frame.data) + { + ConLog.Error("adecDecodeAu: av_frame_alloc() failed"); + Emu.Pause(); + break; + } + + int got_frame = 0; + + int decode = avcodec_decode_audio4(adec.ctx, frame.data, &got_frame, &au); + + if (decode < 0) + { + ConLog.Error("adecDecodeAu: AU decoding error(0x%x)", decode); + break; + } + + if (got_frame) + { + ConLog.Write("got_frame (%d, vdec: pts=0x%llx, dts=0x%llx)", got_frame, au.pts, au.dts); + + frame.pts = task.au.pts; // ??? + frame.auAddr = task.au.addr; + frame.auSize = task.au.size; + frame.userdata = task.au.userdata; + frame.size = 32768; // ???? + adec.frames.Push(frame); + frame.data = nullptr; // to prevent destruction + + /*Callback cb; + cb.SetAddr(adec.cbFunc); + cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); + cb.Branch(false);*/ + adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); + } + } + + /*Callback cb; + cb.SetAddr(adec.cbFunc); + cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg); + cb.Branch(false);*/ + adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg); + } + break; + + case adecClose: + { + adec.is_finished = true; + ConLog.Write("Audio Decoder exit"); + return; + } + + default: + ConLog.Error("Audio Decoder error: unknown task(%d)", task.type); + } + } + adec.is_finished = true; + ConLog.Warning("Audio Decoder aborted"); + }); + + t.detach(); + + return adec_id; +} + +bool adecCheckType(AudioCodecType type) +{ + switch (type) + { + case CELL_ADEC_TYPE_ATRACX: ConLog.Write("*** (???) type: ATRAC3plus"); break; + case CELL_ADEC_TYPE_ATRACX_2CH: ConLog.Write("*** type: ATRAC3plus 2ch"); break; + + case CELL_ADEC_TYPE_ATRACX_6CH: + case CELL_ADEC_TYPE_ATRACX_8CH: + case CELL_ADEC_TYPE_LPCM_PAMF: + case CELL_ADEC_TYPE_AC3: + case CELL_ADEC_TYPE_MP3: + case CELL_ADEC_TYPE_ATRAC3: + case CELL_ADEC_TYPE_MPEG_L2: + case CELL_ADEC_TYPE_CELP: + case CELL_ADEC_TYPE_M4AAC: + case CELL_ADEC_TYPE_CELP8: + cellAdec.Error("Unimplemented audio codec type (%d)", type); + break; + default: + return false; + } + + return true; +} + int cellAdecQueryAttr(mem_ptr_t type, mem_ptr_t attr) { - cellAdec.Error("cellAdecQueryAttr(type_addr=0x%x, attr_addr=0x%x)", type.GetAddr(), attr.GetAddr()); + cellAdec.Warning("cellAdecQueryAttr(type_addr=0x%x, attr_addr=0x%x)", type.GetAddr(), attr.GetAddr()); + + if (!type.IsGood() || !attr.IsGood()) + { + return CELL_ADEC_ERROR_FATAL; + } + + if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG; + + // TODO: check values + attr->adecVerLower = 0x280000; // from dmux + attr->adecVerUpper = 0x260000; + attr->workMemSize = 4 * 1024 * 1024; + return CELL_OK; } int cellAdecOpen(mem_ptr_t type, mem_ptr_t res, mem_ptr_t cb, mem32_t handle) { - cellAdec.Error("cellAdecOpen(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", + cellAdec.Warning("cellAdecOpen(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", type.GetAddr(), res.GetAddr(), cb.GetAddr(), handle.GetAddr()); + + if (!type.IsGood() || !res.IsGood() || !cb.IsGood() || !handle.IsGood()) + { + return CELL_ADEC_ERROR_FATAL; + } + + if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG; + + handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg)); + return CELL_OK; } int cellAdecOpenEx(mem_ptr_t type, mem_ptr_t res, mem_ptr_t cb, mem32_t handle) { - cellAdec.Error("cellAdecOpenEx(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", + cellAdec.Warning("cellAdecOpenEx(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", type.GetAddr(), res.GetAddr(), cb.GetAddr(), handle.GetAddr()); + + if (!type.IsGood() || !res.IsGood() || !cb.IsGood() || !handle.IsGood()) + { + return CELL_ADEC_ERROR_FATAL; + } + + if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG; + + handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg)); + return CELL_OK; } int cellAdecClose(u32 handle) { - cellAdec.Error("cellAdecClose(handle=0x%x)", handle); + cellAdec.Warning("cellAdecClose(handle=%d)", handle); + + AudioDecoder* adec; + if (!Emu.GetIdManager().GetIDData(handle, adec)) + { + return CELL_ADEC_ERROR_ARG; + } + + adec->job.Push(AdecTask(adecClose)); + + while (!adec->is_finished || !adec->frames.IsEmpty()) + { + if (Emu.IsStopped()) + { + ConLog.Warning("cellAdecClose(%d) aborted", handle); + break; + } + Sleep(1); + } + + if (adec->adecCb) Emu.GetCPU().RemoveThread(adec->adecCb->GetId()); + Emu.GetIdManager().RemoveID(handle); return CELL_OK; } int cellAdecStartSeq(u32 handle, u32 param_addr) { - cellAdec.Error("cellAdecStartSeq(handle=0x%x, param_addr=0x%x)", handle, param_addr); + cellAdec.Log("cellAdecStartSeq(handle=%d, param_addr=0x%x)", handle, param_addr); + + AudioDecoder* adec; + if (!Emu.GetIdManager().GetIDData(handle, adec)) + { + return CELL_ADEC_ERROR_ARG; + } + + AdecTask task(adecStartSeq); + /*if (adec->type == CELL_ADEC_TYPE_ATRACX_2CH) + { + + } + else*/ + { + cellAdec.Warning("cellAdecStartSeq: (TODO) initialization"); + } + + adec->job.Push(task); return CELL_OK; } int cellAdecEndSeq(u32 handle) { - cellAdec.Error("cellAdecEndSeq(handle=0x%x)", handle); + cellAdec.Warning("cellAdecEndSeq(handle=%d)", handle); + + AudioDecoder* adec; + if (!Emu.GetIdManager().GetIDData(handle, adec)) + { + return CELL_ADEC_ERROR_ARG; + } + + adec->job.Push(AdecTask(adecEndSeq)); return CELL_OK; } int cellAdecDecodeAu(u32 handle, mem_ptr_t auInfo) { - cellAdec.Error("cellAdecDecodeAu(handle=0x%x, auInfo_addr=0x%x)", handle, auInfo.GetAddr()); + cellAdec.Log("cellAdecDecodeAu(handle=%d, auInfo_addr=0x%x)", handle, auInfo.GetAddr()); + + AudioDecoder* adec; + if (!Emu.GetIdManager().GetIDData(handle, adec)) + { + return CELL_ADEC_ERROR_ARG; + } + + if (!auInfo.IsGood()) + { + return CELL_ADEC_ERROR_FATAL; + } + + AdecTask task(adecDecodeAu); + task.au.auInfo_addr = auInfo.GetAddr(); + task.au.addr = auInfo->startAddr; + task.au.size = auInfo->size; + task.au.pts = ((u64)auInfo->pts.upper << 32) | (u64)auInfo->pts.lower; + task.au.userdata = auInfo->userData; + + adec->job.Push(task); return CELL_OK; } int cellAdecGetPcm(u32 handle, u32 outBuffer_addr) { - cellAdec.Error("cellAdecGetPcm(handle=0x%x, outBuffer_addr=0x%x)", handle, outBuffer_addr); - return CELL_OK; + cellAdec.Log("cellAdecGetPcm(handle=%d, outBuffer_addr=0x%x)", handle, outBuffer_addr); + + AudioDecoder* adec; + if (!Emu.GetIdManager().GetIDData(handle, adec)) + { + return CELL_ADEC_ERROR_ARG; + } + + if (adec->frames.IsEmpty()) + { + return CELL_ADEC_ERROR_EMPTY; + } + + AdecFrame af; + adec->frames.Pop(af); + //AVFrame& frame = *af.data; + + int result = CELL_OK; + + if (!Memory.IsGoodAddr(outBuffer_addr, af.size)) + { + result = CELL_ADEC_ERROR_FATAL; + } + else + { + // copy data + if (!af.data) // fake: empty data + { + u8* buf = (u8*)malloc(4096); + memset(buf, 0, 4096); + Memory.CopyFromReal(outBuffer_addr, buf, 4096); + free(buf); + return CELL_OK; + } + } + + if (af.data) + { + av_frame_unref(af.data); + av_frame_free(&af.data); + } + return result; } -int cellAdecGetPcmItem(u32 handle, u32 pcmItem_ptr_addr) +int cellAdecGetPcmItem(u32 handle, mem32_t pcmItem_ptr) { - cellAdec.Error("cellAdecGetPcmItem(handle=0x%x, pcmItem_ptr_addr=0x%x)", handle, pcmItem_ptr_addr); + cellAdec.Log("cellAdecGetPcmItem(handle=%d, pcmItem_ptr_addr=0x%x)", handle, pcmItem_ptr.GetAddr()); + + AudioDecoder* adec; + if (!Emu.GetIdManager().GetIDData(handle, adec)) + { + return CELL_ADEC_ERROR_ARG; + } + + if (!pcmItem_ptr.IsGood()) + { + return CELL_ADEC_ERROR_FATAL; + } + + AdecFrame& af = adec->frames.Peek(); + + if (adec->frames.IsEmpty()) + { + return CELL_ADEC_ERROR_EMPTY; + } + + //AVFrame& frame = *af.data; + + mem_ptr_t pcm(adec->memAddr + adec->memBias); + + adec->memBias += 512; + if (adec->memBias + 512 > adec->memSize) + { + adec->memBias = 0; + } + + pcm->pcmHandle = 0; // ??? + pcm->pcmAttr.bsiInfo_addr = pcm.GetAddr() + sizeof(CellAdecPcmItem); + pcm->startAddr = 0x00000312; // invalid address (no output) + pcm->size = af.size; + pcm->status = CELL_OK; + pcm->auInfo.pts.lower = af.pts; // ??? + pcm->auInfo.pts.upper = af.pts >> 32; + pcm->auInfo.size = af.auSize; + pcm->auInfo.startAddr = af.auAddr; + pcm->auInfo.userData = af.userdata; + + mem_ptr_t atx(pcm.GetAddr() + sizeof(CellAdecPcmItem)); + atx->samplingFreq = 48000; // ??? + atx->nbytes = 2048; // ??? + atx->channelConfigIndex = CELL_ADEC_CH_STEREO; // ??? + + pcmItem_ptr = pcm.GetAddr(); + return CELL_OK; } @@ -73,4 +595,7 @@ void cellAdec_init() cellAdec.AddFunc(0x1529e506, cellAdecDecodeAu); cellAdec.AddFunc(0x97ff2af1, cellAdecGetPcm); cellAdec.AddFunc(0xbd75f78b, cellAdecGetPcmItem); + + av_register_all(); + avcodec_register_all(); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.h b/rpcs3/Emu/SysCalls/Modules/cellAdec.h index d2e034b9bb..bab8ccd6c9 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.h @@ -1,5 +1,6 @@ #pragma once -#include "cellPamf.h" + +#include "Utilities/SQueue.h" // Error Codes enum @@ -341,6 +342,17 @@ struct CellAdecResource be_t ppuThreadStackSize; }; +struct CellAdecResourceEx +{ + be_t totalMemSize; + be_t startAddr; + be_t ppuThreadPriority; + be_t ppuThreadStackSize; + be_t spurs_addr; + u8 priority[8]; + be_t maxContention; +}; + // Callback Messages enum CellAdecMsgType { @@ -348,12 +360,14 @@ enum CellAdecMsgType CELL_ADEC_MSG_TYPE_PCMOUT, CELL_ADEC_MSG_TYPE_ERROR, CELL_ADEC_MSG_TYPE_SEQDONE, -}; +}; + +typedef mem_func_ptr_t CellAdecCbMsg; struct CellAdecCb { - be_t> cbFunc; - be_t cbArg_addr; + be_t cbFunc; + be_t cbArg; }; typedef CellCodecTimeStamp CellAdecTimeStamp; @@ -399,17 +413,6 @@ struct CellAdecLpcmInfo be_t outputDataSize; }; -struct CellAdecResourceEx -{ - be_t totalMemSize; - be_t startAddr; - be_t ppuThreadPriority; - be_t ppuThreadStackSize; - be_t spurs_addr; - u8 priority[8]; - be_t maxContention; -}; - // CELP Excitation Mode enum CELP_ExcitationMode { @@ -985,3 +988,143 @@ struct CellAdecMpmcInfo be_t lfePresent; be_t channelCoufiguration; }; + +/* Audio Decoder Thread Classes */ + +enum AdecJobType : u32 +{ + adecStartSeq, + adecEndSeq, + adecDecodeAu, + adecClose, +}; + +struct AdecTask +{ + AdecJobType type; + union + { + struct + { + u32 auInfo_addr; + u32 addr; + u32 size; + u64 pts; + u64 userdata; + } au; + }; + + AdecTask(AdecJobType type) + : type(type) + { + } + + AdecTask() + { + } +}; + +struct AdecFrame +{ + AVFrame* data; + u64 pts; + u64 userdata; + u32 auAddr; + u32 auSize; + u32 size; +}; + +int adecRead(void* opaque, u8* buf, int buf_size); + +class AudioDecoder +{ +public: + SQueue job; + u32 id; + volatile bool is_running; + volatile bool is_finished; + bool just_started; + + AVCodecContext* ctx; + AVFormatContext* fmt; + u8* io_buf; + + struct AudioReader + { + u32 addr; + u32 size; + } reader; + + SQueue frames; + + const AudioCodecType type; + const u32 memAddr; + const u32 memSize; + const u32 cbFunc; + const u32 cbArg; + u32 memBias; + + CPUThread* adecCb; + + AudioDecoder(AudioCodecType type, u32 addr, u32 size, u32 func, u32 arg) + : type(type) + , memAddr(addr) + , memSize(size) + , memBias(0) + , cbFunc(func) + , cbArg(arg) + , adecCb(nullptr) + , is_running(false) + , is_finished(false) + , just_started(false) + , ctx(nullptr) + , fmt(nullptr) + { + AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P); + if (!codec) + { + ConLog.Error("AudioDecoder(): avcodec_find_decoder(ATRAC3P) failed"); + Emu.Pause(); + return; + } + fmt = avformat_alloc_context(); + if (!fmt) + { + ConLog.Error("AudioDecoder(): avformat_alloc_context failed"); + Emu.Pause(); + return; + } + io_buf = (u8*)av_malloc(4096); + fmt->pb = avio_alloc_context(io_buf, 4096, 0, this, adecRead, NULL, NULL); + if (!fmt->pb) + { + ConLog.Error("AudioDecoder(): avio_alloc_context failed"); + Emu.Pause(); + return; + } + } + + ~AudioDecoder() + { + if (ctx) + { + for (u32 i = frames.GetCount() - 1; ~i; i--) + { + AdecFrame& af = frames.Peek(i); + av_frame_unref(af.data); + av_frame_free(&af.data); + } + avcodec_close(ctx); + avformat_close_input(&fmt); + } + if (fmt) + { + if (io_buf) + { + av_free(io_buf); + } + if (fmt->pb) av_free(fmt->pb); + avformat_free_context(fmt); + } + } +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 8c5915d6ff..486b1720a4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -2,289 +2,24 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" #include "Emu/Audio/cellAudio.h" +#include "Emu/Audio/AudioManager.h" +#include "Emu/Audio/AudioDumper.h" void cellAudio_init(); -void cellAudio_load(); void cellAudio_unload(); -Module cellAudio(0x0011, cellAudio_init, cellAudio_load, cellAudio_unload); +Module cellAudio(0x0011, cellAudio_init, nullptr, cellAudio_unload); extern u64 get_system_time(); -enum -{ - //libaudio Error Codes - CELL_AUDIO_ERROR_ALREADY_INIT = 0x80310701, - CELL_AUDIO_ERROR_AUDIOSYSTEM = 0x80310702, - CELL_AUDIO_ERROR_NOT_INIT = 0x80310703, - CELL_AUDIO_ERROR_PARAM = 0x80310704, - CELL_AUDIO_ERROR_PORT_FULL = 0x80310705, - CELL_AUDIO_ERROR_PORT_ALREADY_RUN = 0x80310706, - CELL_AUDIO_ERROR_PORT_NOT_OPEN = 0x80310707, - CELL_AUDIO_ERROR_PORT_NOT_RUN = 0x80310708, - CELL_AUDIO_ERROR_TRANS_EVENT = 0x80310709, - CELL_AUDIO_ERROR_PORT_OPEN = 0x8031070a, - CELL_AUDIO_ERROR_SHAREDMEMORY = 0x8031070b, - CELL_AUDIO_ERROR_MUTEX = 0x8031070c, - CELL_AUDIO_ERROR_EVENT_QUEUE = 0x8031070d, - CELL_AUDIO_ERROR_AUDIOSYSTEM_NOT_FOUND = 0x8031070e, - CELL_AUDIO_ERROR_TAG_NOT_FOUND = 0x8031070f, - - //libmixer Error Codes - CELL_LIBMIXER_ERROR_NOT_INITIALIZED = 0x80310002, - CELL_LIBMIXER_ERROR_INVALID_PARAMATER = 0x80310003, - CELL_LIBMIXER_ERROR_NO_MEMORY = 0x80310005, - CELL_LIBMIXER_ERROR_ALREADY_EXIST = 0x80310006, - CELL_LIBMIXER_ERROR_FULL = 0x80310007, - CELL_LIBMIXER_ERROR_NOT_EXIST = 0x80310008, - CELL_LIBMIXER_ERROR_TYPE_MISMATCH = 0x80310009, - CELL_LIBMIXER_ERROR_NOT_FOUND = 0x8031000a, - - //libsnd3 Error Codes - CELL_SND3_ERROR_PARAM = 0x80310301, - CELL_SND3_ERROR_CREATE_MUTEX = 0x80310302, - CELL_SND3_ERROR_SYNTH = 0x80310303, - CELL_SND3_ERROR_ALREADY = 0x80310304, - CELL_SND3_ERROR_NOTINIT = 0x80310305, - CELL_SND3_ERROR_SMFFULL = 0x80310306, - CELL_SND3_ERROR_HD3ID = 0x80310307, - CELL_SND3_ERROR_SMF = 0x80310308, - CELL_SND3_ERROR_SMFCTX = 0x80310309, - CELL_SND3_ERROR_FORMAT = 0x8031030a, - CELL_SND3_ERROR_SMFID = 0x8031030b, - CELL_SND3_ERROR_SOUNDDATAFULL = 0x8031030c, - CELL_SND3_ERROR_VOICENUM = 0x8031030d, - CELL_SND3_ERROR_RESERVEDVOICE = 0x8031030e, - CELL_SND3_ERROR_REQUESTQUEFULL = 0x8031030f, - CELL_SND3_ERROR_OUTPUTMODE = 0x80310310, - - //libsynt2 Error Codes - CELL_SOUND_SYNTH2_ERROR_FATAL = 0x80310201, - CELL_SOUND_SYNTH2_ERROR_INVALID_PARAMETER = 0x80310202, - CELL_SOUND_SYNTH2_ERROR_ALREADY_INITIALIZED = 0x80310203, -}; - -struct WAVHeader -{ - struct RIFFHeader - { - u32 ID; // "RIFF" - u32 Size; // FileSize - 8 - u32 WAVE; // "WAVE" - - RIFFHeader(u32 size) - : ID(*(u32*)"RIFF") - , WAVE(*(u32*)"WAVE") - , Size(size) - { - } - } RIFF; - struct FMTHeader - { - u32 ID; // "fmt " - u32 Size; // 16 - u16 AudioFormat; // 1 for PCM, 3 for IEEE Floating Point - u16 NumChannels; // 1, 2, 6, 8 - u32 SampleRate; // 48000 - u32 ByteRate; // SampleRate * NumChannels * BitsPerSample/8 - u16 BlockAlign; // NumChannels * BitsPerSample/8 - u16 BitsPerSample; // sizeof(float) * 8 - - FMTHeader(u8 ch) - : ID(*(u32*)"fmt ") - , Size(16) - , AudioFormat(3) - , NumChannels(ch) - , SampleRate(48000) - , ByteRate(SampleRate * ch * sizeof(float)) - , BlockAlign(ch * sizeof(float)) - , BitsPerSample(sizeof(float) * 8) - { - } - } FMT; - u32 ID; // "data" - u32 Size; // size of data (256 * NumChannels * sizeof(float)) - - WAVHeader(u8 ch) - : ID(*(u32*)"data") - , Size(0) - , FMT(ch) - , RIFF(sizeof(RIFFHeader) + sizeof(FMTHeader)) - { - } -}; - - -//libaudio datatypes -struct CellAudioPortParam -{ - be_t nChannel; - be_t nBlock; - be_t attr; - be_t level; -}; - -struct CellAudioPortConfig -{ - be_t readIndexAddr; - be_t status; - be_t nChannel; - be_t nBlock; - be_t portSize; - be_t portAddr; -}; - -struct AudioPortConfig -{ - SMutex m_mutex; - bool m_is_audio_port_opened; - bool m_is_audio_port_started; - u8 channel; - u8 block; - float level; - u64 attr; - u64 tag; - u64 counter; // copy of global counter -}; - -struct AudioConfig //custom structure -{ - enum - { - AUDIO_PORT_COUNT = 8, - }; - AudioPortConfig m_ports[AUDIO_PORT_COUNT]; - u32 m_buffer; // 1 MB memory for audio ports - u32 m_indexes; // current block indexes and other info - bool m_is_audio_initialized; - bool m_is_audio_finalized; - u32 m_port_in_use; - u64 event_key; - u64 counter; - u64 start_time; - - AudioConfig() - : m_is_audio_initialized(false) - , m_is_audio_finalized(false) - , m_port_in_use(0) - , event_key(0) - , counter(0) - { - memset(&m_ports, 0, sizeof(AudioPortConfig) * AUDIO_PORT_COUNT); - } - - void Clear() - { - memset(&m_ports, 0, sizeof(AudioPortConfig) * AUDIO_PORT_COUNT); - m_port_in_use = 0; - } -} m_config; - -//libmixer datatypes -typedef void * CellAANHandle; - -struct CellSSPlayerConfig -{ - be_t channels; - be_t outputMode; -}; - -struct CellSSPlayerWaveParam -{ - void *addr; - be_t format; - be_t samples; - be_t loopStartOffset; - be_t startOffset; -}; - -struct CellSSPlayerCommonParam -{ - be_t loopMode; - be_t attackMode; -}; - -struct CellSurMixerPosition -{ - be_t x; - be_t y; - be_t z; -}; - -struct CellSSPlayerRuntimeInfo -{ - be_t level; - be_t speed; - CellSurMixerPosition position; -}; - -struct CellSurMixerConfig -{ - be_t priority; - be_t chStrips1; - be_t chStrips2; - be_t chStrips6; - be_t chStrips8; -}; - -struct CellSurMixerChStripParam -{ - be_t param; - void *attribute; - be_t dBSwitch; - be_t floatVal; - be_t intVal; -}; - -CellSSPlayerWaveParam current_SSPlayerWaveParam; - -//libsnd3 datatypes -struct CellSnd3DataCtx -{ - s8 system; //[CELL_SND3_DATA_CTX_SIZE], unknown identifier -}; - -struct CellSnd3SmfCtx -{ - s8 system; //[CELL_SND3_SMF_CTX_SIZE], unknown identifier -}; - -struct CellSnd3KeyOnParam -{ - u8 vel; - u8 pan; - u8 panEx; - be_t addPitch; -}; - -struct CellSnd3VoiceBitCtx -{ - be_t core; //[CELL_SND3_MAX_CORE], unknown identifier -}; - -struct CellSnd3RequestQueueCtx -{ - void *frontQueue; - be_t frontQueueSize; - void *rearQueue; - be_t rearQueueSize; -}; - -//libsynt2 datatypes -struct CellSoundSynth2EffectAttr -{ - be_t core; - be_t mode; - be_t depth_L; - be_t depth_R; - be_t delay; - be_t feedback; -}; - // libaudio Functions int cellAudioInit() { cellAudio.Warning("cellAudioInit()"); + + if(Ini.AudioOutMode.GetValue() == 1) + m_audio_out->Init(); + if (m_config.m_is_audio_initialized) { return CELL_AUDIO_ERROR_ALREADY_INIT; @@ -301,14 +36,11 @@ int cellAudioInit() thread t("Audio Thread", []() { - WAVHeader header(2); // WAV file header (stereo) - - static const wxString& output_name = "audio.wav"; - - wxFile output; // create output file - if (Ini.AudioDumpToFile.GetValue() && !output.Open(output_name, wxFile::write)) + AudioDumper m_dump(2); // WAV file header (stereo) + + if (Ini.AudioDumpToFile.GetValue() && !m_dump.Init()) { - ConLog.Error("Audio aborted: cannot create %s", output_name.wx_str()); + ConLog.Error("Audio aborted: cannot create file!"); return; } @@ -317,12 +49,18 @@ int cellAudioInit() m_config.start_time = get_system_time(); if (Ini.AudioDumpToFile.GetValue()) - output.Write(&header, sizeof(header)); // write file header + m_dump.WriteHeader(); float buffer[2*256]; // buffer for 2 channels be_t buffer2[8*256]; // buffer for 8 channels (max count) + u16 oal_buffer[2*256]; // buffer for OpenAL + memset(&buffer, 0, sizeof(buffer)); memset(&buffer2, 0, sizeof(buffer2)); + memset(&oal_buffer, 0, sizeof(oal_buffer)); + + if(Ini.AudioOutMode.GetValue() == 1) + m_audio_out->Open(oal_buffer, sizeof(oal_buffer)); while (m_config.m_is_audio_initialized) { @@ -368,7 +106,7 @@ int cellAudioInit() memset(Memory + buf_addr, 0, block_size * sizeof(float)); { - SMutexLocker lock(port.m_mutex); + SMutexGeneralLocker lock(port.m_mutex); port.counter = m_config.counter; port.tag++; // absolute index of block that will be read index = (position + 1) % port.block; // write new value @@ -380,6 +118,9 @@ int cellAudioInit() { // reverse byte order (TODO: use port.m_param.level) buffer[i] = buffer2[i]; + + // convert the data from float to u16 + oal_buffer[i] = (u16)((float)buffer[i] * (1 << 16)); } first_mix = false; } @@ -388,6 +129,9 @@ int cellAudioInit() for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) { buffer[i] = (buffer[i] + buffer2[i]) * 0.5; // TODO: valid mixing + + // convert the data from float to u16 + oal_buffer[i] = (u16)((float)buffer[i] * (1 << 16)); } } } @@ -396,29 +140,28 @@ int cellAudioInit() // TODO: check event source Emu.GetEventManager().SendEvent(m_config.event_key, 0x10103000e010e07, 0, 0, 0); + if(Ini.AudioOutMode.GetValue() == 1) + m_audio_out->AddData(oal_buffer, sizeof(oal_buffer)); + if(Ini.AudioDumpToFile.GetValue()) { - if (output.Write(&buffer, sizeof(buffer)) != sizeof(buffer)) // write file data + if (m_dump.WriteData(&buffer, sizeof(buffer)) != sizeof(buffer)) // write file data { - ConLog.Error("Port aborted: cannot write %s", output_name.wx_str()); + ConLog.Error("Port aborted: cannot write file!"); goto abort; } - header.Size += sizeof(buffer); // update file header - header.RIFF.Size += sizeof(buffer); + m_dump.UpdateHeader(sizeof(buffer)); } } ConLog.Write("Audio finished"); abort: if(Ini.AudioDumpToFile.GetValue()) - { - output.Seek(0); - output.Write(&header, sizeof(header)); // write fixed file header - - output.Close(); - } + m_dump.Finalize(); m_config.m_is_audio_finalized = true; + if(Ini.AudioOutMode.GetValue() == 1) + m_audio_out->Quit(); }); t.detach(); @@ -448,6 +191,9 @@ int cellAudioQuit() Memory.Free(m_config.m_buffer); Memory.Free(m_config.m_indexes); + if(Ini.AudioOutMode.GetValue() == 1) + m_audio_out->Quit(); + return CELL_OK; } @@ -555,6 +301,9 @@ int cellAudioPortStart(u32 portNum) m_config.m_ports[portNum].m_is_audio_port_started = true; + if(Ini.AudioOutMode.GetValue() == 1) + m_audio_out->Play(); + return CELL_OK; } @@ -621,7 +370,7 @@ int cellAudioGetPortTimestamp(u32 portNum, u64 tag, mem64_t stamp) AudioPortConfig& port = m_config.m_ports[portNum]; - SMutexLocker lock(port.m_mutex); + SMutexGeneralLocker lock(port.m_mutex); stamp = m_config.start_time + (port.counter + (tag - port.tag)) * 256000000 / 48000; @@ -655,7 +404,7 @@ int cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, mem64_t tag) return CELL_AUDIO_ERROR_PARAM; } - SMutexLocker lock(port.m_mutex); + SMutexGeneralLocker lock(port.m_mutex); u64 tag_base = port.tag; if (tag_base % port.block > blockNo) @@ -796,168 +545,6 @@ int cellAudioUnsetPersonalDevice(int iPersonalStream) return CELL_OK; } - -//Callback Functions -typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples); //Currently unused. - -// libmixer Functions, NOT active in this moment -int cellAANConnect(CellAANHandle receive, u32 receivePortNo, CellAANHandle source, u32 sourcePortNo) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellAANDisconnect(CellAANHandle receive, u32 receivePortNo, CellAANHandle source, u32 sourcePortNo) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellAANAddData(CellAANHandle handle, u32 port, u32 offset, float *addr, u32 samples) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSSPlayerCreate(CellAANHandle *handle, CellSSPlayerConfig *config) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSSPlayerRemove(CellAANHandle handle) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSSPlayerSetWave() //CellAANHandle handle, CellSSPlayerWaveParam *waveInfo, CellSSPlayerCommonParam *commonInfo //mem_class_t waveInfo -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSSPlayerPlay() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSSPlayerStop() //CellAANHandle handle, u32 mode -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSSPlayerSetParam() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -s32 cellSSPlayerGetState() //CellAANHandle handle -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerCreate() //const CellSurMixerConfig *config -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerGetAANHandle() //CellAANHandle *handle -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerChStripGetAANPortNo() //u32 *port, u32 type, u32 index -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerSetNotifyCallback() //CellSurMixerNotifyCallbackFunction callback, void *arg -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerRemoveNotifyCallback() //CellSurMixerNotifyCallbackFunction callback -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerStart() -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerSurBusAddData() //u32 busNo, u32 offset, float *addr, u32 samples -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerSetParameter() //u32 param, float value -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerChStripSetParameter() //u32 type, u32 index, CellSurMixerChStripParam *param -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerPause() //u32 switch -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerGetCurrentBlockTag() //u64 *tag -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerGetTimestamp() //u64 tag, u64 *stamp -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -void cellSurMixerBeep(); //void *arg - -float cellSurMixerUtilGetLevelFromDB() //float dB -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO; -} - -float cellSurMixerUtilGetLevelFromDBIndex() //int index -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO; -} - -float cellSurMixerUtilNoteToRatio() //unsigned char refNote, unsigned char note -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -int cellSurMixerFinalize(); //Currently unused. Returns 0 (in the current release). - //*libsnd3 Functions, NOT active in this moment s32 cellSnd3Init() //u32 maxVoice, u32 samples, CellSnd3RequestQueueCtx *queue { @@ -1399,14 +986,7 @@ void cellAudio_init() //TODO: Find addresses for libmixer, libsnd3 and libsynth2 functions } -void cellAudio_load() -{ - m_config.m_is_audio_initialized = false; - m_config.Clear(); -} - void cellAudio_unload() { - m_config.m_is_audio_initialized = false; - m_config.Clear(); + //StaticFinalize(); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index aadfaf1a85..36b8ffef44 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -18,9 +18,9 @@ void dmuxQueryEsAttr(u32 info_addr /* may be 0 */, const mem_ptr_t attr) { if (esFilterId->filterIdMajor >= 0xe0) - attr->memSize = 0x600000; // 0x45fa49 from ps3 + attr->memSize = 0x1000000; // 0x45fa49 from ps3 else - attr->memSize = 0x10000; // 0x73d9 from ps3 + attr->memSize = 0x200000; // 0x73d9 from ps3 cellDmux.Warning("*** filter(0x%x, 0x%x, 0x%x, 0x%x)", (u32)esFilterId->filterIdMajor, (u32)esFilterId->filterIdMinor, (u32)esFilterId->supplementalInfo1, (u32)esFilterId->supplementalInfo2); @@ -30,10 +30,14 @@ u32 dmuxOpen(Demuxer* data) { Demuxer& dmux = *data; + dmux.dmuxCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU); + u32 dmux_id = cellDmux.GetNewId(data); dmux.id = dmux_id; + dmux.dmuxCb->SetName("Demuxer[" + std::to_string(dmux_id) + "] Callback"); + thread t("Demuxer[" + std::to_string(dmux_id) + "] Thread", [&]() { ConLog.Write("Demuxer enter (mem=0x%x, size=0x%x, cb=0x%x, arg=0x%x)", dmux.memAddr, dmux.memSize, dmux.cbFunc, dmux.cbArg); @@ -50,6 +54,9 @@ u32 dmuxOpen(Demuxer* data) u32 cb_add = 0; + u32 updates_count = 0; + u32 updates_signaled = 0; + while (true) { if (Emu.IsStopped()) @@ -66,9 +73,17 @@ u32 dmuxOpen(Demuxer* data) if (!stream.peek(code)) { + dmux.is_running = false; // demuxing finished - task.type = dmuxResetStream; - goto task; + mem_ptr_t dmuxMsg(a128(dmux.memAddr) + (cb_add ^= 16)); + dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; + dmuxMsg->supplementalInfo = stream.userdata; + /*Callback cb; + cb.SetAddr(dmux.cbFunc); + cb.Handle(dmux.id, dmuxMsg.GetAddr(), dmux.cbArg); + cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/ + dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, true, dmux.id, dmuxMsg.GetAddr(), dmux.cbArg); + updates_signaled++; } else switch (code.ToLE()) { @@ -102,12 +117,61 @@ u32 dmuxOpen(Demuxer* data) case PRIVATE_STREAM_1: { + DemuxerStream backup = stream; + // audio AT3+ (and probably LPCM or user data) stream.skip(4); stream.get(len); - // skipping... - stream.skip(len); + PesHeader pes(stream); + + if (!pes.new_au) // temporarily + { + ConLog.Error("No pts info found"); + } + + // read additional header: + stream.peek(ch); + //stream.skip(4); + //pes.size += 4; + + if (esATX[ch]) + { + ElementaryStream& es = *esATX[ch]; + while (es.isfull()) + { + if (Emu.IsStopped()) + { + ConLog.Warning("esATX[%d] was full, waiting aborted", ch); + return; + } + Sleep(1); + } + + /*if (es.hasunseen()) // hack, probably useless + { + stream = backup; + continue; + }*/ + + //ConLog.Write("*** AT3+ AU sent (pts=0x%llx, dts=0x%llx)", pes.pts, pes.dts); + + es.push(stream, len - pes.size - 3, pes); + es.finish(stream); + + mem_ptr_t esMsg(a128(dmux.memAddr) + (cb_add ^= 16)); + esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; + esMsg->supplementalInfo = stream.userdata; + /*Callback cb; + cb.SetAddr(es.cbFunc); + cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg); + cb.Branch(false);*/ + dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.GetAddr(), es.cbArg); + } + else + { + stream.skip(len - pes.size - 3); + } } break; @@ -121,10 +185,14 @@ u32 dmuxOpen(Demuxer* data) if (esAVC[ch]) { ElementaryStream& es = *esAVC[ch]; - if (es.isfull()) + while (es.isfull()) { + if (Emu.IsStopped()) + { + ConLog.Warning("esAVC[%d] was full, waiting aborted", ch); + return; + } Sleep(1); - continue; } DemuxerStream backup = stream; @@ -133,33 +201,28 @@ u32 dmuxOpen(Demuxer* data) stream.get(len); PesHeader pes(stream); - if (!pes.new_au && !es.hasdata()) // fatal error - { - ConLog.Error("PES not found"); - return; - } - if (pes.new_au && es.hasdata()) // new AU detected { - if (es.hasunseen()) // hack, probably useless + /*if (es.hasunseen()) // hack, probably useless { stream = backup; continue; - } + }*/ es.finish(stream); // callback mem_ptr_t esMsg(a128(dmux.memAddr) + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; esMsg->supplementalInfo = stream.userdata; - Callback cb; + /*Callback cb; cb.SetAddr(es.cbFunc); cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg); - cb.Branch(false); + cb.Branch(false);*/ + dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.GetAddr(), es.cbArg); } if (pes.new_au) { - ConLog.Write("*** AVC AU detected (pts=0x%llx, dts=0x%llx)", pes.pts, pes.dts); + //ConLog.Write("*** AVC AU detected (pts=0x%llx, dts=0x%llx)", pes.pts, pes.dts); } if (es.isfull()) @@ -167,8 +230,10 @@ u32 dmuxOpen(Demuxer* data) stream = backup; continue; } - //stream = backup; - es.push(stream, len - pes.size - 3, pes); + + //hack: reconstruction of MPEG2-PS stream for vdec module (seems it works without it too) + stream = backup; + es.push(stream, len + 6 /*- pes.size - 3*/, pes); } else { @@ -218,24 +283,11 @@ u32 dmuxOpen(Demuxer* data) { break; // Emu is stopped } -task: + switch (task.type) { case dmuxSetStream: { - bool do_wait = false; - for (u32 i = 0; i < 192; i++) - { - if (esALL[i]) - { - if (esALL[i]->hasunseen()) // hack, probably useless - { - do_wait = true; - break; - } - } - } - if (do_wait) continue; stream = task.stream; ConLog.Write("*** stream updated(addr=0x%x, size=0x%x, discont=%d, userdata=0x%llx)", stream.addr, stream.size, stream.discontinuity, stream.userdata); @@ -246,6 +298,7 @@ task: esALL[i]->reset(); } } + updates_count++; dmux.is_running = true; } break; @@ -253,14 +306,16 @@ task: case dmuxResetStream: case dmuxResetStreamAndWaitDone: { - // TODO: send CELL_DMUX_MSG_TYPE_DEMUX_DONE callback and provide waiting condition mem_ptr_t dmuxMsg(a128(dmux.memAddr) + (cb_add ^= 16)); dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; dmuxMsg->supplementalInfo = stream.userdata; - Callback cb; + /*Callback cb; cb.SetAddr(dmux.cbFunc); cb.Handle(dmux.id, dmuxMsg.GetAddr(), dmux.cbArg); - cb.Branch(task.type == dmuxResetStreamAndWaitDone); + cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/ + dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, task.type == dmuxResetStreamAndWaitDone, + dmux.id, dmuxMsg.GetAddr(), dmux.cbArg); + updates_signaled++; dmux.is_running = false; } break; @@ -283,6 +338,13 @@ task: { esAVC[es.fidMajor - 0xe0] = task.es.es_ptr; } + else if (es.fidMajor == 0xbd && + es.fidMinor == 0 && + es.sup1 == 0 && + es.sup2 == 0) + { + esATX[0] = task.es.es_ptr; + } else { ConLog.Warning("dmuxEnableEs: (TODO) unsupported filter (0x%x, 0x%x, 0x%x, 0x%x)", es.fidMajor, es.fidMinor, es.sup1, es.sup2); @@ -311,11 +373,11 @@ task: } break; - case dmuxReleaseAu: + /*case dmuxReleaseAu: { task.es.es_ptr->release(); } - break; + break;*/ case dmuxFlushEs: { @@ -328,20 +390,22 @@ task: mem_ptr_t esMsg(a128(dmux.memAddr) + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; esMsg->supplementalInfo = stream.userdata; - Callback cb; + /*Callback cb; cb.SetAddr(es.cbFunc); cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg); - cb.Branch(false); + cb.Branch(false);*/ + dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.GetAddr(), es.cbArg); } // callback mem_ptr_t esMsg(a128(dmux.memAddr) + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_FLUSH_DONE; esMsg->supplementalInfo = stream.userdata; - Callback cb; + /*Callback cb; cb.SetAddr(es.cbFunc); cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg); - cb.Branch(false); + cb.Branch(false);*/ + dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.GetAddr(), es.cbArg); } break; @@ -507,6 +571,7 @@ int cellDmuxClose(u32 demuxerHandle) Sleep(1); } + if (dmux->dmuxCb) Emu.GetCPU().RemoveThread(dmux->dmuxCb->GetId()); Emu.GetIdManager().RemoveID(demuxerHandle); return CELL_OK; } @@ -527,9 +592,14 @@ int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize return CELL_DMUX_ERROR_FATAL; } - if (dmux->is_running) + while (dmux->is_running) // !!! { - Sleep(1); // performance hack + if (Emu.IsStopped()) + { + ConLog.Warning("cellDmuxSetStream(%d) aborted (waiting)", demuxerHandle); + break; + } + Sleep(1); return CELL_DMUX_ERROR_BUSY; } @@ -851,7 +921,7 @@ int cellDmuxPeekAuEx(u32 esHandle, mem32_t auInfoEx_ptr, mem32_t auSpecificInfo_ int cellDmuxReleaseAu(u32 esHandle) { - cellDmux.Warning("(disabled) cellDmuxReleaseAu(esHandle=0x%x)", esHandle); + cellDmux.Log("cellDmuxReleaseAu(esHandle=0x%x)", esHandle); return CELL_OK; @@ -865,14 +935,19 @@ int cellDmuxReleaseAu(u32 esHandle) { cellDmux.Error("cellDmuxReleaseAu: no AU"); return CELL_DMUX_ERROR_SEQ; - //return CELL_OK; } - DemuxerTask task(dmuxReleaseAu); + /*DemuxerTask task(dmuxReleaseAu); task.es.es = esHandle; task.es.es_ptr = es; - es->dmux->job.Push(task); + es->dmux->job.Push(task);*/ + + if (!es->release()) + { + cellDmux.Error("cellDmuxReleaseAu failed"); + return CELL_DMUX_ERROR_SEQ; + } return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.h b/rpcs3/Emu/SysCalls/Modules/cellDmux.h index 51e805ab07..cc504fe2f0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.h +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.h @@ -329,11 +329,11 @@ struct DemuxerStream } template - bool peek(T& out) + bool peek(T& out, u32 shift = 0) { - if (sizeof(T) > size) return false; + if (sizeof(T) + shift > size) return false; - out = *(T*)Memory.VirtualToRealAddr(addr); + out = *(T*)Memory.VirtualToRealAddr(addr + shift); return true; } @@ -364,45 +364,54 @@ struct PesHeader { u64 pts; u64 dts; - u8 ch; u8 size; bool new_au; PesHeader(DemuxerStream& stream) : pts(0xffffffffffffffff) , dts(0xffffffffffffffff) - , ch(0) , size(0) - , new_au(true) + , new_au(false) { u16 header; stream.get(header); stream.get(size); if (size) { - //ConLog.Write(">>>>> Pes Header (size=%d)", size); - if (size < 10) - { - stream.skip(size); - return; - } - new_au = true; + u8 empty = 0; u8 v; - stream.get(v); - if ((v & 0xF0) != 0x30) + while (true) { - ConLog.Error("Pts not found"); - Emu.Pause(); - } - pts = stream.get_ts(v); - stream.get(v); - if ((v & 0xF0) != 0x10) + stream.get(v); + if (v != 0xFF) break; // skip padding bytes + empty++; + if (empty = size) return; + }; + + if ((v & 0xF0) == 0x20 && (size - empty) >= 5) // pts only { - ConLog.Error("Dts not found"); - Emu.Pause(); + new_au = true; + pts = stream.get_ts(v); + stream.skip(size - empty - 5); + } + else + { + new_au = true; + if ((v & 0xF0) != 0x30 || (size - empty) < 10) + { + ConLog.Error("PesHeader(): pts not found"); + Emu.Pause(); + } + pts = stream.get_ts(v); + stream.get(v); + if ((v & 0xF0) != 0x10) + { + ConLog.Error("PesHeader(): dts not found"); + Emu.Pause(); + } + dts = stream.get_ts(v); + stream.skip(size - empty - 10); } - dts = stream.get_ts(v); - stream.skip(size - 10); } } }; @@ -417,7 +426,6 @@ enum DemuxerJobType dmuxEnableEs, dmuxDisableEs, dmuxResetEs, - dmuxReleaseAu, dmuxFlushEs, dmuxClose, }; @@ -461,6 +469,7 @@ public: volatile bool is_finished; volatile bool is_running; + CPUThread* dmuxCb; Demuxer(u32 addr, u32 size, u32 func, u32 arg) : is_finished(false) @@ -469,6 +478,7 @@ public: , memSize(size) , cbFunc(func) , cbArg(arg) + , dmuxCb(nullptr) { } }; @@ -497,8 +507,8 @@ public: ElementaryStream(Demuxer* dmux, u32 addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, u32 cbFunc, u32 cbArg, u32 spec) : dmux(dmux) - , memAddr(addr) - , memSize(size) + , memAddr(a128(addr)) + , memSize(size - (addr - memAddr)) , fidMajor(fidMajor) , fidMinor(fidMinor) , sup1(sup1) @@ -508,7 +518,7 @@ public: , spec(spec) , first_addr(0) , peek_addr(0) - , last_addr(a128(addr)) + , last_addr(memAddr) , last_size(0) { } @@ -523,8 +533,9 @@ public: return last_size; } - bool isfull() // not multithread-safe + bool isfull() { + SMutexLocker lock(mutex); if (first_addr) { if (first_addr > last_addr) @@ -570,7 +581,24 @@ public: { SMutexLocker lock(mutex); //ConLog.Write("es::push(): peek=0x%x, first=0x%x, last=0x%x, size=0x%x", peek_addr, first_addr, last_addr, last_size); - if (isfull()) + bool is_full; + if (first_addr) + { + if (first_addr > last_addr) + { + is_full = (first_addr - last_addr) < MAX_AU; + } + else + { + is_full = (first_addr + MAX_AU) > (memAddr + memSize); + } + } + else + { + is_full = false; + } + + if (is_full) { ConLog.Error("ElementaryStream::push(): buffer is full"); Emu.Pause(); @@ -590,7 +618,7 @@ public: mem_ptr_t info(last_addr); info->auAddr = last_addr + 128; info->auSize = last_size; - if (pes.size) + if (pes.new_au) { info->dts.lower = (u32)pes.dts; info->dts.upper = (u32)(pes.dts >> 32); @@ -607,7 +635,7 @@ public: mem_ptr_t inf(last_addr + 64); inf->auAddr = last_addr + 128; inf->auSize = last_size; - if (pes.size) + if (pes.new_au) { inf->dtsLower = (u32)pes.dts; inf->dtsUpper = (u32)(pes.dts >> 32); @@ -623,20 +651,26 @@ public: return first_addr; } - void release() + bool release() { SMutexLocker lock(mutex); - ConLog.Write("es::release(): peek=0x%x, first=0x%x, last=0x%x, size=0x%x", peek_addr, first_addr, last_addr, last_size); + //ConLog.Write("es::release(): peek=0x%x, first=0x%x, last=0x%x, size=0x%x", peek_addr, first_addr, last_addr, last_size); if (!canrelease()) { ConLog.Error("ElementaryStream::release(): buffer is empty"); - Emu.Pause(); - return; + return false; } u32 size = a128(Memory.Read32(first_addr + 4) + 128); u32 new_addr = first_addr + size; - if (peek_addr <= first_addr) peek_addr = new_addr; + + if (peek_addr == first_addr) + { + ConLog.Error("ElementaryStream::release(): buffer has not been seen yet"); + return false; + } + + //if (peek_addr <= first_addr) peek_addr = new_addr; if (new_addr == last_addr) { first_addr = 0; @@ -649,6 +683,8 @@ public: { first_addr = new_addr; } + + return true; } bool peek(u32& out_data, bool no_ex, u32& out_spec, bool update_index) @@ -687,7 +723,7 @@ public: SMutexLocker lock(mutex); first_addr = 0; peek_addr = 0; - last_addr = a128(memAddr); + last_addr = memAddr; last_size = 0; } }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp index f78f667030..dcf34cd9d7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp @@ -2,6 +2,8 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" +#include + void cellL10n_init(); Module cellL10n(0x001e, cellL10n_init); @@ -22,24 +24,18 @@ int UTF16stoUTF8s(mem16_ptr_t utf16, mem64_t utf16_len, mem8_ptr_t utf8, mem64_t if (!utf16.IsGood() || !utf16_len.IsGood() || !utf8_len.IsGood()) return SRCIllegal; - std::wstring wstr = (wchar_t*)Memory.VirtualToRealAddr(utf16); - std::string str; + std::u16string wstr =(char16_t*)Memory.VirtualToRealAddr(utf16); + wstr.resize(utf16_len.GetValue()); // TODO: Is this really the role of utf16_len in this function? - int len = min((int)utf16_len.GetValue(), (int)wstr.size()); - int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL); + std::wstring_convert,char16_t> convert; + std::string str = convert.to_bytes(wstr); - if (!utf8.IsGood()) - utf8_len = size; - if (utf8_len.GetValue() < size) + if (!utf8.IsGood() || utf8_len.GetValue() < str.size()) + utf8_len = str.size(); return DSTExhausted; - -#ifdef WIN32 - WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &str[0], size, NULL, NULL); -#else - // TODO -#endif - - Memory.WriteString(utf8, str); + + utf8_len = str.size(); + Memory.WriteString(utf8, str.c_str()); return ConversionOK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp new file mode 100644 index 0000000000..aca92144af --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -0,0 +1,235 @@ +#include "stdafx.h" +#include "cellSpurs.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" + +void cellSpurs_init(); +Module cellSpurs(0x000a, cellSpurs_init); + +int _cellSpursAttributeInitialize(mem_ptr_t attr, int nSpus, int spuPriority, + int ppuPriority, bool exitIfNoWork) +{ + cellSpurs.Warning("cellSpursAttributeInitialize(attr_addr=0x%x, nSpus=%u, spuPriority=%u, ppuPriority=%u, exitIfNoWork=%u)", + attr.GetAddr(), nSpus, spuPriority, ppuPriority, exitIfNoWork); + if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursAttributeSetMemoryContainerForSpuThread(mem_ptr_t attr, u32 container) +{ + cellSpurs.Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=0x%x)", + attr.GetAddr(), container); + if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursAttributeSetNamePrefix(mem_ptr_t attr, const mem8_t prefix, u32 size) +{ + cellSpurs.Warning("cellSpursAttributeSetNamePrefix(attr_addr=0x%x, prefix_addr=0x%x, size=0x%x)", + attr.GetAddr(), prefix.GetAddr(), size); + if(!attr.IsGood() || !prefix.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + if(size > 15) return CELL_SPURS_CORE_ERROR_INVAL; + + return CELL_OK; +} + +int cellSpursAttributeEnableSpuPrintfIfAvailable(mem_ptr_t attr) +{ + cellSpurs.Warning("cellSpursAttributeEnableSpuPrintfIfAvailable(attr_addr=0x%x)", attr.GetAddr()); + if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursAttributeSetSpuThreadGroupType(mem_ptr_t attr, int type) +{ + cellSpurs.Warning("cellSpursAttributeSetSpuThreadGroupType(attr_addr=0x%x, type=%u)", attr.GetAddr(), type); + if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursAttributeEnableSystemWorkload(mem_ptr_t attr, const u8 priority[8], + uint maxSpu, const bool isPreemptible[8]) +{ + cellSpurs.Warning("cellSpursAttributeEnableSystemWorkload(attr_addr=0x%x, priority[%u], maxSpu=%u, isPreemptible[%u])", + attr.GetAddr(), priority, maxSpu, isPreemptible); + if(!attr.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + for (int i=0; i<8; i++) + if(priority[i] != 1 || maxSpu == 0) return CELL_SPURS_CORE_ERROR_INVAL; + + return CELL_OK; +} + +int cellSpursInitializeWithAttribute2(mem_ptr_t spurs, const mem_ptr_t attr) +{ + cellSpurs.Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, spurs_addr=0x%x)", + spurs.GetAddr(), attr.GetAddr()); + if(!attr.IsGood() || !spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursFinalize(mem_ptr_t spurs) +{ + cellSpurs.Warning("cellSpursFinalize(spurs_addr=0x%x)", spurs.GetAddr()); + if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursGetSpuThreadGroupId(mem_ptr_t spurs, mem32_t group) +{ + cellSpurs.Warning("cellSpursGetSpuThreadGroupId(spurs_addr=0x%x, group_addr=0x%x)", + spurs.GetAddr(), group.GetAddr()); + if(!spurs.IsGood() || group.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursGetNumSpuThread(mem_ptr_t spurs, mem32_t nThreads) +{ + cellSpurs.Warning("cellSpursGetNumSpuThread(spurs_addr=0x%x, nThreads_addr=0x%x)", + spurs.GetAddr(), nThreads.GetAddr()); + if(!spurs.IsGood() || nThreads.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursGetSpuThreadId(mem_ptr_t spurs, mem32_t thread, mem32_t nThreads) +{ + cellSpurs.Warning("cellSpursGetSpuThreadId(spurs_addr=0x%x, thread_addr=0x%x, nThreads_addr=0x%x)", + spurs.GetAddr(), thread.GetAddr(), nThreads.GetAddr()); + if(!spurs.IsGood() || !thread.IsGood() || nThreads.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursSetMaxContention(mem_ptr_t spurs, uint workloadId, uint maxContention) +{ + cellSpurs.Warning("cellSpursSetMaxContention(spurs_addr=0x%x, workloadId=%u, maxContention=%u)", + spurs.GetAddr(), workloadId, maxContention); + if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursSetPriorities(mem_ptr_t spurs, uint workloadId, const u8 priorities[CELL_SPURS_MAX_SPU]) +{ + cellSpurs.Warning("cellSpursSetPriorities(spurs_addr=0x%x, workloadId=%u, priorities[%u])", + spurs.GetAddr(), workloadId, priorities); + if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursSetPriority(mem_ptr_t spurs, uint workloadId, uint spuId, uint priority) +{ + cellSpurs.Warning("cellSpursSetPriority(spurs_addr=0x%x, workloadId=%u, spuId=%u, priority=%u)", + spurs.GetAddr(), workloadId, spuId, priority); + if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursSetPreemptionVictimHints(mem_ptr_t spurs, const bool isPreemptible[8]) +{ + cellSpurs.Warning("cellSpursSetPreemptionVictimHints(spurs_addr=0x%x, isPreemptible[%u])", + spurs.GetAddr(), isPreemptible); + if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursAttachLv2EventQueue(mem_ptr_t spurs, u32 queue, mem8_t port, int isDynamic) +{ + cellSpurs.Warning("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=0x%x, port_addr=0x%x, isDynamic=%u)", + spurs.GetAddr(), queue, port.GetAddr(), isDynamic); + if(!spurs.IsGood() || !port.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursDetachLv2EventQueue(mem_ptr_t spurs, u8 port) +{ + cellSpurs.Warning("cellSpursDetachLv2EventQueue(spurs_addr=0x%x, port=0x%x)", spurs.GetAddr(), port); + if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursEnableExceptionEventHandler(mem_ptr_t spurs, bool flag) +{ + cellSpurs.Warning("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, flag=%u)", spurs.GetAddr(), flag); + if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursSetGlobalExceptionEventHandler(mem_ptr_t spurs, + mem_func_ptr_t eaHandler, mem_ptr_t arg) +{ + cellSpurs.Warning("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, eaHandler_addr=0x%x, arg_addr=0x%x,)", + spurs.GetAddr(), eaHandler.GetAddr(), arg.GetAddr()); + if(!spurs.IsGood() || eaHandler.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursUnsetGlobalExceptionEventHandler(mem_ptr_t spurs) +{ + cellSpurs.Warning("cellSpursUnsetGlobalExceptionEventHandler(spurs_addr=0x%x)", spurs.GetAddr()); + if(!spurs.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +int cellSpursGetInfo(mem_ptr_t spurs, mem_ptr_t info) +{ + cellSpurs.Warning("cellSpursGetInfo(spurs_addr=0x%x, info_addr=0x%x)", spurs.GetAddr(), info.GetAddr()); + if(!spurs.IsGood() || !info.IsGood()) return CELL_SPURS_CORE_ERROR_NULL_POINTER; + + return CELL_OK; +} + +// Task functions +int cellSpursGetTasksetId(mem_ptr_t taskset, mem32_t workloadId) +{ + cellSpurs.Warning("cellSpursGetTasksetId(taskset_addr=0x%x, workloadId_addr=0x%x)", taskset.GetAddr(), workloadId.GetAddr()); + if(!taskset.IsGood() || !taskset.IsGood()) return CELL_SPURS_TASK_ERROR_NULL_POINTER; + + return CELL_OK; +} + + + + +void cellSpurs_init() +{ + //libspurs core functions + cellSpurs.AddFunc(0x95180230, _cellSpursAttributeInitialize); + cellSpurs.AddFunc(0x82275c1c, cellSpursAttributeSetMemoryContainerForSpuThread); + cellSpurs.AddFunc(0x07529113, cellSpursAttributeSetNamePrefix); + cellSpurs.AddFunc(0x1051d134, cellSpursAttributeEnableSpuPrintfIfAvailable); + cellSpurs.AddFunc(0xa839a4d9, cellSpursAttributeSetSpuThreadGroupType); + cellSpurs.AddFunc(0x9dcbcb5d, cellSpursAttributeEnableSystemWorkload); + cellSpurs.AddFunc(0x30aa96c4, cellSpursInitializeWithAttribute2); + cellSpurs.AddFunc(0xca4c4600, cellSpursFinalize); + cellSpurs.AddFunc(0x39c173fb, cellSpursGetSpuThreadGroupId); + cellSpurs.AddFunc(0xc56defb5, cellSpursGetNumSpuThread); + cellSpurs.AddFunc(0x6c960f6d, cellSpursGetSpuThreadId); + cellSpurs.AddFunc(0x84d2f6d5,cellSpursSetMaxContention); + cellSpurs.AddFunc(0x80a29e27,cellSpursSetPriorities); + //cellSpurs.AddFunc(,cellSpursSetPriority); + cellSpurs.AddFunc(0x4de203e2, cellSpursSetPreemptionVictimHints); + cellSpurs.AddFunc(0xb9bc6207, cellSpursAttachLv2EventQueue); + cellSpurs.AddFunc(0x4e66d483, cellSpursDetachLv2EventQueue); + cellSpurs.AddFunc(0x32b94add, cellSpursEnableExceptionEventHandler); + cellSpurs.AddFunc(0x7517724a, cellSpursSetGlobalExceptionEventHandler); + cellSpurs.AddFunc(0x861237f8, cellSpursUnsetGlobalExceptionEventHandler); + cellSpurs.AddFunc(0x1f402f8f, cellSpursGetInfo); + + //libspurs task functions +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h new file mode 100644 index 0000000000..af9f4c4e6c --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h @@ -0,0 +1,296 @@ +#pragma once + +// return codes +enum +{ + CELL_SPURS_CORE_ERROR_AGAIN = 0x80410701, + CELL_SPURS_CORE_ERROR_INVAL = 0x80410702, + CELL_SPURS_CORE_ERROR_NOMEM = 0x80410704, + CELL_SPURS_CORE_ERROR_SRCH = 0x80410705, + CELL_SPURS_CORE_ERROR_PERM = 0x80410709, + CELL_SPURS_CORE_ERROR_BUSY = 0x8041070A, + CELL_SPURS_CORE_ERROR_STAT = 0x8041070F, + CELL_SPURS_CORE_ERROR_ALIGN = 0x80410710, + CELL_SPURS_CORE_ERROR_NULL_POINTER = 0x80410711, +}; + +//defines +enum SPURSKernelInterfaces +{ + CELL_SPURS_MAX_SPU = 8, + CELL_SPURS_MAX_WORKLOAD = 16, + CELL_SPURS_MAX_WORKLOAD2 = 32, + CELL_SPURS_MAX_PRIORITY = 16, + CELL_SPURS_NAME_MAX_LENGTH = 15, + CELL_SPURS_SIZE = 4096, + CELL_SPURS_SIZE2 = 8192, + CELL_SPURS_ALIGN = 128, + CELL_SPURS_ATTRIBUTE_SIZE = 512, + CELL_SPURS_ATTRIBUTE_ALIGN = 8, + CELL_SPURS_INTERRUPT_VECTOR = 0x0, + CELL_SPURS_LOCK_LINE = 0x80, + CELL_SPURS_KERNEL_DMA_TAG_ID = 31, +}; + +enum RangeofEventQueuePortNumbers +{ + CELL_SPURS_STATIC_PORT_RANGE_BOTTOM = 15, + CELL_SPURS_DYNAMIC_PORT_RANGE_TOP = 16, + CELL_SPURS_DYNAMIC_PORT_RANGE_BOTTOM = 63, +}; + +enum SPURSTraceTypes +{ + CELL_SPURS_TRACE_TAG_LOAD = 0x2a, + CELL_SPURS_TRACE_TAG_MAP = 0x2b, + CELL_SPURS_TRACE_TAG_START = 0x2c, + CELL_SPURS_TRACE_TAG_STOP = 0x2d, + CELL_SPURS_TRACE_TAG_USER = 0x2e, + CELL_SPURS_TRACE_TAG_GUID = 0x2f, +}; + +struct CellSpursInfo +{ + be_t nSpus; + be_t spuThreadGroupPriority; + be_t ppuThreadPriority; + bool exitIfNoWork; + bool spurs2; + be_t traceBuffer_addr; //void *traceBuffer; + be_t traceBufferSize; + be_t traceMode; + be_t spuThreadGroup; //typedef u32 sys_spu_thread_group_t; + be_t spuThreads[8]; //typedef u32 sys_spu_thread_t; + be_t spursHandlerThread0; + be_t spursHandlerThread1; + char namePrefix[CELL_SPURS_NAME_MAX_LENGTH+1]; + be_t namePrefixLength; + be_t deadlineMissCounter; + be_t deadlineMeetCounter; + //u8 padding[]; +}; + +struct CellSpursExceptionInfo +{ + be_t spu_thread; + be_t spu_npc; + be_t cause; + be_t option; +}; + +struct CellSpursTraceInfo +{ + be_t spu_thread[8]; + be_t count[8]; + be_t spu_thread_grp; + be_t nspu; + //u8 padding[]; +}; + +__declspec(align(8)) struct CellTraceHeader +{ + u8 tag; + u8 length; + u8 cpu; + u8 thread; + be_t time; +}; + +struct CellSpursTracePacket +{ + struct header_struct + { + u8 tag; + u8 length; + u8 spu; + u8 workload; + be_t time; + } header; + + struct data_struct + { + struct load_struct + { + be_t ea; + be_t ls; + be_t size; + } load; + + struct map_struct + { + be_t offset; + be_t ls; + be_t size; + } map; + + struct start_struct + { + char module[4]; + be_t level; + be_t ls; + } start; + + be_t user; + be_t guid; + } data; +}; + +__declspec(align(128)) struct CellSpurs +{ + u8 skip[CELL_SPURS_SIZE]; +}; + +__declspec(align(128)) struct CellSpurs2 +{ + u8 skip[CELL_SPURS_SIZE2 - CELL_SPURS_SIZE]; +}; + +__declspec(align(8)) struct CellSpursAttribute +{ + u8 skip[CELL_SPURS_ATTRIBUTE_SIZE]; +}; + + +//typedef unsigned CellSpursWorkloadId; + +typedef void (*CellSpursGlobalExceptionEventHandler)(mem_ptr_t spurs, const mem_ptr_t info, + uint id, mem_ptr_t arg); + + +// task datatypes and constans +enum TaskConstants +{ + CELL_SPURS_MAX_TASK = 128, + CELL_SPURS_TASK_TOP = 0x3000, + CELL_SPURS_TASK_BOTTOM = 0x40000, + CELL_SPURS_MAX_TASK_NAME_LENGTH = 32, +}; + +enum +{ + CELL_SPURS_TASK_ERROR_AGAIN = 0x80410901, + CELL_SPURS_TASK_ERROR_INVAL = 0x80410902, + CELL_SPURS_TASK_ERROR_NOMEM = 0x80410904, + CELL_SPURS_TASK_ERROR_SRCH = 0x80410905, + CELL_SPURS_TASK_ERROR_NOEXEC = 0x80410907, + CELL_SPURS_TASK_ERROR_PERM = 0x80410909, + CELL_SPURS_TASK_ERROR_BUSY = 0x8041090A, + CELL_SPURS_TASK_ERROR_FAULT = 0x8041090D, + CELL_SPURS_TASK_ERROR_STAT = 0x8041090F, + CELL_SPURS_TASK_ERROR_ALIGN = 0x80410910, + CELL_SPURS_TASK_ERROR_NULL_POINTER = 0x80410911, + CELL_SPURS_TASK_ERROR_FATAL = 0x80410914, + CELL_SPURS_TASK_ERROR_SHUTDOWN = 0x80410920, +}; + + +__declspec(align(128)) struct CellSpursTaskset +{ + u8 skip[6400]; +}; + +typedef void(*CellSpursTasksetExceptionEventHandler)(mem_ptr_t spurs, mem_ptr_t taskset, + uint idTask, const mem_ptr_t info, mem_ptr_t arg); + + +struct CellSpursTasksetInfo +{ + //CellSpursTaskInfo taskInfo[CELL_SPURS_MAX_TASK]; + be_t argument; + be_t idWorkload; + be_t idLastScheduledTask; //typedef unsigned CellSpursTaskId + be_t name_addr; + CellSpursTasksetExceptionEventHandler exceptionEventHandler; + be_t exceptionEventHandlerArgument_addr; //void *exceptionEventHandlerArgument + be_t sizeTaskset; + //be_t reserved[]; +}; + + +/* +#define CELL_SPURS_TASKSET_CLASS0_SIZE (128 * 50) +#define _CELL_SPURS_TASKSET_CLASS1_EXTENDED_SIZE (128 + 128 * 16 + 128 * 15) +#define CELL_SPURS_TASKSET_CLASS1_SIZE (CELL_SPURS_TASKSET_CLASS0_SIZE + _CELL_SPURS_TASKSET_CLASS1_EXTENDED_SIZE) +#define CELL_SPURS_TASKSET2_SIZE (CELL_SPURS_TASKSET_CLASS1_SIZE) +#define CELL_SPURS_TASKSET2_ALIGN 128 +#define CELL_SPURS_TASKSET_ALIGN 128 +#define CELL_SPURS_TASKSET_SIZE CELL_SPURS_TASKSET_CLASS0_SIZE +*/ + +__declspec(align(128)) struct CellSpursTaskset2 +{ + be_t skip[10496]; +}; + +struct CellSpursTasksetAttribute2 +{ + be_t revision; + be_t name_addr; + be_t argTaskset; + u8 priority[8]; + be_t maxContention; + be_t enableClearLs; + be_t CellSpursTaskNameBuffer_addr; //??? *taskNameBuffer + //be_t __reserved__[]; +}; + +struct CellSpursTaskNameBuffer +{ + char taskName[CELL_SPURS_MAX_TASK][CELL_SPURS_MAX_TASK_NAME_LENGTH]; +}; + +struct CellSpursTraceTaskData +{ + be_t incident; + be_t task; +}; + +struct CellSpursTaskArgument +{ + be_t u32[4]; + be_t u64[2]; +}; + +struct CellSpursTaskLsPattern +{ + be_t u32[4]; + be_t u64[2]; +}; + +struct CellSpursTaskAttribute2 +{ + be_t revision; + be_t sizeContext; + be_t eaContext; + CellSpursTaskLsPattern lsPattern; //??? + be_t name_addr; + //be_t __reserved__[]; +}; + +__declspec(align(128)) struct CellSpursTaskExitCode +{ + unsigned char skip[128]; +}; + +struct CellSpursTaskInfo +{ + CellSpursTaskLsPattern lsPattern; + CellSpursTaskArgument argument; + const be_t eaElf_addr; //void *eaElf + const be_t eaContext_addr; //void *eaContext + be_t sizeContext; + be_t state; + be_t hasSignal; + const be_t CellSpursTaskExitCode_addr; + u8 guid[8]; + //be_t reserved[]; +}; + +struct CellSpursTaskBinInfo +{ + be_t eaElf; + be_t sizeContext; + be_t __reserved__; + CellSpursTaskLsPattern lsPattern; +}; + diff --git a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp new file mode 100644 index 0000000000..3c0a541d56 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp @@ -0,0 +1,75 @@ +#include "stdafx.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" + +#include "cellUserInfo.h" + +void cellUserInfo_init(); +Module cellUserInfo(0x0032, cellUserInfo_init); + +int cellUserInfoGetStat(u32 id, mem_ptr_t stat) +{ + cellUserInfo.Warning("cellUserInfoGetStat(id=%d, stat_addr=0x%x)", id, stat.GetAddr()); + + if (!stat.IsGood()) + return CELL_USERINFO_ERROR_PARAM; + if (id > CELL_USERINFO_USER_MAX) + return CELL_USERINFO_ERROR_NOUSER; + + char path [256]; + sprintf(path, "/dev_hdd0/home/%08d", id); + if (!Emu.GetVFS().ExistsDir(path)) + return CELL_USERINFO_ERROR_NOUSER; + + sprintf(path, "/dev_hdd0/home/%08d/localusername", id); + vfsStream* stream = Emu.GetVFS().OpenFile(path, vfsRead); + if (!stream || !(stream->IsOpened())) + return CELL_USERINFO_ERROR_INTERNAL; + + char name [CELL_USERINFO_USERNAME_SIZE]; + memset(name, 0, CELL_USERINFO_USERNAME_SIZE); + stream->Read(name, CELL_USERINFO_USERNAME_SIZE); + stream->Close(); + + stat->id = id; + memcpy(stat->name, name, CELL_USERINFO_USERNAME_SIZE); + return CELL_OK; +} + +int cellUserInfoSelectUser_ListType() +{ + UNIMPLEMENTED_FUNC(cellUserInfo); + return CELL_OK; +} + +int cellUserInfoSelectUser_SetList() +{ + UNIMPLEMENTED_FUNC(cellUserInfo); + return CELL_OK; +} + +int cellUserInfoEnableOverlay() +{ + UNIMPLEMENTED_FUNC(cellUserInfo); + return CELL_OK; +} + +int cellUserInfoGetList(mem32_t listNum, mem_ptr_t listBuf, mem32_t currentUserId) +{ + cellUserInfo.Warning("cellUserInfoGetList(listNum_addr=0x%x, listBuf_addr=0x%x, currentUserId_addr=0x%x)", + listNum.GetAddr(), listBuf.GetAddr(), currentUserId.GetAddr()); + + listNum = 1; + listBuf->userId[0] = 1; + currentUserId = 1; + return CELL_OK; +} + +void cellUserInfo_init() +{ + cellUserInfo.AddFunc(0x2b761140, cellUserInfoGetStat); + cellUserInfo.AddFunc(0x3097cc1c, cellUserInfoSelectUser_ListType); + cellUserInfo.AddFunc(0x55123a25, cellUserInfoSelectUser_SetList); + cellUserInfo.AddFunc(0xb3516536, cellUserInfoEnableOverlay); + cellUserInfo.AddFunc(0xc55e338b, cellUserInfoGetList); +} diff --git a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.h b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.h new file mode 100644 index 0000000000..3498b0293c --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.h @@ -0,0 +1,55 @@ +#pragma once + +// Return Codes +enum +{ + CELL_USERINFO_RET_OK = 0, + CELL_USERINFO_RET_CANCEL = 1, + CELL_USERINFO_ERROR_BUSY = 0x8002c301, + CELL_USERINFO_ERROR_INTERNAL = 0x8002c302, + CELL_USERINFO_ERROR_PARAM = 0x8002c303, + CELL_USERINFO_ERROR_NOUSER = 0x8002c304, +}; + +// Enums +enum CellUserInfoParamSize +{ + CELL_USERINFO_USER_MAX = 16, + CELL_USERINFO_TITLE_SIZE = 256, + CELL_USERINFO_USERNAME_SIZE = 64, +}; + +enum CellUserInfoListType +{ + CELL_USERINFO_LISTTYPE_ALL = 0, + CELL_USERINFO_LISTTYPE_NOCURRENT = 1, +}; + +// Structs +struct CellUserInfoUserStat +{ + u32 id; + u8 name[CELL_USERINFO_USERNAME_SIZE]; +}; + +struct CellUserInfoUserList +{ + u32 userId[CELL_USERINFO_USER_MAX]; +}; + +struct CellUserInfoListSet +{ + u32 title_addr; // (char*) + u32 focus; + u32 fixedListNum; + mem_ptr_t fixedList; + u32 reserved_addr; // (void*) +}; + +struct CellUserInfoTypeSet +{ + u32 title_addr; // (char*) + u32 focus; + CellUserInfoListType type; + u32 reserved_addr; // (void*) +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp index 232e389f8e..31fab366d6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp @@ -3,6 +3,8 @@ #include "Emu/SysCalls/SC_FUNC.h" #include "cellPamf.h" +SMutexGeneral g_mutex_avcodec_open2; + extern "C" { #include "libavcodec/avcodec.h" @@ -19,10 +21,68 @@ int vdecRead(void* opaque, u8* buf, int buf_size) { VideoDecoder& vdec = *(VideoDecoder*)opaque; - if (vdec.reader.size < (u32)buf_size) buf_size = vdec.reader.size; + int res = 0; + + if (vdec.reader.size < (u32)buf_size && !vdec.just_started) + { + while (vdec.job.IsEmpty()) + { + if (Emu.IsStopped()) + { + ConLog.Warning("vdecRead() aborted"); + return 0; + } + Sleep(1); + } + + switch (vdec.job.Peek().type) + { + case vdecEndSeq: + { + buf_size = vdec.reader.size; + } + break; + case vdecDecodeAu: + { + if (!Memory.CopyToReal(buf, vdec.reader.addr, vdec.reader.size)) + { + ConLog.Error("vdecRead: data reading failed (reader.size=0x%x)", vdec.reader.size); + Emu.Pause(); + return 0; + } + + buf += vdec.reader.size; + buf_size -= vdec.reader.size; + res += vdec.reader.size; + + /*Callback cb; + cb.SetAddr(vdec.cbFunc); + cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg); + cb.Branch(false);*/ + vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg); + + vdec.job.Pop(vdec.task); + + vdec.reader.addr = vdec.task.addr; + vdec.reader.size = vdec.task.size; + + vdec.last_pts = vdec.task.pts; + vdec.last_dts = vdec.task.dts; + } + break; + default: + ConLog.Error("vdecRead(): sequence error (task %d)", vdec.job.Peek().type); + return 0; + } + } + else if (vdec.reader.size < (u32)buf_size) + { + buf_size = vdec.reader.size; + } + if (!buf_size) { - return AVERROR_EOF; + return res; } else if (!Memory.CopyToReal(buf, vdec.reader.addr, buf_size)) { @@ -34,7 +94,7 @@ int vdecRead(void* opaque, u8* buf, int buf_size) { vdec.reader.addr += buf_size; vdec.reader.size -= buf_size; - return buf_size; + return res + buf_size; } } @@ -60,15 +120,19 @@ u32 vdecOpen(VideoDecoder* data) { VideoDecoder& vdec = *data; + vdec.vdecCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU); + u32 vdec_id = cellVdec.GetNewId(data); vdec.id = vdec_id; + vdec.vdecCb->SetName("Video Decoder[" + std::to_string(vdec_id) + "] Callback"); + thread t("Video Decoder[" + std::to_string(vdec_id) + "] Thread", [&]() { ConLog.Write("Video Decoder enter()"); - VdecTask task; + VdecTask& task = vdec.task; while (true) { @@ -79,12 +143,11 @@ u32 vdecOpen(VideoDecoder* data) if (vdec.job.IsEmpty() && vdec.is_running) { - // TODO: default task (not needed?) Sleep(1); continue; } - if (vdec.has_picture) // hack + if (vdec.frames.GetCount() >= 50) { Sleep(1); continue; @@ -100,55 +163,36 @@ u32 vdecOpen(VideoDecoder* data) case vdecStartSeq: { // TODO: reset data - ConLog.Warning("vdecStartSeq()"); + ConLog.Warning("vdecStartSeq:"); + + vdec.reader.addr = 0; + vdec.reader.size = 0; vdec.is_running = true; + vdec.just_started = true; } break; case vdecEndSeq: { - Callback cb; + // TODO: finalize + ConLog.Warning("vdecEndSeq:"); + + vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg); + /*Callback cb; cb.SetAddr(vdec.cbFunc); - cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, 0, vdec.cbArg); - cb.Branch(false); - ConLog.Warning("vdecEndSeq()"); + cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg); + cb.Branch(true); // ???*/ + + avcodec_close(vdec.ctx); + avformat_close_input(&vdec.fmt); + vdec.is_running = false; } break; case vdecDecodeAu: { - struct vdecPacket : AVPacket - { - vdecPacket(u32 size) - { - av_init_packet(this); - data = (u8*)av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - this->size = size + FF_INPUT_BUFFER_PADDING_SIZE; - } - - ~vdecPacket() - { - av_free(data); - //av_free_packet(this); - } - - } au(task.size); - - if ((task.pts || task.dts) && task.pts != ~0 && task.dts != ~0) - { - vdec.pts = task.pts; - vdec.dts = task.dts; - au.pts = vdec.pts; - au.dts = vdec.dts; - au.flags = AV_PKT_FLAG_KEY; - } - else - { - au.pts = vdec.pts; - au.dts = vdec.dts; - } + int err; if (task.mode != CELL_VDEC_DEC_MODE_NORMAL) { @@ -159,72 +203,166 @@ u32 vdecOpen(VideoDecoder* data) vdec.reader.addr = task.addr; vdec.reader.size = task.size; - if (!Memory.CopyToReal(au.data, task.addr, task.size)) + vdec.last_pts = task.pts; + vdec.last_dts = task.dts; + + struct AVPacketHolder : AVPacket { - ConLog.Error("vdecDecodeAu: AU data accessing failed(addr=0x%x, size=0x%x)", task.addr, task.size); - break; - } - - /*{ - wxFile dump; - dump.Open(wxString::Format("0x%llx-0x%llx.dump", au.pts, au.dts), wxFile::write); - dump.Write(au.data, task.size + FF_INPUT_BUFFER_PADDING_SIZE); - dump.Close(); - }*/ - - int got_picture = 0; - - //vdec.ctx->flags |= CODEC_FLAG_TRUNCATED; - //vdec.ctx->flags2 |= CODEC_FLAG2_CHUNKS; - vdec.ctx->flags2 |= CODEC_FLAG2_LOCAL_HEADER; - vdec.ctx->codec_tag = *(u32*)"DAVC"; - //vdec.ctx->stream_codec_tag = *(u32*)"DAVC"; - - //avcodec_get_frame_defaults(vdec.frame); - - - int decode = avcodec_decode_video2(vdec.ctx, vdec.frame, &got_picture, &au); - if (decode < 0) - { - ConLog.Error("vdecDecodeAu: AU decoding error(%d)", decode); - break; - } - - if (got_picture) - { - ConLog.Write("got_picture (%d, vdec: pts=0x%llx, dts=0x%llx)", got_picture, vdec.pts, vdec.dts); - - /*if (vdec.out_data[0]) av_freep(vdec.out_data[0]); - - int err = av_image_alloc(vdec.out_data, vdec.linesize, vdec.ctx->width, vdec.ctx->height, vdec.ctx->pix_fmt, 1); - if (err < 0) + AVPacketHolder(u32 size) { - ConLog.Error("vdecDecodeAu: av_image_alloc failed(%d)", err); + av_init_packet(this); + + if (size) + { + data = (u8*)av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + this->size = size + FF_INPUT_BUFFER_PADDING_SIZE; + } + else + { + data = NULL; + size = 0; + } + } + + ~AVPacketHolder() + { + av_free(data); + //av_free_packet(this); + } + + } au(0); + + if (vdec.just_started) // deferred initialization + { + err = avformat_open_input(&vdec.fmt, NULL, NULL, NULL); + if (err) + { + ConLog.Error("vdecDecodeAu: avformat_open_input() failed"); Emu.Pause(); + break; + } + err = avformat_find_stream_info(vdec.fmt, NULL); + if (err) + { + ConLog.Error("vdecDecodeAu: avformat_find_stream_info() failed"); + Emu.Pause(); + break; + } + if (!vdec.fmt->nb_streams) + { + ConLog.Error("vdecDecodeAu: no stream found"); + Emu.Pause(); + break; + } + vdec.ctx = vdec.fmt->streams[0]->codec; // TODO: check data + + AVCodec* codec = avcodec_find_decoder(vdec.ctx->codec_id); // ??? + if (!codec) + { + ConLog.Error("vdecDecodeAu: avcodec_find_decoder() failed"); + Emu.Pause(); + break; + } + + AVDictionary* opts = nullptr; + av_dict_set(&opts, "refcounted_frames", "1", 0); + { + SMutexGeneralLocker lock(g_mutex_avcodec_open2); + // not multithread-safe + err = avcodec_open2(vdec.ctx, codec, &opts); + } + if (err) + { + ConLog.Error("vdecDecodeAu: avcodec_open2() failed"); + Emu.Pause(); + break; + } + //vdec.ctx->flags |= CODEC_FLAG_TRUNCATED; + //vdec.ctx->flags2 |= CODEC_FLAG2_CHUNKS; + vdec.just_started = false; + } + + bool last_frame = false; + + while (true) + { + if (Emu.IsStopped()) + { + ConLog.Warning("vdecDecodeAu aborted"); return; } - - vdec.buf_size = err; + last_frame = av_read_frame(vdec.fmt, &au) < 0; + if (last_frame) + { + //break; + av_free(au.data); + au.data = NULL; + au.size = 0; + } - av_image_copy(vdec.out_data, vdec.linesize, (const u8**)(vdec.frame->data), vdec.frame->linesize, - vdec.ctx->pix_fmt, vdec.ctx->width, vdec.ctx->height);*/ - vdec.buf_size = a128(av_image_get_buffer_size(vdec.ctx->pix_fmt, vdec.ctx->width, vdec.ctx->height, 1)); + struct VdecFrameHolder : VdecFrame + { + VdecFrameHolder() + { + data = av_frame_alloc(); + } - vdec.userdata = task.userData; - vdec.has_picture = true; + ~VdecFrameHolder() + { + if (data) + { + av_frame_unref(data); + av_frame_free(&data); + } + } - Callback cb; - cb.SetAddr(vdec.cbFunc); - cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, 0, vdec.cbArg); - cb.Branch(false); + } frame; + + if (!frame.data) + { + ConLog.Error("vdecDecodeAu: av_frame_alloc() failed"); + Emu.Pause(); + break; + } + + int got_picture = 0; + + int decode = avcodec_decode_video2(vdec.ctx, frame.data, &got_picture, &au); + + if (decode <= 0) + { + if (!last_frame && decode < 0) + { + ConLog.Error("vdecDecodeAu: AU decoding error(0x%x)", decode); + break; + } + if (!got_picture && vdec.reader.size == 0) break; // video end? + } + + if (got_picture) + { + //ConLog.Write("got_picture (%d, vdec: pts=0x%llx, dts=0x%llx)", got_picture, au.pts, au.dts); + + frame.dts = vdec.last_dts; vdec.last_dts += 3003; // + duration??? + frame.pts = vdec.last_pts; vdec.last_pts += 3003; + frame.userdata = task.userData; + vdec.frames.Push(frame); // !!!!!!!! + frame.data = nullptr; // to prevent destruction + + vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg); + /*Callback cb; + cb.SetAddr(vdec.cbFunc); + cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg); + cb.Branch(false);*/ + } } - - ConLog.Write("Frame decoded (pts=0x%llx, dts=0x%llx, addr=0x%x, result=0x%x)", au.pts, au.dts, task.addr, decode); - Callback cb; + vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg); + /*Callback cb; cb.SetAddr(vdec.cbFunc); - cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, 0, vdec.cbArg); - cb.Branch(false); + cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg); + cb.Branch(false);*/ } break; @@ -238,15 +376,15 @@ u32 vdecOpen(VideoDecoder* data) case vdecSetFrameRate: { ConLog.Error("TODO: vdecSetFrameRate(%d)", task.frc); - return; } + break; default: ConLog.Error("Video Decoder error: unknown task(%d)", task.type); - return; } } + vdec.is_finished = true; ConLog.Warning("Video Decoder aborted"); }); @@ -331,7 +469,7 @@ int cellVdecClose(u32 handle) vdec->job.Push(VdecTask(vdecClose)); - while (!vdec->is_finished) + while (!vdec->is_finished || !vdec->frames.IsEmpty()) { if (Emu.IsStopped()) { @@ -341,6 +479,7 @@ int cellVdecClose(u32 handle) Sleep(1); } + if (vdec->vdecCb) Emu.GetCPU().RemoveThread(vdec->vdecCb->GetId()); Emu.GetIdManager().RemoveID(handle); return CELL_OK; } @@ -361,7 +500,7 @@ int cellVdecStartSeq(u32 handle) int cellVdecEndSeq(u32 handle) { - cellVdec.Log("cellVdecEndSeq(handle=%d)", handle); + cellVdec.Warning("cellVdecEndSeq(handle=%d)", handle); VideoDecoder* vdec; if (!Emu.GetIdManager().GetIDData(handle, vdec)) @@ -369,6 +508,28 @@ int cellVdecEndSeq(u32 handle) return CELL_VDEC_ERROR_ARG; } + /*if (!vdec->job.IsEmpty()) + { + Sleep(1); + return CELL_VDEC_ERROR_BUSY; // ??? + } + + if (!vdec->frames.IsEmpty()) + { + Sleep(1); + return CELL_VDEC_ERROR_BUSY; // ??? + }*/ + + while (!vdec->job.IsEmpty() || !vdec->frames.IsEmpty()) + { + if (Emu.IsStopped()) + { + ConLog.Warning("cellVdecEndSeq(%d) aborted", handle); + return CELL_OK; + } + Sleep(1); + } + vdec->job.Push(VdecTask(vdecEndSeq)); return CELL_OK; } @@ -399,7 +560,7 @@ int cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, const mem_ptr_t format, u32 out_addr) { - cellVdec.Warning("cellVdecGetPicture(handle=%d, format_addr=0x%x, out_addr=0x%x)", handle, format.GetAddr(), out_addr); + cellVdec.Log("cellVdecGetPicture(handle=%d, format_addr=0x%x, out_addr=0x%x)", handle, format.GetAddr(), out_addr); VideoDecoder* vdec; if (!Emu.GetIdManager().GetIDData(handle, vdec)) @@ -412,14 +573,16 @@ int cellVdecGetPicture(u32 handle, const mem_ptr_t format, u3 return CELL_VDEC_ERROR_FATAL; } - if (!vdec->has_picture) + if (vdec->frames.IsEmpty()) { return CELL_VDEC_ERROR_EMPTY; } if (out_addr) { - if (!Memory.IsGoodAddr(out_addr, vdec->buf_size)) + u32 buf_size = a128(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1)); + + if (!Memory.IsGoodAddr(out_addr, buf_size)) { return CELL_VDEC_ERROR_FATAL; } @@ -429,54 +592,47 @@ int cellVdecGetPicture(u32 handle, const mem_ptr_t format, u3 cellVdec.Error("cellVdecGetPicture: TODO: unknown formatType(%d)", (u32)format->formatType); return CELL_OK; } + if (format->colorMatrixType != CELL_VDEC_COLOR_MATRIX_TYPE_BT709) { cellVdec.Error("cellVdecGetPicture: TODO: unknown colorMatrixType(%d)", (u32)format->colorMatrixType); return CELL_OK; } - AVFrame& frame = *vdec->frame; + VdecFrame vf; - u8* buf = (u8*)malloc(vdec->buf_size); - if (!buf) - { - cellVdec.Error("cellVdecGetPicture: malloc failed (out of memory)"); - Emu.Pause(); - return CELL_OK; - } + vdec->frames.Pop(vf); + + AVFrame& frame = *vf.data; + + u8* buf = (u8*)malloc(buf_size); // TODO: zero padding bytes - int err = av_image_copy_to_buffer(buf, vdec->buf_size, frame.data, frame.linesize, vdec->ctx->pix_fmt, frame.width, frame.height, 1); + int err = av_image_copy_to_buffer(buf, buf_size, frame.data, frame.linesize, vdec->ctx->pix_fmt, frame.width, frame.height, 1); if (err < 0) { cellVdec.Error("cellVdecGetPicture: av_image_copy_to_buffer failed(%d)", err); Emu.Pause(); } - if (!Memory.CopyFromReal(out_addr, buf, vdec->buf_size)) + if (!Memory.CopyFromReal(out_addr, buf, buf_size)) { cellVdec.Error("cellVdecGetPicture: data copying failed"); Emu.Pause(); } - /* - u32 size0 = frame.linesize[0] * frame.height; - u32 size1 = frame.linesize[1] * frame.height / 2; - u32 size2 = frame.linesize[2] * frame.height / 2; - ConLog.Write("*** size0=0x%x, size1=0x%x, size2=0x%x, buf_size=0x%x (res=0x%x)", size0, size1, size2, vdec->buf_size, err); - */ - + av_frame_unref(vf.data); + av_frame_free(&vf.data); free(buf); } - vdec->has_picture = false; return CELL_OK; } int cellVdecGetPicItem(u32 handle, mem32_t picItem_ptr) { - cellVdec.Warning("cellVdecGetPicItem(handle=%d, picItem_ptr_addr=0x%x)", handle, picItem_ptr.GetAddr()); + cellVdec.Log("cellVdecGetPicItem(handle=%d, picItem_ptr_addr=0x%x)", handle, picItem_ptr.GetAddr()); VideoDecoder* vdec; if (!Emu.GetIdManager().GetIDData(handle, vdec)) @@ -489,36 +645,47 @@ int cellVdecGetPicItem(u32 handle, mem32_t picItem_ptr) return CELL_VDEC_ERROR_FATAL; } - if (!vdec->has_picture) + VdecFrame& vf = vdec->frames.Peek(); + + if (vdec->frames.IsEmpty()) { + Sleep(1); return CELL_VDEC_ERROR_EMPTY; } - mem_ptr_t info(vdec->memAddr); + AVFrame& frame = *vf.data; + + mem_ptr_t info(vdec->memAddr + vdec->memBias); + + vdec->memBias += 512; + if (vdec->memBias + 512 > vdec->memSize) + { + vdec->memBias = 0; + } info->codecType = vdec->type; info->startAddr = 0x00000123; // invalid value (no address for picture) - info->size = vdec->buf_size; + info->size = a128(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1)); info->auNum = 1; - info->auPts[0].lower = vdec->pts; - info->auPts[0].upper = vdec->pts >> 32; + info->auPts[0].lower = vf.pts; + info->auPts[0].upper = vf.pts >> 32; info->auPts[1].lower = 0xffffffff; info->auPts[1].upper = 0xffffffff; - info->auDts[0].lower = vdec->dts; - info->auDts[0].upper = vdec->dts >> 32; + info->auDts[0].lower = vf.dts; + info->auDts[0].upper = vf.dts >> 32; info->auDts[1].lower = 0xffffffff; info->auDts[1].upper = 0xffffffff; - info->auUserData[0] = vdec->userdata; + info->auUserData[0] = vf.userdata; info->auUserData[1] = 0; info->status = CELL_OK; info->attr = CELL_VDEC_PICITEM_ATTR_NORMAL; - info->picInfo_addr = vdec->memAddr + sizeof(CellVdecPicItem); + info->picInfo_addr = info.GetAddr() + sizeof(CellVdecPicItem); - mem_ptr_t avc(vdec->memAddr + sizeof(CellVdecPicItem)); + mem_ptr_t avc(info.GetAddr() + sizeof(CellVdecPicItem)); - avc->horizontalSize = vdec->frame->width; // ??? - avc->verticalSize = vdec->frame->height; - switch (vdec->frame->pict_type) + avc->horizontalSize = frame.width; + avc->verticalSize = frame.height; + switch (frame.pict_type) { case AV_PICTURE_TYPE_I: avc->pictureType[0] = CELL_VDEC_AVC_PCT_I; break; case AV_PICTURE_TYPE_P: avc->pictureType[0] = CELL_VDEC_AVC_PCT_P; break; @@ -590,5 +757,6 @@ void cellVdec_init() cellVdec.AddFunc(0x17c702b9, cellVdecGetPicItem); cellVdec.AddFunc(0xe13ef6fc, cellVdecSetFrameRate); + av_register_all(); avcodec_register_all(); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.h b/rpcs3/Emu/SysCalls/Modules/cellVdec.h index f2ca2320fd..96534cdbe2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.h @@ -679,6 +679,14 @@ struct VdecTask } }; +struct VdecFrame +{ + AVFrame* data; + u64 dts; + u64 pts; + u64 userdata; +}; + int vdecRead(void* opaque, u8* buf, int buf_size); class VideoDecoder @@ -688,19 +696,11 @@ public: u32 id; volatile bool is_running; volatile bool is_finished; + bool just_started; - AVCodec* codec; AVCodecContext* ctx; AVFormatContext* fmt; - AVFrame* frame; - AVDictionary* opts; u8* io_buf; - u32 buf_size; - u64 pts; - u64 dts; - u64 pos; - u64 userdata; - volatile bool has_picture; struct VideoReader { @@ -708,51 +708,39 @@ public: u32 size; } reader; + SQueue frames; + const CellVdecCodecType type; const u32 profile; const u32 memAddr; const u32 memSize; const u32 cbFunc; const u32 cbArg; + u32 memBias; + + VdecTask task; // current task variable + u64 last_pts, last_dts; + + CPUThread* vdecCb; VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, u32 func, u32 arg) : type(type) , profile(profile) , memAddr(addr) , memSize(size) + , memBias(0) , cbFunc(func) , cbArg(arg) , is_finished(false) , is_running(false) - , has_picture(false) - , pos(0) + , just_started(false) + , ctx(nullptr) + , vdecCb(nullptr) { - codec = avcodec_find_decoder(AV_CODEC_ID_H264); + AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_H264); if (!codec) { - ConLog.Error("VideoDecoder(): avcodec_find_decoder failed"); - Emu.Pause(); - return; - } - ctx = avcodec_alloc_context3(codec); - if (!ctx) - { - ConLog.Error("VideoDecoder(): avcodec_alloc_context3 failed"); - Emu.Pause(); - return; - } - opts = nullptr; - int err = avcodec_open2(ctx, codec, &opts); - if (err) // TODO: not multithread safe - { - ConLog.Error("VideoDecoder(): avcodec_open2 failed(%d)", err); - Emu.Pause(); - return; - } - frame = av_frame_alloc(); - if (!frame) - { - ConLog.Error("VideoDecoder(): av_frame_alloc failed"); + ConLog.Error("VideoDecoder(): avcodec_find_decoder(H264) failed"); Emu.Pause(); return; } @@ -771,23 +759,29 @@ public: Emu.Pause(); return; } - //memset(&out_data, 0, sizeof(out_data)); - //memset(&linesize, 0, sizeof(linesize)); } ~VideoDecoder() { - if (io_buf) av_free(io_buf); - if (fmt) - { - avformat_free_context(fmt); - } - if (frame) av_frame_free(&frame); if (ctx) { + for (u32 i = frames.GetCount() - 1; ~i; i--) + { + VdecFrame& vf = frames.Peek(i); + av_frame_unref(vf.data); + av_frame_free(&vf.data); + } avcodec_close(ctx); - av_free(ctx); + avformat_close_input(&fmt); + } + if (fmt) + { + if (io_buf) + { + av_free(io_buf); + } + if (fmt->pb) av_free(fmt->pb); + avformat_free_context(fmt); } - //if (out_data[0]) av_freep(out_data[0]); } }; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp b/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp index 8073080424..92ead9c6a4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp @@ -77,7 +77,7 @@ int cellVpostClose(u32 handle) int cellVpostExec(u32 handle, const u32 inPicBuff_addr, const mem_ptr_t ctrlParam, u32 outPicBuff_addr, mem_ptr_t picInfo) { - cellVpost.Warning("cellVpostExec(handle=0x%x, inPicBuff_addr=0x%x, ctrlParam_addr=0x%x, outPicBuff_addr=0x%x, picInfo_addr=0x%x)", + cellVpost.Log("cellVpostExec(handle=0x%x, inPicBuff_addr=0x%x, ctrlParam_addr=0x%x, outPicBuff_addr=0x%x, picInfo_addr=0x%x)", handle, inPicBuff_addr, ctrlParam.GetAddr(), outPicBuff_addr, picInfo.GetAddr()); VpostInstance* vpost; @@ -139,31 +139,34 @@ int cellVpostExec(u32 handle, const u32 inPicBuff_addr, const mem_ptr_treserved1 = 0; picInfo->reserved2 = 0; - u8* pY = (u8*)malloc(w*h); + u8* pY = (u8*)malloc(w*h); // color planes u8* pU = (u8*)malloc(w*h/4); u8* pV = (u8*)malloc(w*h/4); - u32* res = (u32*)malloc(w*h*4); + u32* res = (u32*)malloc(w*h*4); // RGBA interleaved output const u8 alpha = ctrlParam->outAlpha; if (!Memory.CopyToReal(pY, inPicBuff_addr, w*h)) { cellVpost.Error("cellVpostExec: data copying failed(pY)"); + Emu.Pause(); } if (!Memory.CopyToReal(pU, inPicBuff_addr + w*h, w*h/4)) { cellVpost.Error("cellVpostExec: data copying failed(pU)"); + Emu.Pause(); } if (!Memory.CopyToReal(pV, inPicBuff_addr + w*h + w*h/4, w*h/4)) { cellVpost.Error("cellVpostExec: data copying failed(pV)"); + Emu.Pause(); } for (u32 i = 0; i < h; i++) for (u32 j = 0; j < w; j++) { - float Cr = pV[(i/2)*(w/2)+j/2]; - float Cb = pU[(i/2)*(w/2)+j/2]; + float Cr = pV[(i/2)*(w/2)+j/2] - 128; + float Cb = pU[(i/2)*(w/2)+j/2] - 128; float Y = pY[i*w+j]; int R = Y + 1.5701f * Cr; diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp new file mode 100644 index 0000000000..cb2b3bb547 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -0,0 +1,478 @@ +#include "stdafx.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" +#include "libmixer.h" + +void libmixer_init(); +Module libmixer("libmixer", libmixer_init); + +int cellAANAddData(u32 handle, u32 port, u32 offset, u32 addr, u32 samples) +{ + libmixer.Error("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr=0x%x, samples=0x%x)", + handle, port, offset, addr, samples); + return CELL_OK; +} + +int cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) +{ + libmixer.Error("cellAANConnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcrPortNo=0x%x)", + receive, receivePortNo, source, sourcePortNo); + return 0; +} + +int cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) +{ + libmixer.Error("cellAANDisconnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcrPortNo=0x%x)", + receive, receivePortNo, source, sourcePortNo); + return 0; +} + +/*int cellSSPlayerCreate(CellAANHandle *handle, CellSSPlayerConfig *config) +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSSPlayerRemove(CellAANHandle handle) +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSSPlayerSetWave() //CellAANHandle handle, CellSSPlayerWaveParam *waveInfo, CellSSPlayerCommonParam *commonInfo //mem_class_t waveInfo +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSSPlayerPlay() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSSPlayerStop() //CellAANHandle handle, u32 mode +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSSPlayerSetParam() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +s32 cellSSPlayerGetState() //CellAANHandle handle +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +}*/ + +int cellSurMixerCreate(const mem_ptr_t config) +{ + libmixer.Error("cellSurMixerCreate(config_addr=0x%x)", config.GetAddr()); + return CELL_OK; +} + +int cellSurMixerGetAANHandle(mem32_t handle) +{ + libmixer.Error("cellSurMixerGetAANHandle(handle_addr=0x%x)", handle.GetAddr()); + return CELL_OK; +} + +int cellSurMixerChStripGetAANPortNo(mem32_t port, u32 type, u32 index) +{ + libmixer.Error("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x)", port.GetAddr(), type, index); + return CELL_OK; +} + +int cellSurMixerSetNotifyCallback(u32 func, u32 arg) +{ + libmixer.Error("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x)", func, arg); + return CELL_OK; +} + +int cellSurMixerRemoveNotifyCallback(u32 func) +{ + libmixer.Error("cellSurMixerSetNotifyCallback(func_addr=0x%x)", func); + return CELL_OK; +} + +int cellSurMixerStart() +{ + libmixer.Error("cellSurMixerStart()"); + return CELL_OK; +} + +int cellSurMixerSetParameter(u32 param, float value) +{ + libmixer.Error("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); + return CELL_OK; +} + +int cellSurMixerFinalize() +{ + libmixer.Error("cellSurMixerFinalize()"); + return CELL_OK; +} + +/*int cellSurMixerSurBusAddData() //u32 busNo, u32 offset, float *addr, u32 samples +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSurMixerChStripSetParameter() //u32 type, u32 index, CellSurMixerChStripParam *param +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSurMixerPause() //u32 switch +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSurMixerGetCurrentBlockTag() //u64 *tag +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSurMixerGetTimestamp() //u64 tag, u64 *stamp +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +void cellSurMixerBeep(); //void *arg + +float cellSurMixerUtilGetLevelFromDB() //float dB +{ + UNIMPLEMENTED_FUNC(libmixer); + return CELL_OK; //it's NOT real value + //TODO; +} + +float cellSurMixerUtilGetLevelFromDBIndex() //int index +{ + UNIMPLEMENTED_FUNC(libmixer); + return CELL_OK; //it's NOT real value + //TODO; +} + +float cellSurMixerUtilNoteToRatio() //unsigned char refNote, unsigned char note +{ + UNIMPLEMENTED_FUNC(libmixer); + return CELL_OK; //it's NOT real value + //TODO +}*/ + +void libmixer_init() +{ + static const u64 cellAANAddData_table[] = { + // TODO + 0xffffffff7c691b78, + 0xffffffff7c0802a6, + 0xfffffffff821ff91, + 0xfffffffff8010080, + 0xffffffff7c802378, + 0xffffffff7caa2b78, + 0xffffffff81690000, + 0xffffffff7c050378, + 0xffffffff7cc43378, + 0xffffffff7d465378, + 0xffffffff812b0030, + 0xffffffff80090000, + 0xfffffffff8410028, + 0xffffffff7c0903a6, + 0xffffffff80490004, + 0xffffffff4e800421, + 0xffffffffe8410028, + 0xffffffffe8010080, + 0xffffffff7c6307b4, + 0xffffffff7c0803a6, + 0xffffffff38210070, + 0xffffffff4e800020, + 0 + }; + libmixer.AddFuncSub(cellAANAddData_table, "cellAANAddData", cellAANAddData); + + u64 cellAANConnect_table[39] = { + 0xfffffffff821ff71, + 0xffffffff7c0802a6, + 0xffffffff2f830000, + 0xfffffffff80100a0, + 0xffffffff3c008031, + 0xffffffff7c691b78, + 0xffffffff7c8a2378, + 0xffffffff60000003, + 0xffffff00409e0018, // bne + 0xffffffff7c0307b4, + 0xffffffffe80100a0, + 0xffffffff38210090, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + 0xffffffff2f850000, + 0xffffffff78630020, + 0xffffffff38810070, + 0xffffff00419effe0, // beq + 0xffffffff81690000, + 0xffffffff38000001, + 0xffffffff91210074, + 0xffffffff90a10070, + 0xffffffff90c10078, + 0xffffffff9141007c, + 0xffffffff812b0018, // [24] + 0xffffffff90010080, + 0xffffffff80090000, + 0xfffffffff8410028, + 0xffffffff7c0903a6, + 0xffffffff80490004, + 0xffffffff4e800421, + 0xffffffffe8410028, + 0xffffffff7c601b78, + 0xffffffff7c0307b4, + 0xffffffffe80100a0, + 0xffffffff38210090, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + 0, // [38] + }; + libmixer.AddFuncSub(cellAANConnect_table, "cellAANConnect", cellAANConnect); + cellAANConnect_table[24] = 0xffffffff812b001c; + libmixer.AddFuncSub(cellAANConnect_table, "cellAANDisconnect", cellAANDisconnect); + + static const u64 cellAANAddData_table1[] = { + // TODO + 0xffffffff7c691b78, + 0xffffffff7c0802a6, + 0xfffffffff821ff91, + 0xfffffffff8010080, + 0xffffffff7c802378, + 0xffffffff7caa2b78, + 0xffffffff81690000, + 0xffffffff7c050378, + 0xffffffff7cc43378, + 0xffffffff78630020, // clrldi r3,r3,32 + 0xffffffff7d465378, + 0xffffffff812b0030, + 0xffffffff80090000, + 0xfffffffff8410028, + 0xffffffff7c0903a6, + 0xffffffff80490004, + 0xffffffff4e800421, + 0xffffffffe8410028, + 0xffffffffe8010080, + 0xffffffff7c6307b4, + 0xffffffff7c0803a6, + 0xffffffff38210070, + 0xffffffff4e800020, + 0 + }; + libmixer.AddFuncSub(cellAANAddData_table1, "cellAANAddData(1)", cellAANAddData); + + static const u64 cellSurMixerCreate_table[] = { + 0xffffffff2f830000, + 0xffffffff7c0802a6, + 0xfffffffff821ff51, + 0xfffffffffbc100a0, + 0xfffffffffb210078, + 0xfffffffffb410080, + 0xfffffffffb610088, + 0xfffffffffb810090, + 0xfffffffffba10098, + 0xfffffffffbe100a8, + 0xfffffffff80100c0, + 0xffffffff7c7e1b78, + 0xf000000040000000, // bne + 0xffffffff3fe08031, + 0xffffffff63ff0003, + 0xffffffffe80100c0, + 0xffffffff7fe307b4, + 0xffffffffeb210078, + 0xffffffffeb410080, + 0xffffffff7c0803a6, + 0xffffffffeb610088, + 0xffffffffeb810090, + 0xffffffffeba10098, + 0xffffffffebc100a0, + 0xffffffffebe100a8, + 0xffffffff382100b0, + 0 + }; + libmixer.AddFuncSub(cellSurMixerCreate_table, "cellSurMixerCreate", cellSurMixerCreate); + + static const u64 cellSurMixerGetAANHandle_table[] = { + // first instruction ignored + 0xffffffff3d607fce, + 0xffffffff616bfffe, + 0xffffffff812a0018, + 0xffffffff7d2afe70, + 0xffffffff91230000, + 0xffffffff7d404a78, + 0xffffffff7c005050, + 0xffffffff7c00fe70, + 0xffffffff7c035838, + 0xffffffff3c638031, + 0xffffffff38630002, + 0xffffffff7c6307b4, + 0xffffffff4e800020, + 0 + }; + libmixer.AddFuncSub(cellSurMixerGetAANHandle_table, "cellSurMixerGetAANHandle", cellSurMixerGetAANHandle); + + static const u64 cellSurMixerChStripGetAANPortNo_table[] = { + // first instruction ignored + 0xffffffff7c661b78, + 0xffffffff3c608031, + 0xffffffff78c60020, + 0xffffffff78840020, + 0xffffffff60630002, + 0xffffffff80090018, + 0xffffffff78a50020, + 0xffffffff2f800000, + 0xffffffff4d9e0020, + 0xffffffff78030020, + 0xf000000040000000, // b + 0 + }; + libmixer.AddFuncSub(cellSurMixerChStripGetAANPortNo_table, "cellSurMixerChStripGetAANPortNo", cellSurMixerChStripGetAANPortNo); + + static const u64 cellSurMixerSetNotifyCallback_table[] = { + // first instruction ignored + 0xffffffff7c0802a6, + 0xfffffffff821ff81, + 0xfffffffff8010090, + 0xffffffff7c6b1b78, + 0xffffffff3c608031, + 0xffffffff812a0018, + 0xffffffff7c882378, + 0xffffffff60630003, + 0xffffffff2f890000, + 0xffffffff2f0b0000, + 0xffffff00409e0020, // bne + 0xffffffff3c608031, + 0xffffffff60630002, + 0xffffffffe8010090, + 0xffffffff7c6307b4, + 0xffffffff38210080, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + 0xffffff00419affec, // beq + 0xf0000000800a001c, // lwz + 0xffffffff79290020, + 0xffffffff38810070, + 0xffffffff2f800000, + 0xffffffff7d234b78, + 0 + }; + libmixer.AddFuncSub(cellSurMixerSetNotifyCallback_table, "cellSurMixerSetNotifyCallback", cellSurMixerSetNotifyCallback); + + static const u64 cellSurMixerRemoveNotifyCallback_table[] = { + // first instruction ignored + 0xffffffff7c0802a6, + 0xfffffffff821ff81, + 0xfffffffff8010090, + 0xffffffff7c6a1b78, + 0xffffffff3d208031, + 0xffffffff806b0018, + 0xffffffff61290002, + 0xffffffff2f830000, + 0xf0000000409e0018, // bne + 0xffffffffe8010090, + 0xffffffff7d2307b4, + 0xffffffff38210080, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + 0 + }; + libmixer.AddFuncSub(cellSurMixerRemoveNotifyCallback_table, "cellSurMixerRemoveNotifyCallback", cellSurMixerRemoveNotifyCallback); + + static const u64 cellSurMixerStart_table[] = { + 0xfffffffff821ff71, + 0xffffffff7c0802a6, + 0xfffffffffbc10080, + 0xf000000083c20000, // lwz + 0xfffffffff80100a0, + 0xfffffffffba10078, + 0xfffffffffbe10088, + 0xffffffff801e0018, + 0xffffffff2f800000, + 0xf0000000409e002c, // bne + 0xffffffff3fe08031, + 0xffffffff63ff0002, + 0xffffffffe80100a0, + 0xffffffff7fe307b4, + 0xffffffffeba10078, + 0xffffffffebc10080, + 0xffffffff7c0803a6, + 0xffffffffebe10088, + 0xffffffff38210090, + 0xffffffff4e800020, + 0 + }; + libmixer.AddFuncSub(cellSurMixerStart_table, "cellSurMixerStart", cellSurMixerStart); + + static const u64 cellSurMixerSetParameter_table[] = { + 0xfffffffff821ff81, + 0xffffffff7c0802a6, + 0xfffffffffbc10070, + 0xfffffffffc000890, + 0xf000000083c28250, // lwz + 0xffffffff3d208031, + 0xfffffffff8010090, + 0xfffffffffbe10078, + 0xffffffff61290002, + 0xffffffff7c7f1b78, + 0xffffffff801e0018, + 0xffffffff2f800000, + 0xffff0000409e0020, // bne + 0xffffffffe8010090, + 0xffffffff7d2307b4, + 0xffffffffebc10070, + 0xffffffffebe10078, + 0xffffffff7c0803a6, + 0xffffffff38210080, + 0xffffffff4e800020, + 0xffffffff801e001c, + 0xffffffff2b03001f, + 0xffffffff2f800000, + 0xffff0000419cffd8, // blt + 0xffffffff2b83002b, + 0xffff000040990008, // ble + 0xffff0000409d0054, // ble + 0 + }; + libmixer.AddFuncSub(cellSurMixerSetParameter_table, "cellSurMixerSetParameter", cellSurMixerSetParameter); + + static const u64 cellSurMixerFinalize_table[] = { + 0xfffffffff821ff91, + 0xffffffff7c0802a6, + 0xfffffffff8010080, + 0xffffff004bfffde1, // bl + 0xffffffffe8010080, + 0xffffffff38600000, + 0xffffffff38210070, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + 0xfffffffff821ff71, + 0xffffffff7c0802a6, + 0xfffffffffba10078, + 0xf000000083a28250, // lwz + 0xfffffffff80100a0, + 0xffffffff817d0018, + 0xffffffff7d635b78, + 0xffffffff812b0000, + 0xffffffff81490000, + 0xffffffff800a0000, + 0xfffffffff8410028, + 0xffffffff7c0903a6, + 0xffffffff804a0004, + 0xffffffff4e800421, + 0 + }; + libmixer.AddFuncSub(cellSurMixerFinalize_table, "cellSurMixerFinalize", cellSurMixerFinalize); +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.h b/rpcs3/Emu/SysCalls/Modules/libmixer.h new file mode 100644 index 0000000000..24c30c7b70 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.h @@ -0,0 +1,63 @@ +#pragma once + + +//Callback Functions +typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples); //Currently unused. + +//libmixer datatypes +typedef void * CellAANHandle; + +struct CellSSPlayerConfig +{ + be_t channels; + be_t outputMode; +}; + +struct CellSSPlayerWaveParam +{ + void *addr; + be_t format; + be_t samples; + be_t loopStartOffset; + be_t startOffset; +}; + +struct CellSSPlayerCommonParam +{ + be_t loopMode; + be_t attackMode; +}; + +struct CellSurMixerPosition +{ + be_t x; + be_t y; + be_t z; +}; + +struct CellSSPlayerRuntimeInfo +{ + be_t level; + be_t speed; + CellSurMixerPosition position; +}; + +struct CellSurMixerConfig +{ + be_t priority; + be_t chStrips1; + be_t chStrips2; + be_t chStrips6; + be_t chStrips8; +}; + +struct CellSurMixerChStripParam +{ + be_t param; + void *attribute; + be_t dBSwitch; + be_t floatVal; + be_t intVal; +}; + +CellSSPlayerWaveParam current_SSPlayerWaveParam; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp index 2198525289..872c25556d 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp @@ -110,7 +110,7 @@ int sceNpTrophyRegisterContext(u32 context, u32 handle, u32 statusCb_addr, u32 a if (!Memory.IsGoodAddr(statusCb_addr)) return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT; if (options & (~(u64)1)) - SCE_NP_TROPHY_ERROR_NOT_SUPPORTED; + return SCE_NP_TROPHY_ERROR_NOT_SUPPORTED; if (context >= s_npTrophyInstance.contexts.size()) return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT; // TODO: There are other possible errors @@ -181,9 +181,32 @@ int sceNpTrophyAbortHandle() return CELL_OK; } -int sceNpTrophyGetGameInfo() +int sceNpTrophyGetGameInfo(u32 context, u32 handle, mem_ptr_t details, mem_ptr_t data) { - UNIMPLEMENTED_FUNC(sceNpTrophy); + sceNpTrophy.Warning("sceNpTrophyGetGameInfo(context=%d, handle=%d, details_addr=0x%x, data_addr=0x%x)", + context, handle, details.GetAddr(), data.GetAddr()); + + if (!s_npTrophyInstance.m_bInitialized) + return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; + if (!details.IsGood() || !data.IsGood()) + return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT; + // TODO: There are other possible errors + + // sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context]; + + // TODO: This data is faked, implement a XML reader and get it from TROP.SFM + memcpy(details->title, "Trophy Set", SCE_NP_TROPHY_NAME_MAX_SIZE); + memcpy(details->description, "Hey! Implement a XML reader, and load the description from TROP.SFM", SCE_NP_TROPHY_DESCR_MAX_SIZE); + details->numTrophies = 0; + details->numPlatinum = 0; + details->numGold = 0; + details->numSilver = 0; + details->numBronze = 0; + data->unlockedTrophies = 0; + data->unlockedPlatinum = 0; + data->unlockedGold = 0; + data->unlockedSilver = 0; + data->unlockedBronze = 0; return CELL_OK; } @@ -229,6 +252,8 @@ int sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, mem_ptr_tname, "Some Trophy", SCE_NP_TROPHY_NAME_MAX_SIZE); memcpy(details->description, "Hey! Implement a XML reader, and load the description from TROP.SFM", SCE_NP_TROPHY_DESCR_MAX_SIZE); details->hidden = false; diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h index 2bcf4b15c8..f57f18679b 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h @@ -57,7 +57,7 @@ enum SCE_NP_TROPHY_DESCR_MAX_SIZE = 1024, }; -enum +enum SceNpTrophyGrade { SCE_NP_TROPHY_GRADE_UNKNOWN = 0, SCE_NP_TROPHY_GRADE_PLATINUM = 1, @@ -66,6 +66,27 @@ enum SCE_NP_TROPHY_GRADE_BRONZE = 4, }; +struct SceNpTrophyGameDetails +{ + u32 numTrophies; + u32 numPlatinum; + u32 numGold; + u32 numSilver; + u32 numBronze; + u8 title[SCE_NP_TROPHY_TITLE_MAX_SIZE]; + u8 description[SCE_NP_TROPHY_GAME_DESCR_MAX_SIZE]; + u8 reserved[4]; +}; + +struct SceNpTrophyGameData +{ + u32 unlockedTrophies; + u32 unlockedPlatinum; + u32 unlockedGold; + u32 unlockedSilver; + u32 unlockedBronze; +}; + struct SceNpTrophyDetails { s32 trophyId; // SceNpTrophyId diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index cf05cbf3b7..07c7c73a8e 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -270,6 +270,25 @@ int cellFsAioFinish(mem8_ptr_t mount_point) return CELL_OK; } +int cellFsReadWithOffset(u32 fd, u64 offset, u32 buf_addr, u64 buffer_size, mem64_t nread) +{ + sys_fs.Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf_addr=0x%x, buffer_size=%lld nread=0x%llx)", + fd, offset, buf_addr, buffer_size, nread.GetAddr()); + + int ret; + MemoryAllocator> oldPos, newPos; + ret = cellFsLseek(fd, 0, CELL_SEEK_CUR, oldPos.GetAddr()); // Save the current position + if (ret) return ret; + ret = cellFsLseek(fd, offset, CELL_SEEK_SET, newPos.GetAddr()); // Move to the specified offset + if (ret) return ret; + ret = cellFsRead(fd, buf_addr, buffer_size, nread.GetAddr()); // Read the file + if (ret) return ret; + ret = cellFsLseek(fd, Memory.Read64(oldPos.GetAddr()), CELL_SEEK_SET, newPos.GetAddr()); // Return to the old position + if (ret) return ret; + + return CELL_OK; +} + void sys_fs_init() { sys_fs.AddFunc(0x718bf5f8, cellFsOpen); @@ -295,5 +314,6 @@ void sys_fs_init() sys_fs.AddFunc(0x9f951810, cellFsAioFinish); sys_fs.AddFunc(0x1a108ab7, cellFsGetBlockSize); sys_fs.AddFunc(0xaa3b4bcd, cellFsGetFreeSize); + sys_fs.AddFunc(0x0d5b4a14, cellFsReadWithOffset); aio_init = false; } diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp index 3b83186840..a171925f52 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp @@ -2,25 +2,119 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" +#include "sys_net.h" + +#ifdef _WIN32 +#include +#elif +#include +#include +#endif + void sys_net_init(); Module sys_net((u16)0x0000, sys_net_init); -int accept() +mem32_t g_lastError(NULL); + + +// Auxiliary Functions +int inet_pton4(const char *src, char *dst) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + const char digits[] = "0123456789"; + int saw_digit, octets, ch; + unsigned char tmp[4], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + unsigned int n = *tp * 10 + (pch - digits); + + if (n > 255) + return (0); + *tp = n; + if (! saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return 0; + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return 0; + + memcpy(dst, tmp, 4); + return 1; } -int bind() +int inet_pton(int af, const char *src, char *dst) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + switch (af) { + case AF_INET: + return (inet_pton4(src, dst)); + + default: + errno = EAFNOSUPPORT; + return -1; + } } -int connect() +s32 getLastError() { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; +#ifdef _WIN32 + s32 ret = WSAGetLastError(); + if (ret > 10000 && ret < 11000) + return ret % 10000; + else + return -1; +#else + return errno; +#endif +} + + +// Functions +int sys_net_accept(s32 s, mem_ptr_t addr, mem32_t paddrlen) +{ + sys_net.Warning("accept(s=%d, family_addr=0x%x, paddrlen=0x%x)", s, addr.GetAddr(), paddrlen.GetAddr()); + sockaddr _addr; + memcpy(&_addr, Memory.VirtualToRealAddr(addr.GetAddr()), sizeof(sockaddr)); + _addr.sa_family = addr->sa_family; + s32 *_paddrlen = (s32 *)Memory.VirtualToRealAddr(paddrlen.GetAddr()); + int ret = accept(s, &_addr, _paddrlen); + g_lastError = getLastError(); + return ret; +} + +int sys_net_bind(s32 s, mem_ptr_t family, u32 addrlen) +{ + sys_net.Warning("bind(s=%d, family_addr=0x%x, addrlen=%u)", s, family.GetAddr(), addrlen); + sockaddr _family; + memcpy(&_family, Memory.VirtualToRealAddr(family.GetAddr()), sizeof(sockaddr)); + _family.sa_family = family->sa_family; + int ret = bind(s, &_family, addrlen); + g_lastError = getLastError(); + return ret; +} + +int sys_net_connect(s32 s, mem_ptr_t family, u32 addrlen) +{ + sys_net.Warning("connect(s=%d, family_addr=0x%x, addrlen=%u)", s, family.GetAddr(), addrlen); + sockaddr _family; + memcpy(&_family, Memory.VirtualToRealAddr(family.GetAddr()), sizeof(sockaddr)); + _family.sa_family = family->sa_family; + int ret = connect(s, &_family, addrlen); + g_lastError = getLastError(); + return ret; } int gethostbyaddr() @@ -101,10 +195,12 @@ int inet_ntop() return CELL_OK; } -int inet_pton() +int sys_net_inet_pton(s32 af, u32 src_addr, u32 dst_addr) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("inet_pton(af=%d, src_addr=0x%x, dst_addr=0x%x)", af, src_addr, dst_addr); + char *src = (char *)Memory.VirtualToRealAddr(src_addr); + char *dst = (char *)Memory.VirtualToRealAddr(dst_addr); + return inet_pton(af, src, dst); } int listen() @@ -113,16 +209,28 @@ int listen() return CELL_OK; } -int recv() +int sys_net_recv(s32 s, u32 buf_addr, u32 len, s32 flags) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("recv(s=%d, buf_addr=0x%x, len=%d, flags=0x%x)", s, buf_addr, len, flags); + char *buf = (char *)Memory.VirtualToRealAddr(buf_addr); + int ret = recv(s, buf, len, flags); + g_lastError = getLastError(); + return ret; } -int recvfrom() +int sys_net_recvfrom(s32 s, u32 buf_addr, u32 len, s32 flags, mem_ptr_t addr, mem32_t paddrlen) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("recvfrom(s=%d, buf_addr=0x%x, len=%u, flags=0x%x, addr_addr=0x%x, paddrlen=0x%x)", + s, buf_addr, len, flags, addr.GetAddr(), paddrlen.GetAddr()); + + char *_buf_addr = (char *)Memory.VirtualToRealAddr(buf_addr); + sockaddr _addr; + memcpy(&_addr, Memory.VirtualToRealAddr(addr.GetAddr()), sizeof(sockaddr)); + _addr.sa_family = addr->sa_family; + s32 *_paddrlen = (s32 *)Memory.VirtualToRealAddr(paddrlen.GetAddr()); + int ret = recvfrom(s, _buf_addr, len, flags, &_addr, _paddrlen); + g_lastError = getLastError(); + return ret; } int recvmsg() @@ -131,10 +239,13 @@ int recvmsg() return CELL_OK; } -int send() +int sys_net_send(s32 s, u32 buf_addr, u32 len, s32 flags) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("send(s=%d, buf_addr=0x%x, len=%d, flags=0x%x)", s, buf_addr, len, flags); + char *buf = (char *)Memory.VirtualToRealAddr(buf_addr); + int ret = send(s, buf, len, flags); + g_lastError = getLastError(); + return ret; } int sendmsg() @@ -143,34 +254,51 @@ int sendmsg() return CELL_OK; } -int sendto() +int sys_net_sendto(s32 s, u32 buf_addr, u32 len, s32 flags, mem_ptr_t addr, u32 addrlen) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("sendto(s=%d, buf_addr=0x%x, len=%u, flags=0x%x, addr=0x%x, addrlen=%u)", + s, buf_addr, len, flags, addr.GetAddr(), addrlen); + + char *_buf_addr = (char *)Memory.VirtualToRealAddr(buf_addr); + sockaddr _addr; + memcpy(&_addr, Memory.VirtualToRealAddr(addr.GetAddr()), sizeof(sockaddr)); + _addr.sa_family = addr->sa_family; + int ret = sendto(s, _buf_addr, len, flags, &_addr, addrlen); + g_lastError = getLastError(); + return ret; } -int setsockopt() +int sys_net_setsockopt(s32 s, s32 level, s32 optname, u32 optval_addr, u32 optlen) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("socket(s=%d, level=%d, optname=%d, optval_addr=0x%x, optlen=%u)", s, level, optname, optval_addr, optlen); + char *_optval_addr = (char *)Memory.VirtualToRealAddr(optval_addr); + int ret = setsockopt(s, level, optname, _optval_addr, optlen); + g_lastError = getLastError(); + return ret; } -int shutdown() +int sys_net_shutdown(s32 s, s32 how) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("shutdown(s=%d, how=%d)", s, how); + int ret = shutdown(s, how); + g_lastError = getLastError(); + return ret; } -int socket() +int sys_net_socket(s32 family, s32 type, s32 protocol) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("socket(family=%d, type=%d, protocol=%d", family, type, protocol); + int ret = socket(family, type, protocol); + g_lastError = getLastError(); + return ret; } -int socketclose() +int sys_net_socketclose(s32 s) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("socket(s=%d)", s); + int ret = closesocket(s); + g_lastError = getLastError(); + return ret; } int socketpoll() @@ -185,9 +313,17 @@ int socketselect() return CELL_OK; } -int sys_net_initialize_network_ex() +int sys_net_initialize_network_ex(mem_ptr_t param) { - UNIMPLEMENTED_FUNC(sys_net); + sys_net.Warning("sys_net_initialize_network_ex(param_addr=0x%x)", param.GetAddr()); + g_lastError.SetAddr(Memory.Alloc(4, 1)); +#ifdef _WIN32 + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD(1,1); + WSAStartup(wVersionRequested, &wsaData); +#elif + // TODO ? +#endif return CELL_OK; } @@ -245,10 +381,10 @@ int sys_net_show_nameserver() return CELL_OK; } -int _sys_net_errno_loc() +s32 _sys_net_errno_loc() { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("_sys_net_errno_loc()"); + return g_lastError.GetAddr(); } int sys_net_set_resolver_configurations() @@ -313,7 +449,14 @@ int sys_net_show_ifconfig() int sys_net_finalize_network() { - UNIMPLEMENTED_FUNC(sys_net); + sys_net.Warning("sys_net_initialize_network_ex()"); + Memory.Free(g_lastError.GetAddr()); + g_lastError.SetAddr(NULL); +#ifdef _WIN32 + WSACleanup(); +#else + // TODO ? +#endif return CELL_OK; } @@ -337,40 +480,39 @@ int sys_net_free_thread_context() void sys_net_init() { - // (TODO: Fix function overloading problem due to winsock.h and find addresses for ntohl and ntohs) - - //sys_net.AddFunc(0xc94f6939, accept); - //sys_net.AddFunc(0xb0a59804, bind); - //sys_net.AddFunc(0x64f66d35, connect); - //sys_net.AddFunc(0xf7ac8941, gethostbyaddr); - //sys_net.AddFunc(0x71f4c717, gethostbyname); - //sys_net.AddFunc(0xf9ec2db6, getpeername); - //sys_net.AddFunc(0x13efe7f5, getsockname); - //sys_net.AddFunc(0x5a045bd1, getsockopt); - //sys_net.AddFunc(0xdabbc2c0, inet_addr); - sys_net.AddFunc(0xa9a079e0, inet_aton); - sys_net.AddFunc(0x566893ce, inet_lnaof); - sys_net.AddFunc(0xb4152c74, inet_makeaddr); - sys_net.AddFunc(0xe39a62a7, inet_netof); - sys_net.AddFunc(0x506ad863, inet_network); - //sys_net.AddFunc(0x858a930b, inet_ntoa); - sys_net.AddFunc(0xc98a3146, inet_ntop); - sys_net.AddFunc(0x8af3825e, inet_pton); - //sys_net.AddFunc(0x28e208bb, listen); - //sys_net.AddFunc(, ntohl); - //sys_net.AddFunc(, ntohs); - //sys_net.AddFunc(0xfba04f37, recv); - //sys_net.AddFunc(0x1f953b9f, recvfrom); - sys_net.AddFunc(0xc9d09c34, recvmsg); - //sys_net.AddFunc(0xdc751b40, send); - sys_net.AddFunc(0xad09481b, sendmsg); - //sys_net.AddFunc(0x9647570b, sendto); - //sys_net.AddFunc(0x88f03575, setsockopt); - //sys_net.AddFunc(0xa50777c6, shutdown); - //sys_net.AddFunc(0x9c056962, socket); - sys_net.AddFunc(0x6db6e8cd, socketclose); - sys_net.AddFunc(0x051ee3ee, socketpoll); - sys_net.AddFunc(0x3f09e20a, socketselect); + // The names of the following functions are modified to avoid overloading problems + sys_net.AddFunc(0xc94f6939, sys_net_accept); + sys_net.AddFunc(0xb0a59804, sys_net_bind); + sys_net.AddFunc(0x64f66d35, sys_net_connect); + //sys_net.AddFunc(0xf7ac8941, sys_net_gethostbyaddr); + //sys_net.AddFunc(0x71f4c717, sys_net_gethostbyname); + //sys_net.AddFunc(0xf9ec2db6, sys_net_getpeername); + //sys_net.AddFunc(0x13efe7f5, sys_net_getsockname); + //sys_net.AddFunc(0x5a045bd1, sys_net_getsockopt); + //sys_net.AddFunc(0xdabbc2c0, sys_net_inet_addr); + //sys_net.AddFunc(0xa9a079e0, sys_net_inet_aton); + //sys_net.AddFunc(0x566893ce, sys_net_inet_lnaof); + //sys_net.AddFunc(0xb4152c74, sys_net_inet_makeaddr); + //sys_net.AddFunc(0xe39a62a7, sys_net_inet_netof); + //sys_net.AddFunc(0x506ad863, sys_net_inet_network); + //sys_net.AddFunc(0x858a930b, sys_net_inet_ntoa); + //sys_net.AddFunc(0xc98a3146, sys_net_inet_ntop); + sys_net.AddFunc(0x8af3825e, sys_net_inet_pton); + //sys_net.AddFunc(0x28e208bb, sys_net_listen); + //sys_net.AddFunc(, sys_net_ntohl); + //sys_net.AddFunc(, sys_net_ntohs); + sys_net.AddFunc(0xfba04f37, sys_net_recv); + sys_net.AddFunc(0x1f953b9f, sys_net_recvfrom); + //sys_net.AddFunc(0xc9d09c34, sys_net_recvmsg); + sys_net.AddFunc(0xdc751b40, sys_net_send); + //sys_net.AddFunc(0xad09481b, sys_net_sendmsg); + sys_net.AddFunc(0x9647570b, sys_net_sendto); + sys_net.AddFunc(0x88f03575, sys_net_setsockopt); + sys_net.AddFunc(0xa50777c6, sys_net_shutdown); + sys_net.AddFunc(0x9c056962, sys_net_socket); + sys_net.AddFunc(0x6db6e8cd, sys_net_socketclose); + //sys_net.AddFunc(0x051ee3ee, sys_net_socketpoll); + //sys_net.AddFunc(0x3f09e20a, sys_net_socketselect); sys_net.AddFunc(0x139a9e9b, sys_net_initialize_network_ex); sys_net.AddFunc(0x05bd4438, sys_net_get_udpp2p_test_param); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.h b/rpcs3/Emu/SysCalls/Modules/sys_net.h new file mode 100644 index 0000000000..770a6958c2 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/sys_net.h @@ -0,0 +1,16 @@ +#pragma once + +struct sys_net_initialize_parameter +{ + u32 memory_addr; + int memory_size; + int flags; +}; + +// The names of the following structs are modified to avoid overloading problems +struct sys_net_sockaddr +{ + u8 sa_len; + u8 sa_family; // sa_family_t + u8 sa_data[14]; +}; diff --git a/rpcs3/Emu/SysCalls/Static.cpp b/rpcs3/Emu/SysCalls/Static.cpp new file mode 100644 index 0000000000..2628a77272 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Static.cpp @@ -0,0 +1,65 @@ +#include "stdafx.h" +#include "Modules.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" + +extern ArrayF g_static_funcs_list; + +void StaticAnalyse(void* ptr, u32 size) +{ + u32* data = (u32*)ptr; size /= 4; + + return; // disabled + + // TODO: optimize search + for (u32 i = 0; i < size; i++) + { + for (u32 j = 0; j < g_static_funcs_list.GetCount(); j++) + { + if ((data[i] & g_static_funcs_list[j].ops[0].mask) == g_static_funcs_list[j].ops[0].crc && (i + g_static_funcs_list[j].ops.GetCount()) < size) + { + bool found = true; + for (u32 k = i + 1, x = 1; x < g_static_funcs_list[j].ops.GetCount(); k++, x++) + { + // skip NOP + if (data[k] == se32(0x60000000)) + { + k++; + continue; + } + + if ((data[k] & g_static_funcs_list[j].ops[x].mask) != g_static_funcs_list[j].ops[x].crc) + { + found = false; + break; + } + } + if (found) + { + ConLog.Success("Function '%s' hooked", wxString(g_static_funcs_list[j].name).wx_str()); + data[i] = re(0x39600000 | j); // li r11, j + data[i+1] = se32(0x44000003); // sc 3 + data[i+2] = se32(0x4e800020); // blr + i += 2; // ??? + } + } + } + } +} + +void StaticExecute(u32 code) +{ + if (code < g_static_funcs_list.GetCount()) + { + (*g_static_funcs_list[code].func)(); + } + else + { + ConLog.Error("StaticExecute(%d): unknown function or illegal opcode", code); + } +} + +void StaticFinalize() +{ + g_static_funcs_list.Clear(); +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 51242b9b30..c97518f7a4 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -201,9 +201,9 @@ extern int sys_rwlock_trywlock(u32 rw_lock_id); extern int sys_rwlock_wunlock(u32 rw_lock_id); //ppu_thread -extern void sys_ppu_thread_exit(int errorcode); +extern void sys_ppu_thread_exit(u64 errorcode); extern int sys_ppu_thread_yield(); -extern int sys_ppu_thread_join(u32 thread_id, u32 vptr_addr); +extern int sys_ppu_thread_join(u32 thread_id, mem64_t vptr); extern int sys_ppu_thread_detach(u32 thread_id); extern void sys_ppu_thread_get_join_state(u32 isjoinable_addr); extern int sys_ppu_thread_set_priority(u32 thread_id, int prio); @@ -433,3 +433,7 @@ public: }; //extern SysCalls SysCallsManager; + +void StaticAnalyse(void* ptr, u32 size); +void StaticExecute(u32 code); +void StaticFinalize(); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp index 97555928d8..8f0785ab96 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp @@ -77,8 +77,26 @@ int sys_cond_signal(u32 cond_id) if (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop())) { + CPUThread* tt = Emu.GetCPU().GetThread(target); + bool valid = tt && tt->IsAlive(); + if (!valid) + { + sys_cond.Error("sys_cond_signal(%d): signal to invalid thread(%d)", cond_id, target); + return CELL_OK; + } + if (!was_locked) // mutex hasn't been locked (don't care about mutex state) { + if (u32 owner = mutex->m_mutex.GetOwner()) + { + tt = Emu.GetCPU().GetThread(owner); + valid = tt && tt->IsAlive(); + if (!valid) + { + sys_cond.Error("sys_cond_signal(%d): deadlock on invalid thread(%d)", cond_id, owner); + return CELL_OK; + } + } mutex->m_mutex.lock(tid); mutex->recursive = 1; mutex->m_mutex.unlock(tid, target); @@ -117,8 +135,26 @@ int sys_cond_signal_all(u32 cond_id) while (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop())) { + CPUThread* tt = Emu.GetCPU().GetThread(target); + bool valid = tt && tt->IsAlive(); + if (!valid) + { + sys_cond.Error("sys_cond_signal_all(%d): signal to invalid thread(%d)", cond_id, target); + return CELL_OK; + } + if (!was_locked) { + if (u32 owner = mutex->m_mutex.GetOwner()) + { + tt = Emu.GetCPU().GetThread(owner); + valid = tt && tt->IsAlive(); + if (!valid) + { + sys_cond.Error("sys_cond_signal_all(%d): deadlock on invalid thread(%d)", cond_id, owner); + return CELL_OK; + } + } mutex->m_mutex.lock(tid); mutex->recursive = 1; mutex->m_mutex.unlock(tid, target); @@ -130,11 +166,11 @@ int sys_cond_signal_all(u32 cond_id) mutex->m_mutex.lock(tid); mutex->recursive = 1; } - } - if (Emu.IsStopped()) - { - ConLog.Warning("sys_cond_signal_all(id=%d) aborted", cond_id); + if (Emu.IsStopped()) + { + ConLog.Warning("sys_cond_signal_all(id=%d) aborted", cond_id); + } } return CELL_OK; @@ -169,6 +205,16 @@ int sys_cond_signal_to(u32 cond_id, u32 thread_id) { if (!was_locked) { + if (u32 owner = mutex->m_mutex.GetOwner()) + { + CPUThread* tt = Emu.GetCPU().GetThread(owner); + bool valid = tt && tt->IsAlive(); + if (!valid) + { + sys_cond.Error("sys_cond_signal_to(%d): deadlock on invalid thread(%d)", cond_id, owner); + return CELL_OK; + } + } mutex->m_mutex.lock(tid); mutex->recursive = 1; mutex->m_mutex.unlock(tid, target); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp index 2e0e9abc2b..b662ee10c5 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp @@ -74,17 +74,17 @@ int sys_event_queue_destroy(u32 equeue_id, int mode) u32 tid = GetCurrentPPUThread().GetId(); - eq->sq.m_mutex.lock(tid); + eq->sq.m_mutex.lock(); eq->owner.lock(tid); // check if some threads are waiting for an event if (!mode && eq->sq.list.GetCount()) { eq->owner.unlock(tid); - eq->sq.m_mutex.unlock(tid); + eq->sq.m_mutex.unlock(); return CELL_EBUSY; } eq->owner.unlock(tid, ~0); - eq->sq.m_mutex.unlock(tid); + eq->sq.m_mutex.unlock(); while (eq->sq.list.GetCount()) { Sleep(1); @@ -136,18 +136,18 @@ int sys_event_queue_tryreceive(u32 equeue_id, mem_ptr_t event_ar u32 tid = GetCurrentPPUThread().GetId(); - eq->sq.m_mutex.lock(tid); + eq->sq.m_mutex.lock(); eq->owner.lock(tid); if (eq->sq.list.GetCount()) { number = 0; eq->owner.unlock(tid); - eq->sq.m_mutex.unlock(tid); + eq->sq.m_mutex.unlock(); return CELL_OK; } number = eq->events.pop_all((sys_event_data*)(Memory + event_array.GetAddr()), size); eq->owner.unlock(tid); - eq->sq.m_mutex.unlock(tid); + eq->sq.m_mutex.unlock(); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp index 2a42841c31..10cd0af5ff 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp @@ -57,7 +57,7 @@ int sys_lwmutex_destroy(mem_ptr_t lwmutex) { case CELL_OK: lwmutex->all_info() = 0; - lwmutex->attribute = 0; + lwmutex->attribute = 0xDEADBEEF; lwmutex->sleep_queue = 0; Emu.GetIdManager().RemoveID(sq_id); default: return res; @@ -99,13 +99,13 @@ int sys_lwmutex_unlock(mem_ptr_t lwmutex) void SleepQueue::push(u32 tid) { - SMutexLocker lock(m_mutex); + std::lock_guard lock(m_mutex); list.AddCpy(tid); } u32 SleepQueue::pop() // SYS_SYNC_FIFO { - SMutexLocker lock(m_mutex); + std::lock_guard lock(m_mutex); while (true) { @@ -125,7 +125,7 @@ u32 SleepQueue::pop() // SYS_SYNC_FIFO u32 SleepQueue::pop_prio() // SYS_SYNC_PRIORITY { - SMutexLocker lock(m_mutex); + std::lock_guard lock(m_mutex); while (true) { @@ -171,7 +171,7 @@ u32 SleepQueue::pop_prio_inherit() // (TODO) bool SleepQueue::invalidate(u32 tid) { - SMutexLocker lock(m_mutex); + std::lock_guard lock(m_mutex); if (tid) for (u32 i = 0; i < list.GetCount(); i++) { @@ -187,15 +187,13 @@ bool SleepQueue::invalidate(u32 tid) bool SleepQueue::finalize() { - u32 tid = GetCurrentPPUThread().GetId(); - - m_mutex.lock(tid); + if (!m_mutex.try_lock()) return false; for (u32 i = 0; i < list.GetCount(); i++) { if (list[i]) { - m_mutex.unlock(tid); + m_mutex.unlock(); return false; } } @@ -205,9 +203,42 @@ bool SleepQueue::finalize() int sys_lwmutex_t::trylock(be_t tid) { - if (!attribute.ToBE()) return CELL_EINVAL; + if (attribute.ToBE() == se32(0xDEADBEEF)) return CELL_EINVAL; - if (tid == mutex.GetOwner()) + be_t owner_tid = mutex.GetOwner(); + + if (owner_tid != mutex.GetFreeValue()) + { + if (CPUThread* tt = Emu.GetCPU().GetThread(owner_tid)) + { + if (!tt->IsAlive()) + { + sc_lwmutex.Error("sys_lwmutex_t::(try)lock(%d): deadlock on invalid thread(%d)", (u32)sleep_queue, (u32)owner_tid); + mutex.unlock(owner_tid, tid); + recursive_count = 1; + return CELL_OK; + } + } + else + { + sc_lwmutex.Error("sys_lwmutex_t::(try)lock(%d): deadlock on invalid thread(%d)", (u32)sleep_queue, (u32)owner_tid); + mutex.unlock(owner_tid, tid); + recursive_count = 1; + return CELL_OK; + } + } + + /*while ((attribute.ToBE() & se32(SYS_SYNC_ATTR_RECURSIVE_MASK)) == 0) + { + if (Emu.IsStopped()) + { + ConLog.Warning("(hack) sys_lwmutex_t::(try)lock aborted (waiting for recursive attribute, attr=0x%x)", (u32)attribute); + return CELL_ESRCH; + } + Sleep(1); + }*/ + + if (tid == owner_tid) { if (attribute.ToBE() & se32(SYS_SYNC_RECURSIVE)) { @@ -237,6 +268,11 @@ int sys_lwmutex_t::unlock(be_t tid) } else { + if (!recursive_count || (recursive_count.ToBE() != se32(1) && (attribute.ToBE() & se32(SYS_SYNC_NOT_RECURSIVE)))) + { + sc_lwmutex.Error("sys_lwmutex_t::unlock(%d): wrong recursive value (%d)", (u32)sleep_queue, (u32)recursive_count); + recursive_count = 1; + } recursive_count -= 1; if (!recursive_count.ToBE()) { diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h index 971363a92f..2fa724b52d 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h @@ -47,7 +47,7 @@ struct SleepQueue q_rec(u32 tid, u64 prio): tid(tid), prio(prio) {} }; */ Array list; - SMutex m_mutex; + std::mutex m_mutex; u64 m_name; SleepQueue(u64 name = 0) @@ -65,7 +65,7 @@ struct SleepQueue struct sys_lwmutex_t { - /* volatile */ SMutexBase, ~0, 0> mutex; + /* volatile */ SMutexBase> mutex; /* volatile */ be_t waiter; // not used u64 &all_info(){return *(reinterpret_cast(this));} be_t attribute; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp index 4ae474631b..ce1b3f51d3 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp @@ -37,7 +37,13 @@ int sys_mutex_create(mem32_t mutex_id, mem_ptr_t attr) return CELL_EINVAL; } - mutex_id = sys_mtx.GetNewId(new Mutex((u32)attr->protocol, is_recursive, attr->name_u64)); + u32 tid = GetCurrentPPUThread().GetId(); + Mutex* mutex = new Mutex((u32)attr->protocol, is_recursive, attr->name_u64); + u32 id = sys_mtx.GetNewId(mutex); + mutex->m_mutex.lock(tid); + mutex->id = id; + mutex_id = id; + mutex->m_mutex.unlock(tid); sys_mtx.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%s): id = %d", wxString(attr->name, 8).wx_str(), (u32)attr->protocol, wxString(is_recursive ? "true" : "false").wx_str(), mutex_id.GetValue()); @@ -90,7 +96,8 @@ int sys_mutex_lock(u32 mutex_id, u64 timeout) return CELL_ESRCH; } - u32 tid = GetCurrentPPUThread().GetId(); + PPUThread& t = GetCurrentPPUThread(); + u32 tid = t.GetId(); u32 owner = mutex->m_mutex.GetOwner(); if (owner == tid) @@ -108,17 +115,32 @@ int sys_mutex_lock(u32 mutex_id, u64 timeout) return CELL_EDEADLK; } } - else if (owner && !Emu.GetIdManager().CheckID(owner)) + else if (owner) { - sys_mtx.Error("sys_mutex_lock(%d): deadlock on invalid thread(%d)", mutex_id, owner); - mutex->m_mutex.unlock(owner, tid); - mutex->recursive = 1; - return CELL_OK; + if (CPUThread* tt = Emu.GetCPU().GetThread(owner)) + { + if (!tt->IsAlive()) + { + if (owner == mutex->m_mutex.GetOwner()) sys_mtx.Error("sys_mutex_lock(%d): deadlock on invalid thread(%d)", mutex_id, owner); + /*mutex->m_mutex.unlock(owner, tid); + mutex->recursive = 1; + t.owned_mutexes++; + return CELL_OK;*/ + } + } + else + { + sys_mtx.Error("sys_mutex_lock(%d): deadlock on invalid thread(%d)", mutex_id, owner); + /*mutex->m_mutex.unlock(owner, tid); + mutex->recursive = 1; + t.owned_mutexes++; + return CELL_OK;*/ + } } switch (mutex->m_mutex.trylock(tid)) { - case SMR_OK: mutex->recursive = 1; return CELL_OK; + case SMR_OK: mutex->recursive = 1; t.owned_mutexes++; return CELL_OK; case SMR_FAILED: break; default: goto abort; } @@ -130,7 +152,7 @@ int sys_mutex_lock(u32 mutex_id, u64 timeout) case SMR_OK: mutex->m_queue.invalidate(tid); case SMR_SIGNAL: - mutex->recursive = 1; return CELL_OK; + mutex->recursive = 1; t.owned_mutexes++; return CELL_OK; case SMR_TIMEOUT: mutex->m_queue.invalidate(tid); return CELL_ETIMEDOUT; default: @@ -156,7 +178,8 @@ int sys_mutex_trylock(u32 mutex_id) return CELL_ESRCH; } - u32 tid = GetCurrentPPUThread().GetId(); + PPUThread& t = GetCurrentPPUThread(); + u32 tid = t.GetId(); u32 owner = mutex->m_mutex.GetOwner(); if (owner == tid) @@ -174,17 +197,32 @@ int sys_mutex_trylock(u32 mutex_id) return CELL_EDEADLK; } } - else if (owner && !Emu.GetIdManager().CheckID(owner)) + else if (owner) { - sys_mtx.Error("sys_mutex_trylock(%d): deadlock on invalid thread(%d)", mutex_id, owner); - mutex->m_mutex.unlock(owner, tid); - mutex->recursive = 1; - return CELL_OK; + if (CPUThread* tt = Emu.GetCPU().GetThread(owner)) + { + if (!tt->IsAlive()) + { + if (owner == mutex->m_mutex.GetOwner()) sys_mtx.Error("sys_mutex_trylock(%d): deadlock on invalid thread(%d)", mutex_id, owner); + /*mutex->m_mutex.unlock(owner, tid); + mutex->recursive = 1; + t.owned_mutexes++; + return CELL_OK;*/ + } + } + else + { + sys_mtx.Error("sys_mutex_trylock(%d): deadlock on invalid thread(%d)", mutex_id, owner); + /*mutex->m_mutex.unlock(owner, tid); + mutex->recursive = 1; + t.owned_mutexes++; + return CELL_OK;*/ + } } switch (mutex->m_mutex.trylock(tid)) { - case SMR_OK: mutex->recursive = 1; return CELL_OK; + case SMR_OK: mutex->recursive = 1; t.owned_mutexes++; return CELL_OK; } return CELL_EBUSY; @@ -200,18 +238,21 @@ int sys_mutex_unlock(u32 mutex_id) return CELL_ESRCH; } - u32 tid = GetCurrentPPUThread().GetId(); + PPUThread& t = GetCurrentPPUThread(); + u32 tid = t.GetId(); if (mutex->m_mutex.GetOwner() == tid) { - if (!mutex->recursive || (mutex->recursive > 1 && !mutex->is_recursive)) + if (!mutex->recursive || (mutex->recursive != 1 && !mutex->is_recursive)) { - sys_mtx.Warning("sys_mutex_unlock(%d): wrong recursive value (%d)", mutex_id, mutex->recursive); + sys_mtx.Error("sys_mutex_unlock(%d): wrong recursive value fixed (%d)", mutex_id, mutex->recursive); + mutex->recursive = 1; } mutex->recursive--; if (!mutex->recursive) { mutex->m_mutex.unlock(tid, mutex->protocol == SYS_SYNC_PRIORITY ? mutex->m_queue.pop_prio() : mutex->m_queue.pop()); + t.owned_mutexes--; } return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Mutex.h b/rpcs3/Emu/SysCalls/lv2/SC_Mutex.h index 2366d1656a..735f20a240 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Mutex.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_Mutex.h @@ -18,6 +18,7 @@ struct sys_mutex_attribute struct Mutex { + u32 id; SMutex m_mutex; SleepQueue m_queue; u32 recursive; // recursive locks count @@ -33,4 +34,21 @@ struct Mutex , cond_count(0) { } + + ~Mutex() + { + if (u32 owner = m_mutex.GetOwner()) + { + ConLog.Write("Mutex(%d) was owned by thread %d (recursive=%d)", id, owner, recursive); + } + + if (!m_queue.m_mutex.try_lock()) return; + + for (u32 i = 0; i < m_queue.list.GetCount(); i++) + { + if (u32 owner = m_queue.list[i]) ConLog.Write("Mutex(%d) was waited by thread %d", id, owner); + } + + m_queue.m_mutex.unlock(); + } }; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp index fb39296f6e..30c31bea17 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp @@ -10,24 +10,21 @@ enum SYS_PPU_THREAD_DONE_INIT, }; -void sys_ppu_thread_exit(int errorcode) +void sys_ppu_thread_exit(u64 errorcode) { - if(errorcode == 0) - { - sysPrxForUser.Log("sys_ppu_thread_exit(errorcode=%d)", errorcode); - } - else - { - sysPrxForUser.Warning("sys_ppu_thread_exit(errorcode=%d)", errorcode); - } + sysPrxForUser.Log("sys_ppu_thread_exit(0x%llx)", errorcode); PPUThread& thr = GetCurrentPPUThread(); + u32 tid = thr.GetId(); + + if (thr.owned_mutexes) + { + ConLog.Error("Owned mutexes found (%d)", thr.owned_mutexes); + thr.owned_mutexes = 0; + } + thr.SetExitStatus(errorcode); thr.Stop(); - - //Emu.GetCPU().RemoveThread(thr.GetId()); - - //throw errorcode; } int sys_ppu_thread_yield() @@ -37,14 +34,24 @@ int sys_ppu_thread_yield() return CELL_OK; } -int sys_ppu_thread_join(u32 thread_id, u32 vptr_addr) +int sys_ppu_thread_join(u32 thread_id, mem64_t vptr) { - sysPrxForUser.Warning("sys_ppu_thread_join(thread_id=%d, vptr_addr=0x%x)", thread_id, vptr_addr); + sysPrxForUser.Warning("sys_ppu_thread_join(thread_id=%d, vptr_addr=0x%x)", thread_id, vptr.GetAddr()); CPUThread* thr = Emu.GetCPU().GetThread(thread_id); if(!thr) return CELL_ESRCH; - GetCurrentPPUThread().Wait(*thr); + while (thr->IsAlive()) + { + if (Emu.IsStopped()) + { + ConLog.Warning("sys_ppu_thread_join(%d) aborted", thread_id); + return CELL_OK; + } + Sleep(1); + } + + vptr = thr->GetExitStatus(); return CELL_OK; } diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index e910413c66..08f356707e 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -267,6 +267,8 @@ void Emulator::Load() ppu_thr_exit_data += ADDI(11, 0, 41); ppu_thr_exit_data += SC(2); ppu_thr_exit_data += BCLR(0x10 | 0x04, 0, 0, 0); + + Memory.Write64(Memory.PRXMem.AllocAlign(0x10000), 0xDEADBEEFABADCAFE); } break; diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index e37799a3c5..f56c305934 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -358,8 +358,8 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) wxCheckBox* chbox_cpu_ignore_rwerrors = new wxCheckBox(&diag, wxID_ANY, "Ignore Read/Write errors"); wxCheckBox* chbox_gs_log_prog = new wxCheckBox(&diag, wxID_ANY, "Log vertex/fragment programs"); - wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(&diag, wxID_ANY, "Dump Depth Buffer"); - wxCheckBox* chbox_gs_dump_color = new wxCheckBox(&diag, wxID_ANY, "Dump Color Buffers"); + wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(&diag, wxID_ANY, "Write Depth Buffer"); + wxCheckBox* chbox_gs_dump_color = new wxCheckBox(&diag, wxID_ANY, "Write Color Buffers"); wxCheckBox* chbox_gs_vsync = new wxCheckBox(&diag, wxID_ANY, "VSync"); wxCheckBox* chbox_audio_dump = new wxCheckBox(&diag, wxID_ANY, "Dump to file"); wxCheckBox* chbox_hle_logging = new wxCheckBox(&diag, wxID_ANY, "Log all SysCalls"); @@ -395,6 +395,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) //cbox_mouse_handler->Append("DirectInput"); cbox_audio_out->Append("Null"); + cbox_audio_out->Append("OpenAL"); chbox_cpu_ignore_rwerrors->SetValue(Ini.CPUIgnoreRWErrors.GetValue()); chbox_gs_log_prog->SetValue(Ini.GSLogPrograms.GetValue()); diff --git a/rpcs3/Ini.h b/rpcs3/Ini.h index 940e9e876a..c7b08a3f8f 100644 --- a/rpcs3/Ini.h +++ b/rpcs3/Ini.h @@ -192,7 +192,7 @@ public: PadHandlerMode.Load(1); KeyboardHandlerMode.Load(0); MouseHandlerMode.Load(0); - AudioOutMode.Load(0); + AudioOutMode.Load(1); AudioDumpToFile.Load(0); HLELogging.Load(false); HLESaveTTY.Load(false); diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index 0abf3866ea..6604d86d64 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -246,6 +246,7 @@ bool ELF64Loader::LoadPhdrData(u64 offset) { elf64_f.Seek(phdr_arr[i].p_offset); elf64_f.Read(&Memory[offset + phdr_arr[i].p_vaddr], phdr_arr[i].p_filesz); + StaticAnalyse(&Memory[offset + phdr_arr[i].p_vaddr], phdr_arr[i].p_filesz); } } break; diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 4ff6fe50d4..1dfb346159 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -69,20 +69,20 @@ - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\Include;$(IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\Include;.\OpenAL\include;$(IncludePath) $(SolutionDir)bin\ ..\libs\$(Configuration)\;$(LibraryPath) $(ProjectName)-$(PlatformShortName)-dbg - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath) $(SolutionDir)bin\ ..\libs\$(Configuration)\;$(LibraryPath) $(ProjectName)-$(PlatformShortName)-dbg false - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\Include;$(IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\Include;.\OpenAL\include;$(IncludePath) $(SolutionDir)bin\ ..\libs\$(Configuration)\;$(LibraryPath) false @@ -91,7 +91,7 @@ false - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath) $(SolutionDir)bin\ ..\libs\$(Configuration)\;$(LibraryPath) false @@ -109,10 +109,10 @@ true - wxmsw31ud_adv.lib;wxbase31ud.lib;wxmsw31ud_core.lib;wxmsw31ud_aui.lib;wxtiffd.lib;wxjpegd.lib;wxpngd.lib;wxzlibd.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies) + wxmsw31ud_adv.lib;wxbase31ud.lib;wxmsw31ud_core.lib;wxmsw31ud_aui.lib;wxtiffd.lib;wxjpegd.lib;wxpngd.lib;wxzlibd.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;OpenAL32.lib;EFX-Util.lib;%(AdditionalDependencies) %(IgnoreSpecificDefaultLibraries) false - ..\wxWidgets\lib\vc_lib;..\ffmpeg\Windows\x86\lib + ..\wxWidgets\lib\vc_lib;..\ffmpeg\Windows\x86\lib;..\OpenAL\Win32 @@ -129,10 +129,10 @@ true - wxmsw31ud_adv.lib;wxbase31ud.lib;wxmsw31ud_core.lib;wxmsw31ud_aui.lib;wxtiffd.lib;wxjpegd.lib;wxpngd.lib;wxzlibd.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies) + wxmsw31ud_adv.lib;wxbase31ud.lib;wxmsw31ud_core.lib;wxmsw31ud_aui.lib;wxtiffd.lib;wxjpegd.lib;wxpngd.lib;wxzlibd.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;OpenAL32.lib;EFX-Util.lib;%(AdditionalDependencies) %(IgnoreSpecificDefaultLibraries) false - ..\wxWidgets\lib\vc_x64_lib;..\ffmpeg\Windows\x86_64\lib + ..\wxWidgets\lib\vc_x64_lib;..\ffmpeg\Windows\x86_64\lib;..\OpenAL\Win64 "$(SolutionDir)\Utilities\git-version-gen.cmd" @@ -161,12 +161,12 @@ true true true - wxmsw31u_adv.lib;wxbase31u.lib;wxmsw31u_core.lib;wxmsw31u_aui.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;wsock32.lib;wininet.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies) + wxmsw31u_adv.lib;wxbase31u.lib;wxmsw31u_core.lib;wxmsw31u_aui.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;wsock32.lib;wininet.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;OpenAL32.lib;EFX-Util.lib %(IgnoreSpecificDefaultLibraries) false - ..\wxWidgets\lib\vc_lib;..\ffmpeg\Windows\x86\lib + ..\wxWidgets\lib\vc_lib;..\ffmpeg\Windows\x86\lib;..\OpenAL\Win32 @@ -193,12 +193,12 @@ true true true - wxmsw31u_adv.lib;wxbase31u.lib;wxmsw31u_core.lib;wxmsw31u_aui.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;wsock32.lib;wininet.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies) + wxmsw31u_adv.lib;wxbase31u.lib;wxmsw31u_core.lib;wxmsw31u_aui.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;wsock32.lib;wininet.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;OpenAL32.lib;EFX-Util.lib;%(AdditionalDependencies) %(IgnoreSpecificDefaultLibraries) false - ..\wxWidgets\lib\vc_x64_lib;..\ffmpeg\Windows\x86_64\lib + ..\wxWidgets\lib\vc_x64_lib;..\ffmpeg\Windows\x86_64\lib;..\OpenAL\Win64 @@ -216,6 +216,8 @@ + + @@ -297,17 +299,22 @@ + + + + + @@ -358,7 +365,6 @@ - diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index bc2aa277e0..b10d1cb470 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -59,6 +59,9 @@ {28cf8d4a-ff56-45ef-a824-3bd71c626257} + + {e9937271-a8ff-49f6-a326-c4659f96703f} + @@ -436,12 +439,33 @@ Crypto + + Emu\SysCalls + Emu\SysCalls\Modules Emu\SysCalls\Modules + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + + + Emu\Audio + + + Emu\Audio\AL + + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + @@ -615,9 +639,6 @@ Include - - Include - Include