summaryrefslogtreecommitdiffstats
path: root/docs/release/src/osd/winui/mui_util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'docs/release/src/osd/winui/mui_util.cpp')
-rw-r--r--docs/release/src/osd/winui/mui_util.cpp760
1 files changed, 760 insertions, 0 deletions
diff --git a/docs/release/src/osd/winui/mui_util.cpp b/docs/release/src/osd/winui/mui_util.cpp
new file mode 100644
index 00000000000..abb45522b1b
--- /dev/null
+++ b/docs/release/src/osd/winui/mui_util.cpp
@@ -0,0 +1,760 @@
+// For licensing and usage information, read docs/winui_license.txt
+// MASTER
+//****************************************************************************
+
+/***************************************************************************
+
+ mui_util.c
+
+ ***************************************************************************/
+
+// standard windows headers
+#include <windows.h>
+#include <shellapi.h>
+
+// standard C headers
+#include <stdio.h>
+#include <tchar.h>
+
+// MAME/MAMEUI headers
+#include "emu.h"
+#include "screen.h"
+#include "speaker.h"
+#include "unzip.h"
+#include "sound/samples.h"
+#include "winutf8.h"
+#include "strconv.h"
+#include "winui.h"
+#include "mui_util.h"
+#include "mui_opts.h"
+#include "drivenum.h"
+#include "machine/ram.h"
+
+#include <shlwapi.h>
+#include <vector>
+
+/***************************************************************************
+ function prototypes
+ ***************************************************************************/
+
+/***************************************************************************
+ External variables
+ ***************************************************************************/
+
+/***************************************************************************
+ Internal structures
+ ***************************************************************************/
+struct DriversInfo
+{
+ int screenCount;
+ bool isClone;
+ bool isBroken;
+ bool isHarddisk;
+ bool hasOptionalBIOS;
+ bool isStereo;
+ bool isVector;
+ bool usesRoms;
+ bool usesSamples;
+ bool usesTrackball;
+ bool usesLightGun;
+ bool usesMouse;
+ bool supportsSaveState;
+ bool isVertical;
+ bool hasRam;
+};
+
+static std::vector<DriversInfo> drivers_info;
+
+
+enum
+{
+ DRIVER_CACHE_SCREEN = 0x000F,
+ DRIVER_CACHE_ROMS = 0x0010,
+ DRIVER_CACHE_CLONE = 0x0020,
+ DRIVER_CACHE_STEREO = 0x0040,
+ DRIVER_CACHE_BIOS = 0x0080,
+ DRIVER_CACHE_TRACKBALL = 0x0100,
+ DRIVER_CACHE_HARDDISK = 0x0200,
+ DRIVER_CACHE_SAMPLES = 0x0400,
+ DRIVER_CACHE_LIGHTGUN = 0x0800,
+ DRIVER_CACHE_VECTOR = 0x1000,
+ DRIVER_CACHE_MOUSE = 0x2000,
+ DRIVER_CACHE_RAM = 0x4000,
+};
+
+/***************************************************************************
+ External functions
+ ***************************************************************************/
+
+/*
+ ErrorMsg
+*/
+void __cdecl ErrorMsg(const char* fmt, ...)
+{
+ static FILE* pFile = NULL;
+ DWORD dwWritten;
+ char buf[5000];
+ char buf2[5000];
+ va_list va;
+
+ va_start(va, fmt);
+
+ vsprintf(buf, fmt, va);
+
+ win_message_box_utf8(GetActiveWindow(), buf, MAMEUINAME, MB_OK | MB_ICONERROR);
+
+ strcpy(buf2, MAMEUINAME ": ");
+ strcat(buf2,buf);
+ strcat(buf2, "\n");
+
+ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf2, strlen(buf2), &dwWritten, NULL);
+
+ if (pFile == NULL)
+ pFile = fopen("debug.txt", "wt");
+
+ if (pFile != NULL)
+ {
+ fprintf(pFile, "%s", buf2);
+ fflush(pFile);
+ }
+
+ va_end(va);
+}
+
+void __cdecl dprintf(const char* fmt, ...)
+{
+ char buf[5000];
+ va_list va;
+
+ va_start(va, fmt);
+
+ _vsnprintf(buf,sizeof(buf),fmt,va);
+
+ win_output_debug_string_utf8(buf);
+
+ va_end(va);
+}
+
+UINT GetDepth(HWND hWnd)
+{
+ UINT nBPP;
+ HDC hDC;
+
+ hDC = GetDC(hWnd);
+
+ nBPP = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
+
+ ReleaseDC(hWnd, hDC);
+
+ return nBPP;
+}
+
+/*
+ * Return TRUE if comctl32.dll is version 4.71 or greater
+ * otherwise return FALSE.
+ */
+LONG GetCommonControlVersion()
+{
+ HMODULE hModule = GetModuleHandle(TEXT("comctl32"));
+
+ if (hModule)
+ {
+ FARPROC lpfnICCE = GetProcAddress(hModule, "InitCommonControlsEx");
+
+ if (NULL != lpfnICCE)
+ {
+ FARPROC lpfnDLLI = GetProcAddress(hModule, "DllInstall");
+
+ if (NULL != lpfnDLLI)
+ {
+ /* comctl 4.71 or greater */
+
+ // see if we can find out exactly
+
+ DLLGETVERSIONPROC pDllGetVersion;
+ pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hModule, "DllGetVersion");
+
+ /* Because some DLLs might not implement this function, you
+ must test for it explicitly. Depending on the particular
+ DLL, the lack of a DllGetVersion function can be a useful
+ indicator of the version. */
+
+ if(pDllGetVersion)
+ {
+ DLLVERSIONINFO dvi;
+ HRESULT hr;
+
+ ZeroMemory(&dvi, sizeof(dvi));
+ dvi.cbSize = sizeof(dvi);
+
+ hr = (*pDllGetVersion)(&dvi);
+
+ if (SUCCEEDED(hr))
+ {
+ return PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
+ }
+ }
+ return PACKVERSION(4,71);
+ }
+ return PACKVERSION(4,7);
+ }
+ return PACKVERSION(4,0);
+ }
+ /* DLL not found */
+ return PACKVERSION(0,0);
+}
+
+void DisplayTextFile(HWND hWnd, const char *cName)
+{
+ HINSTANCE hErr;
+ LPCTSTR msg = 0;
+ LPTSTR tName;
+
+ tName = ui_wstring_from_utf8(cName);
+ if( !tName )
+ return;
+
+ hErr = ShellExecute(hWnd, NULL, tName, NULL, NULL, SW_SHOWNORMAL);
+ if ((uintptr_t)hErr > 32)
+ {
+ free(tName);
+ return;
+ }
+
+ switch((uintptr_t)hErr)
+ {
+ case 0:
+ msg = TEXT("The operating system is out of memory or resources.");
+ break;
+
+ case ERROR_FILE_NOT_FOUND:
+ msg = TEXT("The specified file was not found.");
+ break;
+
+ case SE_ERR_NOASSOC :
+ msg = TEXT("There is no application associated with the given filename extension.");
+ break;
+
+ case SE_ERR_OOM :
+ msg = TEXT("There was not enough memory to complete the operation.");
+ break;
+
+ case SE_ERR_PNF :
+ msg = TEXT("The specified path was not found.");
+ break;
+
+ case SE_ERR_SHARE :
+ msg = TEXT("A sharing violation occurred.");
+ break;
+
+ default:
+ msg = TEXT("Unknown error.");
+ }
+
+ MessageBox(NULL, msg, tName, MB_OK);
+
+ free(tName);
+}
+
+char* MyStrStrI(const char* pFirst, const char* pSrch)
+{
+ char* cp = (char*)pFirst;
+ char* s1;
+ char* s2;
+
+ while (*cp)
+ {
+ s1 = cp;
+ s2 = (char*)pSrch;
+
+ while (*s1 && *s2 && !core_strnicmp(s1, s2, 1))
+ s1++, s2++;
+
+ if (!*s2)
+ return cp;
+
+ cp++;
+ }
+ return NULL;
+}
+
+char * ConvertToWindowsNewlines(const char *source)
+{
+ static char buf[2048 * 2048];
+ char *dest;
+
+ dest = buf;
+ while (*source != 0)
+ {
+ if (*source == '\n')
+ {
+ *dest++ = '\r';
+ *dest++ = '\n';
+ }
+ else
+ *dest++ = *source;
+ source++;
+ }
+ *dest = 0;
+ return buf;
+}
+
+/* Lop off path and extention from a source file name
+ * This assumes their is a pathname passed to the function
+ * like src\drivers\blah.c
+ */
+const char * GetDriverFilename(int nIndex)
+{
+ static char tmp[40];
+ std::string driver = core_filename_extract_base(driver_list::driver(nIndex).source_file);
+ strcpy(tmp, driver.c_str());
+ return tmp;
+}
+
+BOOL isDriverVector(const machine_config *config)
+{
+ const screen_device *screen = config->first_screen();
+
+ if (screen)
+ {
+ if (SCREEN_TYPE_VECTOR == screen->screen_type())
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int numberOfScreens(const machine_config *config)
+{
+ screen_device_iterator scriter(config->root_device());
+ return scriter.count();
+}
+
+int numberOfSpeakers(const machine_config *config)
+{
+ speaker_device_iterator iter(config->root_device());
+ return iter.count();
+}
+
+static void SetDriversInfo(void)
+{
+ int ndriver;
+ int cache = -1;
+ int total = driver_list::total();
+ struct DriversInfo *gameinfo = NULL;
+
+ for (ndriver = 0; ndriver < total; ndriver++)
+ {
+ gameinfo = &drivers_info[ndriver];
+ cache = (gameinfo->screenCount & DRIVER_CACHE_SCREEN);
+ if (gameinfo->isClone) cache += DRIVER_CACHE_CLONE;
+ if (gameinfo->isHarddisk) cache += DRIVER_CACHE_HARDDISK;
+ if (gameinfo->hasOptionalBIOS) cache += DRIVER_CACHE_BIOS;
+ if (gameinfo->isStereo) cache += DRIVER_CACHE_STEREO;
+ if (gameinfo->isVector) cache += DRIVER_CACHE_VECTOR;
+ if (gameinfo->usesRoms) cache += DRIVER_CACHE_ROMS;
+ if (gameinfo->usesSamples) cache += DRIVER_CACHE_SAMPLES;
+ if (gameinfo->usesTrackball) cache += DRIVER_CACHE_TRACKBALL;
+ if (gameinfo->usesLightGun) cache += DRIVER_CACHE_LIGHTGUN;
+ if (gameinfo->usesMouse) cache += DRIVER_CACHE_MOUSE;
+ if (gameinfo->hasRam) cache += DRIVER_CACHE_RAM;
+
+ SetDriverCache(ndriver, cache);
+ }
+}
+
+static void InitDriversInfo(void)
+{
+ int ndriver;
+ int num_speakers;
+ int total = driver_list::total();
+ const game_driver *gamedrv = NULL;
+ struct DriversInfo *gameinfo = NULL;
+ const rom_entry *region, *rom;
+
+ for (ndriver = 0; ndriver < total; ndriver++)
+ {
+ gamedrv = &driver_list::driver(ndriver);
+ gameinfo = &drivers_info[ndriver];
+ machine_config config(*gamedrv, MameUIGlobal());
+
+ gameinfo->isClone = (GetParentRomSetIndex(gamedrv) != -1);
+ gameinfo->isBroken = (gamedrv->flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_MECHANICAL)) ? true : false;
+ gameinfo->supportsSaveState = ((gamedrv->flags & MACHINE_SUPPORTS_SAVE) != 0);
+ gameinfo->isHarddisk = FALSE;
+ gameinfo->isVertical = (gamedrv->flags & ORIENTATION_SWAP_XY) ? TRUE : FALSE;
+
+ ram_device_iterator iter1(config.root_device());
+ gameinfo->hasRam = (iter1.first() );
+
+ for (device_t &device : device_iterator(config.root_device()))
+ for (region = rom_first_region(device); region; region = rom_next_region(region))
+ if (ROMREGION_ISDISKDATA(region))
+ gameinfo->isHarddisk = TRUE;
+
+ gameinfo->hasOptionalBIOS = FALSE;
+ if (gamedrv->rom)
+ {
+ auto rom_entries = rom_build_entries(gamedrv->rom);
+ for (rom = rom_entries.data(); !ROMENTRY_ISEND(rom); rom++)
+ if (ROMENTRY_ISSYSTEM_BIOS(rom))
+ gameinfo->hasOptionalBIOS = TRUE;
+ }
+
+ num_speakers = numberOfSpeakers(&config);
+
+ gameinfo->isStereo = (num_speakers > 1);
+ gameinfo->screenCount = numberOfScreens(&config);
+ gameinfo->isVector = isDriverVector(&config); // ((drv.video_attributes & VIDEO_TYPE_VECTOR) != 0);
+ gameinfo->usesRoms = FALSE;
+ for (device_t &device : device_iterator(config.root_device()))
+ for (region = rom_first_region(device); region; region = rom_next_region(region))
+ for (rom = rom_first_file(region); rom; rom = rom_next_file(rom))
+ gameinfo->usesRoms = TRUE;
+
+ gameinfo->usesSamples = FALSE;
+
+ samples_device_iterator iter(config.root_device());
+ if (iter.first())
+ gameinfo->usesSamples = TRUE;
+
+ gameinfo->usesTrackball = FALSE;
+ gameinfo->usesLightGun = FALSE;
+ if (gamedrv->ipt)
+ {
+ ioport_list portlist;
+ std::string errors;
+ for (device_t &cfg : device_iterator(config.root_device()))
+ if (cfg.input_ports())
+ portlist.append(cfg, errors);
+
+ for (auto &port : portlist)
+ {
+ for (ioport_field &field : port.second->fields())
+ {
+ UINT32 type;
+ type = field.type();
+ if (type == IPT_END)
+ break;
+ if (type == IPT_DIAL || type == IPT_PADDLE ||
+ type == IPT_TRACKBALL_X || type == IPT_TRACKBALL_Y ||
+ type == IPT_AD_STICK_X || type == IPT_AD_STICK_Y)
+ gameinfo->usesTrackball = TRUE;
+ if (type == IPT_LIGHTGUN_X || type == IPT_LIGHTGUN_Y)
+ gameinfo->usesLightGun = TRUE;
+ if (type == IPT_MOUSE_X || type == IPT_MOUSE_Y)
+ gameinfo->usesMouse = TRUE;
+ }
+ }
+ }
+ }
+
+ SetDriversInfo();
+}
+
+static int InitDriversCache(void)
+{
+ int cache = -1;
+ int total = driver_list::total();
+ const game_driver *gamedrv = NULL;
+ struct DriversInfo *gameinfo = NULL;
+ int ndriver;
+
+ if (RequiredDriverCache())
+ {
+ InitDriversInfo();
+ return 0;
+ }
+
+ for (ndriver = 0; ndriver < total; ndriver++)
+ {
+ gamedrv = &driver_list::driver(ndriver);
+ gameinfo = &drivers_info[ndriver];
+ cache = GetDriverCache(ndriver);
+
+ if (cache == -1)
+ {
+ InitDriversInfo();
+ break;
+ }
+
+ gameinfo->isBroken = (gamedrv->flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_MECHANICAL)) ? true : false;
+ gameinfo->supportsSaveState = ((gamedrv->flags & MACHINE_SUPPORTS_SAVE) != 0);
+ gameinfo->isVertical = (gamedrv->flags & ORIENTATION_SWAP_XY) ? TRUE : FALSE;
+ gameinfo->screenCount = cache & DRIVER_CACHE_SCREEN;
+ gameinfo->isClone = ((cache & DRIVER_CACHE_CLONE) != 0);
+ gameinfo->isHarddisk = ((cache & DRIVER_CACHE_HARDDISK) != 0);
+ gameinfo->hasOptionalBIOS = ((cache & DRIVER_CACHE_BIOS) != 0);
+ gameinfo->isStereo = ((cache & DRIVER_CACHE_STEREO) != 0);
+ gameinfo->isVector = ((cache & DRIVER_CACHE_VECTOR) != 0);
+ gameinfo->usesRoms = ((cache & DRIVER_CACHE_ROMS) != 0);
+ gameinfo->usesSamples = ((cache & DRIVER_CACHE_SAMPLES) != 0);
+ gameinfo->usesTrackball = ((cache & DRIVER_CACHE_TRACKBALL) != 0);
+ gameinfo->usesLightGun = ((cache & DRIVER_CACHE_LIGHTGUN) != 0);
+ gameinfo->usesMouse = ((cache & DRIVER_CACHE_MOUSE) != 0);
+ gameinfo->hasRam = ((cache & DRIVER_CACHE_RAM) != 0);
+ }
+
+ return 0;
+}
+
+static struct DriversInfo* GetDriversInfo(int driver_index)
+{
+ static bool bFirst = true;
+
+ if (bFirst)
+ {
+ bFirst = false;
+
+ drivers_info.clear();
+ drivers_info.reserve(driver_list::total());
+
+ InitDriversCache();
+ }
+
+ return &drivers_info[driver_index];
+}
+
+BOOL DriverIsClone(int driver_index)
+{
+ return GetDriversInfo(driver_index)->isClone;
+}
+
+BOOL DriverIsBroken(int driver_index)
+{
+ return GetDriversInfo(driver_index)->isBroken;
+}
+
+BOOL DriverIsHarddisk(int driver_index)
+{
+ return GetDriversInfo(driver_index)->isHarddisk;
+}
+
+BOOL DriverIsBios(int driver_index)
+{
+ return ( driver_list::driver(driver_index).flags & MACHINE_IS_BIOS_ROOT ) ? TRUE : FALSE;
+}
+
+BOOL DriverIsMechanical(int driver_index)
+{
+ return ( driver_list::driver(driver_index).flags & MACHINE_MECHANICAL ) ? TRUE : FALSE;
+}
+
+BOOL DriverIsArcade(int driver_index)
+{
+ return ( driver_list::driver(driver_index).flags & MACHINE_TYPE_ARCADE ) ? TRUE : FALSE;
+}
+
+BOOL DriverHasOptionalBIOS(int driver_index)
+{
+ return GetDriversInfo(driver_index)->hasOptionalBIOS;
+}
+
+BOOL DriverIsStereo(int driver_index)
+{
+ return GetDriversInfo(driver_index)->isStereo;
+}
+
+int DriverNumScreens(int driver_index)
+{
+ return GetDriversInfo(driver_index)->screenCount;
+}
+
+BOOL DriverIsVector(int driver_index)
+{
+ return GetDriversInfo(driver_index)->isVector;
+}
+
+BOOL DriverUsesRoms(int driver_index)
+{
+ return GetDriversInfo(driver_index)->usesRoms;
+}
+
+BOOL DriverUsesSamples(int driver_index)
+{
+ return GetDriversInfo(driver_index)->usesSamples;
+}
+
+BOOL DriverUsesTrackball(int driver_index)
+{
+ return GetDriversInfo(driver_index)->usesTrackball;
+}
+
+BOOL DriverUsesLightGun(int driver_index)
+{
+ return GetDriversInfo(driver_index)->usesLightGun;
+}
+
+BOOL DriverUsesMouse(int driver_index)
+{
+ return GetDriversInfo(driver_index)->usesMouse;
+}
+
+BOOL DriverSupportsSaveState(int driver_index)
+{
+ return GetDriversInfo(driver_index)->supportsSaveState;
+}
+
+BOOL DriverIsVertical(int driver_index)
+{
+ return GetDriversInfo(driver_index)->isVertical;
+}
+
+BOOL DriverHasRam(int driver_index)
+{
+ return GetDriversInfo(driver_index)->hasRam;
+}
+
+void FlushFileCaches(void)
+{
+ util::archive_file::cache_clear();
+}
+
+BOOL StringIsSuffixedBy(const char *s, const char *suffix)
+{
+ return (strlen(s) > strlen(suffix)) && (strcmp(s + strlen(s) - strlen(suffix), suffix) == 0);
+}
+
+/***************************************************************************
+ Win32 wrappers
+ ***************************************************************************/
+
+BOOL SafeIsAppThemed(void)
+{
+ BOOL bResult = FALSE;
+ HMODULE hThemes;
+ BOOL (WINAPI *pfnIsAppThemed)(void);
+
+ hThemes = LoadLibrary(TEXT("uxtheme.dll"));
+ if (hThemes)
+ {
+ pfnIsAppThemed = (BOOL (WINAPI *)(void)) GetProcAddress(hThemes, "IsAppThemed");
+ if (pfnIsAppThemed)
+ bResult = pfnIsAppThemed();
+ FreeLibrary(hThemes);
+ }
+ return bResult;
+
+}
+
+
+void GetSystemErrorMessage(DWORD dwErrorId, TCHAR **tErrorMessage)
+{
+ if( FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErrorId, 0, (LPTSTR)tErrorMessage, 0, NULL) == 0 )
+ {
+ *tErrorMessage = (LPTSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(TCHAR));
+ _tcscpy(*tErrorMessage, TEXT("Unknown Error"));
+ }
+}
+
+
+//============================================================
+// win_extract_icon_utf8
+//============================================================
+
+HICON win_extract_icon_utf8(HINSTANCE inst, const char* exefilename, UINT iconindex)
+{
+ HICON icon = 0;
+ TCHAR* t_exefilename = ui_wstring_from_utf8(exefilename);
+ if( !t_exefilename )
+ return icon;
+
+ icon = ExtractIcon(inst, t_exefilename, iconindex);
+
+ free(t_exefilename);
+
+ return icon;
+}
+
+
+
+//============================================================
+// win_tstring_strdup
+//============================================================
+
+TCHAR* win_tstring_strdup(LPCTSTR str)
+{
+ TCHAR *cpy = NULL;
+ if (str)
+ {
+ cpy = (TCHAR*)malloc((_tcslen(str) + 1) * sizeof(TCHAR));
+ if (cpy)
+ _tcscpy(cpy, str);
+ }
+ return cpy;
+}
+
+//============================================================
+// win_create_file_utf8
+//============================================================
+
+HANDLE win_create_file_utf8(const char* filename, DWORD desiredmode, DWORD sharemode,
+ LPSECURITY_ATTRIBUTES securityattributes, DWORD creationdisposition,
+ DWORD flagsandattributes, HANDLE templatehandle)
+{
+ HANDLE result = 0;
+ TCHAR* t_filename = ui_wstring_from_utf8(filename);
+ if( !t_filename )
+ return result;
+
+ result = CreateFile(t_filename, desiredmode, sharemode, securityattributes, creationdisposition, flagsandattributes, templatehandle);
+
+ free(t_filename);
+
+ return result;
+}
+
+//============================================================
+// win_get_current_directory_utf8
+//============================================================
+
+DWORD win_get_current_directory_utf8(DWORD bufferlength, char* buffer)
+{
+ DWORD result = 0;
+ TCHAR* t_buffer = NULL;
+ char* utf8_buffer = NULL;
+
+ if( bufferlength > 0 ) {
+ t_buffer = (TCHAR*)malloc((bufferlength * sizeof(TCHAR)) + 1);
+ if( !t_buffer )
+ return result;
+ }
+
+ result = GetCurrentDirectory(bufferlength, t_buffer);
+
+ if( bufferlength > 0 ) {
+ utf8_buffer = ui_utf8_from_wstring(t_buffer);
+ if( !utf8_buffer ) {
+ free(t_buffer);
+ return result;
+ }
+ }
+
+ strncpy(buffer, utf8_buffer, bufferlength);
+
+ if( utf8_buffer )
+ free(utf8_buffer);
+
+ if( t_buffer )
+ free(t_buffer);
+
+ return result;
+}
+
+//============================================================
+// win_find_first_file_utf8
+//============================================================
+
+HANDLE win_find_first_file_utf8(const char* filename, LPWIN32_FIND_DATA findfiledata)
+{
+ HANDLE result = 0;
+ TCHAR* t_filename = ui_wstring_from_utf8(filename);
+ if( !t_filename )
+ return result;
+
+ result = FindFirstFile(t_filename, findfiledata);
+
+ free(t_filename);
+
+ return result;
+}
+