static SDL_bool WIN_AddDisplay(_THIS, LPTSTR DeviceName) { SDL_VideoDisplay display; SDL_DisplayData *displaydata; SDL_DisplayMode mode; DISPLAY_DEVICE device; #ifdef DEBUG_MODES printf("Display: %s\n", WIN_StringToUTF8(DeviceName)); #endif if (!WIN_GetDisplayMode(_this, DeviceName, ENUM_CURRENT_SETTINGS, &mode)) { return SDL_FALSE; } displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata)); if (!displaydata) { return SDL_FALSE; } SDL_memcpy(displaydata->DeviceName, DeviceName, sizeof(displaydata->DeviceName)); SDL_zero(display); device.cb = sizeof(device); if (EnumDisplayDevices(DeviceName, 0, &device, 0)) { display.name = WIN_StringToUTF8(device.DeviceString); } display.desktop_mode = mode; display.current_mode = mode; display.driverdata = displaydata; SDL_AddVideoDisplay(&display); SDL_free(display.name); return SDL_TRUE; }
void SDL_DXGIGetOutputInfo( int displayIndex, int *adapterIndex, int *outputIndex ) { void *pDXGIDLL; IDXGIFactory *pDXGIFactory; *adapterIndex = -1; *outputIndex = -1; if (!DXGI_LoadDLL(&pDXGIDLL, &pDXGIFactory)) { SDL_SetError("Unable to create DXGI interface"); } else { SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData(displayIndex); if (!pData) { SDL_SetError("Invalid display index"); } else { char *displayName = WIN_StringToUTF8(pData->DeviceName); int nAdapter = 0, nOutput = 0; IDXGIAdapter* pDXGIAdapter; while ( *adapterIndex == -1 && IDXGIFactory_EnumAdapters(pDXGIFactory, nAdapter, &pDXGIAdapter) != DXGI_ERROR_NOT_FOUND ) { IDXGIOutput* pDXGIOutput; while ( *adapterIndex == -1 && IDXGIAdapter_EnumOutputs(pDXGIAdapter, nOutput, &pDXGIOutput) != DXGI_ERROR_NOT_FOUND ) { DXGI_OUTPUT_DESC outputDesc; if (SUCCEEDED(IDXGIOutput_GetDesc(pDXGIOutput, &outputDesc))) { char *outputName = WIN_StringToUTF8(outputDesc.DeviceName); if(!SDL_strcmp(outputName, displayName)) { *adapterIndex = nAdapter; *outputIndex = nOutput; } SDL_free( outputName ); } IDXGIOutput_Release( pDXGIOutput ); nOutput++; } IDXGIAdapter_Release( pDXGIAdapter ); nAdapter++; } SDL_free(displayName); } /* free up the D3D stuff we inited */ IDXGIFactory_AddRef( pDXGIFactory ); SDL_UnloadObject(pDXGIDLL); } }
static UINT D3D_FindAdapter(IDirect3D9 * d3d, SDL_VideoDisplay * display) { SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; UINT adapter, count; count = IDirect3D9_GetAdapterCount(d3d); for (adapter = 0; adapter < count; ++adapter) { HRESULT result; D3DADAPTER_IDENTIFIER9 info; char *name; result = IDirect3D9_GetAdapterIdentifier(d3d, adapter, 0, &info); if (FAILED(result)) { continue; } name = WIN_StringToUTF8(displaydata->DeviceName); if (SDL_strcmp(name, info.DeviceName) == 0) { SDL_free(name); return adapter; } SDL_free(name); } /* This should never happen, but just in case... */ return D3DADAPTER_DEFAULT; }
int WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) { HWND hwnd = (HWND) data; LPTSTR title; int titleLen; /* Query the title from the existing window */ titleLen = GetWindowTextLength(hwnd); title = SDL_stack_alloc(TCHAR, titleLen + 1); if (title) { titleLen = GetWindowText(hwnd, title, titleLen); } else { titleLen = 0; } if (titleLen > 0) { window->title = WIN_StringToUTF8(title); } if (title) { SDL_stack_free(title); } if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) { return -1; } return 0; }
char * WIN_GetClipboardText(_THIS) { char *text; text = NULL; if (IsClipboardFormatAvailable(TEXT_FORMAT) && OpenClipboard(GetWindowHandle(_this))) { HANDLE hMem; LPTSTR tstr; hMem = GetClipboardData(TEXT_FORMAT); if (hMem) { tstr = (LPTSTR)GlobalLock(hMem); text = WIN_StringToUTF8(tstr); GlobalUnlock(hMem); } else { WIN_SetError("Couldn't get clipboard data"); } CloseClipboard(); } if (!text) { text = SDL_strdup(""); } return text; }
static void XAUDIO2_DetectDevices(void) { IXAudio2 *ixa2 = NULL; UINT32 devcount = 0; UINT32 i = 0; if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) { SDL_SetError("XAudio2: XAudio2Create() failed at detection."); return; } else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) { SDL_SetError("XAudio2: IXAudio2::GetDeviceCount() failed."); IXAudio2_Release(ixa2); return; } for (i = 0; i < devcount; i++) { XAUDIO2_DEVICE_DETAILS details; if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) { char *str = WIN_StringToUTF8(details.DisplayName); if (str != NULL) { SDL_AddAudioDevice(SDL_FALSE, str, (void *) ((size_t) i+1)); SDL_free(str); /* SDL_AddAudioDevice made a copy of the string. */ } } } IXAudio2_Release(ixa2); }
static SDL_bool WIN_AddDisplay(LPTSTR DeviceName) { SDL_VideoDisplay display; SDL_DisplayData *displaydata; SDL_DisplayMode mode; #ifdef DEBUG_MODES printf("Display: %s\n", WIN_StringToUTF8(DeviceName)); #endif if (!WIN_GetDisplayMode(DeviceName, ENUM_CURRENT_SETTINGS, &mode)) { return SDL_FALSE; } displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata)); if (!displaydata) { return SDL_FALSE; } SDL_memcpy(displaydata->DeviceName, DeviceName, sizeof(displaydata->DeviceName)); SDL_zero(display); display.desktop_mode = mode; display.current_mode = mode; display.driverdata = displaydata; SDL_AddVideoDisplay(&display); return SDL_TRUE; }
int WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) { HWND hwnd = (HWND) data; LPTSTR title; int titleLen; /* Query the title from the existing window */ titleLen = GetWindowTextLength(hwnd); title = SDL_stack_alloc(TCHAR, titleLen + 1); if (title) { titleLen = GetWindowText(hwnd, title, titleLen); } else { titleLen = 0; } if (titleLen > 0) { window->title = WIN_StringToUTF8(title); } if (title) { SDL_stack_free(title); } if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) { return -1; } // Urho3D: if window will be used for OpenGL, choose pixel format if (window->flags & SDL_WINDOW_OPENGL) { if (WIN_GL_SetupWindow(_this, window) < 0) { return -1; } } return 0; }
static void XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) { IXAudio2 *ixa2 = NULL; UINT32 devcount = 0; UINT32 i = 0; if (iscapture) { SDL_SetError("XAudio2: capture devices unsupported."); return; } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) { SDL_SetError("XAudio2: XAudio2Create() failed at detection."); return; } else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) { SDL_SetError("XAudio2: IXAudio2::GetDeviceCount() failed."); IXAudio2_Release(ixa2); return; } for (i = 0; i < devcount; i++) { XAUDIO2_DEVICE_DETAILS details; if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) { char *str = WIN_StringToUTF8(details.DisplayName); if (str != NULL) { addfn(str); SDL_free(str); /* addfn() made a copy of the string. */ } } } IXAudio2_Release(ixa2); }
int WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) { HWND hwnd = (HWND) data; LPTSTR title; int titleLen; /* Query the title from the existing window */ titleLen = GetWindowTextLength(hwnd); title = SDL_stack_alloc(TCHAR, titleLen + 1); if (title) { titleLen = GetWindowText(hwnd, title, titleLen); } else { titleLen = 0; } if (titleLen > 0) { window->title = WIN_StringToUTF8(title); } if (title) { SDL_stack_free(title); } if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) { return -1; } // Urho3D: if window will be used for OpenGL, choose pixel format if (window->flags & SDL_WINDOW_OPENGL) { if (WIN_GL_SetupWindow(_this, window) < 0) { return -1; } } #if SDL_VIDEO_OPENGL_WGL { const char *hint = SDL_GetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT); if (hint) { // This hint is a pointer (in string form) of the address of // the window to share a pixel format with SDL_Window *otherWindow = NULL; SDL_sscanf(hint, "%p", (void**)&otherWindow); // Do some error checking on the pointer if (otherWindow != NULL && otherWindow->magic == &_this->window_magic) { // If the otherWindow has SDL_WINDOW_OPENGL set, set it for the new window as well if (otherWindow->flags & SDL_WINDOW_OPENGL) { window->flags |= SDL_WINDOW_OPENGL; if(!WIN_GL_SetPixelFormatFrom(_this, otherWindow, window)) { return -1; } } } } } #endif return 0; }
int SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance) { HRESULT ret; LPDIRECTINPUTDEVICE8 device; const DWORD needflags = DIDC_ATTACHED | DIDC_FORCEFEEDBACK; DIDEVCAPS capabilities; SDL_hapticlist_item *item = NULL; if (dinput == NULL) { return -1; /* not initialized. We'll pick these up on enumeration if we init later. */ } /* Make sure we don't already have it */ for (item = SDL_hapticlist; item; item = item->next) { if ((!item->bXInputHaptic) && (SDL_memcmp(&item->instance, pdidInstance, sizeof(*pdidInstance)) == 0)) { return -1; /* Already added */ } } /* Open the device */ ret = IDirectInput8_CreateDevice(dinput, &pdidInstance->guidInstance, &device, NULL); if (FAILED(ret)) { /* DI_SetError("Creating DirectInput device",ret); */ return -1; } /* Get capabilities. */ SDL_zero(capabilities); capabilities.dwSize = sizeof(DIDEVCAPS); ret = IDirectInputDevice8_GetCapabilities(device, &capabilities); IDirectInputDevice8_Release(device); if (FAILED(ret)) { /* DI_SetError("Getting device capabilities",ret); */ return -1; } if ((capabilities.dwFlags & needflags) != needflags) { return -1; /* not a device we can use. */ } item = (SDL_hapticlist_item *)SDL_calloc(1, sizeof(SDL_hapticlist_item)); if (item == NULL) { return SDL_OutOfMemory(); } item->name = WIN_StringToUTF8(pdidInstance->tszProductName); if (!item->name) { SDL_free(item); return -1; } /* Copy the instance over, useful for creating devices. */ SDL_memcpy(&item->instance, pdidInstance, sizeof(DIDEVICEINSTANCE)); SDL_memcpy(&item->capabilities, &capabilities, sizeof(capabilities)); return SDL_SYS_AddHapticDevice(item); }
/* helper function for direct input, gets called for each connected joystick */ static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) { JoyStick_DeviceData *pNewJoystick; JoyStick_DeviceData *pPrevJoystick = NULL; const DWORD devtype = (pdidInstance->dwDevType & 0xFF); if (devtype == DI8DEVTYPE_SUPPLEMENTAL) { return DIENUM_CONTINUE; /* Ignore touchpads, etc. */ } if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) { return DIENUM_CONTINUE; /* ignore XInput devices here, keep going. */ } pNewJoystick = *(JoyStick_DeviceData **)pContext; while (pNewJoystick) { if (!SDL_memcmp(&pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance))) { /* if we are replacing the front of the list then update it */ if (pNewJoystick == *(JoyStick_DeviceData **)pContext) { *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext; } else if (pPrevJoystick) { pPrevJoystick->pNext = pNewJoystick->pNext; } pNewJoystick->pNext = SYS_Joystick; SYS_Joystick = pNewJoystick; return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */ } pPrevJoystick = pNewJoystick; pNewJoystick = pNewJoystick->pNext; } pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData)); if (!pNewJoystick) { return DIENUM_CONTINUE; /* better luck next time? */ } SDL_zerop(pNewJoystick); pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName); if (!pNewJoystick->joystickname) { SDL_free(pNewJoystick); return DIENUM_CONTINUE; /* better luck next time? */ } SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance, sizeof(DIDEVICEINSTANCE)); SDL_memcpy(&pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid)); SDL_SYS_AddJoystickDevice(pNewJoystick); return DIENUM_CONTINUE; /* get next device, please */ }
/* Sets an error message based on GetLastError() */ void WIN_SetError(const char *prefix) { TCHAR buffer[1024]; char *message; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, buffer, SDL_arraysize(buffer), NULL); message = WIN_StringToUTF8(buffer); SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message); SDL_free(message); }
/* Sets an error message based on GetLastError() */ int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr) { TCHAR buffer[1024]; char *message; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0, buffer, SDL_arraysize(buffer), NULL); message = WIN_StringToUTF8(buffer); SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message); SDL_free(message); return -1; }
static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) { SDL_memcpy(&SYS_Joystick[SYS_NumJoysticks], pdidInstance, sizeof(DIDEVICEINSTANCE)); SYS_JoystickNames[SYS_NumJoysticks] = WIN_StringToUTF8(pdidInstance->tszProductName); SYS_NumJoysticks++; if (SYS_NumJoysticks >= MAX_JOYSTICKS) return DIENUM_STOP; return DIENUM_CONTINUE; }
static BOOL CALLBACK FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data) { SDL_AddAudioDevice addfn = (SDL_AddAudioDevice) data; if (guid != NULL) { /* skip default device */ char *str = WIN_StringToUTF8(desc); if (str != NULL) { addfn(str); SDL_free(str); /* addfn() makes a copy of this string. */ } } return TRUE; /* keep enumerating. */ }
static BOOL CALLBACK FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data) { const int iscapture = (int) ((size_t) data); if (guid != NULL) { /* skip default device */ char *str = WIN_StringToUTF8(desc); if (str != NULL) { LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID)); SDL_memcpy(cpyguid, guid, sizeof (GUID)); SDL_AddAudioDevice(iscapture, str, cpyguid); SDL_free(str); /* addfn() makes a copy of this string. */ } } return TRUE; /* keep enumerating. */ }
static BOOL CALLBACK FindDevGUID(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID _data) { if (guid != NULL) { /* skip the default device. */ FindDevGUIDData *data = (FindDevGUIDData *) _data; char *str = WIN_StringToUTF8(desc); const int match = (SDL_strcmp(str, data->devname) == 0); SDL_free(str); if (match) { data->found = 1; SDL_memcpy(&data->guid, guid, sizeof (data->guid)); return FALSE; /* found it! stop enumerating. */ } } return TRUE; /* keep enumerating. */ }
static char * GetWasapiDeviceName(IMMDevice *device) { /* PKEY_Device_FriendlyName gives you "Speakers (SoundBlaster Pro)" which drives me nuts. I'd rather it be "SoundBlaster Pro (Speakers)" but I guess that's developers vs users. Windows uses the FriendlyName in its own UIs, like Volume Control, etc. */ char *utf8dev = NULL; IPropertyStore *props = NULL; if (SUCCEEDED(IMMDevice_OpenPropertyStore(device, STGM_READ, &props))) { PROPVARIANT var; PropVariantInit(&var); if (SUCCEEDED(IPropertyStore_GetValue(props, &SDL_PKEY_Device_FriendlyName, &var))) { utf8dev = WIN_StringToUTF8(var.pwszVal); } PropVariantClear(&var); IPropertyStore_Release(props); } return utf8dev; }
/* * Callback to find the haptic devices. */ static BOOL CALLBACK EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) { HRESULT ret; LPDIRECTINPUTDEVICE device; /* Copy the instance over, useful for creating devices. */ SDL_memcpy(&SDL_hapticlist[SDL_numhaptics].instance, pdidInstance, sizeof(DIDEVICEINSTANCE)); /* Open the device */ ret = IDirectInput_CreateDevice(dinput, &pdidInstance->guidInstance, &device, NULL); if (FAILED(ret)) { /* DI_SetError("Creating DirectInput device",ret); */ return DIENUM_CONTINUE; } /* Get capabilities. */ SDL_hapticlist[SDL_numhaptics].capabilities.dwSize = sizeof(DIDEVCAPS); ret = IDirectInputDevice_GetCapabilities(device, &SDL_hapticlist[SDL_numhaptics]. capabilities); if (FAILED(ret)) { /* DI_SetError("Getting device capabilities",ret); */ IDirectInputDevice_Release(device); return DIENUM_CONTINUE; } /* Copy the name */ SDL_hapticlist[SDL_numhaptics].name = WIN_StringToUTF8(SDL_hapticlist[SDL_numhaptics].instance.tszProductName); /* Close up device and count it. */ IDirectInputDevice_Release(device); SDL_numhaptics++; /* Watch out for hard limit. */ if (SDL_numhaptics >= MAX_HAPTICS) return DIENUM_STOP; return DIENUM_CONTINUE; }
int WIN_InitModes(_THIS) { SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; DWORD i, j, count; DISPLAY_DEVICE device; device.cb = sizeof(device); for (i = 0;; ++i) { TCHAR DeviceName[32]; if (!EnumDisplayDevices(NULL, i, &device, 0)) { break; } if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) { continue; } SDL_memcpy(DeviceName, device.DeviceName, sizeof(DeviceName)); #ifdef DEBUG_MODES printf("Device: %s\n", WIN_StringToUTF8(DeviceName)); #endif count = 0; for (j = 0;; ++j) { if (!EnumDisplayDevices(DeviceName, j, &device, 0)) { break; } if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) { continue; } count += WIN_AddDisplay(device.DeviceName); } if (count == 0) { WIN_AddDisplay(DeviceName); } } if (_this->num_displays == 0) { SDL_SetError("No displays available"); return -1; } return 0; }
int SDL_Direct3D9GetAdapterIndex( int displayIndex ) { void *pD3DDLL; IDirect3D9 *pD3D; if (!D3D_LoadDLL(&pD3DDLL, &pD3D)) { SDL_SetError("Unable to create Direct3D interface"); return D3DADAPTER_DEFAULT; } else { SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData(displayIndex); int adapterIndex = D3DADAPTER_DEFAULT; if (!pData) { SDL_SetError("Invalid display index"); adapterIndex = -1; /* make sure we return something invalid */ } else { char *displayName = WIN_StringToUTF8(pData->DeviceName); unsigned int count = IDirect3D9_GetAdapterCount(pD3D); unsigned int i; for (i=0; i<count; i++) { D3DADAPTER_IDENTIFIER9 id; IDirect3D9_GetAdapterIdentifier(pD3D, i, 0, &id); if (SDL_strcmp(id.DeviceName, displayName) == 0) { adapterIndex = i; break; } } SDL_free(displayName); } /* free up the D3D stuff we inited */ IDirect3D9_Release(pD3D); SDL_UnloadObject(pD3DDLL); return adapterIndex; } }
SDL_bool SDL_DXGIGetOutputInfo(int displayIndex, int *adapterIndex, int *outputIndex) { #if !HAVE_DXGI_H if (adapterIndex) *adapterIndex = -1; if (outputIndex) *outputIndex = -1; SDL_SetError("SDL was compiled without DXGI support due to missing dxgi.h header"); return SDL_FALSE; #else SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData(displayIndex); void *pDXGIDLL; char *displayName; int nAdapter, nOutput; IDXGIFactory *pDXGIFactory; IDXGIAdapter *pDXGIAdapter; IDXGIOutput* pDXGIOutput; if (!adapterIndex) { SDL_InvalidParamError("adapterIndex"); return SDL_FALSE; } if (!outputIndex) { SDL_InvalidParamError("outputIndex"); return SDL_FALSE; } *adapterIndex = -1; *outputIndex = -1; if (!pData) { SDL_SetError("Invalid display index"); return SDL_FALSE; } if (!DXGI_LoadDLL(&pDXGIDLL, &pDXGIFactory)) { SDL_SetError("Unable to create DXGI interface"); return SDL_FALSE; } displayName = WIN_StringToUTF8(pData->DeviceName); nAdapter = 0; while (*adapterIndex == -1 && SUCCEEDED(IDXGIFactory_EnumAdapters(pDXGIFactory, nAdapter, &pDXGIAdapter))) { nOutput = 0; while (*adapterIndex == -1 && SUCCEEDED(IDXGIAdapter_EnumOutputs(pDXGIAdapter, nOutput, &pDXGIOutput))) { DXGI_OUTPUT_DESC outputDesc; if (SUCCEEDED(IDXGIOutput_GetDesc(pDXGIOutput, &outputDesc))) { char *outputName = WIN_StringToUTF8(outputDesc.DeviceName); if (SDL_strcmp(outputName, displayName) == 0) { *adapterIndex = nAdapter; *outputIndex = nOutput; } SDL_free(outputName); } IDXGIOutput_Release(pDXGIOutput); nOutput++; } IDXGIAdapter_Release(pDXGIAdapter); nAdapter++; } SDL_free(displayName); /* free up the DXGI factory */ IDXGIFactory_Release(pDXGIFactory); SDL_UnloadObject(pDXGIDLL); if (*adapterIndex == -1) { return SDL_FALSE; } else { return SDL_TRUE; } #endif }
const char* System::GetDirectory (SystemDirectory type, const char* company, const char* title) { switch (type) { case APPLICATION: return SDL_GetBasePath (); break; case APPLICATION_STORAGE: return SDL_GetPrefPath (company, title); break; case DESKTOP: { #if defined (HX_WINRT) Windows::Storage::StorageFolder folder = Windows::Storage::KnownFolders::HomeGroup; std::wstring resultW (folder->Begin ()); std::string result (resultW.begin (), resultW.end ()); return result.c_str (); #elif defined (HX_WINDOWS) char result[MAX_PATH] = ""; SHGetFolderPath (NULL, CSIDL_DESKTOPDIRECTORY, NULL, SHGFP_TYPE_CURRENT, result); return WIN_StringToUTF8 (result); #else std::string result = std::string (getenv ("HOME")) + std::string ("/Desktop"); return result.c_str (); #endif break; } case DOCUMENTS: { #if defined (HX_WINRT) Windows::Storage::StorageFolder folder = Windows::Storage::KnownFolders::DocumentsLibrary; std::wstring resultW (folder->Begin ()); std::string result (resultW.begin (), resultW.end ()); return result.c_str (); #elif defined (HX_WINDOWS) char result[MAX_PATH] = ""; SHGetFolderPath (NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, result); return WIN_StringToUTF8 (result); #else std::string result = std::string (getenv ("HOME")) + std::string ("/Documents"); return result.c_str (); #endif break; } case FONTS: { #if defined (HX_WINRT) return 0; #elif defined (HX_WINDOWS) char result[MAX_PATH] = ""; SHGetFolderPath (NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, result); return WIN_StringToUTF8 (result); #elif defined (HX_MACOS) return "/Library/Fonts"; #elif defined (IPHONEOS) return "/System/Library/Fonts"; #elif defined (ANDROID) return "/system/fonts"; #elif defined (BLACKBERRY) return "/usr/fonts/font_repository/monotype"; #else return "/usr/share/fonts/truetype"; #endif break; } case USER: { #if defined (HX_WINRT) Windows::Storage::StorageFolder folder = Windows::Storage::ApplicationData::Current->RoamingFolder; std::wstring resultW (folder->Begin ()); std::string result (resultW.begin (), resultW.end ()); return result.c_str (); #elif defined (HX_WINDOWS) char result[MAX_PATH] = ""; SHGetFolderPath (NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, result); return WIN_StringToUTF8 (result); #else std::string result = getenv ("HOME"); return result.c_str (); #endif break; } } return 0; }
/* helper function for direct input, gets called for each connected joystick */ static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) { const Uint16 BUS_USB = 0x03; const Uint16 BUS_BLUETOOTH = 0x05; JoyStick_DeviceData *pNewJoystick; JoyStick_DeviceData *pPrevJoystick = NULL; const DWORD devtype = (pdidInstance->dwDevType & 0xFF); Uint16 *guid16; if (devtype == DI8DEVTYPE_SUPPLEMENTAL) { return DIENUM_CONTINUE; /* Ignore touchpads, etc. */ } if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) { return DIENUM_CONTINUE; /* ignore XInput devices here, keep going. */ } pNewJoystick = *(JoyStick_DeviceData **)pContext; while (pNewJoystick) { if (!SDL_memcmp(&pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance))) { /* if we are replacing the front of the list then update it */ if (pNewJoystick == *(JoyStick_DeviceData **)pContext) { *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext; } else if (pPrevJoystick) { pPrevJoystick->pNext = pNewJoystick->pNext; } pNewJoystick->pNext = SYS_Joystick; SYS_Joystick = pNewJoystick; return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */ } pPrevJoystick = pNewJoystick; pNewJoystick = pNewJoystick->pNext; } pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData)); if (!pNewJoystick) { return DIENUM_CONTINUE; /* better luck next time? */ } SDL_zerop(pNewJoystick); pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName); if (!pNewJoystick->joystickname) { SDL_free(pNewJoystick); return DIENUM_CONTINUE; /* better luck next time? */ } SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance, sizeof(DIDEVICEINSTANCE)); SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data)); guid16 = (Uint16 *)pNewJoystick->guid.data; if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) { *guid16++ = SDL_SwapLE16(BUS_USB); *guid16++ = 0; *guid16++ = SDL_SwapLE16((Uint16)LOWORD(pdidInstance->guidProduct.Data1)); /* vendor */ *guid16++ = 0; *guid16++ = SDL_SwapLE16((Uint16)HIWORD(pdidInstance->guidProduct.Data1)); /* product */ *guid16++ = 0; *guid16++ = 0; /* version */ *guid16++ = 0; } else { *guid16++ = SDL_SwapLE16(BUS_BLUETOOTH); *guid16++ = 0; SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4); } SDL_SYS_AddJoystickDevice(pNewJoystick); return DIENUM_CONTINUE; /* get next device, please */ }
int WIN_InitModes(_THIS) { int pass; DWORD i, j, count; DISPLAY_DEVICE device; device.cb = sizeof(device); /* Get the primary display in the first pass */ for (pass = 0; pass < 2; ++pass) { for (i = 0; ; ++i) { TCHAR DeviceName[32]; if (!EnumDisplayDevices(NULL, i, &device, 0)) { break; } if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) { continue; } if (pass == 0) { if (!(device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) { continue; } } else { if (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) { continue; } } SDL_memcpy(DeviceName, device.DeviceName, sizeof(DeviceName)); #ifdef DEBUG_MODES printf("Device: %s\n", WIN_StringToUTF8(DeviceName)); #endif count = 0; for (j = 0; ; ++j) { if (!EnumDisplayDevices(DeviceName, j, &device, 0)) { break; } if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) { continue; } if (pass == 0) { if (!(device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) { continue; } } else { if (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) { continue; } } count += WIN_AddDisplay(_this, device.DeviceName); } if (count == 0) { WIN_AddDisplay(_this, DeviceName); } } } if (_this->num_displays == 0) { return SDL_SetError("No displays available"); } return 0; }
static int XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) { HRESULT result = S_OK; WAVEFORMATEX waveformat; int valid_format = 0; SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); IXAudio2 *ixa2 = NULL; IXAudio2SourceVoice *source = NULL; #if defined(SDL_XAUDIO2_WIN8) LPCWSTR devId = NULL; #else UINT32 devId = 0; /* 0 == system default device. */ #endif static IXAudio2VoiceCallbackVtbl callbacks_vtable = { VoiceCBOnVoiceProcessPassStart, VoiceCBOnVoiceProcessPassEnd, VoiceCBOnStreamEnd, VoiceCBOnBufferStart, VoiceCBOnBufferEnd, VoiceCBOnLoopEnd, VoiceCBOnVoiceError }; static IXAudio2VoiceCallback callbacks = { &callbacks_vtable }; if (iscapture) { return SDL_SetError("XAudio2: capture devices unsupported."); } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) { return SDL_SetError("XAudio2: XAudio2Create() failed at open."); } /* XAUDIO2_DEBUG_CONFIGURATION debugConfig; debugConfig.TraceMask = XAUDIO2_LOG_ERRORS; //XAUDIO2_LOG_WARNINGS | XAUDIO2_LOG_DETAIL | XAUDIO2_LOG_FUNC_CALLS | XAUDIO2_LOG_TIMING | XAUDIO2_LOG_LOCKS | XAUDIO2_LOG_MEMORY | XAUDIO2_LOG_STREAMING; debugConfig.BreakMask = XAUDIO2_LOG_ERRORS; //XAUDIO2_LOG_WARNINGS; debugConfig.LogThreadID = TRUE; debugConfig.LogFileline = TRUE; debugConfig.LogFunctionName = TRUE; debugConfig.LogTiming = TRUE; ixa2->SetDebugConfiguration(&debugConfig); */ #if ! defined(__WINRT__) if (devname != NULL) { UINT32 devcount = 0; UINT32 i = 0; if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) { IXAudio2_Release(ixa2); return SDL_SetError("XAudio2: IXAudio2_GetDeviceCount() failed."); } for (i = 0; i < devcount; i++) { XAUDIO2_DEVICE_DETAILS details; if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) { char *str = WIN_StringToUTF8(details.DisplayName); if (str != NULL) { const int match = (SDL_strcmp(str, devname) == 0); SDL_free(str); if (match) { devId = i; break; } } } } if (i == devcount) { IXAudio2_Release(ixa2); return SDL_SetError("XAudio2: Requested device not found."); } } #endif /* Initialize all variables that we clean on shutdown */ this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc((sizeof *this->hidden)); if (this->hidden == NULL) { IXAudio2_Release(ixa2); return SDL_OutOfMemory(); } SDL_memset(this->hidden, 0, (sizeof *this->hidden)); this->hidden->ixa2 = ixa2; this->hidden->semaphore = SDL_CreateSemaphore(1); if (this->hidden->semaphore == NULL) { XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: CreateSemaphore() failed!"); } while ((!valid_format) && (test_format)) { switch (test_format) { case AUDIO_U8: case AUDIO_S16: case AUDIO_S32: case AUDIO_F32: this->spec.format = test_format; valid_format = 1; break; } test_format = SDL_NextAudioFormat(); } if (!valid_format) { XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: Unsupported audio format"); } /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(&this->spec); /* We feed a Source, it feeds the Mastering, which feeds the device. */ this->hidden->mixlen = this->spec.size; this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * this->hidden->mixlen); if (this->hidden->mixbuf == NULL) { XAUDIO2_CloseDevice(this); return SDL_OutOfMemory(); } this->hidden->nextbuf = this->hidden->mixbuf; SDL_memset(this->hidden->mixbuf, 0, 2 * this->hidden->mixlen); /* We use XAUDIO2_DEFAULT_CHANNELS instead of this->spec.channels. On Xbox360, this means 5.1 output, but on Windows, it means "figure out what the system has." It might be preferable to let XAudio2 blast stereo output to appropriate surround sound configurations instead of clamping to 2 channels, even though we'll configure the Source Voice for whatever number of channels you supply. */ #if SDL_XAUDIO2_WIN8 result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering, XAUDIO2_DEFAULT_CHANNELS, this->spec.freq, 0, devId, NULL, AudioCategory_GameEffects); #else result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering, XAUDIO2_DEFAULT_CHANNELS, this->spec.freq, 0, devId, NULL); #endif if (result != S_OK) { XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: Couldn't create mastering voice"); } SDL_zero(waveformat); if (SDL_AUDIO_ISFLOAT(this->spec.format)) { waveformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; } else { waveformat.wFormatTag = WAVE_FORMAT_PCM; } waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); waveformat.nChannels = this->spec.channels; waveformat.nSamplesPerSec = this->spec.freq; waveformat.nBlockAlign = waveformat.nChannels * (waveformat.wBitsPerSample / 8); waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign; waveformat.cbSize = sizeof(waveformat); #ifdef __WINRT__ // DLudwig: for now, make XAudio2 do sample rate conversion, just to // get the loopwave test to work. // // TODO, WinRT: consider removing WinRT-specific source-voice creation code from SDL_xaudio2.c result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat, 0, 1.0f, &callbacks, NULL, NULL); #else result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat, XAUDIO2_VOICE_NOSRC | XAUDIO2_VOICE_NOPITCH, 1.0f, &callbacks, NULL, NULL); #endif if (result != S_OK) { XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: Couldn't create source voice"); } this->hidden->source = source; /* Start everything playing! */ result = IXAudio2_StartEngine(ixa2); if (result != S_OK) { XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: Couldn't start engine"); } result = IXAudio2SourceVoice_Start(source, 0, XAUDIO2_COMMIT_NOW); if (result != S_OK) { XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: Couldn't start source voice"); } return 0; /* good to go. */ }
static SDL_bool WIN_AddDisplay(LPTSTR DeviceName) { SDL_VideoDisplay display; SDL_DisplayData *displaydata; SDL_DisplayMode mode; #ifdef DEBUG_MODES printf("Display: %s\n", WIN_StringToUTF8(DeviceName)); #endif #if _MSC_VER == 1200 if (!WIN_GetDisplayMode(NULL, ENUM_CURRENT_SETTINGS, &mode)) { #else if (!WIN_GetDisplayMode(DeviceName, ENUM_CURRENT_SETTINGS, &mode)) { #endif return SDL_FALSE; } displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata)); if (!displaydata) { return SDL_FALSE; } SDL_memcpy(displaydata->DeviceName, DeviceName, sizeof(displaydata->DeviceName)); SDL_zero(display); display.desktop_mode = mode; display.current_mode = mode; display.driverdata = displaydata; SDL_AddVideoDisplay(&display); return SDL_TRUE; } int WIN_InitModes(_THIS) { DWORD i, j, count; DISPLAY_DEVICE device; #if _MSC_VER == 1200 WIN_AddDisplay("\\\\.\\DISPLAY1"); #else device.cb = sizeof(device); for (i = 0;; ++i) { TCHAR DeviceName[32] = {0}; if (!EnumDisplayDevices(NULL, i, &device, 0)) { break; } if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) { continue; } SDL_memcpy(DeviceName, device.DeviceName, sizeof(DeviceName)); #ifdef DEBUG_MODES printf("Device: %s\n", WIN_StringToUTF8(DeviceName)); #endif count = 0; for (j = 0;; ++j) { if (!EnumDisplayDevices(DeviceName, j, &device, 0)) { break; } if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) { continue; } count += WIN_AddDisplay(device.DeviceName); } if (count == 0) { WIN_AddDisplay(DeviceName); } } #endif if (_this->num_displays == 0) { SDL_SetError("No displays available"); return -1; } return 0; }
/* helper function for direct input, gets called for each connected joystick */ static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) { const Uint16 BUS_USB = 0x03; const Uint16 BUS_BLUETOOTH = 0x05; JoyStick_DeviceData *pNewJoystick; JoyStick_DeviceData *pPrevJoystick = NULL; const DWORD devtype = (pdidInstance->dwDevType & 0xFF); Uint16 *guid16; if (devtype == DI8DEVTYPE_SUPPLEMENTAL) { /* Add any supplemental devices that should be ignored here */ #define MAKE_TABLE_ENTRY(VID, PID) ((((DWORD)PID)<<16)|VID) static DWORD ignored_devices[] = { MAKE_TABLE_ENTRY(0, 0) }; #undef MAKE_TABLE_ENTRY unsigned int i; for (i = 0; i < SDL_arraysize(ignored_devices); ++i) { if (pdidInstance->guidProduct.Data1 == ignored_devices[i]) { return DIENUM_CONTINUE; } } } if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) { return DIENUM_CONTINUE; /* ignore XInput devices here, keep going. */ } pNewJoystick = *(JoyStick_DeviceData **)pContext; while (pNewJoystick) { if (!SDL_memcmp(&pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance))) { /* if we are replacing the front of the list then update it */ if (pNewJoystick == *(JoyStick_DeviceData **)pContext) { *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext; } else if (pPrevJoystick) { pPrevJoystick->pNext = pNewJoystick->pNext; } pNewJoystick->pNext = SYS_Joystick; SYS_Joystick = pNewJoystick; return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */ } pPrevJoystick = pNewJoystick; pNewJoystick = pNewJoystick->pNext; } pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData)); if (!pNewJoystick) { return DIENUM_CONTINUE; /* better luck next time? */ } SDL_zerop(pNewJoystick); pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName); if (!pNewJoystick->joystickname) { SDL_free(pNewJoystick); return DIENUM_CONTINUE; /* better luck next time? */ } SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance, sizeof(DIDEVICEINSTANCE)); SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data)); guid16 = (Uint16 *)pNewJoystick->guid.data; if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) { *guid16++ = SDL_SwapLE16(BUS_USB); *guid16++ = 0; *guid16++ = SDL_SwapLE16((Uint16)LOWORD(pdidInstance->guidProduct.Data1)); /* vendor */ *guid16++ = 0; *guid16++ = SDL_SwapLE16((Uint16)HIWORD(pdidInstance->guidProduct.Data1)); /* product */ *guid16++ = 0; *guid16++ = 0; /* version */ *guid16++ = 0; } else { *guid16++ = SDL_SwapLE16(BUS_BLUETOOTH); *guid16++ = 0; SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4); } if (SDL_IsGameControllerNameAndGUID(pNewJoystick->joystickname, pNewJoystick->guid) && SDL_ShouldIgnoreGameController(pNewJoystick->joystickname, pNewJoystick->guid)) { SDL_free(pNewJoystick); return DIENUM_CONTINUE; } SDL_SYS_AddJoystickDevice(pNewJoystick); return DIENUM_CONTINUE; /* get next device, please */ }
static int WINMM_OpenDevice(_THIS, const char *devname, int iscapture) { SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); int valid_datatype = 0; MMRESULT result; WAVEFORMATEX waveformat; UINT_PTR devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */ char *utf8 = NULL; int i; if (devname != NULL) { /* specific device requested? */ if (iscapture) { const int devcount = (int) waveInGetNumDevs(); WAVEINCAPS caps; for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) { result = waveInGetDevCaps(i, &caps, sizeof (caps)); if (result != MMSYSERR_NOERROR) continue; else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL) continue; else if (SDL_strcmp(devname, utf8) == 0) devId = (UINT_PTR) i; SDL_free(utf8); } } else { const int devcount = (int) waveOutGetNumDevs(); WAVEOUTCAPS caps; for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) { result = waveOutGetDevCaps(i, &caps, sizeof (caps)); if (result != MMSYSERR_NOERROR) continue; else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL) continue; else if (SDL_strcmp(devname, utf8) == 0) devId = (UINT_PTR) i; SDL_free(utf8); } } if (devId == WAVE_MAPPER) { SDL_SetError("Requested device not found"); return 0; } } /* Initialize all variables that we clean on shutdown */ this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc((sizeof *this->hidden)); if (this->hidden == NULL) { SDL_OutOfMemory(); return 0; } SDL_memset(this->hidden, 0, (sizeof *this->hidden)); /* Initialize the wavebuf structures for closing */ for (i = 0; i < NUM_BUFFERS; ++i) this->hidden->wavebuf[i].dwUser = 0xFFFF; while ((!valid_datatype) && (test_format)) { valid_datatype = 1; this->spec.format = test_format; switch (test_format) { case AUDIO_U8: case AUDIO_S16: case AUDIO_S32: break; /* valid. */ default: valid_datatype = 0; test_format = SDL_NextAudioFormat(); break; } } if (!valid_datatype) { WINMM_CloseDevice(this); SDL_SetError("Unsupported audio format"); return 0; } /* Set basic WAVE format parameters */ SDL_memset(&waveformat, '\0', sizeof(waveformat)); waveformat.wFormatTag = WAVE_FORMAT_PCM; waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); if (this->spec.channels > 2) this->spec.channels = 2; /* !!! FIXME: is this right? */ waveformat.nChannels = this->spec.channels; waveformat.nSamplesPerSec = this->spec.freq; waveformat.nBlockAlign = waveformat.nChannels * (waveformat.wBitsPerSample / 8); waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign; /* Check the buffer size -- minimum of 1/4 second (word aligned) */ if (this->spec.samples < (this->spec.freq / 4)) this->spec.samples = ((this->spec.freq / 4) + 3) & ~3; /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(&this->spec); /* Open the audio device */ if (iscapture) { result = waveInOpen(&this->hidden->hin, devId, &waveformat, (DWORD_PTR) CaptureSound, (DWORD_PTR) this, CALLBACK_FUNCTION); } else { result = waveOutOpen(&this->hidden->hout, devId, &waveformat, (DWORD_PTR) FillSound, (DWORD_PTR) this, CALLBACK_FUNCTION); } if (result != MMSYSERR_NOERROR) { WINMM_CloseDevice(this); SetMMerror("waveOutOpen()", result); return 0; } #ifdef SOUND_DEBUG /* Check the sound device we retrieved */ { WAVEOUTCAPS caps; result = waveOutGetDevCaps((UINT) this->hidden->hout, &caps, sizeof(caps)); if (result != MMSYSERR_NOERROR) { WINMM_CloseDevice(this); SetMMerror("waveOutGetDevCaps()", result); return 0; } printf("Audio device: %s\n", caps.szPname); } #endif /* Create the audio buffer semaphore */ this->hidden->audio_sem = CreateSemaphore(NULL, NUM_BUFFERS - 1, NUM_BUFFERS, NULL); if (this->hidden->audio_sem == NULL) { WINMM_CloseDevice(this); SDL_SetError("Couldn't create semaphore"); return 0; } /* Create the sound buffers */ this->hidden->mixbuf = (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size); if (this->hidden->mixbuf == NULL) { WINMM_CloseDevice(this); SDL_OutOfMemory(); return 0; } for (i = 0; i < NUM_BUFFERS; ++i) { SDL_memset(&this->hidden->wavebuf[i], 0, sizeof(this->hidden->wavebuf[i])); this->hidden->wavebuf[i].dwBufferLength = this->spec.size; this->hidden->wavebuf[i].dwFlags = WHDR_DONE; this->hidden->wavebuf[i].lpData = (LPSTR) & this->hidden->mixbuf[i * this->spec.size]; result = waveOutPrepareHeader(this->hidden->hout, &this->hidden->wavebuf[i], sizeof(this->hidden->wavebuf[i])); if (result != MMSYSERR_NOERROR) { WINMM_CloseDevice(this); SetMMerror("waveOutPrepareHeader()", result); return 0; } } return 1; /* Ready to go! */ }