From 9ce44fa048793de5e14d1e7af98e8b5ca148d0f3 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Thu, 26 May 2022 03:07:28 +1000 Subject: osd: Cleaned up Windows API usage a little. * Bumped target windows version to 6.0.0 (Vista). * Use WRL COM pointers to manage some COM-like objects. * Cleaned up logging in DirectSound module. * Cleaned up includes in Windows input modules. * Switched to Common Item Dialogs in Windows debugger. * Replaced disabled code that never really worked with a TODO comment. --- src/osd/modules/debugger/win/consolewininfo.cpp | 450 +++++++++++------------- src/osd/modules/debugger/win/consolewininfo.h | 9 +- src/osd/modules/input/input_dinput.cpp | 29 +- src/osd/modules/input/input_dinput.h | 36 +- src/osd/modules/input/input_rawinput.cpp | 29 +- src/osd/modules/input/input_win32.cpp | 17 +- src/osd/modules/input/input_windows.cpp | 7 +- src/osd/modules/input/input_windows.h | 8 +- src/osd/modules/input/input_winhybrid.cpp | 31 +- src/osd/modules/input/input_xinput.cpp | 20 +- src/osd/modules/input/input_xinput.h | 7 + src/osd/modules/sound/direct_sound.cpp | 373 ++++++++++---------- src/osd/windows/winutil.cpp | 16 +- src/osd/windows/winutil.h | 17 +- 14 files changed, 501 insertions(+), 548 deletions(-) (limited to 'src/osd') diff --git a/src/osd/modules/debugger/win/consolewininfo.cpp b/src/osd/modules/debugger/win/consolewininfo.cpp index afddcf31d6c..b2f12b69331 100644 --- a/src/osd/modules/debugger/win/consolewininfo.cpp +++ b/src/osd/modules/debugger/win/consolewininfo.cpp @@ -12,15 +12,196 @@ #include "debugviewinfo.h" #include "uimetrics.h" -#include "debugger.h" +// emu #include "debug/debugcon.h" +#include "debugger.h" +#include "image.h" +#include "softlist_dev.h" #include "debug/debugcpu.h" + +// devices #include "imagedev/cassette.h" -#include "strconv.h" +// osd/windows #include "winutf8.h" -#include "softlist_dev.h" +// osd +#include "strconv.h" + +// C++ +#include + +// Windows +#include +#include +#include +#include +#include + + +namespace { + +class comdlg_filter_helper +{ +public: + comdlg_filter_helper(comdlg_filter_helper const &) = delete; + comdlg_filter_helper &operator=(comdlg_filter_helper const &) = delete; + + comdlg_filter_helper(device_image_interface &device, bool include_archives) + { + m_count = 0U; + + std::wstring const extensions = osd::text::to_wstring(device.file_extensions()); + std::wstring_view extview = extensions; + m_description = L"Media Image Files ("; + for (auto comma = extview.find(','); !extview.empty(); comma = extview.find(',')) + { + bool const found = std::wstring_view::npos != comma; + std::wstring_view const ext = found ? extview.substr(0, comma) : extview; + extview.remove_prefix(found ? (comma + 1) : extview.length()); + if (m_extensions.empty()) + { + m_default = ext; + m_description.append(L"*."); + m_extensions.append(L"*."); + } + else + { + m_description.append(L"; *."); + m_extensions.append(L";*."); + } + m_description.append(ext); + m_extensions.append(ext); + } + m_description.append(1, L')'); + m_specs[m_count].pszName = m_description.c_str(); + m_specs[m_count].pszSpec = m_extensions.c_str(); + ++m_count; + + if (include_archives) + { + m_specs[m_count].pszName = L"Archive Files (*.zip; *.7z)"; + m_specs[m_count].pszSpec = L"*.zip;*.7z"; + ++m_count; + } + + m_specs[m_count].pszName = L"All Files (*.*)"; + m_specs[m_count].pszSpec = L"*.*"; + ++m_count; + } + + UINT file_types() const noexcept + { + return m_count; + } + + COMDLG_FILTERSPEC const *filter_spec() const noexcept + { + return m_specs; + } + + LPCWSTR default_extension() const noexcept + { + return m_default.c_str(); + } + +private: + COMDLG_FILTERSPEC m_specs[3]; + std::wstring m_description; + std::wstring m_extensions; + std::wstring m_default; + UINT m_count; +}; + + +template +void choose_image(device_image_interface &device, HWND owner, REFCLSID class_id, bool allow_archives, T &&handler) +{ + HRESULT hr; + + // create file dialog + Microsoft::WRL::ComPtr dialog; + hr = CoCreateInstance(class_id, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(dialog.GetAddressOf())); + + // set file types + if (SUCCEEDED(hr)) + { + DWORD flags; + hr = dialog->GetOptions(&flags); + if (SUCCEEDED(hr)) + hr = dialog->SetOptions(flags | FOS_NOCHANGEDIR | FOS_FORCEFILESYSTEM); + comdlg_filter_helper filters(device, allow_archives); + if (SUCCEEDED(hr)) + hr = dialog->SetFileTypes(filters.file_types(), filters.filter_spec()); + if (SUCCEEDED(hr)) + hr = dialog->SetFileTypeIndex(1); + if (SUCCEEDED(hr)) + hr = dialog->SetDefaultExtension(filters.default_extension()); + } + + // set starting folder + if (SUCCEEDED(hr)) + { + std::string dir = device.working_directory(); + if (dir.empty()) + { + dir = device.device().machine().image().setup_working_directory(); + device.set_working_directory(dir); + } + std::string full; + if (!dir.empty() && !osd_get_full_path(full, dir)) + { + // FIXME: strip off archive names - opening a file inside an archive decompresses it to a temporary location + std::wstring wfull = osd::text::to_wstring(full); + Microsoft::WRL::ComPtr item; + if (SUCCEEDED(SHCreateItemFromParsingName(wfull.c_str(), nullptr, IID_PPV_ARGS(item.GetAddressOf())))) + { + //dialog->SetFolder(item); disabled until + } + } + } + + // show the dialog + if (SUCCEEDED(hr)) + { + hr = dialog->Show(owner); + if (HRESULT_FROM_WIN32(ERROR_CANCELLED) == hr) + return; + } + if (SUCCEEDED(hr)) + { + Microsoft::WRL::ComPtr result; + hr = dialog->GetResult(result.GetAddressOf()); + if (SUCCEEDED(hr)) + { + PWSTR selection = nullptr; + hr = result->GetDisplayName(SIGDN_FILESYSPATH, &selection); + if (SUCCEEDED(hr)) + { + std::string const utf_selection = osd::text::from_wstring(selection); + CoTaskMemFree(selection); + handler(utf_selection); + } + } + } + + if (!SUCCEEDED(hr)) + { + int pressed; + TaskDialog( + owner, + nullptr, // instance + nullptr, // title + L"Error showing file dialog", + nullptr, // content + TDCBF_OK_BUTTON, + TD_ERROR_ICON, + &pressed); + } +} + +} // anonymous namespace + consolewin_info::consolewin_info(debugger_windows_interface &debugger) : @@ -186,8 +367,8 @@ void consolewin_info::update_menu() if (img.is_readonly()) flags_for_writing |= MF_GRAYED; - // not working properly, removed for now until investigation can be done - //if (get_softlist_info(&img)) + // FIXME: needs a real software item picker to be useful + //if (get_softlist_info(img)) // AppendMenu(devicesubmenu, MF_STRING, new_item + DEVOPTION_ITEM, TEXT("Mount Item...")); AppendMenu(devicesubmenu, MF_STRING, new_item + DEVOPTION_OPEN, TEXT("Mount File...")); @@ -265,179 +446,14 @@ bool consolewin_info::handle_command(WPARAM wparam, LPARAM lparam) { switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX) { - case DEVOPTION_ITEM : - { - std::string filter; - build_generic_filter(nullptr, false, filter); - { - osd::text::tstring t_filter = osd::text::to_tstring(filter); - - // convert a pipe-char delimited string into a NUL delimited string - for (int i = 0; t_filter[i] != '\0'; i++) - { - if (t_filter[i] == '|') - t_filter[i] = '\0'; - } - - std::string opt_name = img->instance_name(); - std::string as = slmap.find(opt_name)->second; - - /* Make sure a folder was specified, and that it exists */ - if ((!osd::directory::open(as)) || (as.find(':') == std::string::npos)) - { - /* Default to emu directory */ - osd_get_full_path(as, "."); - } - osd::text::tstring t_dir = osd::text::to_tstring(as); - - // display the dialog - TCHAR selectedFilename[MAX_PATH]; - selectedFilename[0] = '\0'; - OPENFILENAME ofn; - memset(&ofn, 0, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = nullptr; - ofn.lpstrFile = selectedFilename; - ofn.lpstrFile[0] = '\0'; - ofn.nMaxFile = MAX_PATH; - ofn.lpstrFilter = t_filter.c_str(); - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = nullptr; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = t_dir.c_str(); - ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - - if (GetOpenFileName(&ofn)) - { - std::string buf = std::string(osd::text::from_tstring(selectedFilename)); - // Get the Item name out of the full path - size_t t1 = buf.find(".zip"); // get rid of zip name and anything after - if (t1 != std::string::npos) - buf.erase(t1); - t1 = buf.find(".7z"); // get rid of 7zip name and anything after - if (t1 != std::string::npos) - buf.erase(t1); - t1 = buf.find_last_of("\\"); // put the swlist name in - buf[t1] = ':'; - t1 = buf.find_last_of("\\"); // get rid of path; we only want the item name - buf.erase(0, t1+1); - - // load software - img->load_software(buf); - } - } - } + case DEVOPTION_ITEM: + // TODO: this is supposed to show a software list item picker - it never worked properly return true; case DEVOPTION_OPEN : - { - std::string filter; - build_generic_filter(img, false, filter); - { - osd::text::tstring t_filter = osd::text::to_tstring(filter); - - // convert a pipe-char delimited string into a NUL delimited string - for (int i = 0; t_filter[i] != '\0'; i++) - { - if (t_filter[i] == '|') - t_filter[i] = '\0'; - } - - char buf[400]; - std::string as; - strcpy(buf, machine().options().emu_options::sw_path()); - // This pulls out the first path from a multipath field - const char* t1 = strtok(buf, ";"); - if (t1) - as = t1; // the first path of many - else - as = buf; // the only path - - /* Make sure a folder was specified, and that it exists */ - if ((!osd::directory::open(as)) || (as.find(':') == std::string::npos)) - { - /* Default to emu directory */ - osd_get_full_path(as, "."); - } - osd::text::tstring t_dir = osd::text::to_tstring(as); - - TCHAR selectedFilename[MAX_PATH]; - selectedFilename[0] = '\0'; - OPENFILENAME ofn; - memset(&ofn, 0, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = nullptr; - ofn.lpstrFile = selectedFilename; - ofn.lpstrFile[0] = '\0'; - ofn.nMaxFile = MAX_PATH; - ofn.lpstrFilter = t_filter.c_str(); - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = nullptr; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = t_dir.c_str(); - ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - - if (GetOpenFileName(&ofn)) - { - auto utf8_buf = osd::text::from_tstring(selectedFilename); - img->load(utf8_buf); - } - } - } + open_image_file(*img); return true; case DEVOPTION_CREATE: - { - std::string filter; - build_generic_filter(img, true, filter); - { - osd::text::tstring t_filter = osd::text::to_tstring(filter); - // convert a pipe-char delimited string into a NUL delimited string - for (int i = 0; t_filter[i] != '\0'; i++) - { - if (t_filter[i] == '|') - t_filter[i] = '\0'; - } - - char buf[400]; - std::string as; - strcpy(buf, machine().options().emu_options::sw_path()); - // This pulls out the first path from a multipath field - const char* t1 = strtok(buf, ";"); - if (t1) - as = t1; // the first path of many - else - as = buf; // the only path - - /* Make sure a folder was specified, and that it exists */ - if ((!osd::directory::open(as)) || (as.find(':') == std::string::npos)) - { - /* Default to emu directory */ - osd_get_full_path(as, "."); - } - osd::text::tstring t_dir = osd::text::to_tstring(as); - - TCHAR selectedFilename[MAX_PATH]; - selectedFilename[0] = '\0'; - OPENFILENAME ofn; - memset(&ofn, 0, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = nullptr; - ofn.lpstrFile = selectedFilename; - ofn.lpstrFile[0] = '\0'; - ofn.nMaxFile = MAX_PATH; - ofn.lpstrFilter = t_filter.c_str(); - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = nullptr; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = t_dir.c_str(); - ofn.Flags = OFN_PATHMUSTEXIST; - - if (GetSaveFileName(&ofn)) - { - auto utf8_buf = osd::text::from_tstring(selectedFilename); - img->create(utf8_buf, img->device_get_indexed_creatable_format(0), nullptr); - } - } - } + create_image_file(*img); return true; case DEVOPTION_CLOSE: img->unload(); @@ -492,77 +508,39 @@ void consolewin_info::process_string(std::string const &string) } -void consolewin_info::build_generic_filter(device_image_interface *img, bool is_save, std::string &filter) +void consolewin_info::open_image_file(device_image_interface &device) { - std::string file_extension; - - if (img) - file_extension = img->file_extensions(); - - if (!is_save) - file_extension.append(",zip,7z"); - - add_filter_entry(filter, "Common image types", file_extension.c_str()); - - filter.append("All files (*.*)|*.*|"); - - if (!is_save) - filter.append("Compressed Images (*.zip;*.7z)|*.zip;*.7z|"); + choose_image( + device, + window(), + CLSID_FileOpenDialog, + true, + [&device] (std::string_view selection) + { + device.load(selection); + }); } -void consolewin_info::add_filter_entry(std::string &dest, const char *description, const char *extensions) +void consolewin_info::create_image_file(device_image_interface &device) { - // add the description - dest.append(description); - dest.append(" ("); - - // add the extensions to the description - copy_extension_list(dest, extensions); - - // add the trailing rparen and '|' character - dest.append(")|"); - - // now add the extension list itself - copy_extension_list(dest, extensions); - - // append a '|' - dest.append("|"); + choose_image( + device, + window(), + CLSID_FileSaveDialog, + false, + [&device] (std::string_view selection) + { + device.create(selection, device.device_get_indexed_creatable_format(0), nullptr); + }); } -void consolewin_info::copy_extension_list(std::string &dest, const char *extensions) -{ - // our extension lists are comma delimited; Win32 expects to see lists - // delimited by semicolons - char const *s = extensions; - while (*s) - { - // append a semicolon if not at the beginning - if (s != extensions) - dest.push_back(';'); - - // append ".*" - dest.append("*."); - - // append the file extension - while (*s && (*s != ',')) - dest.push_back(*s++); - - // if we found a comma, advance - while(*s == ',') - s++; - } -} - -//============================================================ -// get_softlist_info -//============================================================ -bool consolewin_info::get_softlist_info(device_image_interface *img) +bool consolewin_info::get_softlist_info(device_image_interface &device) { bool has_software = false; bool passes_tests = false; - std::string sl_dir, opt_name = img->instance_name(); + std::string sl_dir, opt_name = device.instance_name(); // Get the path to suitable software for (software_list_device &swlist : software_list_device_enumerator(machine().root_device())) @@ -578,8 +556,8 @@ bool consolewin_info::get_softlist_info(device_image_interface *img) continue; if (!has_software && (opt_name == image.instance_name())) { - const char *interface = image.image_interface(); - if (interface && part.matches_interface(interface)) + const char *intf = image.image_interface(); + if (intf && part.matches_interface(intf)) { sl_dir = "\\" + swlist.list_name(); has_software = true; diff --git a/src/osd/modules/debugger/win/consolewininfo.h b/src/osd/modules/debugger/win/consolewininfo.h index e391100ed33..2d93895b64d 100644 --- a/src/osd/modules/debugger/win/consolewininfo.h +++ b/src/osd/modules/debugger/win/consolewininfo.h @@ -47,14 +47,13 @@ private: virtual void process_string(std::string const &string) override; - static void build_generic_filter(device_image_interface *img, bool is_save, std::string &filter); - static void add_filter_entry(std::string &dest, char const *description, char const *extensions); - static void copy_extension_list(std::string &dest, char const *extensions); - bool get_softlist_info(device_image_interface *img); + void open_image_file(device_image_interface &device); + void create_image_file(device_image_interface &device); + bool get_softlist_info(device_image_interface &img); device_t *m_current_cpu; HMENU m_devices_menu; std::map slmap; }; -#endif +#endif // MAME_DEBUGGER_WIN_CONSOLEWININFO_H diff --git a/src/osd/modules/input/input_dinput.cpp b/src/osd/modules/input/input_dinput.cpp index 7295b23de12..f98ba69ae93 100644 --- a/src/osd/modules/input/input_dinput.cpp +++ b/src/osd/modules/input/input_dinput.cpp @@ -6,40 +6,27 @@ // //============================================================ -#include "input_module.h" #include "modules/osdmodule.h" #if defined(OSD_WINDOWS) -// standard windows headers -#include -#include -#include -#include +#include "emu.h" -// undef WINNT for dinput.h to prevent duplicate definition -#undef WINNT -#include -#undef interface +#include "input_dinput.h" + +#include "winutil.h" #include -// MAME headers -#include "emu.h" -#include "strconv.h" +// standard windows headers +#include +#include -// MAMEOS headers -#include "window.h" -#include "winutil.h" -#include "input_common.h" -#include "input_windows.h" -#include "input_dinput.h" +namespace { using namespace Microsoft::WRL; -namespace { - //============================================================ // dinput_joystick_pov_get_state //============================================================ diff --git a/src/osd/modules/input/input_dinput.h b/src/osd/modules/input/input_dinput.h index 20bced84883..c9e84d1f633 100644 --- a/src/osd/modules/input/input_dinput.h +++ b/src/osd/modules/input/input_dinput.h @@ -1,10 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles, Brad Hughes +//============================================================ +// +// input_dinput.h - Windows DirectInput support +// +//============================================================ #ifndef MAME_OSD_INPUT_INPUT_DINPUT_H #define MAME_OSD_INPUT_INPUT_DINPUT_H #pragma once -#include "input_common.h" +#include "input_windows.h" + #include "modules/lib/osdlib.h" +#include "modules/lib/osdobj_common.h" + +#include "window.h" + +#include "strconv.h" + +#include +#include +#include + //============================================================ // dinput_device - base directinput device @@ -52,14 +70,14 @@ public: virtual ~dinput_api_helper(); int initialize(); - template - TDevice* create_device( - running_machine &machine, - input_module_base &module, - LPCDIDEVICEINSTANCE instance, - LPCDIDATAFORMAT format1, - LPCDIDATAFORMAT format2, - dinput_cooperative_level cooperative_level) + template + TDevice *create_device( + running_machine &machine, + input_module_base &module, + LPCDIDEVICEINSTANCE instance, + LPCDIDATAFORMAT format1, + LPCDIDATAFORMAT format2, + dinput_cooperative_level cooperative_level) { HRESULT result; std::shared_ptr window; diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp index 6424a0d1099..10bc38fad05 100644 --- a/src/osd/modules/input/input_rawinput.cpp +++ b/src/osd/modules/input/input_rawinput.cpp @@ -6,32 +6,29 @@ // //============================================================ -#include "input_module.h" #include "modules/osdmodule.h" #if defined(OSD_WINDOWS) -// standard windows headers -#include -#include -#undef interface - -#include -#include -#include -#include - // MAME headers #include "emu.h" -#include "strconv.h" -// MAMEOS headers -#include "modules/lib/osdlib.h" +#include "input_windows.h" + #include "winmain.h" #include "window.h" -#include "input_common.h" -#include "input_windows.h" +#include "modules/lib/osdlib.h" +#include "strconv.h" + +#include +#include +#include +#include + +// standard windows headers +#include +#include namespace { diff --git a/src/osd/modules/input/input_win32.cpp b/src/osd/modules/input/input_win32.cpp index a02b2ee426e..17128d7c0d6 100644 --- a/src/osd/modules/input/input_win32.cpp +++ b/src/osd/modules/input/input_win32.cpp @@ -7,25 +7,18 @@ //============================================================ #include "input_module.h" -#include "modules/osdmodule.h" #if defined(OSD_WINDOWS) -// standard windows headers -#include -#include -#undef interface - -// MAME headers #include "emu.h" + +#include "input_windows.h" + #include "strconv.h" -// MAMEOS headers -#include "winmain.h" -#include "window.h" +// standard windows headers +#include -#include "input_common.h" -#include "input_windows.h" namespace { diff --git a/src/osd/modules/input/input_windows.cpp b/src/osd/modules/input/input_windows.cpp index 4415e71f3a4..60306765f72 100644 --- a/src/osd/modules/input/input_windows.cpp +++ b/src/osd/modules/input/input_windows.cpp @@ -13,16 +13,15 @@ // MAME headers #include "emu.h" -// MAMEOS headers +#include "input_windows.h" + +#include "window.h" #include "winmain.h" #include "util/language.h" #include "osdepend.h" -#include "input_common.h" -#include "input_windows.h" - bool windows_osd_interface::should_hide_mouse() const { diff --git a/src/osd/modules/input/input_windows.h b/src/osd/modules/input/input_windows.h index 67a2efbc780..7acf8586876 100644 --- a/src/osd/modules/input/input_windows.h +++ b/src/osd/modules/input/input_windows.h @@ -10,13 +10,15 @@ #pragma once -// standard windows headers -#include -#undef interface +#include "input_common.h" #include "window.h" #include "winmain.h" +// standard windows headers +#include + + //============================================================ // TYPEDEFS //============================================================ diff --git a/src/osd/modules/input/input_winhybrid.cpp b/src/osd/modules/input/input_winhybrid.cpp index 4aad202ad4c..a2a020cde9f 100644 --- a/src/osd/modules/input/input_winhybrid.cpp +++ b/src/osd/modules/input/input_winhybrid.cpp @@ -6,46 +6,31 @@ // //============================================================ -#include "input_module.h" #include "modules/osdmodule.h" #if defined(OSD_WINDOWS) +#include "emu.h" + +#include "input_dinput.h" +#include "input_xinput.h" + #include #include -// standard windows headers -#include -#include +#include #include -// XInput/DirectInput -#include -#include - -#undef interface - -// MAME headers -#include "emu.h" - -// MAMEOS headers -#include "strconv.h" -#include "winmain.h" - -#include "input_common.h" -#include "input_windows.h" -#include "input_xinput.h" -#include "input_dinput.h" namespace { using namespace Microsoft::WRL; -template +template class ComArray { private: - std::vector m_entries; + std::vector m_entries; public: ComArray(size_t capacity) : m_entries(capacity, nullptr) diff --git a/src/osd/modules/input/input_xinput.cpp b/src/osd/modules/input/input_xinput.cpp index 152e16b4e81..92874acde07 100644 --- a/src/osd/modules/input/input_xinput.cpp +++ b/src/osd/modules/input/input_xinput.cpp @@ -6,30 +6,18 @@ // //============================================================ -#include "input_module.h" #include "modules/osdmodule.h" #if defined(OSD_WINDOWS) -// standard windows headers -#include - -// XInput header -#include - -#undef interface - -// MAME headers #include "emu.h" -// MAMEOS headers -#include "winutil.h" -#include "winmain.h" - -#include "input_common.h" -#include "input_windows.h" #include "input_xinput.h" +// standard windows headers +#include + + #define XINPUT_LIBRARIES { "xinput1_4.dll", "xinput9_1_0.dll" } #define XINPUT_AXIS_MINVALUE -32767 diff --git a/src/osd/modules/input/input_xinput.h b/src/osd/modules/input/input_xinput.h index 77aa7009a6c..bd918f9aacb 100644 --- a/src/osd/modules/input/input_xinput.h +++ b/src/osd/modules/input/input_xinput.h @@ -3,6 +3,8 @@ #pragma once +#include "input_windows.h" + #include "modules/lib/osdlib.h" #include @@ -10,8 +12,12 @@ #include #include +#include + + class xinput_joystick_device; + class xinput_api_helper : public std::enable_shared_from_this { public: @@ -40,6 +46,7 @@ private: xinput_get_caps_fn XInputGetCapabilities = nullptr; }; + class xinput_joystick_device : public device_info { public: diff --git a/src/osd/modules/sound/direct_sound.cpp b/src/osd/modules/sound/direct_sound.cpp index fcdc13e07df..5f245bd6359 100644 --- a/src/osd/modules/sound/direct_sound.cpp +++ b/src/osd/modules/sound/direct_sound.cpp @@ -11,15 +11,6 @@ #if defined(OSD_WINDOWS) || defined(SDLMAME_WIN32) -// standard windows headers -#include -#include - -// undef WINNT for dsound.h to prevent duplicate definition -#undef WINNT -#include -#undef interface - // MAME headers #include "emu.h" #include "osdepend.h" @@ -33,214 +24,217 @@ #include "winmain.h" #include "window.h" #endif + #include +// standard windows headers +#include +#include +#include +#include + + //============================================================ // DEBUGGING //============================================================ #define LOG_SOUND 0 -#define LOG(x) do { if (LOG_SOUND) osd_printf_verbose x; } while(0) +#define LOG(...) do { if (LOG_SOUND) osd_printf_verbose(__VA_ARGS__); } while(0) -class sound_direct_sound : public osd_module, public sound_module +namespace { + +class buffer_base { public: + explicit operator bool() const { return bool(m_buffer); } - sound_direct_sound() : - osd_module(OSD_SOUND_PROVIDER, "dsound"), - sound_module(), - m_dsound(nullptr), - m_bytes_per_sample(0), - m_primary_buffer(), - m_stream_buffer(), - m_stream_buffer_in(0), - m_buffer_underflows(0), - m_buffer_overflows(0) + unsigned long release() { return m_buffer.Reset(); } + +protected: + Microsoft::WRL::ComPtr m_buffer; +}; + + +class primary_buffer : public buffer_base +{ +public: + HRESULT create(LPDIRECTSOUND dsound) { + assert(!m_buffer); + DSBUFFERDESC desc; + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_GETCURRENTPOSITION2; + desc.lpwfxFormat = nullptr; + return dsound->CreateSoundBuffer(&desc, &m_buffer, nullptr); } - virtual ~sound_direct_sound() { } - - virtual int init(osd_options const &options) override; - virtual void exit() override; - // sound_module - virtual void update_audio_stream(bool is_throttled, int16_t const *buffer, int samples_this_frame) override; - virtual void set_mastervolume(int attenuation) override; + HRESULT get_format(WAVEFORMATEX &format) const + { + assert(m_buffer); + return m_buffer->GetFormat(&format, sizeof(format), nullptr); + } -private: - class buffer + HRESULT set_format(WAVEFORMATEX const &format) const { - public: - buffer() : m_buffer(nullptr) { } - ~buffer() { release(); } + assert(m_buffer); + return m_buffer->SetFormat(&format); + } +}; - ULONG release() - { - ULONG const result = m_buffer ? m_buffer->Release() : 0; - m_buffer = nullptr; - return result; - } - operator bool() const { return m_buffer; } +class stream_buffer : public buffer_base +{ +public: + HRESULT create(LPDIRECTSOUND dsound, DWORD size, WAVEFORMATEX &format) + { + assert(!m_buffer); + DSBUFFERDESC desc; + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; + desc.dwBufferBytes = size; + desc.lpwfxFormat = &format; + m_size = size; + return dsound->CreateSoundBuffer(&desc, &m_buffer, nullptr); + } - protected: - LPDIRECTSOUNDBUFFER m_buffer; - }; + HRESULT play_looping() const + { + assert(m_buffer); + return m_buffer->Play(0, 0, DSBPLAY_LOOPING); + } + HRESULT stop() const + { + assert(m_buffer); + return m_buffer->Stop(); + } + HRESULT set_volume(LONG volume) const + { + assert(m_buffer); + return m_buffer->SetVolume(volume); + } + HRESULT set_min_volume() { return set_volume(DSBVOLUME_MIN); } - class primary_buffer : public buffer + HRESULT get_current_positions(DWORD &play_pos, DWORD &write_pos) const { - public: - HRESULT create(LPDIRECTSOUND dsound) - { - assert(!m_buffer); - DSBUFFERDESC desc; - memset(&desc, 0, sizeof(desc)); - desc.dwSize = sizeof(desc); - desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_GETCURRENTPOSITION2; - desc.lpwfxFormat = nullptr; - return dsound->CreateSoundBuffer(&desc, &m_buffer, nullptr); - } + assert(m_buffer); + return m_buffer->GetCurrentPosition(&play_pos, &write_pos); + } + HRESULT copy_data(DWORD cursor, DWORD bytes, void const *data) + { + HRESULT result = lock(cursor, bytes); + if (DS_OK != result) + return result; - HRESULT get_format(WAVEFORMATEX &format) const - { - assert(m_buffer); - return m_buffer->GetFormat(&format, sizeof(format), nullptr); - } - HRESULT set_format(WAVEFORMATEX const &format) const + assert(m_bytes1); + assert((m_locked1 + m_locked2) >= bytes); + memcpy(m_bytes1, data, std::min(m_locked1, bytes)); + if (m_locked1 < bytes) { - assert(m_buffer); - return m_buffer->SetFormat(&format); + assert(m_bytes2); + memcpy(m_bytes2, (uint8_t const *)data + m_locked1, bytes - m_locked1); } - }; - class stream_buffer : public buffer + unlock(); + return DS_OK; + } + HRESULT clear() { - public: - stream_buffer() : m_size(0), m_bytes1(nullptr), m_bytes2(nullptr), m_locked1(0), m_locked2(0) { } + HRESULT result = lock_all(); + if (DS_OK != result) + return result; - HRESULT create(LPDIRECTSOUND dsound, DWORD size, WAVEFORMATEX &format) - { - assert(!m_buffer); - DSBUFFERDESC desc; - memset(&desc, 0, sizeof(desc)); - desc.dwSize = sizeof(desc); - desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; - desc.dwBufferBytes = size; - desc.lpwfxFormat = &format; - m_size = size; - return dsound->CreateSoundBuffer(&desc, &m_buffer, nullptr); - } + assert(m_bytes1); + assert(!m_bytes2); + assert(m_size == m_locked1); + assert(0U == m_locked2); + memset(m_bytes1, 0, m_locked1); - HRESULT play_looping() const - { - assert(m_buffer); - return m_buffer->Play(0, 0, DSBPLAY_LOOPING); - } - HRESULT stop() const - { - assert(m_buffer); - return m_buffer->Stop(); - } - HRESULT set_volume(LONG volume) const - { - assert(m_buffer); - return m_buffer->SetVolume(volume); - } - HRESULT set_min_volume() { return set_volume(DSBVOLUME_MIN); } + unlock(); + return DS_OK; + } - HRESULT get_current_positions(DWORD &play_pos, DWORD &write_pos) const - { - assert(m_buffer); - return m_buffer->GetCurrentPosition(&play_pos, &write_pos); - } - HRESULT copy_data(DWORD cursor, DWORD bytes, void const *data) - { - HRESULT result = lock(cursor, bytes); - if (DS_OK != result) - return result; - - assert(m_bytes1); - assert((m_locked1 + m_locked2) >= bytes); - memcpy(m_bytes1, data, std::min(m_locked1, bytes)); - if (m_locked1 < bytes) - { - assert(m_bytes2); - memcpy(m_bytes2, (uint8_t const *)data + m_locked1, bytes - m_locked1); - } - - unlock(); - return DS_OK; - } - HRESULT clear() - { - HRESULT result = lock_all(); - if (DS_OK != result) - return result; - - assert(m_bytes1); - assert(!m_bytes2); - assert(m_size == m_locked1); - assert(0U == m_locked2); - memset(m_bytes1, 0, m_locked1); - - unlock(); - return DS_OK; - } + DWORD size() const { return m_size; } - DWORD size() const { return m_size; } +private: + HRESULT lock(DWORD cursor, DWORD bytes) + { + assert(cursor < m_size); + assert(bytes <= m_size); + assert(m_buffer); + assert(!m_bytes1); + return m_buffer->Lock( + cursor, bytes, + &m_bytes1, + &m_locked1, + &m_bytes2, + &m_locked2, + 0); + } + HRESULT lock_all() { return lock(0, m_size); } + HRESULT unlock() + { + assert(m_buffer); + assert(m_bytes1); + HRESULT const result = m_buffer->Unlock( + m_bytes1, + m_locked1, + m_bytes2, + m_locked2); + m_bytes1 = m_bytes2 = nullptr; + m_locked1 = m_locked2 = 0; + return result; + } - protected: - HRESULT lock(DWORD cursor, DWORD bytes) - { - assert(cursor < m_size); - assert(bytes <= m_size); - assert(m_buffer); - assert(!m_bytes1); - return m_buffer->Lock( - cursor, bytes, - &m_bytes1, - &m_locked1, - &m_bytes2, - &m_locked2, - 0); - } - HRESULT lock_all() { return lock(0, m_size); } - HRESULT unlock() - { - assert(m_buffer); - assert(m_bytes1); - HRESULT const result = m_buffer->Unlock( - m_bytes1, - m_locked1, - m_bytes2, - m_locked2); - m_bytes1 = m_bytes2 = nullptr; - m_locked1 = m_locked2 = 0; - return result; - } + DWORD m_size = 0; + void *m_bytes1 = nullptr, *m_bytes2 = nullptr; + DWORD m_locked1 = 0, m_locked2 = 0; +}; - DWORD m_size; - void *m_bytes1, *m_bytes2; - DWORD m_locked1, m_locked2; - }; +class sound_direct_sound : public osd_module, public sound_module +{ +public: + + sound_direct_sound() : + osd_module(OSD_SOUND_PROVIDER, "dsound"), + sound_module(), + m_bytes_per_sample(0), + m_primary_buffer(), + m_stream_buffer(), + m_stream_buffer_in(0), + m_buffer_underflows(0), + m_buffer_overflows(0) + { + } + virtual ~sound_direct_sound() { } + + virtual int init(osd_options const &options) override; + virtual void exit() override; + + // sound_module + virtual void update_audio_stream(bool is_throttled, int16_t const *buffer, int samples_this_frame) override; + virtual void set_mastervolume(int attenuation) override; + +private: HRESULT dsound_init(); void dsound_kill(); HRESULT create_buffers(DWORD size, WAVEFORMATEX &format); void destroy_buffers(); // DirectSound objects - LPDIRECTSOUND m_dsound; + Microsoft::WRL::ComPtr m_dsound; // descriptors and formats - uint32_t m_bytes_per_sample; + uint32_t m_bytes_per_sample; // sound buffers primary_buffer m_primary_buffer; stream_buffer m_stream_buffer; - uint32_t m_stream_buffer_in; + uint32_t m_stream_buffer_in; // buffer over/underflow counts unsigned m_buffer_underflows; @@ -281,7 +275,7 @@ void sound_direct_sound::exit() m_buffer_underflows); } - LOG(("Sound buffer: overflows=%u underflows=%u\n", m_buffer_overflows, m_buffer_underflows)); + LOG("Sound buffer: overflows=%u underflows=%u\n", m_buffer_overflows, m_buffer_underflows); } @@ -385,7 +379,7 @@ HRESULT sound_direct_sound::dsound_init() result = DirectSoundCreate(nullptr, &m_dsound, nullptr); if (result != DS_OK) { - osd_printf_error("Error creating DirectSound: %08x\n", (unsigned)result); + osd_printf_error("Error creating DirectSound: %08x\n", result); goto error; } @@ -395,7 +389,7 @@ HRESULT sound_direct_sound::dsound_init() result = m_dsound->GetCaps(&dsound_caps); if (result != DS_OK) { - osd_printf_error("Error getting DirectSound capabilities: %08x\n", (unsigned)result); + osd_printf_error("Error getting DirectSound capabilities: %08x\n", result); goto error; } @@ -413,7 +407,7 @@ HRESULT sound_direct_sound::dsound_init() } if (result != DS_OK) { - osd_printf_error("Error setting DirectSound cooperative level: %08x\n", (unsigned)result); + osd_printf_error("Error setting DirectSound cooperative level: %08x\n", result); goto error; } @@ -432,7 +426,7 @@ HRESULT sound_direct_sound::dsound_init() DWORD stream_buffer_size = stream_format.nSamplesPerSec * stream_format.nBlockAlign * audio_latency / 10; stream_buffer_size = std::max(DWORD(1024), (stream_buffer_size / 1024) * 1024); - LOG(("stream_buffer_size = %u\n", (unsigned)stream_buffer_size)); + LOG("stream_buffer_size = %u\n", stream_buffer_size); // create the buffers m_bytes_per_sample = stream_format.nBlockAlign; @@ -446,7 +440,7 @@ HRESULT sound_direct_sound::dsound_init() result = m_stream_buffer.play_looping(); if (result != DS_OK) { - osd_printf_error("Error playing: %08x\n", (uint32_t)result); + osd_printf_error("Error playing: %08x\n", result); goto error; } return DS_OK; @@ -466,9 +460,7 @@ error: void sound_direct_sound::dsound_kill() { // release the object - if (m_dsound) - m_dsound->Release(); - m_dsound = nullptr; + m_dsound.Reset(); } @@ -484,10 +476,10 @@ HRESULT sound_direct_sound::create_buffers(DWORD size, WAVEFORMATEX &format) HRESULT result; // create the primary buffer - result = m_primary_buffer.create(m_dsound); + result = m_primary_buffer.create(m_dsound.Get()); if (result != DS_OK) { - osd_printf_error("Error creating primary DirectSound buffer: %08x\n", (unsigned)result); + osd_printf_error("Error creating primary DirectSound buffer: %08x\n", result); goto error; } @@ -495,7 +487,7 @@ HRESULT sound_direct_sound::create_buffers(DWORD size, WAVEFORMATEX &format) result = m_primary_buffer.set_format(format); if (result != DS_OK) { - osd_printf_error("Error setting primary DirectSound buffer format: %08x\n", (unsigned)result); + osd_printf_error("Error setting primary DirectSound buffer format: %08x\n", result); goto error; } @@ -504,20 +496,20 @@ HRESULT sound_direct_sound::create_buffers(DWORD size, WAVEFORMATEX &format) result = m_primary_buffer.get_format(primary_format); if (result != DS_OK) { - osd_printf_error("Error getting primary DirectSound buffer format: %08x\n", (unsigned)result); + osd_printf_error("Error getting primary DirectSound buffer format: %08x\n", result); goto error; } osd_printf_verbose( "DirectSound: Primary buffer: %d Hz, %d bits, %d channels\n", - (int)primary_format.nSamplesPerSec, - (int)primary_format.wBitsPerSample, - (int)primary_format.nChannels); + primary_format.nSamplesPerSec, + primary_format.wBitsPerSample, + primary_format.nChannels); // create the stream buffer - result = m_stream_buffer.create(m_dsound, size, format); + result = m_stream_buffer.create(m_dsound.Get(), size, format); if (result != DS_OK) { - osd_printf_error("Error creating DirectSound stream buffer: %08x\n", (unsigned)result); + osd_printf_error("Error creating DirectSound stream buffer: %08x\n", result); goto error; } @@ -525,7 +517,7 @@ HRESULT sound_direct_sound::create_buffers(DWORD size, WAVEFORMATEX &format) result = m_stream_buffer.clear(); if (result != DS_OK) { - osd_printf_error("Error locking DirectSound stream buffer: %08x\n", (unsigned)result); + osd_printf_error("Error locking DirectSound stream buffer: %08x\n", result); goto error; } @@ -555,8 +547,11 @@ void sound_direct_sound::destroy_buffers() m_primary_buffer.release(); } + #else // defined(OSD_WINDOWS) || defined(SDLMAME_WIN32) MODULE_NOT_SUPPORTED(sound_direct_sound, OSD_SOUND_PROVIDER, "dsound") #endif // defined(OSD_WINDOWS) || defined(SDLMAME_WIN32) +} // anonymous namespace + MODULE_DEFINITION(SOUND_DSOUND, sound_direct_sound) diff --git a/src/osd/windows/winutil.cpp b/src/osd/windows/winutil.cpp index a9358c67737..7d790949178 100644 --- a/src/osd/windows/winutil.cpp +++ b/src/osd/windows/winutil.cpp @@ -6,17 +6,17 @@ // //============================================================ -// standard windows headers -#include -#include +#include "winutil.h" -// MAME headers -#include "emu.h" +// lib/util +#include "timeconv.h" -// MAMEOS headers -#include "winutil.h" +// osd #include "strconv.h" -#include "timeconv.h" + +// standard windows headers +#include +#include //============================================================ diff --git a/src/osd/windows/winutil.h b/src/osd/windows/winutil.h index 4e0eac0d27a..0a5952b5279 100644 --- a/src/osd/windows/winutil.h +++ b/src/osd/windows/winutil.h @@ -6,18 +6,23 @@ // //============================================================ -#ifndef __WINUTIL__ -#define __WINUTIL__ +#ifndef MAME_OSD_WINDOWS_WINUTIL_H +#define MAME_OSD_WINDOWS_WINUTIL_H + +#pragma once #include "osdfile.h" -#include -#include + +#include #include +#include + + // Shared code osd::directory::entry::entry_type win_attributes_to_entry_type(DWORD attributes); std::chrono::system_clock::time_point win_time_point_from_filetime(LPFILETIME file_time); -BOOL win_is_gui_application(void); +BOOL win_is_gui_application(); HMODULE WINAPI GetModuleHandleUni(); -#endif // __WINUTIL__ +#endif // MAME_OSD_WINDOWS_WINUTIL_H -- cgit v1.2.3