// @pymethod |PyIDirectSound|SetCooperativeLevel|The IDirectSound::SetCooperativeLevel method sets the cooperative level of the application for this sound device.
PyObject *PyIDirectSound::SetCooperativeLevel(PyObject *self, PyObject *args)
{
	int level;
	PyObject *obHWND = NULL;
	HWND hwnd;

	IDirectSound *pIDS = GetI(self);
	if ( pIDS == NULL )
		return NULL;
	if ( !PyArg_ParseTuple(args, "Oi:SetCooperativeLevel", 
		&obHWND, // @pyparm int|hwnd||Window handle to the application or None.
		&level) ) // @pyparm int|level||Requested priority level. Specify one of the following values:
		// @flagh Level|Description
		// @flag DSSCL_NORMAL|Sets the application to a fully cooperative status. Most applications should use this level, because it has the smoothest multitasking and resource-sharing behavior.
		// @flag DSSCL_PRIORITY|Sets the application to the priority level. Applications with this cooperative level can call the DirectSoundBuffer.setFormat and DirectSound.compact methods. 
		// @flag DSSCL_EXCLUSIVE|Sets the application to the exclusive level. When it has the input focus, the application will be the only one audible (sounds from applications with the DSBCAPS_GLOBALFOCUS flag set will be muted). With this level, it also has all the privileges of the DSSCL_PRIORITY level. DirectSound will restore the hardware format, as specified by the most recent call to the DirectSoundBuffer.setFormat method, once the application gains the input focus. (Note that DirectSound will always restore the wave format, no matter what priority level is set.) 
		// @flag DSSCL_WRITEPRIMARY|This is the highest priority level. The application has write access to the primary sound buffers. No secondary sound buffers in any application can be played. 

		return NULL;
	if (!PyWinObject_AsHANDLE(obHWND, (HANDLE *)&hwnd))
		return NULL;
	if (hwnd == NULL)
	{
		hwnd = GetForegroundWindow();
		if (hwnd == NULL)
		{
	        hwnd = GetDesktopWindow();
	    }
	}

	HRESULT hr;
	PY_INTERFACE_PRECALL;
	hr = pIDS->SetCooperativeLevel(hwnd, level);
	PY_INTERFACE_POSTCALL;

	if (FAILED(hr)) {
		PyWin_SetAPIError("SetCooperativeLevel", hr);
		return NULL;
	}
	
	Py_INCREF(Py_None);
	return Py_None;

}
// @pymethod |PyIDirectSound|CreateSoundBuffer|The IDirectSound::CreateSoundBuffer method creates a DirectSoundBuffer object to hold a sequence of audio samples.
PyObject *PyIDirectSound::CreateSoundBuffer(PyObject *self, PyObject *args)
{
	PyObject *obDSBD = NULL;
	PyObject *obUnk = NULL;
	IUnknown *pUnkIn = NULL;

	IDirectSound *pIDS = GetI(self);
	if ( pIDS == NULL )
		return NULL;
	if ( !PyArg_ParseTuple(args, "O|O:CreateSoundBuffer", 
		&obDSBD,  // @pyparm <o PyDSCBUFFERDESC>|lpDSCBufferDesc||a DSBUFFERDESC structure containing values for the sound buffer being created.
		&obUnk) ) // @pyparm <o PyIUknown>|unk|None|The IUnknown for COM aggregation.
		return NULL;

	if (!PyDSBUFFERDESC_Check(obDSBD)) {
		PyErr_SetString(PyExc_TypeError, "Argument 1 must be of type DSBUFFERDESC");
		return NULL;
	}

	if (obUnk && !PyCom_InterfaceFromPyInstanceOrObject(obUnk, IID_IUnknown, (void **)&pUnkIn, TRUE)) {
		return NULL;
	}
	

	DSBUFFERDESC *pdsbd = &((PyDSBUFFERDESC*)obDSBD)->m_dsbd;
	HRESULT hr;
	IDirectSoundBuffer *buffer;

	PY_INTERFACE_PRECALL;
	hr = pIDS->CreateSoundBuffer(pdsbd, &buffer, pUnkIn);
	PY_INTERFACE_POSTCALL;

	if (FAILED(hr)) {
		PyWin_SetAPIError("CreateSoundBuffer", hr);
		return NULL;
	}

	PyIDirectSoundBuffer *rc = new PyIDirectSoundBuffer(buffer);

	Py_INCREF(self);
	rc->m_DS = self;

	return rc;
}
// @pymethod |PyIDirectSound|GetSpeakerConfig|The GetSpeakerConfig method retrieves the speaker configuration.
PyObject *PyIDirectSound::GetSpeakerConfig(PyObject *self, PyObject *args)
{
	IDirectSound *pIDS = GetI(self);
	if ( pIDS == NULL )
		return NULL;
	if ( !PyArg_ParseTuple(args, ":GetSpeakerConfig") )
		return NULL;


	HRESULT hr;
	DWORD config;
	PY_INTERFACE_PRECALL;
	hr = pIDS->GetSpeakerConfig(&config);
	PY_INTERFACE_POSTCALL;

	if (FAILED(hr)) {
		PyWin_SetAPIError("GetSpeakerConfig", hr);
		return NULL;
	}

	return PyInt_FromLong(config);
}
// @pymethod |PyIDirectSound|Compact|The Compact method moves the unused portions of on-board sound memory, if any, to a contiguous block so that the largest portion of free memory will be available.
PyObject *PyIDirectSound::Compact(PyObject *self, PyObject *args)
{
	IDirectSound *pIDS = GetI(self);
	if ( pIDS == NULL )
		return NULL;
	if ( !PyArg_ParseTuple(args, ":Compact") )
		return NULL;


	HRESULT hr;
	PY_INTERFACE_PRECALL;
	hr = pIDS->Compact();
	PY_INTERFACE_POSTCALL;

	if (FAILED(hr)) {
		PyWin_SetAPIError("GetCaps", hr);
		return NULL;
	}

	Py_INCREF(Py_None);
	return Py_None;
}
// @pymethod |PyIDirectSound|GetCaps|The GetCaps method retrieves the capabilities of the hardware device that is represented by the DirectSound object. See <l DSCAPS contants>.
PyObject *PyIDirectSound::GetCaps(PyObject *self, PyObject *args)
{
	IDirectSound *pIDS = GetI(self);
	if ( pIDS == NULL )
		return NULL;
	if ( !PyArg_ParseTuple(args, ":GetCaps") )
		return NULL;


	HRESULT hr;
	PyDSCAPS *caps = new PyDSCAPS();
	PY_INTERFACE_PRECALL;
	hr = pIDS->GetCaps(caps->GetCAPS());
	PY_INTERFACE_POSTCALL;

	if (FAILED(hr)) {
		PyWin_SetAPIError("GetCaps", hr);
		return NULL;
	}

	Py_INCREF(caps);
	return caps;
}
// @pymethod |PyIDirectSound|Initialize|Description of Initialize.
PyObject *PyIDirectSound::Initialize(PyObject *self, PyObject *args)
{
	PyObject *obGUID;

	IDirectSound *pIDS = GetI(self);
	if ( pIDS == NULL )
		return NULL;
	if ( !PyArg_ParseTuple(args, "|O:Initialize", 
		&obGUID) )  // @pyparm <o PyIID>|guid||Globally unique identifier (GUID) specifying the sound driver to which this DirectSound object binds. Pass None to select the primary sound driver. 

		return NULL;

	GUID guid;
	LPGUID pguid = NULL;
	if (!obGUID && obGUID != Py_None)
	{
		if (!PyWinObject_AsIID(obGUID, &guid))
			return NULL;

		pguid = &guid;
	}

	HRESULT hr;
	PY_INTERFACE_PRECALL;
	hr = pIDS->Initialize(pguid);
	PY_INTERFACE_POSTCALL;

	if (FAILED(hr)) {
		PyWin_SetAPIError("Initialize", hr);
		return NULL;
	}
	
	Py_INCREF(Py_None);
	return Py_None;

}
// @pymethod |PyIDirectSound|SetSpeakerConfig|The SetSpeakerConfig method specifies the speaker configuration of the DirectSound object.
PyObject *PyIDirectSound::SetSpeakerConfig(PyObject *self, PyObject *args)
{
	DWORD config;
	IDirectSound *pIDS = GetI(self);
	if ( pIDS == NULL )
		return NULL;
	if ( !PyArg_ParseTuple(args, "i:SetSpeakerConfig", 
		&config) ) // @pyparm int|dwSpeakerConfig||Speaker configuration of the specified DirectSound object. See the DSSPEAKER constants.
		return NULL;


	HRESULT hr;
	PY_INTERFACE_PRECALL;
	hr = pIDS->SetSpeakerConfig(config);
	PY_INTERFACE_POSTCALL;

	if (FAILED(hr)) {
		PyWin_SetAPIError("SetSpeakerConfig", hr);
		return NULL;
	}

	Py_INCREF(Py_None);
	return Py_None;
}
Exemple #8
0
extern "C" IDirect3D8* __stdcall MyDirect3DCreate8(UINT SDKVersion)
{
    printf("Direct3DCreate8\n");

    //get real D3D8
    auto realCreate = GetProcAddress(realD3D8Dll, "Direct3DCreate8");

    IDirect3D8* d3d8 = (*(IDirect3D8*(__stdcall*)(UINT))realCreate)(SDKVersion);

    try
    {
        //Swap CreateDevice (virtual #15) with our function
        *(void**)&realCreateDevice = SwapVPtr(d3d8, 15, &MyDirect3D8_CreateDevice);
        printf("IDirect3D8::CreateDevice %p -> %p\n", realCreateDevice, &MyDirect3D8_CreateDevice);
    }
    catch(const exception& e)
    {
        printf("Couldn't replace IDirect3D8::CreateDevice with own wrapper\n%s\n", e.what());
    }

    //hack DirectSound
    IDirectSound* dsound;
    HRESULT hr = DirectSoundCreate(nullptr, &dsound, nullptr);

    if(FAILED(hr))
    {
        printf("Couldn't create DirectSound object\n");
    }

    // Create a sound buffer similar to what Freelancer is using

    WAVEFORMATEX wfex = {
        1,
        1,
        11025,
        22050,
        2,
        16,
        0
    };

    DSBUFFERDESC dsbd = {
        sizeof(DSBUFFERDESC),
        0x400C0,
        DSBSIZE_MIN,
        0,
        &wfex
    };

    IDirectSoundBuffer* dsbuf;
    hr = dsound->CreateSoundBuffer(&dsbd, &dsbuf, nullptr);

    if(FAILED(hr))
    {
        printf("Couldn't create mock DirectSound buffer\n");
    }

    try
    {
        *(void**)&realCreateBuffer = SwapVPtr(dsound, 3, &MyDirectSound_CreateSoundBuffer);
        printf("IDirectSound::CreateSoundBuffer %p -> %p\n", realCreateBuffer, &MyDirectSound_CreateSoundBuffer);
        *(void**)&realDuplicate = SwapVPtr(dsound, 5, &MyDirectSound_DuplicateSoundBuffer);
        printf("IDirectSound::DuplicateSoundBuffer %p -> %p\n", realDuplicate, &MyDirectSound_DuplicateSoundBuffer);

        *(void**)&realRelease_buf = SwapVPtr(dsbuf, 2, &MyDirectSoundBuffer_Release);
        printf("IDirectSoundBuffer::Release %p -> %p\n", realRelease_buf, &MyDirectSoundBuffer_Release);
        *(void**)&realLock = SwapVPtr(dsbuf, 11, &MyDirectSoundBuffer_Lock);
        printf("IDirectSoundBuffer::Lock %p->%p\n", realLock, &MyDirectSoundBuffer_Lock);
        *(void**)&realPlay = SwapVPtr(dsbuf, 12, &MyDirectSoundBuffer_Play);
        printf("IDirectSoundBuffer::Play %p->%p\n", realPlay, &MyDirectSoundBuffer_Play);
        *(void**)&realUnlock = SwapVPtr(dsbuf, 19, &MyDirectSoundBuffer_Unlock);
        printf("IDirectSoundBuffer::Unlock %p->%p\n", realUnlock, &MyDirectSoundBuffer_Unlock);
    }
    catch(const exception& e)
    {
        printf("Couldn't replace IDirectSoundBuffer functions with own wrappers\n%s\n", e.what());
    }

    (*realRelease_buf)(dsbuf);
    dsound->Release();

    return d3d8;
}