Some more work on UWP (nw)
6
3rdparty/lua-linenoise/linenoise_none.c
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include <lua.h>
|
||||||
|
|
||||||
|
int luaopen_linenoise(lua_State *L)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
@ -594,7 +594,11 @@ end
|
|||||||
MAME_DIR .. "3rdparty/lua-zlib/lua_zlib.c",
|
MAME_DIR .. "3rdparty/lua-zlib/lua_zlib.c",
|
||||||
MAME_DIR .. "3rdparty/luafilesystem/src/lfs.c",
|
MAME_DIR .. "3rdparty/luafilesystem/src/lfs.c",
|
||||||
}
|
}
|
||||||
if (_OPTIONS["osd"] ~= "uwp") then
|
if (_OPTIONS["osd"] == "uwp") then
|
||||||
|
files {
|
||||||
|
MAME_DIR .. "3rdparty/lua-linenoise/linenoise_none.c",
|
||||||
|
}
|
||||||
|
else
|
||||||
files {
|
files {
|
||||||
MAME_DIR .. "3rdparty/lua-linenoise/linenoise.c",
|
MAME_DIR .. "3rdparty/lua-linenoise/linenoise.c",
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,10 @@ end
|
|||||||
"ppapi_gles2",
|
"ppapi_gles2",
|
||||||
"pthread",
|
"pthread",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configuration { "winstore*" }
|
||||||
|
kind "WindowedApp"
|
||||||
|
|
||||||
configuration { }
|
configuration { }
|
||||||
|
|
||||||
addprojectflags()
|
addprojectflags()
|
||||||
@ -69,6 +73,32 @@ end
|
|||||||
"Unicode",
|
"Unicode",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configuration { "winstore*" }
|
||||||
|
-- Windows Required Files
|
||||||
|
files {
|
||||||
|
-- Manifest file
|
||||||
|
MAME_DIR .. "src/osd/uwp/Package.appxmanifest",
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration { "winstore*" }
|
||||||
|
files {
|
||||||
|
MAME_DIR .. "src/osd/uwp/assets/*.png"
|
||||||
|
}
|
||||||
|
configuration "**/src/osd/uwp/assets/*.png"
|
||||||
|
flags { "DeploymentContent" }
|
||||||
|
|
||||||
|
-- Effects and Shaders
|
||||||
|
configuration { "winstore*" }
|
||||||
|
files {
|
||||||
|
MAME_DIR .. "artwork/**/*",
|
||||||
|
MAME_DIR .. "bgfx/**/*",
|
||||||
|
MAME_DIR .. "hash/*",
|
||||||
|
MAME_DIR .. "language/**/*",
|
||||||
|
MAME_DIR .. "plugins/**/*",
|
||||||
|
}
|
||||||
|
configuration "**/*"
|
||||||
|
flags { "DeploymentContent" }
|
||||||
|
|
||||||
configuration { "x64", "Release" }
|
configuration { "x64", "Release" }
|
||||||
targetsuffix "64"
|
targetsuffix "64"
|
||||||
if _OPTIONS["PROFILE"] then
|
if _OPTIONS["PROFILE"] then
|
||||||
|
@ -70,6 +70,8 @@ project ("osd_" .. _OPTIONS["osd"])
|
|||||||
MAME_DIR .. "src/osd/modules/render/drawnone.h",
|
MAME_DIR .. "src/osd/modules/render/drawnone.h",
|
||||||
MAME_DIR .. "src/osd/uwp/uwpcompat.cpp",
|
MAME_DIR .. "src/osd/uwp/uwpcompat.cpp",
|
||||||
MAME_DIR .. "src/osd/uwp/uwpcompat.h",
|
MAME_DIR .. "src/osd/uwp/uwpcompat.h",
|
||||||
|
MAME_DIR .. "src/osd/uwp/uwpmain.cpp",
|
||||||
|
MAME_DIR .. "src/osd/uwp/uwpmain.h",
|
||||||
MAME_DIR .. "src/osd/osdepend.h",
|
MAME_DIR .. "src/osd/osdepend.h",
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,17 +95,21 @@ project ("ocore_" .. _OPTIONS["osd"])
|
|||||||
}
|
}
|
||||||
|
|
||||||
files {
|
files {
|
||||||
MAME_DIR .. "src/osd/osdnet.cpp",
|
MAME_DIR .. "src/osd/osdcomm.h",
|
||||||
MAME_DIR .. "src/osd/osdnet.h",
|
|
||||||
MAME_DIR .. "src/osd/osdcore.cpp",
|
MAME_DIR .. "src/osd/osdcore.cpp",
|
||||||
MAME_DIR .. "src/osd/osdcore.h",
|
MAME_DIR .. "src/osd/osdcore.h",
|
||||||
MAME_DIR .. "src/osd/modules/osdmodule.cpp",
|
|
||||||
MAME_DIR .. "src/osd/modules/osdmodule.h",
|
|
||||||
MAME_DIR .. "src/osd/strconv.cpp",
|
MAME_DIR .. "src/osd/strconv.cpp",
|
||||||
MAME_DIR .. "src/osd/strconv.h",
|
MAME_DIR .. "src/osd/strconv.h",
|
||||||
MAME_DIR .. "src/osd/osdsync.cpp",
|
MAME_DIR .. "src/osd/osdsync.cpp",
|
||||||
MAME_DIR .. "src/osd/osdsync.h",
|
MAME_DIR .. "src/osd/osdsync.h",
|
||||||
MAME_DIR .. "src/osd/windows/winutil.cpp",
|
MAME_DIR .. "src/osd/windows/winutil.cpp",
|
||||||
MAME_DIR .. "src/osd/windows/winutil.h",
|
MAME_DIR .. "src/osd/windows/winutil.h",
|
||||||
--MAME_DIR .. "src/osd/modules/lib/osdlib_uwp.cpp",
|
MAME_DIR .. "src/osd/modules/osdmodule.cpp",
|
||||||
|
MAME_DIR .. "src/osd/modules/osdmodule.h",
|
||||||
|
MAME_DIR .. "src/osd/modules/file/winrtdir.cpp",
|
||||||
|
MAME_DIR .. "src/osd/modules/file/winrtfile.cpp",
|
||||||
|
MAME_DIR .. "src/osd/modules/file/winrtfile.h",
|
||||||
|
MAME_DIR .. "src/osd/modules/file/winrtptty.cpp",
|
||||||
|
MAME_DIR .. "src/osd/modules/file/winrtsocket.cpp",
|
||||||
|
MAME_DIR .. "src/osd/modules/lib/osdlib_uwp.cpp",
|
||||||
}
|
}
|
||||||
|
@ -468,6 +468,9 @@ function toolchain(_buildDir, _subDir)
|
|||||||
"StaticRuntime",
|
"StaticRuntime",
|
||||||
"NoExceptions",
|
"NoExceptions",
|
||||||
}
|
}
|
||||||
|
flags {
|
||||||
|
"WinMain"
|
||||||
|
}
|
||||||
|
|
||||||
configuration { "mingw*" }
|
configuration { "mingw*" }
|
||||||
defines { "WIN32" }
|
defines { "WIN32" }
|
||||||
|
142
src/osd/modules/file/winrtdir.cpp
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Aaron Giles
|
||||||
|
//============================================================
|
||||||
|
//
|
||||||
|
// windir.c - Win32 OSD core directory access functions
|
||||||
|
//
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
// standard windows headers
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
// MAME headers
|
||||||
|
#include "osdcore.h"
|
||||||
|
#include "strformat.h"
|
||||||
|
|
||||||
|
// MAMEOS headers
|
||||||
|
#include "strconv.h"
|
||||||
|
#include "../../windows/winutil.h"
|
||||||
|
|
||||||
|
// standard C headers
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
|
namespace osd {
|
||||||
|
namespace {
|
||||||
|
//============================================================
|
||||||
|
// TYPE DEFINITIONS
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
class win_directory : public directory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
win_directory();
|
||||||
|
virtual ~win_directory() override;
|
||||||
|
|
||||||
|
virtual const entry *read() override;
|
||||||
|
|
||||||
|
bool open_impl(std::string const &dirname);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE m_find; // handle to the finder
|
||||||
|
bool m_is_first; // true if this is the first entry
|
||||||
|
entry m_entry; // current entry's data
|
||||||
|
WIN32_FIND_DATA m_data; // current raw data
|
||||||
|
std::string m_name; // converted name of directory
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// win_directory::win_directory
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
win_directory::win_directory()
|
||||||
|
: m_find(INVALID_HANDLE_VALUE)
|
||||||
|
, m_is_first(true)
|
||||||
|
{
|
||||||
|
m_entry.name = nullptr;
|
||||||
|
std::memset(&m_data, 0, sizeof(m_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// win_directory::~win_directory
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
win_directory::~win_directory()
|
||||||
|
{
|
||||||
|
// free any data associated
|
||||||
|
if (m_find != INVALID_HANDLE_VALUE)
|
||||||
|
FindClose(m_find);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// win_directory::read
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
const directory::entry *win_directory::read()
|
||||||
|
{
|
||||||
|
// if this isn't the first file, do a find next
|
||||||
|
if (!m_is_first)
|
||||||
|
{
|
||||||
|
if (!FindNextFile(m_find, &m_data))
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
m_is_first = false;
|
||||||
|
|
||||||
|
// extract the data
|
||||||
|
osd::text::from_tstring(m_name, m_data.cFileName);
|
||||||
|
m_entry.name = m_name.c_str();
|
||||||
|
m_entry.type = win_attributes_to_entry_type(m_data.dwFileAttributes);
|
||||||
|
m_entry.size = m_data.nFileSizeLow | (std::uint64_t(m_data.nFileSizeHigh) << 32);
|
||||||
|
m_entry.last_modified = win_time_point_from_filetime(&m_data.ftLastWriteTime);
|
||||||
|
return (m_entry.name != nullptr) ? &m_entry : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// win_directory::open_impl
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
bool win_directory::open_impl(std::string const &dirname)
|
||||||
|
{
|
||||||
|
assert(m_find == INVALID_HANDLE_VALUE);
|
||||||
|
|
||||||
|
// append \*.* to the directory name
|
||||||
|
std::string dirfilter = string_format("%s\\*.*", dirname);
|
||||||
|
|
||||||
|
// convert the path to TCHARs
|
||||||
|
osd::text::tstring t_dirfilter = osd::text::to_tstring(dirfilter);
|
||||||
|
|
||||||
|
// attempt to find the first file
|
||||||
|
m_find = FindFirstFileEx(t_dirfilter.c_str(), FindExInfoStandard, &m_data, FindExSearchNameMatch, nullptr, 0);
|
||||||
|
return m_find != INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd::directory::open
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
directory::ptr directory::open(std::string const &dirname)
|
||||||
|
{
|
||||||
|
// allocate memory to hold the osd_tool_directory structure
|
||||||
|
std::unique_ptr<win_directory> dir;
|
||||||
|
try { dir.reset(new win_directory()); }
|
||||||
|
catch (...) { return nullptr; }
|
||||||
|
|
||||||
|
if (!dir->open_impl(dirname))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return ptr(std::move(dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namesapce osd
|
465
src/osd/modules/file/winrtfile.cpp
Normal file
@ -0,0 +1,465 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Aaron Giles, Vas Crabb
|
||||||
|
//============================================================
|
||||||
|
//
|
||||||
|
// winfile.c - Win32 OSD core file access functions
|
||||||
|
//
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
|
#include "winfile.h"
|
||||||
|
|
||||||
|
#include "../../windows/winutil.h"
|
||||||
|
|
||||||
|
// MAMEOS headers
|
||||||
|
#include "strconv.h"
|
||||||
|
#include "unicode.h"
|
||||||
|
|
||||||
|
// MAME headers
|
||||||
|
#include "osdcore.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
// standard windows headers
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winioctl.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
//============================================================
|
||||||
|
// TYPE DEFINITIONS
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
class win_osd_file : public osd_file
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
win_osd_file(win_osd_file const &) = delete;
|
||||||
|
win_osd_file(win_osd_file &&) = delete;
|
||||||
|
win_osd_file& operator=(win_osd_file const &) = delete;
|
||||||
|
win_osd_file& operator=(win_osd_file &&) = delete;
|
||||||
|
|
||||||
|
win_osd_file(HANDLE handle) : m_handle(handle)
|
||||||
|
{
|
||||||
|
assert(m_handle);
|
||||||
|
assert(INVALID_HANDLE_VALUE != m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~win_osd_file() override
|
||||||
|
{
|
||||||
|
FlushFileBuffers(m_handle);
|
||||||
|
CloseHandle(m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
|
||||||
|
{
|
||||||
|
// attempt to set the file pointer
|
||||||
|
LARGE_INTEGER largeOffset;
|
||||||
|
largeOffset.QuadPart = offset;
|
||||||
|
if (!SetFilePointerEx(m_handle, largeOffset, nullptr, FILE_BEGIN))
|
||||||
|
return win_error_to_file_error(GetLastError());
|
||||||
|
|
||||||
|
// then perform the read
|
||||||
|
DWORD result = 0;
|
||||||
|
if (!ReadFile(m_handle, buffer, length, &result, nullptr))
|
||||||
|
return win_error_to_file_error(GetLastError());
|
||||||
|
|
||||||
|
actual = result;
|
||||||
|
return error::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
|
||||||
|
{
|
||||||
|
// attempt to set the file pointer
|
||||||
|
LARGE_INTEGER largeOffset;
|
||||||
|
largeOffset.QuadPart = offset;
|
||||||
|
if (!SetFilePointerEx(m_handle, largeOffset, nullptr, FILE_BEGIN))
|
||||||
|
return win_error_to_file_error(GetLastError());
|
||||||
|
|
||||||
|
// then perform the write
|
||||||
|
DWORD result = 0;
|
||||||
|
if (!WriteFile(m_handle, buffer, length, &result, nullptr))
|
||||||
|
return win_error_to_file_error(GetLastError());
|
||||||
|
|
||||||
|
actual = result;
|
||||||
|
return error::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual error truncate(std::uint64_t offset) override
|
||||||
|
{
|
||||||
|
// attempt to set the file pointer
|
||||||
|
LARGE_INTEGER largeOffset;
|
||||||
|
largeOffset.QuadPart = offset;
|
||||||
|
if (!SetFilePointerEx(m_handle, largeOffset, nullptr, FILE_BEGIN))
|
||||||
|
return win_error_to_file_error(GetLastError());
|
||||||
|
|
||||||
|
// then perform the truncation
|
||||||
|
if (!SetEndOfFile(m_handle))
|
||||||
|
return win_error_to_file_error(GetLastError());
|
||||||
|
else
|
||||||
|
return error::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual error flush() override
|
||||||
|
{
|
||||||
|
// shouldn't be any userspace buffers on the file handle
|
||||||
|
return error::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE m_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// INLINE FUNCTIONS
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
inline bool is_path_to_physical_drive(char const *path)
|
||||||
|
{
|
||||||
|
return (_strnicmp(path, "\\\\.\\physicaldrive", 17) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// create_path_recursive
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
DWORD create_path_recursive(TCHAR *path)
|
||||||
|
{
|
||||||
|
// if there's still a separator, and it's not the root, nuke it and recurse
|
||||||
|
TCHAR *sep = _tcsrchr(path, '\\');
|
||||||
|
if (sep && (sep > path) && (sep[0] != ':') && (sep[-1] != '\\'))
|
||||||
|
{
|
||||||
|
*sep = 0;
|
||||||
|
create_path_recursive(path);
|
||||||
|
*sep = '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the path already exists, we're done
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA fileinfo;
|
||||||
|
if (GetFileAttributesEx(path, GetFileExInfoStandard, &fileinfo))
|
||||||
|
return NO_ERROR;
|
||||||
|
else if (!CreateDirectory(path, nullptr))
|
||||||
|
return GetLastError();
|
||||||
|
else
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_open
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags, ptr &file, std::uint64_t &filesize)
|
||||||
|
{
|
||||||
|
std::string path;
|
||||||
|
try { osd_subst_env(path, orig_path); }
|
||||||
|
catch (...) { return error::OUT_OF_MEMORY; }
|
||||||
|
|
||||||
|
if (win_check_socket_path(path))
|
||||||
|
return win_open_socket(path, openflags, file, filesize);
|
||||||
|
else if (win_check_ptty_path(path))
|
||||||
|
return win_open_ptty(path, openflags, file, filesize);
|
||||||
|
|
||||||
|
// convert path to TCHAR
|
||||||
|
osd::text::tstring t_path = osd::text::to_tstring(path);
|
||||||
|
|
||||||
|
// convert the path into something Windows compatible (the actual interesting part appears
|
||||||
|
// to have been commented out???)
|
||||||
|
for (auto iter = t_path.begin(); iter != t_path.end(); iter++)
|
||||||
|
*iter = /* ('/' == *iter) ? '\\' : */ *iter;
|
||||||
|
|
||||||
|
// select the file open modes
|
||||||
|
DWORD disposition, access, sharemode;
|
||||||
|
if (openflags & OPEN_FLAG_WRITE)
|
||||||
|
{
|
||||||
|
disposition = (!is_path_to_physical_drive(path.c_str()) && (openflags & OPEN_FLAG_CREATE)) ? CREATE_ALWAYS : OPEN_EXISTING;
|
||||||
|
access = (openflags & OPEN_FLAG_READ) ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_WRITE;
|
||||||
|
sharemode = FILE_SHARE_READ;
|
||||||
|
}
|
||||||
|
else if (openflags & OPEN_FLAG_READ)
|
||||||
|
{
|
||||||
|
disposition = OPEN_EXISTING;
|
||||||
|
access = GENERIC_READ;
|
||||||
|
sharemode = FILE_SHARE_READ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return error::INVALID_ACCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// attempt to open the file
|
||||||
|
HANDLE h = CreateFile2(t_path.c_str(), access, sharemode, disposition, nullptr);
|
||||||
|
if (INVALID_HANDLE_VALUE == h)
|
||||||
|
{
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
// create the path if necessary
|
||||||
|
if ((ERROR_PATH_NOT_FOUND == err) && (openflags & OPEN_FLAG_CREATE) && (openflags & OPEN_FLAG_CREATE_PATHS))
|
||||||
|
{
|
||||||
|
auto pathsep = t_path.rfind('\\');
|
||||||
|
if (pathsep != decltype(t_path)::npos)
|
||||||
|
{
|
||||||
|
// create the path up to the file
|
||||||
|
t_path[pathsep] = 0;
|
||||||
|
err = create_path_recursive(&t_path[0]);
|
||||||
|
t_path[pathsep] = '\\';
|
||||||
|
|
||||||
|
// attempt to reopen the file
|
||||||
|
if (err == NO_ERROR)
|
||||||
|
{
|
||||||
|
h = CreateFile2(t_path.c_str(), access, sharemode, disposition, nullptr);
|
||||||
|
err = GetLastError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we still failed, clean up and free
|
||||||
|
if (INVALID_HANDLE_VALUE == h)
|
||||||
|
return win_error_to_file_error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the file size
|
||||||
|
FILE_STANDARD_INFO file_info;
|
||||||
|
GetFileInformationByHandleEx(h, FileStandardInfo, &file_info, sizeof(file_info));
|
||||||
|
auto lower = file_info.EndOfFile.QuadPart;
|
||||||
|
|
||||||
|
if (INVALID_FILE_SIZE == lower)
|
||||||
|
{
|
||||||
|
DWORD const err = GetLastError();
|
||||||
|
if (NO_ERROR != err)
|
||||||
|
{
|
||||||
|
CloseHandle(h);
|
||||||
|
return win_error_to_file_error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
file = std::make_unique<win_osd_file>(h);
|
||||||
|
filesize = lower;
|
||||||
|
return error::NONE;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
CloseHandle(h);
|
||||||
|
return error::OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_openpty
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
osd_file::error osd_file::openpty(ptr &file, std::string &name)
|
||||||
|
{
|
||||||
|
return error::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_rmfile
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
osd_file::error osd_file::remove(std::string const &filename)
|
||||||
|
{
|
||||||
|
osd::text::tstring tempstr = osd::text::to_tstring(filename);
|
||||||
|
|
||||||
|
error filerr = error::NONE;
|
||||||
|
if (!DeleteFile(tempstr.c_str()))
|
||||||
|
filerr = win_error_to_file_error(GetLastError());
|
||||||
|
|
||||||
|
return filerr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_get_physical_drive_geometry
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders, uint32_t *heads, uint32_t *sectors, uint32_t *bps)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_stat
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
std::unique_ptr<osd::directory::entry> osd_stat(const std::string &path)
|
||||||
|
{
|
||||||
|
// convert the path to TCHARs
|
||||||
|
osd::text::tstring t_path = osd::text::to_tstring(path);
|
||||||
|
|
||||||
|
// is this path a root directory (e.g. - C:)?
|
||||||
|
WIN32_FIND_DATA find_data;
|
||||||
|
std::memset(&find_data, 0, sizeof(find_data));
|
||||||
|
if (isalpha(path[0]) && (path[1] == ':') && (path[2] == '\0'))
|
||||||
|
{
|
||||||
|
// need to do special logic for root directories
|
||||||
|
if (!GetFileAttributesEx(t_path.c_str(), GetFileExInfoStandard, &find_data.dwFileAttributes))
|
||||||
|
find_data.dwFileAttributes = INVALID_FILE_ATTRIBUTES;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// attempt to find the first file
|
||||||
|
HANDLE find = FindFirstFileEx(t_path.c_str(), FindExInfoStandard, &find_data, FindExSearchNameMatch, nullptr, 0);
|
||||||
|
if (find == INVALID_HANDLE_VALUE)
|
||||||
|
return nullptr;
|
||||||
|
FindClose(find);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create an osd::directory::entry; be sure to make sure that the caller can
|
||||||
|
// free all resources by just freeing the resulting osd::directory::entry
|
||||||
|
osd::directory::entry *result;
|
||||||
|
try { result = reinterpret_cast<osd::directory::entry *>(::operator new(sizeof(*result) + path.length() + 1)); }
|
||||||
|
catch (...) { return nullptr; }
|
||||||
|
new (result) osd::directory::entry;
|
||||||
|
|
||||||
|
strcpy(((char *) result) + sizeof(*result), path.c_str());
|
||||||
|
result->name = ((char *) result) + sizeof(*result);
|
||||||
|
result->type = win_attributes_to_entry_type(find_data.dwFileAttributes);
|
||||||
|
result->size = find_data.nFileSizeLow | ((uint64_t) find_data.nFileSizeHigh << 32);
|
||||||
|
result->last_modified = win_time_point_from_filetime(&find_data.ftLastWriteTime);
|
||||||
|
|
||||||
|
return std::unique_ptr<osd::directory::entry>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_get_full_path
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
|
||||||
|
{
|
||||||
|
// convert the path to TCHARs
|
||||||
|
osd::text::tstring t_path = osd::text::to_tstring(path);
|
||||||
|
|
||||||
|
// cannonicalize the path
|
||||||
|
TCHAR buffer[MAX_PATH];
|
||||||
|
if (!GetFullPathName(t_path.c_str(), ARRAY_LENGTH(buffer), buffer, nullptr))
|
||||||
|
return win_error_to_file_error(GetLastError());
|
||||||
|
|
||||||
|
// convert the result back to UTF-8
|
||||||
|
osd::text::from_tstring(dst, buffer);
|
||||||
|
return osd_file::error::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_is_absolute_path
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
bool osd_is_absolute_path(std::string const &path)
|
||||||
|
{
|
||||||
|
// very dumb hack here that will be imprecise
|
||||||
|
if (strlen(path.c_str()) >= 2 && path[1] == ':')
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_get_volume_name
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
const char *osd_get_volume_name(int idx)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_is_valid_filename_char
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
bool osd_is_valid_filename_char(char32_t uchar)
|
||||||
|
{
|
||||||
|
return osd_is_valid_filepath_char(uchar)
|
||||||
|
&& uchar != '/'
|
||||||
|
&& uchar != '\\'
|
||||||
|
&& uchar != ':';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_is_valid_filepath_char
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
bool osd_is_valid_filepath_char(char32_t uchar)
|
||||||
|
{
|
||||||
|
return uchar >= 0x20
|
||||||
|
&& uchar != '<'
|
||||||
|
&& uchar != '>'
|
||||||
|
&& uchar != '\"'
|
||||||
|
&& uchar != '|'
|
||||||
|
&& uchar != '?'
|
||||||
|
&& uchar != '*'
|
||||||
|
&& !(uchar >= '\x7F' && uchar <= '\x9F')
|
||||||
|
&& uchar_isvalid(uchar);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// win_error_to_file_error
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
osd_file::error win_error_to_file_error(DWORD error)
|
||||||
|
{
|
||||||
|
osd_file::error filerr;
|
||||||
|
|
||||||
|
// convert a Windows error to a osd_file::error
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case ERROR_SUCCESS:
|
||||||
|
filerr = osd_file::error::NONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ERROR_OUTOFMEMORY:
|
||||||
|
filerr = osd_file::error::OUT_OF_MEMORY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ERROR_FILE_NOT_FOUND:
|
||||||
|
case ERROR_FILENAME_EXCED_RANGE:
|
||||||
|
case ERROR_PATH_NOT_FOUND:
|
||||||
|
case ERROR_INVALID_NAME:
|
||||||
|
filerr = osd_file::error::NOT_FOUND;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ERROR_ACCESS_DENIED:
|
||||||
|
filerr = osd_file::error::ACCESS_DENIED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ERROR_SHARING_VIOLATION:
|
||||||
|
filerr = osd_file::error::ALREADY_OPEN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
filerr = osd_file::error::FAILURE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return filerr;
|
||||||
|
}
|
34
src/osd/modules/file/winrtfile.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Aaron Giles, Vas Crabb
|
||||||
|
//============================================================
|
||||||
|
//
|
||||||
|
// winfile.h - File access functions
|
||||||
|
//
|
||||||
|
//============================================================
|
||||||
|
#ifndef MAME_OSD_WINDOWS_WINFILE_H
|
||||||
|
#define MAME_OSD_WINDOWS_WINFILE_H
|
||||||
|
|
||||||
|
#include "osdcore.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// PROTOTYPES
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
bool win_init_sockets();
|
||||||
|
void win_cleanup_sockets();
|
||||||
|
|
||||||
|
bool win_check_socket_path(std::string const &path);
|
||||||
|
osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize);
|
||||||
|
|
||||||
|
bool win_check_ptty_path(std::string const &path);
|
||||||
|
osd_file::error win_open_ptty(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize);
|
||||||
|
|
||||||
|
osd_file::error win_error_to_file_error(DWORD error);
|
||||||
|
|
||||||
|
#endif // MAME_OSD_WINDOWS_WINFILE_H
|
87
src/osd/modules/file/winrtptty.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Aaron Giles, Vas Crabb
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
|
#include "winrtfile.h"
|
||||||
|
|
||||||
|
#include "strconv.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
char const *const winfile_ptty_identifier = "\\\\.\\pipe\\";
|
||||||
|
|
||||||
|
|
||||||
|
class win_osd_ptty : public osd_file
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
win_osd_ptty(win_osd_ptty const &) = delete;
|
||||||
|
win_osd_ptty(win_osd_ptty &&) = delete;
|
||||||
|
win_osd_ptty& operator=(win_osd_ptty const &) = delete;
|
||||||
|
win_osd_ptty& operator=(win_osd_ptty &&) = delete;
|
||||||
|
|
||||||
|
win_osd_ptty(HANDLE handle) : m_handle(handle)
|
||||||
|
{
|
||||||
|
assert(m_handle);
|
||||||
|
assert(INVALID_HANDLE_VALUE != m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
~win_osd_ptty()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
|
||||||
|
{
|
||||||
|
DWORD bytes_read;
|
||||||
|
if (!ReadFile(m_handle, buffer, count, &bytes_read, nullptr))
|
||||||
|
return win_error_to_file_error(GetLastError());
|
||||||
|
|
||||||
|
actual = bytes_read;
|
||||||
|
return error::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
|
||||||
|
{
|
||||||
|
DWORD bytes_written;
|
||||||
|
if (!WriteFile(m_handle, buffer, count, &bytes_written, nullptr))
|
||||||
|
return win_error_to_file_error(GetLastError());
|
||||||
|
|
||||||
|
actual = bytes_written;
|
||||||
|
return error::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual error truncate(std::uint64_t offset) override
|
||||||
|
{
|
||||||
|
// doesn't make sense for a PTTY
|
||||||
|
return error::INVALID_ACCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual error flush() override
|
||||||
|
{
|
||||||
|
// don't want to wait for client to read all data as implied by FlushFileBuffers
|
||||||
|
return error::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE m_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
|
bool win_check_ptty_path(std::string const &path)
|
||||||
|
{
|
||||||
|
if (strncmp(path.c_str(), winfile_ptty_identifier, strlen(winfile_ptty_identifier)) == 0) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
osd_file::error win_open_ptty(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
|
||||||
|
{
|
||||||
|
return osd_file::error::ACCESS_DENIED;
|
||||||
|
}
|
274
src/osd/modules/file/winrtsocket.cpp
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Aaron Giles, Vas Crabb
|
||||||
|
//============================================================
|
||||||
|
//
|
||||||
|
// winsocket.c - Windows socket (inet) access functions
|
||||||
|
//
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
|
#include "winfile.h"
|
||||||
|
|
||||||
|
// MAME headers
|
||||||
|
#include "osdcore.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
// standard windows headers
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winioctl.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
char const *const winfile_socket_identifier = "socket.";
|
||||||
|
|
||||||
|
|
||||||
|
class win_osd_socket : public osd_file
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
win_osd_socket(win_osd_socket const &) = delete;
|
||||||
|
win_osd_socket(win_osd_socket &&) = delete;
|
||||||
|
win_osd_socket& operator=(win_osd_socket const &) = delete;
|
||||||
|
win_osd_socket& operator=(win_osd_socket &&) = delete;
|
||||||
|
|
||||||
|
win_osd_socket(SOCKET s, bool l)
|
||||||
|
: m_socket(s)
|
||||||
|
, m_listening(l)
|
||||||
|
{
|
||||||
|
assert(INVALID_SOCKET != m_socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~win_osd_socket() override
|
||||||
|
{
|
||||||
|
closesocket(m_socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
|
||||||
|
{
|
||||||
|
fd_set readfds;
|
||||||
|
FD_ZERO(&readfds);
|
||||||
|
FD_SET(m_socket, &readfds);
|
||||||
|
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = timeout.tv_usec = 0;
|
||||||
|
|
||||||
|
if (select(m_socket + 1, &readfds, nullptr, nullptr, &timeout) < 0)
|
||||||
|
{
|
||||||
|
char line[80];
|
||||||
|
std::sprintf(line, "win_read_socket : %s : %d ", __FILE__, __LINE__);
|
||||||
|
std::perror(line);
|
||||||
|
return error::FAILURE;
|
||||||
|
}
|
||||||
|
else if (FD_ISSET(m_socket, &readfds))
|
||||||
|
{
|
||||||
|
if (!m_listening)
|
||||||
|
{
|
||||||
|
// connected socket
|
||||||
|
int const result = recv(m_socket, (char*)buffer, length, 0);
|
||||||
|
if (result < 0)
|
||||||
|
{
|
||||||
|
return wsa_error_to_file_error(WSAGetLastError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
actual = result;
|
||||||
|
return error::NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// listening socket
|
||||||
|
SOCKET const accepted = accept(m_socket, nullptr, nullptr);
|
||||||
|
if (INVALID_SOCKET == accepted)
|
||||||
|
{
|
||||||
|
return wsa_error_to_file_error(WSAGetLastError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
closesocket(m_socket);
|
||||||
|
m_socket = accepted;
|
||||||
|
m_listening = false;
|
||||||
|
actual = 0;
|
||||||
|
|
||||||
|
return error::NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return error::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
|
||||||
|
{
|
||||||
|
auto const result = send(m_socket, reinterpret_cast<const char *>(buffer), length, 0);
|
||||||
|
if (result < 0)
|
||||||
|
return wsa_error_to_file_error(WSAGetLastError());
|
||||||
|
|
||||||
|
actual = result;
|
||||||
|
return error::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual error truncate(std::uint64_t offset) override
|
||||||
|
{
|
||||||
|
// doesn't make sense for a socket
|
||||||
|
return error::INVALID_ACCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual error flush() override
|
||||||
|
{
|
||||||
|
// no buffers to flush
|
||||||
|
return error::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error wsa_error_to_file_error(int err)
|
||||||
|
{
|
||||||
|
switch (err)
|
||||||
|
{
|
||||||
|
case 0: return error::NONE;
|
||||||
|
case WSAEACCES: return error::ACCESS_DENIED;
|
||||||
|
case WSAEADDRINUSE: return error::ALREADY_OPEN;
|
||||||
|
case WSAEADDRNOTAVAIL: return error::NOT_FOUND;
|
||||||
|
case WSAECONNREFUSED: return error::NOT_FOUND;
|
||||||
|
case WSAEHOSTUNREACH: return error::NOT_FOUND;
|
||||||
|
case WSAENETUNREACH: return error::NOT_FOUND;
|
||||||
|
default: return error::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SOCKET m_socket;
|
||||||
|
bool m_listening;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
|
bool win_init_sockets()
|
||||||
|
{
|
||||||
|
WSADATA wsaData;
|
||||||
|
WORD const version = MAKEWORD(2, 0);
|
||||||
|
int const error = WSAStartup(version, &wsaData);
|
||||||
|
|
||||||
|
// check for error
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
// error occurred
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for correct version
|
||||||
|
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion ) != 0)
|
||||||
|
{
|
||||||
|
// incorrect WinSock version
|
||||||
|
WSACleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WinSock has been initialized
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void win_cleanup_sockets()
|
||||||
|
{
|
||||||
|
WSACleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool win_check_socket_path(std::string const &path)
|
||||||
|
{
|
||||||
|
if (strncmp(path.c_str(), winfile_socket_identifier, strlen(winfile_socket_identifier)) == 0 &&
|
||||||
|
strchr(path.c_str(), ':') != nullptr) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
|
||||||
|
{
|
||||||
|
char hostname[256];
|
||||||
|
int port;
|
||||||
|
std::sscanf(&path[strlen(winfile_socket_identifier)], "%255[^:]:%d", hostname, &port);
|
||||||
|
|
||||||
|
struct hostent const *const localhost = gethostbyname(hostname);
|
||||||
|
if (!localhost)
|
||||||
|
return osd_file::error::NOT_FOUND;
|
||||||
|
|
||||||
|
struct sockaddr_in sai;
|
||||||
|
memset(&sai, 0, sizeof(sai));
|
||||||
|
sai.sin_family = AF_INET;
|
||||||
|
sai.sin_port = htons(port);
|
||||||
|
sai.sin_addr = *reinterpret_cast<struct in_addr *>(localhost->h_addr);
|
||||||
|
|
||||||
|
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (INVALID_SOCKET == sock)
|
||||||
|
return win_osd_socket::wsa_error_to_file_error(WSAGetLastError());
|
||||||
|
|
||||||
|
int const flag = 1;
|
||||||
|
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<const char *>(&flag), sizeof(flag)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
int const err = WSAGetLastError();
|
||||||
|
closesocket(sock);
|
||||||
|
return win_osd_socket::wsa_error_to_file_error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// listening socket support
|
||||||
|
if (openflags & OPEN_FLAG_CREATE)
|
||||||
|
{
|
||||||
|
//printf("Listening for client at '%s' on port '%d'\n", hostname, port);
|
||||||
|
// bind socket...
|
||||||
|
if (bind(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
int const err = WSAGetLastError();
|
||||||
|
closesocket(sock);
|
||||||
|
return win_osd_socket::wsa_error_to_file_error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// start to listen...
|
||||||
|
if (listen(sock, 1) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
int const err = WSAGetLastError();
|
||||||
|
closesocket(sock);
|
||||||
|
return win_osd_socket::wsa_error_to_file_error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark socket as "listening"
|
||||||
|
try
|
||||||
|
{
|
||||||
|
file = std::make_unique<win_osd_socket>(sock, true);
|
||||||
|
filesize = 0;
|
||||||
|
return osd_file::error::NONE;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
closesocket(sock);
|
||||||
|
return osd_file::error::OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//printf("Connecting to server '%s' on port '%d'\n", hostname, port);
|
||||||
|
if (connect(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
closesocket(sock);
|
||||||
|
return osd_file::error::ACCESS_DENIED; // have to return this value or bitb won't try to bind on connect failure
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
file = std::make_unique<win_osd_socket>(sock, false);
|
||||||
|
filesize = 0;
|
||||||
|
return osd_file::error::NONE;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
closesocket(sock);
|
||||||
|
return osd_file::error::OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
383
src/osd/modules/lib/osdlib_uwp.cpp
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Olivier Galibert, R. Belmont
|
||||||
|
//============================================================
|
||||||
|
//
|
||||||
|
// sdlos_*.c - OS specific low level code
|
||||||
|
//
|
||||||
|
// SDLMAME by Olivier Galibert and R. Belmont
|
||||||
|
//
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <mmsystem.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
// MAME headers
|
||||||
|
#include "osdlib.h"
|
||||||
|
#include "osdcomm.h"
|
||||||
|
#include "osdcore.h"
|
||||||
|
#include "strconv.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <wrl\client.h>
|
||||||
|
|
||||||
|
#include "strconv.h"
|
||||||
|
|
||||||
|
using namespace Platform;
|
||||||
|
using namespace Windows::ApplicationModel::DataTransfer;
|
||||||
|
using namespace Windows::Foundation;
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
//============================================================
|
||||||
|
// MACROS
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
// presumed size of a page of memory
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
|
||||||
|
// align allocations to start or end of the page?
|
||||||
|
#define GUARD_ALIGN_START 0
|
||||||
|
|
||||||
|
#if defined(__BIGGEST_ALIGNMENT__)
|
||||||
|
#define MAX_ALIGNMENT __BIGGEST_ALIGNMENT__
|
||||||
|
#elif defined(__AVX__)
|
||||||
|
#define MAX_ALIGNMENT 32
|
||||||
|
#elif defined(__SSE__) || defined(__x86_64__) || defined(_M_X64)
|
||||||
|
#define MAX_ALIGNMENT 16
|
||||||
|
#else
|
||||||
|
#define MAX_ALIGNMENT sizeof(int64_t)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// GLOBAL VARIABLES
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
std::map<const char *, std::unique_ptr<char>> g_runtime_environment;
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_getenv
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
const char *osd_getenv(const char *name)
|
||||||
|
{
|
||||||
|
for (auto iter = g_runtime_environment.begin(); iter != g_runtime_environment.end(); iter++)
|
||||||
|
{
|
||||||
|
if (stricmp(iter->first, name) == 0)
|
||||||
|
{
|
||||||
|
osd_printf_debug("ENVIRONMENT: Get %s = value: '%s'", name, iter->second.get());
|
||||||
|
return iter->second.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_setenv
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
int osd_setenv(const char *name, const char *value, int overwrite)
|
||||||
|
{
|
||||||
|
if (!overwrite)
|
||||||
|
{
|
||||||
|
if (osd_getenv(name) != nullptr)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto buf = std::make_unique<char>(strlen(name) + strlen(value) + 2);
|
||||||
|
sprintf(buf.get(), "%s=%s", name, value);
|
||||||
|
|
||||||
|
g_runtime_environment[name] = std::move(buf);
|
||||||
|
osd_printf_debug("ENVIRONMENT: Set %s to value: '%s'", name, buf.get());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_process_kill
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
void osd_process_kill()
|
||||||
|
{
|
||||||
|
std::fflush(stdout);
|
||||||
|
std::fflush(stderr);
|
||||||
|
TerminateProcess(GetCurrentProcess(), -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_malloc
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
void *osd_malloc(size_t size)
|
||||||
|
{
|
||||||
|
#ifndef MALLOC_DEBUG
|
||||||
|
return malloc(size);
|
||||||
|
#else
|
||||||
|
// add in space for the size and offset
|
||||||
|
size += MAX_ALIGNMENT + sizeof(size_t) + 2;
|
||||||
|
size &= ~size_t(1);
|
||||||
|
|
||||||
|
// basic objects just come from the heap
|
||||||
|
uint8_t *const block = reinterpret_cast<uint8_t *>(HeapAlloc(GetProcessHeap(), 0, size));
|
||||||
|
if (block == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
uint8_t *const result = reinterpret_cast<uint8_t *>(reinterpret_cast<uintptr_t>(block + sizeof(size_t) + MAX_ALIGNMENT) & ~(uintptr_t(MAX_ALIGNMENT) - 1));
|
||||||
|
|
||||||
|
// store the size and return and pointer to the data afterward
|
||||||
|
*reinterpret_cast<size_t *>(block) = size;
|
||||||
|
*(result - 1) = result - block;
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_malloc_array
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
void *osd_malloc_array(size_t size)
|
||||||
|
{
|
||||||
|
#ifndef MALLOC_DEBUG
|
||||||
|
return malloc(size);
|
||||||
|
#else
|
||||||
|
// add in space for the size and offset
|
||||||
|
size += MAX_ALIGNMENT + sizeof(size_t) + 2;
|
||||||
|
size &= ~size_t(1);
|
||||||
|
|
||||||
|
// round the size up to a page boundary
|
||||||
|
size_t const rounded_size = ((size + sizeof(void *) + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
|
||||||
|
|
||||||
|
// reserve that much memory, plus two guard pages
|
||||||
|
void *page_base = VirtualAlloc(nullptr, rounded_size + 2 * PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS);
|
||||||
|
if (page_base == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// now allow access to everything but the first and last pages
|
||||||
|
page_base = VirtualAlloc(reinterpret_cast<uint8_t *>(page_base) + PAGE_SIZE, rounded_size, MEM_COMMIT, PAGE_READWRITE);
|
||||||
|
if (page_base == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// work backwards from the page base to get to the block base
|
||||||
|
uint8_t *const block = GUARD_ALIGN_START ? reinterpret_cast<uint8_t *>(page_base) : (reinterpret_cast<uint8_t *>(page_base) + rounded_size - size);
|
||||||
|
uint8_t *const result = reinterpret_cast<uint8_t *>(reinterpret_cast<uintptr_t>(block + sizeof(size_t) + MAX_ALIGNMENT) & ~(uintptr_t(MAX_ALIGNMENT) - 1));
|
||||||
|
|
||||||
|
// store the size at the start with a flag indicating it has a guard page
|
||||||
|
*reinterpret_cast<size_t *>(block) = size | 1;
|
||||||
|
*(result - 1) = result - block;
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_free
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
void osd_free(void *ptr)
|
||||||
|
{
|
||||||
|
#ifndef MALLOC_DEBUG
|
||||||
|
free(ptr);
|
||||||
|
#else
|
||||||
|
uint8_t const offset = *(reinterpret_cast<uint8_t *>(ptr) - 1);
|
||||||
|
uint8_t *const block = reinterpret_cast<uint8_t *>(ptr) - offset;
|
||||||
|
size_t const size = *reinterpret_cast<size_t *>(block);
|
||||||
|
|
||||||
|
if ((size & 0x1) == 0)
|
||||||
|
{
|
||||||
|
// if no guard page, just free the pointer
|
||||||
|
HeapFree(GetProcessHeap(), 0, block);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// large items need more care
|
||||||
|
ULONG_PTR const page_base = reinterpret_cast<ULONG_PTR>(block) & ~(PAGE_SIZE - 1);
|
||||||
|
VirtualFree(reinterpret_cast<void *>(page_base - PAGE_SIZE), 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_alloc_executable
|
||||||
|
//
|
||||||
|
// allocates "size" bytes of executable memory. this must take
|
||||||
|
// things like NX support into account.
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
void *osd_alloc_executable(size_t size)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_free_executable
|
||||||
|
//
|
||||||
|
// frees memory allocated with osd_alloc_executable
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
void osd_free_executable(void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_break_into_debugger
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
void osd_break_into_debugger(const char *message)
|
||||||
|
{
|
||||||
|
#ifdef OSD_WINDOWS
|
||||||
|
if (IsDebuggerPresent())
|
||||||
|
{
|
||||||
|
win_output_debug_string_utf8(message);
|
||||||
|
DebugBreak();
|
||||||
|
}
|
||||||
|
else if (s_debugger_stack_crawler != nullptr)
|
||||||
|
(*s_debugger_stack_crawler)();
|
||||||
|
#else
|
||||||
|
if (IsDebuggerPresent())
|
||||||
|
{
|
||||||
|
OutputDebugStringA(message);
|
||||||
|
__debugbreak();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// get_clipboard_text_by_format
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
static char *get_clipboard_text_by_format(UINT format, std::string (*convert)(LPCVOID data))
|
||||||
|
{
|
||||||
|
/*DataPackageView^ dataPackageView;
|
||||||
|
IAsyncOperation<String^>^ getTextOp;
|
||||||
|
String^ clipboardText;
|
||||||
|
|
||||||
|
dataPackageView = Clipboard::GetContent();
|
||||||
|
getTextOp = dataPackageView->GetTextAsync();
|
||||||
|
clipboardText = getTextOp->GetResults();
|
||||||
|
|
||||||
|
return osd::text::from_wstring(clipboardText->Data()).c_str();*/
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// convert_wide
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
static std::string convert_wide(LPCVOID data)
|
||||||
|
{
|
||||||
|
return osd::text::from_wstring((LPCWSTR) data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// convert_ansi
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
static std::string convert_ansi(LPCVOID data)
|
||||||
|
{
|
||||||
|
return osd::text::from_astring((LPCSTR) data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_get_clipboard_text
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
char *osd_get_clipboard_text(void)
|
||||||
|
{
|
||||||
|
// try to access unicode text
|
||||||
|
char *result = get_clipboard_text_by_format(CF_UNICODETEXT, convert_wide);
|
||||||
|
|
||||||
|
// try to access ANSI text
|
||||||
|
if (result == nullptr)
|
||||||
|
result = get_clipboard_text_by_format(CF_TEXT, convert_ansi);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// osd_dynamic_bind
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
// for classic desktop applications
|
||||||
|
#define load_library(filename) LoadLibrary(filename)
|
||||||
|
#else
|
||||||
|
// for Windows Store universal applications
|
||||||
|
#define load_library(filename) LoadPackagedLibrary(filename, 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace osd {
|
||||||
|
class dynamic_module_win32_impl : public dynamic_module
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
dynamic_module_win32_impl(std::vector<std::string> &libraries)
|
||||||
|
: m_module(nullptr)
|
||||||
|
{
|
||||||
|
m_libraries = libraries;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~dynamic_module_win32_impl() override
|
||||||
|
{
|
||||||
|
if (m_module != nullptr)
|
||||||
|
FreeLibrary(m_module);
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual generic_fptr_t get_symbol_address(char const *symbol) override
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* given a list of libraries, if a first symbol is successfully loaded from
|
||||||
|
* one of them, all additional symbols will be loaded from the same library
|
||||||
|
*/
|
||||||
|
if (m_module)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<generic_fptr_t>(GetProcAddress(m_module, symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const &library : m_libraries)
|
||||||
|
{
|
||||||
|
osd::text::tstring tempstr = osd::text::to_tstring(library);
|
||||||
|
HMODULE module = load_library(tempstr.c_str());
|
||||||
|
|
||||||
|
if (module != nullptr)
|
||||||
|
{
|
||||||
|
generic_fptr_t function = reinterpret_cast<generic_fptr_t>(GetProcAddress(module, symbol));
|
||||||
|
|
||||||
|
if (function != nullptr)
|
||||||
|
{
|
||||||
|
m_module = module;
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FreeLibrary(module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::string> m_libraries;
|
||||||
|
HMODULE m_module;
|
||||||
|
};
|
||||||
|
|
||||||
|
dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
|
||||||
|
{
|
||||||
|
return std::make_unique<dynamic_module_win32_impl>(names);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace osd
|
@ -5,7 +5,7 @@
|
|||||||
// strconv.cpp - Win32 string conversion
|
// strconv.cpp - Win32 string conversion
|
||||||
//
|
//
|
||||||
//============================================================
|
//============================================================
|
||||||
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
|
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS) || defined(OSD_UWP)
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
@ -16,7 +16,7 @@
|
|||||||
// MAMEOS headers
|
// MAMEOS headers
|
||||||
#include "strconv.h"
|
#include "strconv.h"
|
||||||
|
|
||||||
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
|
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS) || defined(OSD_UWP)
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
36
src/osd/uwp/Package.appxmanifest
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
|
||||||
|
<Identity Name="f0273023-de0a-46a5-b0db-1514f3a84c71" Publisher="CN=bradhugh" Version="1.0.0.0" />
|
||||||
|
<mp:PhoneIdentity PhoneProductId="f0273023-de0a-46a5-b0db-1514f3a84c71" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||||
|
<Properties>
|
||||||
|
<DisplayName>MAME</DisplayName>
|
||||||
|
<PublisherDisplayName>MAME Team</PublisherDisplayName>
|
||||||
|
<Logo>src\osd\uwp\assets\StoreLogo.png</Logo>
|
||||||
|
</Properties>
|
||||||
|
<Dependencies>
|
||||||
|
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||||
|
</Dependencies>
|
||||||
|
<Resources>
|
||||||
|
<Resource Language="x-generate" />
|
||||||
|
</Resources>
|
||||||
|
<Applications>
|
||||||
|
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="Mameuwp.App">
|
||||||
|
<uap:VisualElements DisplayName="MAME" Square150x150Logo="src\osd\uwp\assets\Square150x150Logo.png" Square44x44Logo="src\osd\uwp\assets\Square44x44Logo.png" Description="MAME for Windows 10" BackgroundColor="transparent">
|
||||||
|
<uap:DefaultTile Wide310x150Logo="src\osd\uwp\assets\Wide310x150Logo.png">
|
||||||
|
<uap:ShowNameOnTiles>
|
||||||
|
<uap:ShowOn Tile="square150x150Logo" />
|
||||||
|
</uap:ShowNameOnTiles>
|
||||||
|
</uap:DefaultTile>
|
||||||
|
<uap:SplashScreen Image="src\osd\uwp\assets\SplashScreen.scale-200.png" />
|
||||||
|
<uap:InitialRotationPreference>
|
||||||
|
<uap:Rotation Preference="landscape" />
|
||||||
|
</uap:InitialRotationPreference>
|
||||||
|
</uap:VisualElements>
|
||||||
|
</Application>
|
||||||
|
</Applications>
|
||||||
|
<Capabilities>
|
||||||
|
<Capability Name="internetClient" />
|
||||||
|
<Capability Name="codeGeneration" />
|
||||||
|
<Capability Name="privateNetworkClientServer" />
|
||||||
|
</Capabilities>
|
||||||
|
</Package>
|
BIN
src/osd/uwp/assets/LockScreenLogo.scale-200.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/osd/uwp/assets/SplashScreen.scale-200.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
src/osd/uwp/assets/Square150x150Logo.scale-200.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
src/osd/uwp/assets/Square44x44Logo.scale-200.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.2 KiB |
BIN
src/osd/uwp/assets/StoreLogo.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/osd/uwp/assets/Wide310x150Logo.scale-200.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
@ -16,15 +16,13 @@
|
|||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
int __cdecl system(const char *command)
|
BOOL WINAPI GetVersionEx(
|
||||||
|
_Inout_ LPOSVERSIONINFO lpVersionInfo
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return ENOENT;
|
lpVersionInfo->dwMajorVersion = 10;
|
||||||
}
|
return TRUE;
|
||||||
|
|
||||||
const char *getenv(const char *varname)
|
|
||||||
{
|
|
||||||
return osd_getenv(varname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
|
186
src/osd/uwp/uwpmain.cpp
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Aaron Giles
|
||||||
|
//============================================================
|
||||||
|
//
|
||||||
|
// main.c - Win32 main program
|
||||||
|
//
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
// standard windows headers
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "uwpmain.h"
|
||||||
|
#include <wrl\client.h>
|
||||||
|
#undef interface
|
||||||
|
|
||||||
|
using namespace Windows::ApplicationModel;
|
||||||
|
using namespace Windows::ApplicationModel::Core;
|
||||||
|
using namespace Windows::ApplicationModel::Activation;
|
||||||
|
using namespace Windows::UI::Core;
|
||||||
|
using namespace Windows::UI::Input;
|
||||||
|
using namespace Windows::System;
|
||||||
|
using namespace Windows::Foundation;
|
||||||
|
using namespace Windows::Graphics::Display;
|
||||||
|
|
||||||
|
using namespace MameUWP;
|
||||||
|
|
||||||
|
Platform::Array<Platform::String^>^ g_command_args;
|
||||||
|
|
||||||
|
// The main function is only used to initialize our IFrameworkView class.
|
||||||
|
[Platform::MTAThread]
|
||||||
|
int main(Platform::Array<Platform::String^>^ args)
|
||||||
|
{
|
||||||
|
g_command_args = args;
|
||||||
|
auto direct3DApplicationSource = ref new Direct3DApplicationSource();
|
||||||
|
CoreApplication::Run(direct3DApplicationSource);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFrameworkView^ Direct3DApplicationSource::CreateView()
|
||||||
|
{
|
||||||
|
return ref new App();
|
||||||
|
}
|
||||||
|
|
||||||
|
App::App() :
|
||||||
|
m_windowClosed(false),
|
||||||
|
m_windowVisible(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first method called when the IFrameworkView is being created.
|
||||||
|
void App::Initialize(CoreApplicationView^ applicationView)
|
||||||
|
{
|
||||||
|
// Register event handlers for app lifecycle. This example includes Activated, so that we
|
||||||
|
// can make the CoreWindow active and start rendering on the window.
|
||||||
|
applicationView->Activated +=
|
||||||
|
ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &App::OnActivated);
|
||||||
|
|
||||||
|
CoreApplication::Suspending +=
|
||||||
|
ref new EventHandler<SuspendingEventArgs^>(this, &App::OnSuspending);
|
||||||
|
|
||||||
|
CoreApplication::Resuming +=
|
||||||
|
ref new EventHandler<Platform::Object^>(this, &App::OnResuming);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when the CoreWindow object is created (or re-created).
|
||||||
|
void App::SetWindow(CoreWindow^ window)
|
||||||
|
{
|
||||||
|
window->SizeChanged +=
|
||||||
|
ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &App::OnWindowSizeChanged);
|
||||||
|
|
||||||
|
window->VisibilityChanged +=
|
||||||
|
ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &App::OnVisibilityChanged);
|
||||||
|
|
||||||
|
window->Closed +=
|
||||||
|
ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &App::OnWindowClosed);
|
||||||
|
|
||||||
|
DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
|
||||||
|
|
||||||
|
currentDisplayInformation->DpiChanged +=
|
||||||
|
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &App::OnDpiChanged);
|
||||||
|
|
||||||
|
currentDisplayInformation->OrientationChanged +=
|
||||||
|
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &App::OnOrientationChanged);
|
||||||
|
|
||||||
|
DisplayInformation::DisplayContentsInvalidated +=
|
||||||
|
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &App::OnDisplayContentsInvalidated);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initializes scene resources, or loads a previously saved app state.
|
||||||
|
void App::Load(Platform::String^ entryPoint)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is called after the window becomes active.
|
||||||
|
void App::Run()
|
||||||
|
{
|
||||||
|
// parse config and cmdline options
|
||||||
|
// DWORD result;
|
||||||
|
{
|
||||||
|
/* winrt_options options;
|
||||||
|
winrt_osd_interface osd(options);
|
||||||
|
|
||||||
|
char exe_path[MAX_PATH];
|
||||||
|
GetModuleFileNameA(NULL, exe_path, MAX_PATH);
|
||||||
|
char* args[2] = { exe_path, (char*)"-verbose" };
|
||||||
|
|
||||||
|
osd.register_options();
|
||||||
|
cli_frontend frontend(options, osd);
|
||||||
|
result = frontend.execute(ARRAY_LENGTH(args), args);*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required for IFrameworkView.
|
||||||
|
// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView
|
||||||
|
// class is torn down while the app is in the foreground.
|
||||||
|
void App::Uninitialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Application lifecycle event handlers.
|
||||||
|
|
||||||
|
void App::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
|
||||||
|
{
|
||||||
|
// Run() won't start until the CoreWindow is activated.
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
|
||||||
|
{
|
||||||
|
// Save app state asynchronously after requesting a deferral. Holding a deferral
|
||||||
|
// indicates that the application is busy performing suspending operations. Be
|
||||||
|
// aware that a deferral may not be held indefinitely. After about five seconds,
|
||||||
|
// the app will be forced to exit.
|
||||||
|
SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
|
||||||
|
|
||||||
|
//create_task([this, deferral]()
|
||||||
|
//{
|
||||||
|
// //m_deviceResources->Trim();
|
||||||
|
|
||||||
|
// // Insert your code here.
|
||||||
|
|
||||||
|
// deferral->Complete();
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::OnResuming(Platform::Object^ sender, Platform::Object^ args)
|
||||||
|
{
|
||||||
|
// Restore any data or state that was unloaded on suspend. By default, data
|
||||||
|
// and state are persisted when resuming from suspend. Note that this event
|
||||||
|
// does not occur if the app was previously terminated.
|
||||||
|
|
||||||
|
// Insert your code here.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window event handlers.
|
||||||
|
|
||||||
|
void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
|
||||||
|
{
|
||||||
|
m_windowVisible = args->Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
|
||||||
|
{
|
||||||
|
m_windowClosed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisplayInformation event handlers.
|
||||||
|
void App::OnDpiChanged(DisplayInformation^ sender, Object^ args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args)
|
||||||
|
{
|
||||||
|
}
|
52
src/osd/uwp/uwpmain.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Brad Hughes
|
||||||
|
//============================================================
|
||||||
|
//
|
||||||
|
// uwpmain.h - Universal Windows Paltform
|
||||||
|
//
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace MameUWP
|
||||||
|
{
|
||||||
|
// Main entry point for our app. Connects the app with the Windows shell and handles application lifecycle events.
|
||||||
|
ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
App();
|
||||||
|
|
||||||
|
// IFrameworkView Methods.
|
||||||
|
virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
|
||||||
|
virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
|
||||||
|
virtual void Load(Platform::String^ entryPoint);
|
||||||
|
virtual void Run();
|
||||||
|
virtual void Uninitialize();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Application lifecycle event handlers.
|
||||||
|
void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
|
||||||
|
void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args);
|
||||||
|
void OnResuming(Platform::Object^ sender, Platform::Object^ args);
|
||||||
|
|
||||||
|
// Window event handlers.
|
||||||
|
void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
|
||||||
|
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
|
||||||
|
void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
|
||||||
|
|
||||||
|
// DisplayInformation event handlers.
|
||||||
|
void OnDpiChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
|
||||||
|
void OnOrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
|
||||||
|
void OnDisplayContentsInvalidated(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_windowClosed;
|
||||||
|
bool m_windowVisible;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ref class Direct3DApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView();
|
||||||
|
};
|