More string swapping and cleaning up main().
This commit is contained in:
parent
18ee972b47
commit
7c5fa88661
|
@ -14,7 +14,6 @@
|
||||||
#include <xenia/config.h>
|
#include <xenia/config.h>
|
||||||
#include <xenia/logging.h>
|
#include <xenia/logging.h>
|
||||||
#include <xenia/malloc.h>
|
#include <xenia/malloc.h>
|
||||||
#include <xenia/platform.h>
|
|
||||||
#include <xenia/profiling.h>
|
#include <xenia/profiling.h>
|
||||||
#include <xenia/string.h>
|
#include <xenia/string.h>
|
||||||
#include <xenia/types.h>
|
#include <xenia/types.h>
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef POLY_MAIN_H_
|
||||||
|
#define POLY_MAIN_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <poly/platform.h>
|
||||||
|
|
||||||
|
namespace poly {
|
||||||
|
|
||||||
|
// Returns true if there is a user-visible console attached to receive stdout.
|
||||||
|
bool has_console_attached();
|
||||||
|
|
||||||
|
// Extern defined by user code. This must be present for the application to
|
||||||
|
// launch.
|
||||||
|
struct EntryInfo {
|
||||||
|
std::wstring name;
|
||||||
|
std::wstring usage;
|
||||||
|
int (*entry_point)(std::vector<std::wstring>& args);
|
||||||
|
};
|
||||||
|
EntryInfo GetEntryInfo();
|
||||||
|
|
||||||
|
#define DEFINE_ENTRY_POINT(name, usage, entry_point) \
|
||||||
|
poly::EntryInfo poly::GetEntryInfo() { return {name, usage, entry_point}; }
|
||||||
|
|
||||||
|
} // namespace poly
|
||||||
|
|
||||||
|
#endif // POLY_MAIN_H_
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <poly/main.h>
|
||||||
|
|
||||||
|
#include <poly/string.h>
|
||||||
|
|
||||||
|
namespace poly {
|
||||||
|
|
||||||
|
bool has_console_attached() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace poly
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" int main(int argc, char** argv) {
|
||||||
|
auto entry_info = poly::GetEntryInfo();
|
||||||
|
|
||||||
|
google::SetUsageMessage(std::string("usage: ") +
|
||||||
|
poly::to_string(entry_info.usage));
|
||||||
|
google::SetVersionString("1.0");
|
||||||
|
google::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
|
|
||||||
|
std::vector<std::wstring> args;
|
||||||
|
for (int n = 0; n < argc; n++) {
|
||||||
|
args.push_back(poly::to_wstring(argv[n]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call app-provided entry point.
|
||||||
|
int result = entry_info.entry_point(args);
|
||||||
|
|
||||||
|
google::ShutDownCommandLineFlags();
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <poly/main.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <shellapi.h>
|
||||||
|
|
||||||
|
#include <gflags/gflags.h>
|
||||||
|
#include <poly/string.h>
|
||||||
|
|
||||||
|
namespace poly {
|
||||||
|
|
||||||
|
bool has_console_attached_ = true;
|
||||||
|
|
||||||
|
bool has_console_attached() { return has_console_attached_; }
|
||||||
|
|
||||||
|
void AttachConsole() {
|
||||||
|
bool has_console = ::AttachConsole(ATTACH_PARENT_PROCESS) == TRUE;
|
||||||
|
if (!has_console) {
|
||||||
|
// We weren't launched from a console, so just return.
|
||||||
|
// We could alloc our own console, but meh:
|
||||||
|
// has_console = AllocConsole() == TRUE;
|
||||||
|
has_console_attached_ = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
has_console_attached_ = true;
|
||||||
|
|
||||||
|
auto std_handle = (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
auto con_handle = _open_osfhandle(std_handle, _O_TEXT);
|
||||||
|
auto fp = _fdopen(con_handle, "w");
|
||||||
|
*stdout = *fp;
|
||||||
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
|
|
||||||
|
std_handle = (intptr_t)GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
con_handle = _open_osfhandle(std_handle, _O_TEXT);
|
||||||
|
fp = _fdopen(con_handle, "w");
|
||||||
|
*stderr = *fp;
|
||||||
|
setvbuf(stderr, NULL, _IONBF, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace poly
|
||||||
|
|
||||||
|
// Used in console mode apps; automatically picked based on subsystem.
|
||||||
|
int wmain(int argc, wchar_t* argv[]) {
|
||||||
|
auto entry_info = poly::GetEntryInfo();
|
||||||
|
|
||||||
|
google::SetUsageMessage(std::string("usage: ") +
|
||||||
|
poly::to_string(entry_info.usage));
|
||||||
|
google::SetVersionString("1.0");
|
||||||
|
|
||||||
|
// Convert all args to narrow, as gflags doesn't support wchar.
|
||||||
|
int argca = argc;
|
||||||
|
char** argva = (char**)alloca(sizeof(char*) * argca);
|
||||||
|
for (int n = 0; n < argca; n++) {
|
||||||
|
size_t len = wcslen(argv[n]);
|
||||||
|
argva[n] = (char*)alloca(len + 1);
|
||||||
|
wcstombs_s(NULL, argva[n], len + 1, argv[n], _TRUNCATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse flags; this may delete some of them.
|
||||||
|
google::ParseCommandLineFlags(&argc, &argva, true);
|
||||||
|
|
||||||
|
// Widen all remaining flags and convert to usable strings.
|
||||||
|
std::vector<std::wstring> args;
|
||||||
|
for (int n = 0; n < argc; n++) {
|
||||||
|
args.push_back(poly::to_wstring(argva[n]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call app-provided entry point.
|
||||||
|
int result = entry_info.entry_point(args);
|
||||||
|
|
||||||
|
google::ShutDownCommandLineFlags();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used in windowed apps; automatically picked based on subsystem.
|
||||||
|
int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR command_line, int) {
|
||||||
|
// Attach a console so we can write output to stdout. If the user hasn't
|
||||||
|
// redirected output themselves it'll pop up a window.
|
||||||
|
poly::AttachConsole();
|
||||||
|
|
||||||
|
auto entry_info = poly::GetEntryInfo();
|
||||||
|
|
||||||
|
// Convert to an argv-like format so we can share code/use gflags.
|
||||||
|
std::wstring buffer = entry_info.name + L" " + command_line;
|
||||||
|
int argc;
|
||||||
|
wchar_t** argv = CommandLineToArgvW(buffer.c_str(), &argc);
|
||||||
|
if (!argv) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run normal entry point.
|
||||||
|
int result = wmain(argc, argv);
|
||||||
|
|
||||||
|
LocalFree(argv);
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef POLY_POLY_PRIVATE_H_
|
|
||||||
#define POLY_POLY_PRIVATE_H_
|
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#endif // POLY_POLY_PRIVATE_H_
|
|
|
@ -1,13 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <poly/poly.h>
|
|
||||||
#include <poly/poly-private.h>
|
|
||||||
|
|
||||||
namespace poly {} // namespace poly
|
|
|
@ -7,13 +7,12 @@
|
||||||
'debugging.h',
|
'debugging.h',
|
||||||
'config.h',
|
'config.h',
|
||||||
'cxx_compat.h',
|
'cxx_compat.h',
|
||||||
|
'main.h',
|
||||||
'math.cc',
|
'math.cc',
|
||||||
'math.h',
|
'math.h',
|
||||||
'memory.cc',
|
'memory.cc',
|
||||||
'memory.h',
|
'memory.h',
|
||||||
'platform.h',
|
'platform.h',
|
||||||
'poly-private.h',
|
|
||||||
'poly.cc',
|
|
||||||
'poly.h',
|
'poly.h',
|
||||||
'string.cc',
|
'string.cc',
|
||||||
'string.h',
|
'string.h',
|
||||||
|
@ -23,6 +22,7 @@
|
||||||
'conditions': [
|
'conditions': [
|
||||||
['OS == "mac" or OS == "linux"', {
|
['OS == "mac" or OS == "linux"', {
|
||||||
'sources': [
|
'sources': [
|
||||||
|
'main_posix.cc',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
['OS == "linux"', {
|
['OS == "linux"', {
|
||||||
|
@ -39,6 +39,7 @@
|
||||||
['OS == "win"', {
|
['OS == "win"', {
|
||||||
'sources': [
|
'sources': [
|
||||||
'debugging_win.cc',
|
'debugging_win.cc',
|
||||||
|
'main_win.cc',
|
||||||
'threading_win.cc',
|
'threading_win.cc',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
|
|
|
@ -39,4 +39,52 @@ std::string::size_type find_first_of_case(const std::string& target,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::wstring to_absolute_path(const std::wstring& path) {
|
||||||
|
#if XE_LIKE_WIN32
|
||||||
|
wchar_t buffer[poly::max_path];
|
||||||
|
_wfullpath(buffer, path.c_str(), sizeof(buffer) / sizeof(wchar_t));
|
||||||
|
return buffer;
|
||||||
|
#else
|
||||||
|
char buffer[poly::max_path];
|
||||||
|
realpath(poly::to_string(path).c_str(), buffer);
|
||||||
|
return poly::to_wstring(buffer);
|
||||||
|
#endif // XE_LIKE_WIN32
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring join_paths(const std::wstring& left, const std::wstring& right,
|
||||||
|
wchar_t sep) {
|
||||||
|
if (!left.size()) {
|
||||||
|
return right;
|
||||||
|
} else if (!right.size()) {
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
if (left[left.size() - 1] == sep) {
|
||||||
|
return left + right;
|
||||||
|
} else {
|
||||||
|
return left + sep + right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring fix_path_separators(const std::wstring& source, wchar_t new_sep) {
|
||||||
|
// Swap all separators to new_sep.
|
||||||
|
wchar_t old_sep = new_sep == '\\' ? '/' : '\\';
|
||||||
|
std::wstring::size_type pos = 0;
|
||||||
|
std::wstring dest = source;
|
||||||
|
while ((pos = source.find_first_of(old_sep, pos)) != std::wstring::npos) {
|
||||||
|
dest[pos] = new_sep;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
// Replace redundant separators.
|
||||||
|
pos = 0;
|
||||||
|
while ((pos = dest.find_first_of(new_sep, pos)) != std::wstring::npos) {
|
||||||
|
if (pos < dest.size() - 1) {
|
||||||
|
if (dest[pos + 1] == new_sep) {
|
||||||
|
dest.erase(pos + 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace poly
|
} // namespace poly
|
||||||
|
|
|
@ -24,9 +24,22 @@ namespace poly {
|
||||||
std::string to_string(const std::wstring& source);
|
std::string to_string(const std::wstring& source);
|
||||||
std::wstring to_wstring(const std::string& source);
|
std::wstring to_wstring(const std::string& source);
|
||||||
|
|
||||||
|
// find_first_of string, case insensitive.
|
||||||
std::string::size_type find_first_of_case(const std::string& target,
|
std::string::size_type find_first_of_case(const std::string& target,
|
||||||
const std::string& search);
|
const std::string& search);
|
||||||
|
|
||||||
|
// Converts the given path to an absolute path based on cwd.
|
||||||
|
std::wstring to_absolute_path(const std::wstring& path);
|
||||||
|
|
||||||
|
// Joins two path segments with the given separator.
|
||||||
|
std::wstring join_paths(const std::wstring& left, const std::wstring& right,
|
||||||
|
wchar_t sep = poly::path_separator);
|
||||||
|
|
||||||
|
// Replaces all path separators with the given value and removes redundant
|
||||||
|
// separators.
|
||||||
|
std::wstring fix_path_separators(const std::wstring& source,
|
||||||
|
wchar_t new_sep = poly::path_separator);
|
||||||
|
|
||||||
} // namespace poly
|
} // namespace poly
|
||||||
|
|
||||||
#endif // POLY_STRING_H_
|
#endif // POLY_STRING_H_
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include <xenia/config.h>
|
#include <xenia/config.h>
|
||||||
#include <xenia/logging.h>
|
#include <xenia/logging.h>
|
||||||
#include <xenia/malloc.h>
|
#include <xenia/malloc.h>
|
||||||
#include <xenia/platform.h>
|
|
||||||
#include <xenia/profiling.h>
|
#include <xenia/profiling.h>
|
||||||
#include <xenia/string.h>
|
#include <xenia/string.h>
|
||||||
#include <xenia/types.h>
|
#include <xenia/types.h>
|
||||||
|
|
|
@ -20,7 +20,6 @@ namespace xe {
|
||||||
#include <xenia/core/hash.h>
|
#include <xenia/core/hash.h>
|
||||||
#include <xenia/core/mmap.h>
|
#include <xenia/core/mmap.h>
|
||||||
#include <xenia/core/pal.h>
|
#include <xenia/core/pal.h>
|
||||||
#include <xenia/core/path.h>
|
|
||||||
#include <xenia/core/ref.h>
|
#include <xenia/core/ref.h>
|
||||||
#include <xenia/core/run_loop.h>
|
#include <xenia/core/run_loop.h>
|
||||||
#include <xenia/core/socket.h>
|
#include <xenia/core/socket.h>
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xenia/core/path.h>
|
|
||||||
|
|
||||||
|
|
||||||
void xe_path_join(const xechar_t* left, const xechar_t* right,
|
|
||||||
xechar_t* out_path, size_t out_path_size) {
|
|
||||||
#if XE_WCHAR
|
|
||||||
xesnprintf(out_path, out_path_size, L"%ls%c%ls",
|
|
||||||
left, poly::path_separator, right);
|
|
||||||
#else
|
|
||||||
xesnprintf(out_path, out_path_size, L"%s%c%s",
|
|
||||||
left, poly::path_separator, right);
|
|
||||||
#endif // XE_WCHAR
|
|
||||||
}
|
|
||||||
|
|
||||||
void xe_path_get_absolute(const xechar_t* path, xechar_t* out_abs_path,
|
|
||||||
size_t abs_path_size) {
|
|
||||||
#if XE_PLATFORM_WIN32
|
|
||||||
#if XE_WCHAR
|
|
||||||
_wfullpath(out_abs_path, path, abs_path_size);
|
|
||||||
#else
|
|
||||||
_fullpath(out_abs_path, path, abs_path_size);
|
|
||||||
#endif // XE_WCHAR
|
|
||||||
#else
|
|
||||||
realpath(path, out_abs_path);
|
|
||||||
#endif // WIN32
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef XENIA_CORE_PATH_H_
|
|
||||||
#define XENIA_CORE_PATH_H_
|
|
||||||
|
|
||||||
#include <xenia/common.h>
|
|
||||||
#include <xenia/core/pal.h>
|
|
||||||
#include <xenia/core/ref.h>
|
|
||||||
|
|
||||||
|
|
||||||
void xe_path_join(const xechar_t* left, const xechar_t* right,
|
|
||||||
xechar_t* out_path, size_t out_path_size);
|
|
||||||
void xe_path_get_absolute(const xechar_t* path, xechar_t* out_abs_path,
|
|
||||||
size_t abs_path_size);
|
|
||||||
|
|
||||||
const xechar_t* xe_path_get_tmp(const xechar_t* prefix);
|
|
||||||
|
|
||||||
#endif // XENIA_CORE_PATH_H_
|
|
|
@ -1,16 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xenia/core/path.h>
|
|
||||||
|
|
||||||
|
|
||||||
const xechar_t* xe_path_get_tmp(const xechar_t* prefix) {
|
|
||||||
//
|
|
||||||
assert_always();
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xenia/core/path.h>
|
|
||||||
|
|
||||||
|
|
||||||
const xechar_t* xe_path_get_tmp(const xechar_t* prefix) {
|
|
||||||
//
|
|
||||||
assert_always();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
|
@ -5,8 +5,6 @@
|
||||||
'hash.h',
|
'hash.h',
|
||||||
'mmap.h',
|
'mmap.h',
|
||||||
'pal.h',
|
'pal.h',
|
||||||
'path.cc',
|
|
||||||
'path.h',
|
|
||||||
'ref.cc',
|
'ref.cc',
|
||||||
'ref.h',
|
'ref.h',
|
||||||
'run_loop.h',
|
'run_loop.h',
|
||||||
|
@ -17,7 +15,6 @@
|
||||||
['OS == "mac" or OS == "linux"', {
|
['OS == "mac" or OS == "linux"', {
|
||||||
'sources': [
|
'sources': [
|
||||||
'mmap_posix.cc',
|
'mmap_posix.cc',
|
||||||
'path_posix.cc',
|
|
||||||
'socket_posix.cc',
|
'socket_posix.cc',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
|
@ -35,7 +32,6 @@
|
||||||
'sources': [
|
'sources': [
|
||||||
'mmap_win.cc',
|
'mmap_win.cc',
|
||||||
'pal_win.cc',
|
'pal_win.cc',
|
||||||
'path_win.cc',
|
|
||||||
'run_loop_win.cc',
|
'run_loop_win.cc',
|
||||||
'socket_win.cc',
|
'socket_win.cc',
|
||||||
],
|
],
|
||||||
|
|
|
@ -59,7 +59,7 @@ Entry* DiscImageDevice::ResolvePath(const char* path) {
|
||||||
char remaining[poly::max_path];
|
char remaining[poly::max_path];
|
||||||
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path));
|
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path));
|
||||||
while (remaining[0]) {
|
while (remaining[0]) {
|
||||||
char* next_slash = xestrchra(remaining, '\\');
|
char* next_slash = strchr(remaining, '\\');
|
||||||
if (next_slash == remaining) {
|
if (next_slash == remaining) {
|
||||||
// Leading slash - shift
|
// Leading slash - shift
|
||||||
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), remaining + 1));
|
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), remaining + 1));
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include <xenia/kernel/fs/devices/host_path_device.h>
|
#include <xenia/kernel/fs/devices/host_path_device.h>
|
||||||
|
|
||||||
#include <xenia/core/path.h>
|
|
||||||
#include <xenia/kernel/fs/devices/host_path_entry.h>
|
#include <xenia/kernel/fs/devices/host_path_entry.h>
|
||||||
#include <xenia/kernel/objects/xfile.h>
|
#include <xenia/kernel/objects/xfile.h>
|
||||||
|
|
||||||
|
@ -30,27 +29,9 @@ Entry* HostPathDevice::ResolvePath(const char* path) {
|
||||||
|
|
||||||
XELOGFS("HostPathDevice::ResolvePath(%s)", path);
|
XELOGFS("HostPathDevice::ResolvePath(%s)", path);
|
||||||
|
|
||||||
#if XE_WCHAR
|
auto rel_path = poly::to_wstring(path);
|
||||||
xechar_t rel_path[poly::max_path];
|
auto full_path = poly::join_paths(local_path_, rel_path);
|
||||||
XEIGNORE(xestrwiden(rel_path, XECOUNT(rel_path), path));
|
full_path = poly::fix_path_separators(full_path);
|
||||||
#else
|
|
||||||
const xechar_t* rel_path = path;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
xechar_t full_path[poly::max_path];
|
|
||||||
xe_path_join(local_path_.c_str(), rel_path, full_path, XECOUNT(full_path));
|
|
||||||
|
|
||||||
// Swap around path separators.
|
|
||||||
if (poly::path_separator != '\\') {
|
|
||||||
for (size_t n = 0; n < XECOUNT(full_path); n++) {
|
|
||||||
if (full_path[n] == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (full_path[n] == '\\') {
|
|
||||||
full_path[n] = poly::path_separator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(benvanik): get file info
|
// TODO(benvanik): get file info
|
||||||
// TODO(benvanik): fail if does not exit
|
// TODO(benvanik): fail if does not exit
|
||||||
|
|
|
@ -59,7 +59,7 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) {
|
||||||
char remaining[poly::max_path];
|
char remaining[poly::max_path];
|
||||||
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path));
|
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path));
|
||||||
while (remaining[0]) {
|
while (remaining[0]) {
|
||||||
char* next_slash = xestrchra(remaining, '\\');
|
char* next_slash = strchr(remaining, '\\');
|
||||||
if (next_slash == remaining) {
|
if (next_slash == remaining) {
|
||||||
// Leading slash - shift
|
// Leading slash - shift
|
||||||
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), remaining + 1));
|
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), remaining + 1));
|
||||||
|
|
|
@ -17,19 +17,20 @@ using namespace xe::cpu;
|
||||||
using namespace xe::kernel;
|
using namespace xe::kernel;
|
||||||
|
|
||||||
|
|
||||||
XModule::XModule(KernelState* kernel_state, const char* path) :
|
XModule::XModule(KernelState* kernel_state, const std::string& path) :
|
||||||
XObject(kernel_state, kTypeModule) {
|
XObject(kernel_state, kTypeModule), path_(path) {
|
||||||
XEIGNORE(xestrcpya(path_, XECOUNT(path_), path));
|
auto last_slash = path.find_last_of('/');
|
||||||
const char* slash = xestrrchra(path, '/');
|
if (last_slash == path.npos) {
|
||||||
if (!slash) {
|
last_slash = path.find_last_of('\\');
|
||||||
slash = xestrrchra(path, '\\');
|
|
||||||
}
|
}
|
||||||
if (slash) {
|
if (last_slash == path.npos) {
|
||||||
XEIGNORE(xestrcpya(name_, XECOUNT(name_), slash + 1));
|
name_ = path_;
|
||||||
|
} else {
|
||||||
|
name_ = path_.substr(last_slash + 1);
|
||||||
}
|
}
|
||||||
char* dot = xestrrchra(name_, '.');
|
auto dot = name_.find_last_of('.');
|
||||||
if (dot) {
|
if (dot != name_.npos) {
|
||||||
*dot = 0;
|
name_ = name_.substr(0, dot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#ifndef XENIA_KERNEL_XBOXKRNL_XMODULE_H_
|
#ifndef XENIA_KERNEL_XBOXKRNL_XMODULE_H_
|
||||||
#define XENIA_KERNEL_XBOXKRNL_XMODULE_H_
|
#define XENIA_KERNEL_XBOXKRNL_XMODULE_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <xenia/kernel/xobject.h>
|
#include <xenia/kernel/xobject.h>
|
||||||
|
|
||||||
#include <xenia/xbox.h>
|
#include <xenia/xbox.h>
|
||||||
|
@ -21,11 +23,11 @@ namespace kernel {
|
||||||
|
|
||||||
class XModule : public XObject {
|
class XModule : public XObject {
|
||||||
public:
|
public:
|
||||||
XModule(KernelState* kernel_state, const char* path);
|
XModule(KernelState* kernel_state, const std::string& path);
|
||||||
virtual ~XModule();
|
virtual ~XModule();
|
||||||
|
|
||||||
const char* path() const { return path_; }
|
const std::string& path() const { return path_; }
|
||||||
const char* name() const { return name_; }
|
const std::string& name() const { return name_; }
|
||||||
|
|
||||||
virtual void* GetProcAddressByOrdinal(uint16_t ordinal) = 0;
|
virtual void* GetProcAddressByOrdinal(uint16_t ordinal) = 0;
|
||||||
virtual X_STATUS GetSection(
|
virtual X_STATUS GetSection(
|
||||||
|
@ -35,8 +37,8 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void OnLoad();
|
void OnLoad();
|
||||||
|
|
||||||
char name_[256];
|
std::string name_;
|
||||||
char path_[poly::max_path];
|
std::string path_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -200,19 +200,19 @@ SHIM_CALL RtlInitUnicodeString_shim(
|
||||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
||||||
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
const wchar_t* source =
|
auto source =
|
||||||
source_ptr ? (const wchar_t*)SHIM_MEM_ADDR(source_ptr) : NULL;
|
source_ptr ? poly::load_and_swap<std::wstring>(SHIM_MEM_ADDR(source_ptr))
|
||||||
XELOGD("RtlInitUnicodeString(%.8X, %.8X = %ls)",
|
: L"";
|
||||||
destination_ptr, source_ptr, source ? source : L"<null>");
|
XELOGD("RtlInitUnicodeString(%.8X, %.8X = %ls)", destination_ptr, source_ptr,
|
||||||
|
source.empty() ? L"<null>" : source.c_str());
|
||||||
|
|
||||||
// VOID
|
// VOID
|
||||||
// _Out_ PUNICODE_STRING DestinationString,
|
// _Out_ PUNICODE_STRING DestinationString,
|
||||||
// _In_opt_ PCWSTR SourceString
|
// _In_opt_ PCWSTR SourceString
|
||||||
|
|
||||||
if (source) {
|
if (source.size()) {
|
||||||
uint16_t length = (uint16_t)xestrlenw(source);
|
SHIM_SET_MEM_16(destination_ptr + 0, source.size() * 2);
|
||||||
SHIM_SET_MEM_16(destination_ptr + 0, length * 2);
|
SHIM_SET_MEM_16(destination_ptr + 2, (source.size() + 1) * 2);
|
||||||
SHIM_SET_MEM_16(destination_ptr + 2, (length + 1) * 2);
|
|
||||||
SHIM_SET_MEM_32(destination_ptr + 4, source_ptr);
|
SHIM_SET_MEM_32(destination_ptr + 4, source_ptr);
|
||||||
} else {
|
} else {
|
||||||
SHIM_SET_MEM_16(destination_ptr + 0, 0);
|
SHIM_SET_MEM_16(destination_ptr + 0, 0);
|
||||||
|
|
|
@ -11,10 +11,9 @@
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <xenia/common.h>
|
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
#include <poly/main.h>
|
||||||
|
#include <xenia/common.h>
|
||||||
|
|
||||||
DEFINE_bool(fast_stdout, false,
|
DEFINE_bool(fast_stdout, false,
|
||||||
"Don't lock around stdout/stderr. May introduce weirdness.");
|
"Don't lock around stdout/stderr. May introduce weirdness.");
|
||||||
|
@ -31,7 +30,7 @@ void xe_format_log_line(
|
||||||
const char* function_name, const char level_char,
|
const char* function_name, const char level_char,
|
||||||
const char* fmt, va_list args) {
|
const char* fmt, va_list args) {
|
||||||
// Strip out just the filename from the path.
|
// Strip out just the filename from the path.
|
||||||
const char* filename = xestrrchra(file_path, poly::path_separator);
|
const char* filename = strrchr(file_path, poly::path_separator);
|
||||||
if (filename) {
|
if (filename) {
|
||||||
// Slash - skip over it.
|
// Slash - skip over it.
|
||||||
filename++;
|
filename++;
|
||||||
|
@ -108,7 +107,7 @@ void xe_handle_fatal(
|
||||||
}
|
}
|
||||||
|
|
||||||
#if XE_LIKE_WIN32
|
#if XE_LIKE_WIN32
|
||||||
if (!xe_has_console()) {
|
if (!poly::has_console_attached()) {
|
||||||
MessageBoxA(NULL, buffer, "Xenia Error",
|
MessageBoxA(NULL, buffer, "Xenia Error",
|
||||||
MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND);
|
MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include <xenia/platform.h>
|
|
||||||
#include <xenia/config.h>
|
#include <xenia/config.h>
|
||||||
#include <xenia/string.h>
|
#include <xenia/string.h>
|
||||||
|
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xenia/platform.h>
|
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <xenia/common.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
typedef int (*user_main_t)(int argc, xechar_t** argv);
|
|
||||||
|
|
||||||
bool _has_console = true;
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
|
|
||||||
#if XE_LIKE_WIN32 && defined(UNICODE) && UNICODE
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <io.h>
|
|
||||||
#include <shellapi.h>
|
|
||||||
|
|
||||||
int xe_main_thunk(
|
|
||||||
int argc, wchar_t* argv[],
|
|
||||||
void* user_main, const char* usage) {
|
|
||||||
google::SetUsageMessage(std::string("usage: ") + usage);
|
|
||||||
google::SetVersionString("1.0");
|
|
||||||
|
|
||||||
int argca = argc;
|
|
||||||
char** argva = (char**)alloca(sizeof(char*) * argca);
|
|
||||||
for (int n = 0; n < argca; n++) {
|
|
||||||
size_t len = xestrlenw(argv[n]);
|
|
||||||
argva[n] = (char*)alloca(len + 1);
|
|
||||||
xestrnarrow(argva[n], len + 1, argv[n]);
|
|
||||||
}
|
|
||||||
|
|
||||||
google::ParseCommandLineFlags(&argc, &argva, true);
|
|
||||||
|
|
||||||
// Parse may have deleted flags - so widen again.
|
|
||||||
int argcw = argc;
|
|
||||||
wchar_t** argvw = (wchar_t**)alloca(sizeof(wchar_t*) * argca);
|
|
||||||
for (int n = 0; n < argc; n++) {
|
|
||||||
size_t len = xestrlena(argva[n]);
|
|
||||||
argvw[n] = (wchar_t*)alloca(sizeof(wchar_t) * (len + 1));
|
|
||||||
xestrwiden(argvw[n], len + 1, argva[n]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int result = ((user_main_t)user_main)(argcw, (xechar_t**)argvw);
|
|
||||||
google::ShutDownCommandLineFlags();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool xe_has_console() {
|
|
||||||
return _has_console;
|
|
||||||
}
|
|
||||||
|
|
||||||
void xe_attach_console() {
|
|
||||||
bool has_console = AttachConsole(ATTACH_PARENT_PROCESS) == TRUE;
|
|
||||||
if (!has_console) {
|
|
||||||
// We weren't launched from a console, so just return.
|
|
||||||
// We could alloc our own console, but meh:
|
|
||||||
// has_console = AllocConsole() == TRUE;
|
|
||||||
_has_console = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_has_console = true;
|
|
||||||
|
|
||||||
auto std_handle = (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
auto con_handle = _open_osfhandle(std_handle, _O_TEXT);
|
|
||||||
auto fp = _fdopen(con_handle, "w");
|
|
||||||
*stdout = *fp;
|
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
|
||||||
|
|
||||||
std_handle = (intptr_t)GetStdHandle(STD_ERROR_HANDLE);
|
|
||||||
con_handle = _open_osfhandle(std_handle, _O_TEXT);
|
|
||||||
fp = _fdopen(con_handle, "w");
|
|
||||||
*stderr = *fp;
|
|
||||||
setvbuf(stderr, NULL, _IONBF, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int xe_main_window_thunk(
|
|
||||||
wchar_t* command_line,
|
|
||||||
void* user_main, const wchar_t* name, const char* usage) {
|
|
||||||
xe_attach_console();
|
|
||||||
wchar_t buffer[2048];
|
|
||||||
xestrcpy(buffer, XECOUNT(buffer), name);
|
|
||||||
xestrcat(buffer, XECOUNT(buffer), L" ");
|
|
||||||
xestrcat(buffer, XECOUNT(buffer), command_line);
|
|
||||||
int argc;
|
|
||||||
wchar_t** argv = CommandLineToArgvW(buffer, &argc);
|
|
||||||
if (!argv) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
int result = xe_main_thunk(argc, argv, user_main, usage);
|
|
||||||
LocalFree(argv);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
bool xe_has_console() {
|
|
||||||
return _has_console;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xe_main_thunk(
|
|
||||||
int argc, char** argv,
|
|
||||||
void* user_main, const char* usage) {
|
|
||||||
google::SetUsageMessage(std::string("usage: ") + usage);
|
|
||||||
google::SetVersionString("1.0");
|
|
||||||
google::ParseCommandLineFlags(&argc, &argv, true);
|
|
||||||
int result = ((user_main_t)user_main)(argc, argv);
|
|
||||||
google::ShutDownCommandLineFlags();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // WIN32
|
|
|
@ -1,44 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef XENIA_PLATFORM_H_
|
|
||||||
#define XENIA_PLATFORM_H_
|
|
||||||
|
|
||||||
#include <poly/platform.h>
|
|
||||||
|
|
||||||
bool xe_has_console();
|
|
||||||
#if XE_LIKE_WIN32 && defined(UNICODE) && UNICODE
|
|
||||||
int xe_main_thunk(
|
|
||||||
int argc, wchar_t* argv[],
|
|
||||||
void* user_main, const char* usage);
|
|
||||||
#define XE_MAIN_THUNK(NAME, USAGE) \
|
|
||||||
int wmain(int argc, wchar_t *argv[]) { \
|
|
||||||
return xe_main_thunk(argc, argv, NAME, USAGE); \
|
|
||||||
}
|
|
||||||
int xe_main_window_thunk(
|
|
||||||
wchar_t* command_line,
|
|
||||||
void* user_main, const wchar_t* name, const char* usage);
|
|
||||||
#define XE_MAIN_WINDOW_THUNK(NAME, APP_NAME, USAGE) \
|
|
||||||
int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPTSTR command_line, int) { \
|
|
||||||
return xe_main_window_thunk(command_line, NAME, APP_NAME, USAGE); \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int xe_main_thunk(
|
|
||||||
int argc, char** argv,
|
|
||||||
void* user_main, const char* usage);
|
|
||||||
#define XE_MAIN_THUNK(NAME, USAGE) \
|
|
||||||
int main(int argc, char **argv) { \
|
|
||||||
return xe_main_thunk(argc, argv, (void*)NAME, USAGE); \
|
|
||||||
}
|
|
||||||
#define XE_MAIN_WINDOW_THUNK(NAME, APP_NAME, USAGE) \
|
|
||||||
XE_MAIN_THUNK(NAME, USAGE)
|
|
||||||
#endif // WIN32
|
|
||||||
|
|
||||||
|
|
||||||
#endif // XENIA_PLATFORM_H_
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <xenia/config.h>
|
#include <xenia/config.h>
|
||||||
#include <xenia/platform.h>
|
|
||||||
#include <xenia/string.h>
|
#include <xenia/string.h>
|
||||||
#include <xenia/types.h>
|
#include <xenia/types.h>
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
'logging.h',
|
'logging.h',
|
||||||
'malloc.cc',
|
'malloc.cc',
|
||||||
'malloc.h',
|
'malloc.h',
|
||||||
'platform.cc',
|
|
||||||
'platform.h',
|
|
||||||
'profiling.cc',
|
'profiling.cc',
|
||||||
'profiling.h',
|
'profiling.h',
|
||||||
'string.h',
|
'string.h',
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#ifndef XENIA_STRING_H_
|
#ifndef XENIA_STRING_H_
|
||||||
#define XENIA_STRING_H_
|
#define XENIA_STRING_H_
|
||||||
|
|
||||||
#include <xenia/platform.h>
|
|
||||||
#include <poly/string.h>
|
#include <poly/string.h>
|
||||||
|
|
||||||
// NOTE: these differing implementations should behave pretty much the same.
|
// NOTE: these differing implementations should behave pretty much the same.
|
||||||
|
@ -23,39 +22,25 @@ int strncpy_s(char* dest, size_t destLength, const char* source, size_t count);
|
||||||
#define _snprintf_s(dest, destLength, x, format, ...) snprintf(dest, destLength, format, ##__VA_ARGS__)
|
#define _snprintf_s(dest, destLength, x, format, ...) snprintf(dest, destLength, format, ##__VA_ARGS__)
|
||||||
#endif // !WIN32
|
#endif // !WIN32
|
||||||
|
|
||||||
#define xestrlenw wcslen
|
|
||||||
#define xestrchrw wcschr
|
|
||||||
#define xestrcpyw(dest, destLength, source) (wcscpy_s(dest, destLength, source) == 0)
|
#define xestrcpyw(dest, destLength, source) (wcscpy_s(dest, destLength, source) == 0)
|
||||||
#define xestrcatw(dest, destLength, source) (wcscat_s(dest, destLength, source) == 0)
|
|
||||||
#define xesnprintfw(buffer, bufferCount, format, ...) _snwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, ##__VA_ARGS__)
|
#define xesnprintfw(buffer, bufferCount, format, ...) _snwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define xestrlena strlen
|
#define xestrlena strlen
|
||||||
#define xestrchra strchr
|
|
||||||
#define xestrrchra strrchr
|
|
||||||
#define xestrcpya(dest, destLength, source) (strcpy_s(dest, destLength, source) == 0)
|
#define xestrcpya(dest, destLength, source) (strcpy_s(dest, destLength, source) == 0)
|
||||||
#define xestrncpya(dest, destLength, source, count) (strncpy_s(dest, destLength, source, count) == 0)
|
#define xestrncpya(dest, destLength, source, count) (strncpy_s(dest, destLength, source, count) == 0)
|
||||||
#define xestrcata(dest, destLength, source) (strcat_s(dest, destLength, source) == 0)
|
|
||||||
#define xesnprintfa(buffer, bufferCount, format, ...) _snprintf_s(buffer, bufferCount, bufferCount, format, ##__VA_ARGS__)
|
#define xesnprintfa(buffer, bufferCount, format, ...) _snprintf_s(buffer, bufferCount, bufferCount, format, ##__VA_ARGS__)
|
||||||
#define xevsnprintfa(buffer, bufferCount, format, args) vsnprintf(buffer, bufferCount, format, args)
|
#define xevsnprintfa(buffer, bufferCount, format, args) vsnprintf(buffer, bufferCount, format, args)
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32 && defined(UNICODE) && UNICODE
|
#if XE_PLATFORM_WIN32 && defined(UNICODE) && UNICODE
|
||||||
|
|
||||||
typedef wchar_t xechar_t;
|
typedef wchar_t xechar_t;
|
||||||
#define XE_WCHAR 1
|
|
||||||
|
|
||||||
// xestrchr 2 uses in fs
|
|
||||||
// xestrrchra xmodule/logging
|
|
||||||
// xestrcpy fs + module
|
// xestrcpy fs + module
|
||||||
// xestrncpya one use in xbox.h
|
// xestrncpya one use in xbox.h
|
||||||
// xestrcat 2 uses in platform
|
|
||||||
// xesnprintf many uses - only remove some?
|
// xesnprintf many uses - only remove some?
|
||||||
// xevsnprintf logging, disasm
|
|
||||||
|
|
||||||
#define xestrcpy xestrcpyw
|
#define xestrcpy xestrcpyw
|
||||||
#define xestrcat xestrcatw
|
|
||||||
#define xesnprintf xesnprintfw
|
#define xesnprintf xesnprintfw
|
||||||
#define xestrnarrow(dest, destLength, source) (wcstombs_s(NULL, dest, destLength, source, _TRUNCATE) == 0)
|
|
||||||
#define xestrwiden(dest, destLength, source) (mbstowcs_s(NULL, dest, destLength, source, _TRUNCATE) == 0)
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -63,10 +48,7 @@ typedef char xechar_t;
|
||||||
#define XE_CHAR 1
|
#define XE_CHAR 1
|
||||||
|
|
||||||
#define xestrcpy xestrcpya
|
#define xestrcpy xestrcpya
|
||||||
#define xestrcat xestrcata
|
|
||||||
#define xesnprintf xesnprintfa
|
#define xesnprintf xesnprintfa
|
||||||
#define xestrnarrow(dest, destLength, source) xestrcpy(dest, destLength, source)
|
|
||||||
#define xestrwiden(dest, destLength, source) xestrcpy(dest, destLength, source)
|
|
||||||
|
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include <xenia/platform.h>
|
#include <poly/platform.h>
|
||||||
|
|
||||||
|
|
||||||
#define XE_EMPTY_MACRO do { } while(0)
|
#define XE_EMPTY_MACRO do { } while(0)
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <alloy/frontend/ppc/ppc_context.h>
|
#include <alloy/frontend/ppc/ppc_context.h>
|
||||||
#include <alloy/frontend/ppc/ppc_frontend.h>
|
#include <alloy/frontend/ppc/ppc_frontend.h>
|
||||||
#include <alloy/runtime/raw_module.h>
|
#include <alloy/runtime/raw_module.h>
|
||||||
|
#include <poly/main.h>
|
||||||
#include <poly/poly.h>
|
#include <poly/poly.h>
|
||||||
#include <xenia/cpu/xenon_memory.h>
|
#include <xenia/cpu/xenon_memory.h>
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@ class ThreadState : public alloy::runtime::ThreadState {
|
||||||
|
|
||||||
// TODO(benvanik): simple memory? move more into core?
|
// TODO(benvanik): simple memory? move more into core?
|
||||||
|
|
||||||
int main(int argc, xechar_t** argv) {
|
int main(std::vector<std::wstring>& args) {
|
||||||
xe::Profiler::Initialize();
|
xe::Profiler::Initialize();
|
||||||
xe::Profiler::ThreadEnter("main");
|
xe::Profiler::ThreadEnter("main");
|
||||||
|
|
||||||
|
@ -122,7 +123,4 @@ int main(int argc, xechar_t** argv) {
|
||||||
} // namespace sandbox
|
} // namespace sandbox
|
||||||
} // namespace alloy
|
} // namespace alloy
|
||||||
|
|
||||||
// TODO(benvanik): move main thunk into poly
|
DEFINE_ENTRY_POINT(L"alloy-sandbox", L"?", alloy::sandbox::main);
|
||||||
// ehhh
|
|
||||||
#include <xenia/platform.cc>
|
|
||||||
XE_MAIN_THUNK(alloy::sandbox::main, "alloy-sandbox");
|
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
'target_name': 'alloy-sandbox',
|
'target_name': 'alloy-sandbox',
|
||||||
'type': 'executable',
|
'type': 'executable',
|
||||||
|
|
||||||
|
'msvs_settings': {
|
||||||
|
'VCLinkerTool': {
|
||||||
|
'SubSystem': '1'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'alloy',
|
'alloy',
|
||||||
'xenia',
|
'xenia',
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
#include <poly/main.h>
|
||||||
#include <poly/poly.h>
|
#include <poly/poly.h>
|
||||||
#include <xdb/postmortem_debug_target.h>
|
#include <xdb/postmortem_debug_target.h>
|
||||||
#include <xdb/xdb.h>
|
#include <xdb/xdb.h>
|
||||||
|
@ -21,7 +22,7 @@ namespace xc {
|
||||||
|
|
||||||
using xdb::PostmortemDebugTarget;
|
using xdb::PostmortemDebugTarget;
|
||||||
|
|
||||||
int main(int argc, xechar_t** argv) {
|
int main(std::vector<std::wstring>& args) {
|
||||||
// Create platform abstraction layer.
|
// Create platform abstraction layer.
|
||||||
xe_pal_options_t pal_options;
|
xe_pal_options_t pal_options;
|
||||||
xe_zero_struct(&pal_options, sizeof(pal_options));
|
xe_zero_struct(&pal_options, sizeof(pal_options));
|
||||||
|
@ -46,6 +47,4 @@ int main(int argc, xechar_t** argv) {
|
||||||
|
|
||||||
} // namespace xc
|
} // namespace xc
|
||||||
|
|
||||||
// TODO(benvanik): move main thunk into poly
|
DEFINE_ENTRY_POINT(L"xenia-compare", L"xenia-compare", xc::main);
|
||||||
// ehhh
|
|
||||||
XE_MAIN_WINDOW_THUNK(xc::main, L"xenia-compare", "xenia-compare");
|
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
'msvs_settings': {
|
'msvs_settings': {
|
||||||
'VCLinkerTool': {
|
'VCLinkerTool': {
|
||||||
'SubSystem': '2'
|
'SubSystem': '1'
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
#include <poly/main.h>
|
||||||
#include <poly/poly.h>
|
#include <poly/poly.h>
|
||||||
#include <third_party/wxWidgets/include/wx/wx.h>
|
#include <third_party/wxWidgets/include/wx/wx.h>
|
||||||
#include <xdb/ui/xdb_app.h>
|
#include <xdb/ui/xdb_app.h>
|
||||||
|
@ -22,7 +23,7 @@ DEFINE_string(content_file, "",
|
||||||
|
|
||||||
namespace xdb {
|
namespace xdb {
|
||||||
|
|
||||||
int main(int argc, xechar_t** argv) {
|
int main(std::vector<std::wstring>& args) {
|
||||||
// Create platform abstraction layer.
|
// Create platform abstraction layer.
|
||||||
xe_pal_options_t pal_options;
|
xe_pal_options_t pal_options;
|
||||||
xe_zero_struct(&pal_options, sizeof(pal_options));
|
xe_zero_struct(&pal_options, sizeof(pal_options));
|
||||||
|
@ -67,6 +68,4 @@ int main(int argc, xechar_t** argv) {
|
||||||
|
|
||||||
} // namespace xdb
|
} // namespace xdb
|
||||||
|
|
||||||
// TODO(benvanik): move main thunk into poly
|
DEFINE_ENTRY_POINT(L"xenia-debug", L"xenia-debug", xdb::main);
|
||||||
// ehhh
|
|
||||||
XE_MAIN_WINDOW_THUNK(xdb::main, L"xenia-debug", "xenia-debug");
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
'msvs_settings': {
|
'msvs_settings': {
|
||||||
'VCLinkerTool': {
|
'VCLinkerTool': {
|
||||||
'SubSystem': '2'
|
'SubSystem': '2'
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
|
|
|
@ -10,16 +10,13 @@
|
||||||
#include <xenia/xenia.h>
|
#include <xenia/xenia.h>
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
#include <poly/main.h>
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
|
|
||||||
|
DEFINE_string(target, "", "Specifies the target .xex or .iso to execute.");
|
||||||
|
|
||||||
DEFINE_string(target, "",
|
int xenia_run(std::vector<std::wstring>& args) {
|
||||||
"Specifies the target .xex or .iso to execute.");
|
|
||||||
|
|
||||||
|
|
||||||
int xenia_run(int argc, xechar_t** argv) {
|
|
||||||
int result_code = 1;
|
int result_code = 1;
|
||||||
|
|
||||||
Profiler::Initialize();
|
Profiler::Initialize();
|
||||||
|
@ -28,33 +25,28 @@ int xenia_run(int argc, xechar_t** argv) {
|
||||||
Emulator* emulator = NULL;
|
Emulator* emulator = NULL;
|
||||||
|
|
||||||
// Grab path from the flag or unnamed argument.
|
// Grab path from the flag or unnamed argument.
|
||||||
if (!FLAGS_target.size() && argc < 2) {
|
if (!FLAGS_target.size() && args.size() < 2) {
|
||||||
google::ShowUsageWithFlags("xenia-run");
|
google::ShowUsageWithFlags("xenia-run");
|
||||||
XEFATAL("Pass a file to launch.");
|
XEFATAL("Pass a file to launch.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
const xechar_t* path = NULL;
|
std::wstring path;
|
||||||
if (FLAGS_target.size()) {
|
if (FLAGS_target.size()) {
|
||||||
// Passed as a named argument.
|
// Passed as a named argument.
|
||||||
// TODO(benvanik): find something better than gflags that supports unicode.
|
// TODO(benvanik): find something better than gflags that supports unicode.
|
||||||
xechar_t buffer[poly::max_path];
|
path = poly::to_wstring(FLAGS_target);
|
||||||
XEIGNORE(xestrwiden(buffer, sizeof(buffer), FLAGS_target.c_str()));
|
|
||||||
path = buffer;
|
|
||||||
} else {
|
} else {
|
||||||
// Passed as an unnamed argument.
|
// Passed as an unnamed argument.
|
||||||
path = argv[1];
|
path = args[1];
|
||||||
}
|
}
|
||||||
|
// Normalize the path and make absolute.
|
||||||
|
std::wstring abs_path = poly::to_absolute_path(path);
|
||||||
|
|
||||||
// Create platform abstraction layer.
|
// Create platform abstraction layer.
|
||||||
xe_pal_options_t pal_options;
|
xe_pal_options_t pal_options;
|
||||||
xe_zero_struct(&pal_options, sizeof(pal_options));
|
xe_zero_struct(&pal_options, sizeof(pal_options));
|
||||||
XEEXPECTZERO(xe_pal_init(pal_options));
|
XEEXPECTZERO(xe_pal_init(pal_options));
|
||||||
|
|
||||||
// Normalize the path and make absolute.
|
|
||||||
// TODO(benvanik): move this someplace common.
|
|
||||||
xechar_t abs_path[poly::max_path];
|
|
||||||
xe_path_get_absolute(path, abs_path, XECOUNT(abs_path));
|
|
||||||
|
|
||||||
// Create the emulator.
|
// Create the emulator.
|
||||||
emulator = new Emulator(L"");
|
emulator = new Emulator(L"");
|
||||||
XEEXPECTNOTNULL(emulator);
|
XEEXPECTNOTNULL(emulator);
|
||||||
|
@ -93,4 +85,5 @@ XECLEANUP:
|
||||||
Profiler::Shutdown();
|
Profiler::Shutdown();
|
||||||
return result_code;
|
return result_code;
|
||||||
}
|
}
|
||||||
XE_MAIN_WINDOW_THUNK(xenia_run, L"xenia-run", "xenia-run some.xex");
|
|
||||||
|
DEFINE_ENTRY_POINT(L"xenia-run", L"xenia-run some.xex", xenia_run);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
'msvs_settings': {
|
'msvs_settings': {
|
||||||
'VCLinkerTool': {
|
'VCLinkerTool': {
|
||||||
'SubSystem': '2'
|
'SubSystem': '2'
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#endif // !WIN32
|
#endif // !WIN32
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
|
||||||
|
#include <poly/main.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
|
@ -273,7 +275,7 @@ int xenia_test(int argc, xechar_t **argv) {
|
||||||
if (argc >= 2) {
|
if (argc >= 2) {
|
||||||
test_name = argv[1];
|
test_name = argv[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
string test_name_str;
|
string test_name_str;
|
||||||
if (test_name) {
|
if (test_name) {
|
||||||
#if XE_WCHAR
|
#if XE_WCHAR
|
||||||
|
@ -290,4 +292,5 @@ int xenia_test(int argc, xechar_t **argv) {
|
||||||
|
|
||||||
return result_code;
|
return result_code;
|
||||||
}
|
}
|
||||||
XE_MAIN_THUNK(xenia_test, "xenia-test some.xex");
|
|
||||||
|
DEFINE_ENTRY_POINT(L"xenia-test", L"xenia-test some.xex", xenia_test);
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
'target_name': 'xenia-test',
|
'target_name': 'xenia-test',
|
||||||
'type': 'executable',
|
'type': 'executable',
|
||||||
|
|
||||||
|
'msvs_settings': {
|
||||||
|
'VCLinkerTool': {
|
||||||
|
'SubSystem': '1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'xenia',
|
'xenia',
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue