Merge branch 'master' into d3d12

This commit is contained in:
Triang3l 2018-11-22 20:59:55 +03:00
commit da280347c4
130 changed files with 481 additions and 248 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
# IF YOU HAVE A QUESTION THAT ISN'T A BUG REPORT, GO TO http://reddit.com/r/xenia # IF YOU HAVE A QUESTION THAT ISN'T A BUG REPORT, GO TO https://reddit.com/r/xenia
# #
# DO NOT CREATE ISSUES ABOUT SPECIFIC GAMES IN THIS REPOSITORY! # DO NOT CREATE ISSUES ABOUT SPECIFIC GAMES IN THIS REPOSITORY!
# a game specific issue would be e.g. "Game X crashes after you hit a character a certain way" # a game specific issue would be e.g. "Game X crashes after you hit a character a certain way"

View File

@ -9,16 +9,16 @@ os:
# - osx # - osx
sudo: required sudo: required
dist: trusty dist: xenial
addons: addons:
apt: apt:
sources: sources:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0 - llvm-toolchain-xenial-6.0
packages: packages:
- clang-4.0 - clang-6.0
- llvm-4.0-dev - llvm-6.0-dev
- g++-5 - g++-8
- python3 - python3
- libc++-dev - libc++-dev
- libc++abi-dev - libc++abi-dev
@ -32,10 +32,10 @@ addons:
matrix: matrix:
include: include:
- env: C_COMPILER=clang-4.0 CXX_COMPILER=clang++-4.0 LINT=true - env: C_COMPILER=clang-6.0 CXX_COMPILER=clang++-6.0 LINT=true
sudo: false sudo: false
- env: C_COMPILER=clang-4.0 CXX_COMPILER=clang++-4.0 BUILD=true CONFIG=Debug - env: C_COMPILER=clang-6.0 CXX_COMPILER=clang++-6.0 BUILD=true CONFIG=Debug
- env: C_COMPILER=clang-4.0 CXX_COMPILER=clang++-4.0 BUILD=true CONFIG=Release - env: C_COMPILER=clang-6.0 CXX_COMPILER=clang++-6.0 BUILD=true CONFIG=Release
git: git:
# We handle submodules ourselves in xenia-build setup. # We handle submodules ourselves in xenia-build setup.
@ -72,3 +72,4 @@ script:
#- ./xenia-build test --config=debug --no-build -- --enable_haswell_instructions=false #- ./xenia-build test --config=debug --no-build -- --enable_haswell_instructions=false
# All tests (with haswell support). # All tests (with haswell support).
#- ./xenia-build test --config=debug --no-build -- --enable_haswell_instructions=true #- ./xenia-build test --config=debug --no-build -- --enable_haswell_instructions=true

View File

@ -2,11 +2,11 @@ Xenia - Xbox 360 Emulator Research Project
========================================== ==========================================
Xenia is an experimental emulator for the Xbox 360. For more information see the Xenia is an experimental emulator for the Xbox 360. For more information see the
[main xenia website](http://xenia.jp/). [main xenia website](https://xenia.jp/).
Come chat with us about **emulator-related topics** on [Discord](https://discord.gg/Q9mxZf9). Come chat with us about **emulator-related topics** on [Discord](https://discord.gg/Q9mxZf9).
For developer chat join `#dev` but stay on topic. Lurking is fine. For developer chat join `#dev` but stay on topic. Lurking is fine.
Please check the [frequently asked questions](http://xenia.jp/faq/) page before Please check the [frequently asked questions](https://xenia.jp/faq/) page before
asking questions. We've got jobs/lives/etc, so don't expect instant answers. asking questions. We've got jobs/lives/etc, so don't expect instant answers.
Discussing illegal activities will get you banned. No warnings. Discussing illegal activities will get you banned. No warnings.
@ -35,7 +35,7 @@ legally purchased devices and games and information made public on the internet
Windows 8.1+ with Python 3.4 and [Visual Studio 2017](https://www.visualstudio.com/downloads/) and the Windows SDKs installed: Windows 8.1+ with Python 3.4 and [Visual Studio 2017](https://www.visualstudio.com/downloads/) and the Windows SDKs installed:
> git clone https://github.com/benvanik/xenia.git > git clone https://github.com/xenia-project/xenia.git
> cd xenia > cd xenia
> xb setup > xb setup
@ -76,16 +76,16 @@ For general rules and guidelines please see [CONTRIBUTING.md](.github/CONTRIBUTI
Fixes and optimizations are always welcome (please!), but in addition to Fixes and optimizations are always welcome (please!), but in addition to
that there are some major work areas still untouched: that there are some major work areas still untouched:
* Help work through missing functionality/bugs in game [compat](https://github.com/benvanik/xenia/issues?labels=compat) * Help work through missing functionality/bugs in game [compat](https://github.com/xenia-project/xenia/issues?labels=compat)
* Add input drivers for [PS4 controllers](https://github.com/benvanik/xenia/issues/60) (or anything else) * Add input drivers for [PS4 controllers](https://github.com/xenia-project/xenia/issues/60) (or anything else)
* Skilled with Linux? A strong contributor is needed to [help with porting](https://github.com/benvanik/xenia/labels/cross%20platform) * Skilled with Linux? A strong contributor is needed to [help with porting](https://github.com/xenia-project/xenia/labels/cross%20platform)
See more projects [good for contributors](https://github.com/benvanik/xenia/labels/good%20first%20issue). It's a good idea to ask on Discord/the bugs before beginning work See more projects [good for contributors](https://github.com/xenia-project/xenia/labels/good%20first%20issue). It's a good idea to ask on Discord/the bugs before beginning work
on something. on something.
## FAQ ## FAQ
For more see the main [frequently asked questions](http://xenia.jp/faq/) page. For more see the main [frequently asked questions](https://xenia.jp/faq/) page.
### Can I get an exe? ### Can I get an exe?

BIN
assets/icon/1024.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
assets/icon/128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

BIN
assets/icon/16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

BIN
assets/icon/256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

BIN
assets/icon/32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

BIN
assets/icon/48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

BIN
assets/icon/512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

BIN
assets/icon/64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

View File

@ -1,26 +0,0 @@
/// -------------- *** -------------- ///
/// ///
/// Rendering Instructions ///
/// ///
/// -------------- *** -------------- ///
For those not well-versed in Blender, this document explains
how to render the icon in any desired resolution and color.
To Change Resolution:
1. Open Icon.blend in Blender.
2. In the right tool pane, look for "Resolution" under the
"Dimensions" settings. It should be defaulted to 512x512.
This is where you'll change the icon output dimensions.
3. After you've set the value to what you want, hit F12 or
select 'Render' > 'Render Image' from the top bar. This
will render the icon.
4. To save, hit F3 or select 'Image' > 'Save As Image' on
the left toward the middle of the screen.
To Change Colors:
1. Open Icon.blend in Blender.
2. The icon's colors will appear in the bottom window as
labeled nodes. Change them by clicking on each node.
3. Render and save as described above.

BIN
assets/icon/extra/114.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
assets/icon/extra/120.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
assets/icon/extra/144.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
assets/icon/extra/150.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
assets/icon/extra/152.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
assets/icon/extra/180.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
assets/icon/extra/192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
assets/icon/extra/310.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
assets/icon/extra/36.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
assets/icon/extra/57.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
assets/icon/extra/60.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
assets/icon/extra/70.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
assets/icon/extra/72.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
assets/icon/extra/76.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
assets/icon/extra/96.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 KiB

View File

@ -12,7 +12,7 @@ video drivers for your card.
* Visual Studio 2017 * Visual Studio 2017
* Windows Universal CRT SDK * Windows Universal CRT SDK
* [Python 3.4+](https://www.python.org/downloads/) * [Python 3.4+](https://www.python.org/downloads/)
* You will also need the [Windows 8.1 SDK](http://msdn.microsoft.com/en-us/windows/desktop/bg162891) * You will also need the [Windows 8.1 SDK](https://msdn.microsoft.com/en-us/windows/desktop/bg162891)
* (for VS2017 just click the Windows 8.1 SDK option in the Individual Components section in the Visual Studio Installer) * (for VS2017 just click the Windows 8.1 SDK option in the Individual Components section in the Visual Studio Installer)
Ensure Python is in your PATH. Ensure Python is in your PATH.
@ -41,7 +41,7 @@ Linux support is extremely experimental and presently incomplete.
The build script uses LLVM/Clang 3.8. GCC should also work, but is not easily The build script uses LLVM/Clang 3.8. GCC should also work, but is not easily
swappable right now. swappable right now.
[CodeLite](http://codelite.org) is the IDE of choice and `xb premake` will spit [CodeLite](https://codelite.org) is the IDE of choice and `xb premake` will spit
out files for that. Make also works via `xb build`. out files for that. Make also works via `xb build`.
To get the latest Clang on an ubuntu system: To get the latest Clang on an ubuntu system:

View File

@ -123,16 +123,16 @@ The CPU is largely similar to the PPC part in the PS3, so Cell documents
often line up for the core instructions. The 360 adds some additional AltiVec often line up for the core instructions. The 360 adds some additional AltiVec
instructions, though, which are only documented in a few places (like the gcc source code, etc). instructions, though, which are only documented in a few places (like the gcc source code, etc).
* [Free60 Info](http://www.free60.org/Xenon_\(CPU\)) * [Free60 Info](https://free60project.github.io/wiki/Xenon_(CPU))
* [Power ISA docs](https://www.power.org/wp-content/uploads/2012/07/PowerISA_V2.06B_V2_PUBLIC.pdf) (aka 'PowerISA') * [Power ISA docs](https://web.archive.org/web/20140603115759/https://www.power.org/wp-content/uploads/2012/07/PowerISA_V2.06B_V2_PUBLIC.pdf) (aka 'PowerISA')
* [PowerPC Programming Environments Manual](https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/F7E732FF811F783187256FDD004D3797/$file/pem_64bit_v3.0.2005jul15.pdf) (aka 'pem_64') * [PowerPC Programming Environments Manual](https://web.archive.org/web/20141028181028/https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/F7E732FF811F783187256FDD004D3797/$file/pem_64bit_v3.0.2005jul15.pdf) (aka 'pem_64')
* [PowerPC Vector PEM](https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/C40E4C6133B31EE8872570B500791108/$file/vector_simd_pem_v_2.07c_26Oct2006_cell.pdf) * [PowerPC Vector PEM](https://web.archive.org/web/20130502201029/https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/C40E4C6133B31EE8872570B500791108/$file/vector_simd_pem_v_2.07c_26Oct2006_cell.pdf)
* [AltiVec PEM](http://cache.freescale.com/files/32bit/doc/ref_manual/ALTIVECPEM.pdf) * [AltiVec PEM](https://web.archive.org/web/20151110180336/https://cache.freescale.com/files/32bit/doc/ref_manual/ALTIVECPEM.pdf)
* [VMX128 Opcodes](http://biallas.net/doc/vmx128/vmx128.txt) * [VMX128 Opcodes](http://biallas.net/doc/vmx128/vmx128.txt)
* [AltiVec Decoding](https://github.com/kakaroto/ps3ida/blob/master/plugins/PPCAltivec/src/main.cpp) * [AltiVec Decoding](https://github.com/kakaroto/ps3ida/blob/master/plugins/PPCAltivec/src/main.cpp)
### x64 ### x64
* [Intel Manuals](http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html) * [Intel Manuals](https://software.intel.com/en-us/articles/intel-sdm)
* [Combined Intel Manuals](http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf) * [Combined Intel Manuals](https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf)
* [Apple AltiVec/SSE Migration Guide](https://developer.apple.com/legacy/library/documentation/Performance/Conceptual/Accelerate_sse_migration/Accelerate_sse_migration.pdf) * [Apple AltiVec/SSE Migration Guide](https://developer.apple.com/legacy/library/documentation/Performance/Conceptual/Accelerate_sse_migration/Accelerate_sse_migration.pdf)

View File

@ -121,6 +121,6 @@ PM4 commands documented at [src/xenia/gpu/xenos.h](../src/xenia/gpu/xenos.h#L521
### Shaders ### Shaders
* [LLVM R600 Tables](http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/R600Instructions.td) * [LLVM R600 Tables](https://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/R600Instructions.td)
** The opcode formats don't match, but the name->psuedo code is correct. ** The opcode formats don't match, but the name->psuedo code is correct.
* [xemit](https://github.com/gligli/libxemit/blob/master/xemitops.c) * [xemit](https://github.com/gligli/libxemit/blob/master/xemitops.c)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -58,13 +58,13 @@ think about tabs and wrapping and such.
To use the `xb format` auto-formatter, you need to have a `clang-format` on your To use the `xb format` auto-formatter, you need to have a `clang-format` on your
PATH. If you're on Windows you can do this by installing an LLVM binary package PATH. If you're on Windows you can do this by installing an LLVM binary package
from [the LLVM downloads page](http://llvm.org/releases/download.html). If you from [the LLVM downloads page](https://llvm.org/releases/download.html). If you
install it to the default location the `xb format` command will find it install it to the default location the `xb format` command will find it
automatically even if you don't choose to put all of LLVM onto your PATH. automatically even if you don't choose to put all of LLVM onto your PATH.
#### Visual Studio #### Visual Studio
Grab the official [experimental Visual Studio plugin](http://llvm.org/builds/). Grab the official [experimental Visual Studio plugin](https://llvm.org/builds/).
To switch to the Google style go Tools -> Options -> LLVM/Clang -> ClangFormat To switch to the Google style go Tools -> Options -> LLVM/Clang -> ClangFormat
and set Style to Google. Then use ctrl-r/ctrl-f to trigger the formatting. and set Style to Google. Then use ctrl-r/ctrl-f to trigger the formatting.
Unfortunately it only does the cursor by default, so you'll have to select the Unfortunately it only does the cursor by default, so you'll have to select the
@ -74,7 +74,7 @@ If you have a better option, let me know!
#### Xcode #### Xcode
Install [Alcatraz](http://alcatraz.io/) to get the [ClangFormat](https://github.com/travisjeffery/ClangFormat-Xcode) Install [Alcatraz](https://github.com/alcatraz/Alcatraz) to get the [ClangFormat](https://github.com/travisjeffery/ClangFormat-Xcode)
package. Set it to use the Google style and format on save. Never think about package. Set it to use the Google style and format on save. Never think about
tabs or linefeeds or whatever again. tabs or linefeeds or whatever again.

View File

@ -260,7 +260,7 @@ bool EmulatorWindow::Initialize() {
std::bind(&EmulatorWindow::ShowHelpWebsite, this))); std::bind(&EmulatorWindow::ShowHelpWebsite, this)));
help_menu->AddChild(MenuItem::Create( help_menu->AddChild(MenuItem::Create(
MenuItem::Type::kString, L"&About...", MenuItem::Type::kString, L"&About...",
[this]() { LaunchBrowser("http://xenia.jp/about/"); })); [this]() { LaunchBrowser("https://xenia.jp/about/"); }));
} }
main_menu->AddChild(std::move(help_menu)); main_menu->AddChild(std::move(help_menu));
@ -384,7 +384,7 @@ void EmulatorWindow::ToggleFullscreen() {
} }
} }
void EmulatorWindow::ShowHelpWebsite() { LaunchBrowser("http://xenia.jp"); } void EmulatorWindow::ShowHelpWebsite() { LaunchBrowser("https://xenia.jp"); }
void EmulatorWindow::UpdateTitle() { void EmulatorWindow::UpdateTitle() {
std::wstring title(base_title_); std::wstring title(base_title_);

View File

@ -47,6 +47,8 @@ DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]");
DEFINE_string(target, "", "Specifies the target .xex or .iso to execute."); DEFINE_string(target, "", "Specifies the target .xex or .iso to execute.");
DEFINE_bool(fullscreen, false, "Toggles fullscreen"); DEFINE_bool(fullscreen, false, "Toggles fullscreen");
DEFINE_string(content_root, "", "Root path for content (save/etc) storage.");
DEFINE_bool(mount_scratch, false, "Enable scratch mount"); DEFINE_bool(mount_scratch, false, "Enable scratch mount");
DEFINE_bool(mount_cache, false, "Enable cache mount"); DEFINE_bool(mount_cache, false, "Enable cache mount");
@ -132,11 +134,18 @@ std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(
drivers.emplace_back(std::move(winkey_driver)); drivers.emplace_back(std::move(winkey_driver));
} }
#endif // XE_PLATFORM_WIN32 #endif // XE_PLATFORM_WIN32
}
for (auto it = drivers.begin(); it != drivers.end();) {
if (XFAILED((*it)->Setup())) {
it = drivers.erase(it);
} else {
++it;
}
}
if (drivers.empty()) { if (drivers.empty()) {
// Fallback to nop if none created. // Fallback to nop if none created.
drivers.emplace_back(xe::hid::nop::Create(window)); drivers.emplace_back(xe::hid::nop::Create(window));
} }
}
return drivers; return drivers;
} }
@ -144,8 +153,35 @@ int xenia_main(const std::vector<std::wstring>& args) {
Profiler::Initialize(); Profiler::Initialize();
Profiler::ThreadEnter("main"); Profiler::ThreadEnter("main");
// Figure out where content should go.
std::wstring content_root;
if (!FLAGS_content_root.empty()) {
content_root = xe::to_wstring(FLAGS_content_root);
} else {
auto base_path = xe::filesystem::GetExecutableFolder();
base_path = xe::to_absolute_path(base_path);
auto portable_path = xe::join_paths(base_path, L"portable.txt");
if (xe::filesystem::PathExists(portable_path)) {
content_root = xe::join_paths(base_path, L"content");
} else {
content_root = xe::filesystem::GetUserFolder();
#if defined(XE_PLATFORM_WIN32)
content_root = xe::join_paths(content_root, L"Xenia");
#elif defined(XE_PLATFORM_LINUX)
content_root = xe::join_paths(content_root, L".xenia");
#else
#warning Unhandled platform for content root.
content_root = xe::join_paths(content_root, L"Xenia");
#endif
content_root = xe::join_paths(content_root, L"content");
}
content_root = xe::to_absolute_path(content_root);
}
// Create the emulator but don't initialize so we can setup the window. // Create the emulator but don't initialize so we can setup the window.
auto emulator = std::make_unique<Emulator>(L""); auto emulator = std::make_unique<Emulator>(L"", content_root);
// Main emulator display window. // Main emulator display window.
auto emulator_window = EmulatorWindow::Create(emulator.get()); auto emulator_window = EmulatorWindow::Create(emulator.get());

View File

@ -25,7 +25,7 @@
// Helpful resources: // Helpful resources:
// https://github.com/koolkdev/libertyv/blob/master/libav_wrapper/xma2dec.c // https://github.com/koolkdev/libertyv/blob/master/libav_wrapper/xma2dec.c
// http://hcs64.com/mboard/forum.php?showthread=14818 // https://hcs64.com/mboard/forum.php?showthread=14818
// https://github.com/hrydgard/minidx9/blob/master/Include/xma2defs.h // https://github.com/hrydgard/minidx9/blob/master/Include/xma2defs.h
// Forward declarations // Forward declarations
@ -41,7 +41,7 @@ namespace apu {
// We load and swap the whole thing to splat here so that we can // We load and swap the whole thing to splat here so that we can
// use bitfields. // use bitfields.
// This could be important: // This could be important:
// http://www.fmod.org/questions/question/forum-15859 // https://www.fmod.org/questions/question/forum-15859
// Appears to be dumped in order (for the most part) // Appears to be dumped in order (for the most part)
struct XMA_CONTEXT_DATA { struct XMA_CONTEXT_DATA {

View File

@ -17,7 +17,9 @@
namespace xe { namespace xe {
// These functions are modeled off of the Apple OSAtomic routines // These functions are modeled off of the Apple OSAtomic routines
// http://developer.apple.com/library/mac/#documentation/DriversKernelHardware/Reference/libkern_ref/OSAtomic_h/ // https://developer.apple.com/documentation/kernel/osatomic_h (?)
// Original link (dead):
// https://developer.apple.com/library/mac/#documentation/DriversKernelHardware/Reference/libkern_ref/OSAtomic_h/
#if XE_PLATFORM_MAC #if XE_PLATFORM_MAC

View File

@ -44,8 +44,8 @@ LONG CALLBACK ExceptionHandlerCallback(PEXCEPTION_POINTERS ex_info) {
std::memcpy(thread_context.xmm_registers, &ex_info->ContextRecord->Xmm0, std::memcpy(thread_context.xmm_registers, &ex_info->ContextRecord->Xmm0,
sizeof(thread_context.xmm_registers)); sizeof(thread_context.xmm_registers));
// http://msdn.microsoft.com/en-us/library/ms679331(v=vs.85).aspx // https://msdn.microsoft.com/en-us/library/ms679331(v=vs.85).aspx
// http://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx // https://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx
Exception ex; Exception ex;
switch (ex_info->ExceptionRecord->ExceptionCode) { switch (ex_info->ExceptionRecord->ExceptionCode) {
case STATUS_ILLEGAL_INSTRUCTION: case STATUS_ILLEGAL_INSTRUCTION:

View File

@ -20,6 +20,15 @@
namespace xe { namespace xe {
namespace filesystem { namespace filesystem {
// Get executable path.
std::wstring GetExecutablePath();
// Get executable folder.
std::wstring GetExecutableFolder();
// Get user folder.
std::wstring GetUserFolder();
// Canonicalizes a path, removing ..'s. // Canonicalizes a path, removing ..'s.
std::string CanonicalizePath(const std::string& original_path); std::string CanonicalizePath(const std::string& original_path);

View File

@ -7,6 +7,7 @@
****************************************************************************** ******************************************************************************
*/ */
#include "xenia/base/assert.h"
#include "xenia/base/filesystem.h" #include "xenia/base/filesystem.h"
#include "xenia/base/logging.h" #include "xenia/base/logging.h"
#include "xenia/base/string.h" #include "xenia/base/string.h"
@ -21,6 +22,21 @@
namespace xe { namespace xe {
namespace filesystem { namespace filesystem {
std::wstring GetExecutablePath() {
assert_always(); // IMPLEMENT ME.
return std::wstring();
}
std::wstring GetExecutableFolder() {
assert_always(); // IMPLEMENT ME.
return std::wstring();
}
std::wstring GetUserFolder() {
assert_always(); // IMPLEMENT ME.
return std::wstring();
}
bool PathExists(const std::wstring& path) { bool PathExists(const std::wstring& path) {
struct stat st; struct stat st;
return stat(xe::to_string(path).c_str(), &st) == 0; return stat(xe::to_string(path).c_str(), &st) == 0;

View File

@ -12,11 +12,33 @@
#include <string> #include <string>
#include <shlobj.h>
#include "xenia/base/platform_win.h" #include "xenia/base/platform_win.h"
namespace xe { namespace xe {
namespace filesystem { namespace filesystem {
std::wstring GetExecutablePath() {
wchar_t* path;
auto error = _get_wpgmptr(&path);
return !error ? std::wstring(path) : std::wstring();
}
std::wstring GetExecutableFolder() {
auto path = GetExecutablePath();
return xe::find_base_path(path);
}
std::wstring GetUserFolder() {
wchar_t path[MAX_PATH];
if (!SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_MYDOCUMENTS, nullptr,
SHGFP_TYPE_CURRENT, path))) {
return std::wstring();
}
return std::wstring(path);
}
bool PathExists(const std::wstring& path) { bool PathExists(const std::wstring& path) {
DWORD attrib = GetFileAttributes(path.c_str()); DWORD attrib = GetFileAttributes(path.c_str());
return attrib != INVALID_FILE_ATTRIBUTES; return attrib != INVALID_FILE_ATTRIBUTES;

View File

@ -15,9 +15,13 @@
namespace xe { namespace xe {
// TODO(benvanik): fancy AVX versions. // TODO(benvanik): fancy AVX versions.
// http://gnuradio.org/redmine/projects/gnuradio/repository/revisions/cb32b70b79f430456208a2cd521d028e0ece5d5b/entry/volk/kernels/volk/volk_16u_byteswap.h // https://github.com/gnuradio/volk/blob/master/kernels/volk/volk_16u_byteswap.h
// http://gnuradio.org/redmine/projects/gnuradio/repository/revisions/f2bc76cc65ffba51a141950f98e75364e49df874/entry/volk/kernels/volk/volk_32u_byteswap.h // https://github.com/gnuradio/volk/blob/master/kernels/volk/volk_32u_byteswap.h
// http://gnuradio.org/redmine/projects/gnuradio/repository/revisions/2c4c371885c31222362f70a1cd714415d1398021/entry/volk/kernels/volk/volk_64u_byteswap.h // https://github.com/gnuradio/volk/blob/master/kernels/volk/volk_64u_byteswap.h
// Original links:
// https://gnuradio.org/redmine/projects/gnuradio/repository/revisions/cb32b70b79f430456208a2cd521d028e0ece5d5b/entry/volk/kernels/volk/volk_16u_byteswap.h
// https://gnuradio.org/redmine/projects/gnuradio/repository/revisions/f2bc76cc65ffba51a141950f98e75364e49df874/entry/volk/kernels/volk/volk_32u_byteswap.h
// https://gnuradio.org/redmine/projects/gnuradio/repository/revisions/2c4c371885c31222362f70a1cd714415d1398021/entry/volk/kernels/volk/volk_64u_byteswap.h
void copy_128_aligned(void* dest, const void* src, size_t count) { void copy_128_aligned(void* dest, const void* src, size_t count) {
std::memcpy(dest, src, count * 16); std::memcpy(dest, src, count * 16);

View File

@ -19,7 +19,9 @@
// NOTE: ordering matters here as sometimes multiple flags are defined on // NOTE: ordering matters here as sometimes multiple flags are defined on
// certain platforms. // certain platforms.
// //
// Great resource on predefined macros: http://predef.sourceforge.net/preos.html // Great resource on predefined macros:
// https://sourceforge.net/p/predef/wiki/OperatingSystems/
// Original link: https://predef.sourceforge.net/preos.html
#if defined(__APPLE__) #if defined(__APPLE__)
#include <TargetConditionals.h> #include <TargetConditionals.h>

View File

@ -114,7 +114,7 @@ void Profiler::ThreadEnter(const char* name) {
void Profiler::ThreadExit() { MicroProfileOnThreadExit(); } void Profiler::ThreadExit() { MicroProfileOnThreadExit(); }
bool Profiler::OnKeyDown(int key_code) { bool Profiler::OnKeyDown(int key_code) {
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx // https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
switch (key_code) { switch (key_code) {
case VK_OEM_3: // ` case VK_OEM_3: // `
MicroProfileTogglePause(); MicroProfileTogglePause();

View File

@ -29,7 +29,7 @@ uint32_t current_thread_system_id() {
return static_cast<uint32_t>(GetCurrentThreadId()); return static_cast<uint32_t>(GetCurrentThreadId());
} }
// http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx // https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
#pragma pack(push, 8) #pragma pack(push, 8)
struct THREADNAME_INFO { struct THREADNAME_INFO {
DWORD dwType; // Must be 0x1000. DWORD dwType; // Must be 0x1000.

View File

@ -187,7 +187,7 @@ uint64_t ReadCapstoneReg(X64Context* context, x86_reg reg) {
#define X86_EFLAGS_SF 0x00000080 // Sign Flag #define X86_EFLAGS_SF 0x00000080 // Sign Flag
#define X86_EFLAGS_OF 0x00000800 // Overflow Flag #define X86_EFLAGS_OF 0x00000800 // Overflow Flag
bool TestCapstoneEflags(uint32_t eflags, uint32_t insn) { bool TestCapstoneEflags(uint32_t eflags, uint32_t insn) {
// http://www.felixcloutier.com/x86/Jcc.html // https://www.felixcloutier.com/x86/Jcc.html
switch (insn) { switch (insn) {
case X86_INS_JAE: case X86_INS_JAE:
// CF=0 && ZF=0 // CF=0 && ZF=0

View File

@ -37,7 +37,7 @@ namespace cpu {
namespace backend { namespace backend {
namespace x64 { namespace x64 {
// http://msdn.microsoft.com/en-us/library/ssa62fwe.aspx // https://msdn.microsoft.com/en-us/library/ssa62fwe.aspx
typedef enum _UNWIND_OP_CODES { typedef enum _UNWIND_OP_CODES {
UWOP_PUSH_NONVOL = 0, /* info == register number */ UWOP_PUSH_NONVOL = 0, /* info == register number */
UWOP_ALLOC_LARGE, /* no info, alloc size in next 2 slots */ UWOP_ALLOC_LARGE, /* no info, alloc size in next 2 slots */
@ -242,7 +242,7 @@ void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
UNWIND_CODE* unwind_code = nullptr; UNWIND_CODE* unwind_code = nullptr;
if (!stack_size) { if (!stack_size) {
// http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx // https://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
unwind_info->Version = 1; unwind_info->Version = 1;
unwind_info->Flags = 0; unwind_info->Flags = 0;
unwind_info->SizeOfProlog = 0; unwind_info->SizeOfProlog = 0;
@ -252,7 +252,7 @@ void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
} else if (stack_size <= 128) { } else if (stack_size <= 128) {
uint8_t prolog_size = 4; uint8_t prolog_size = 4;
// http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx // https://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
unwind_info->Version = 1; unwind_info->Version = 1;
unwind_info->Flags = 0; unwind_info->Flags = 0;
unwind_info->SizeOfProlog = prolog_size; unwind_info->SizeOfProlog = prolog_size;
@ -260,7 +260,7 @@ void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
unwind_info->FrameRegister = 0; unwind_info->FrameRegister = 0;
unwind_info->FrameOffset = 0; unwind_info->FrameOffset = 0;
// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx // https://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++]; unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++];
unwind_code->CodeOffset = unwind_code->CodeOffset =
14; // end of instruction + 1 == offset of next instruction 14; // end of instruction + 1 == offset of next instruction
@ -270,7 +270,7 @@ void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
// TODO(benvanik): take as parameters? // TODO(benvanik): take as parameters?
uint8_t prolog_size = 7; uint8_t prolog_size = 7;
// http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx // https://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
unwind_info->Version = 1; unwind_info->Version = 1;
unwind_info->Flags = 0; unwind_info->Flags = 0;
unwind_info->SizeOfProlog = prolog_size; unwind_info->SizeOfProlog = prolog_size;
@ -278,7 +278,7 @@ void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
unwind_info->FrameRegister = 0; unwind_info->FrameRegister = 0;
unwind_info->FrameOffset = 0; unwind_info->FrameOffset = 0;
// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx // https://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++]; unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++];
unwind_code->CodeOffset = unwind_code->CodeOffset =
7; // end of instruction + 1 == offset of next instruction 7; // end of instruction + 1 == offset of next instruction

View File

@ -82,7 +82,7 @@ X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator)
if (!cpu_.has(Xbyak::util::Cpu::tAVX)) { if (!cpu_.has(Xbyak::util::Cpu::tAVX)) {
xe::FatalError( xe::FatalError(
"Your CPU is too old to support Xenia. See the FAQ for system " "Your CPU is too old to support Xenia. See the FAQ for system "
"requirements at http://xenia.jp"); "requirements at https://xenia.jp");
return; return;
} }
} }
@ -160,7 +160,7 @@ bool X64Emitter::Emit(HIRBuilder* builder, size_t* out_stack_size) {
// Function prolog. // Function prolog.
// Must be 16b aligned. // Must be 16b aligned.
// Windows is very strict about the form of this and the epilog: // Windows is very strict about the form of this and the epilog:
// http://msdn.microsoft.com/en-us/library/tawsa7cb.aspx // https://msdn.microsoft.com/en-us/library/tawsa7cb.aspx
// IMPORTANT: any changes to the prolog must be kept in sync with // IMPORTANT: any changes to the prolog must be kept in sync with
// X64CodeCache, which dynamically generates exception information. // X64CodeCache, which dynamically generates exception information.
// Adding or changing anything here must be matched! // Adding or changing anything here must be matched!
@ -738,7 +738,7 @@ Xbyak::Address X64Emitter::GetXmmConstPtr(XmmConst id) {
} }
void X64Emitter::LoadConstantXmm(Xbyak::Xmm dest, const vec128_t& v) { void X64Emitter::LoadConstantXmm(Xbyak::Xmm dest, const vec128_t& v) {
// http://www.agner.org/optimize/optimizing_assembly.pdf // https://www.agner.org/optimize/optimizing_assembly.pdf
// 13.4 Generating constants // 13.4 Generating constants
if (!v.low && !v.high) { if (!v.low && !v.high) {
// 0000... // 0000...

View File

@ -3367,7 +3367,8 @@ EMITTER_ASSOCIATIVE_COMPARE_XX(ULE, setbe, setae);
EMITTER_ASSOCIATIVE_COMPARE_XX(UGT, seta, setb); EMITTER_ASSOCIATIVE_COMPARE_XX(UGT, seta, setb);
EMITTER_ASSOCIATIVE_COMPARE_XX(UGE, setae, setbe); EMITTER_ASSOCIATIVE_COMPARE_XX(UGE, setae, setbe);
// http://x86.renejeschke.de/html/file_module_x86_id_288.html // https://web.archive.org/web/20171129015931/https://x86.renejeschke.de/html/file_module_x86_id_288.html
// Original link: https://x86.renejeschke.de/html/file_module_x86_id_288.html
#define EMITTER_ASSOCIATIVE_COMPARE_FLT_XX(op, instr) \ #define EMITTER_ASSOCIATIVE_COMPARE_FLT_XX(op, instr) \
struct COMPARE_##op##_F32 \ struct COMPARE_##op##_F32 \
: Sequence<COMPARE_##op##_F32, \ : Sequence<COMPARE_##op##_F32, \
@ -3793,7 +3794,7 @@ struct VECTOR_ADD
// If result is smaller than either of the inputs, we've // If result is smaller than either of the inputs, we've
// overflowed (only need to check one input) // overflowed (only need to check one input)
// if (src1 > res) then overflowed // if (src1 > res) then overflowed
// http://locklessinc.com/articles/sat_arithmetic/ // https://locklessinc.com/articles/sat_arithmetic/
e.vpxor(e.xmm2, src1, e.GetXmmConstPtr(XMMSignMaskI32)); e.vpxor(e.xmm2, src1, e.GetXmmConstPtr(XMMSignMaskI32));
e.vpxor(e.xmm0, e.xmm1, e.GetXmmConstPtr(XMMSignMaskI32)); e.vpxor(e.xmm0, e.xmm1, e.GetXmmConstPtr(XMMSignMaskI32));
e.vpcmpgtd(e.xmm0, e.xmm2, e.xmm0); e.vpcmpgtd(e.xmm0, e.xmm2, e.xmm0);
@ -3804,7 +3805,7 @@ struct VECTOR_ADD
// Overflow results if two inputs are the same sign and the // Overflow results if two inputs are the same sign and the
// result isn't the same sign. if ((s32b)(~(src1 ^ src2) & // result isn't the same sign. if ((s32b)(~(src1 ^ src2) &
// (src1 ^ res)) < 0) then overflowed // (src1 ^ res)) < 0) then overflowed
// http://locklessinc.com/articles/sat_arithmetic/ // https://locklessinc.com/articles/sat_arithmetic/
e.vpxor(e.xmm2, src1, src2); e.vpxor(e.xmm2, src1, src2);
e.vpxor(e.xmm3, src1, e.xmm1); e.vpxor(e.xmm3, src1, e.xmm1);
e.vpandn(e.xmm2, e.xmm2, e.xmm3); e.vpandn(e.xmm2, e.xmm2, e.xmm3);
@ -3950,7 +3951,7 @@ struct VECTOR_SUB
// If result is greater than either of the inputs, we've // If result is greater than either of the inputs, we've
// underflowed (only need to check one input) // underflowed (only need to check one input)
// if (res > src1) then underflowed // if (res > src1) then underflowed
// http://locklessinc.com/articles/sat_arithmetic/ // https://locklessinc.com/articles/sat_arithmetic/
e.vpxor(e.xmm2, src1, e.GetXmmConstPtr(XMMSignMaskI32)); e.vpxor(e.xmm2, src1, e.GetXmmConstPtr(XMMSignMaskI32));
e.vpxor(e.xmm0, e.xmm1, e.GetXmmConstPtr(XMMSignMaskI32)); e.vpxor(e.xmm0, e.xmm1, e.GetXmmConstPtr(XMMSignMaskI32));
e.vpcmpgtd(e.xmm0, e.xmm0, e.xmm2); e.vpcmpgtd(e.xmm0, e.xmm0, e.xmm2);
@ -3962,7 +3963,7 @@ struct VECTOR_SUB
// opposite. If signs are opposite and result sign isn't the // opposite. If signs are opposite and result sign isn't the
// same as src1's sign, we've overflowed. if ((s32b)((src1 ^ // same as src1's sign, we've overflowed. if ((s32b)((src1 ^
// src2) & (src1 ^ res)) < 0) then overflowed // src2) & (src1 ^ res)) < 0) then overflowed
// http://locklessinc.com/articles/sat_arithmetic/ // https://locklessinc.com/articles/sat_arithmetic/
e.vpxor(e.xmm2, src1, src2); e.vpxor(e.xmm2, src1, src2);
e.vpxor(e.xmm3, src1, e.xmm1); e.vpxor(e.xmm3, src1, e.xmm1);
e.vpand(e.xmm2, e.xmm2, e.xmm3); e.vpand(e.xmm2, e.xmm2, e.xmm3);
@ -5062,7 +5063,7 @@ EMITTER_OPCODE_TABLE(OPCODE_RECIP, RECIP_F32, RECIP_F64, RECIP_V128);
// OPCODE_POW2 // OPCODE_POW2
// ============================================================================ // ============================================================================
// TODO(benvanik): use approx here: // TODO(benvanik): use approx here:
// http://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html // https://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html
struct POW2_F32 : Sequence<POW2_F32, I<OPCODE_POW2, F32Op, F32Op>> { struct POW2_F32 : Sequence<POW2_F32, I<OPCODE_POW2, F32Op, F32Op>> {
static __m128 EmulatePow2(void*, __m128 src) { static __m128 EmulatePow2(void*, __m128 src) {
float src_value; float src_value;
@ -5112,7 +5113,7 @@ EMITTER_OPCODE_TABLE(OPCODE_POW2, POW2_F32, POW2_F64, POW2_V128);
// OPCODE_LOG2 // OPCODE_LOG2
// ============================================================================ // ============================================================================
// TODO(benvanik): use approx here: // TODO(benvanik): use approx here:
// http://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html // https://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html
// TODO(benvanik): this emulated fn destroys all xmm registers! don't do it! // TODO(benvanik): this emulated fn destroys all xmm registers! don't do it!
struct LOG2_F32 : Sequence<LOG2_F32, I<OPCODE_LOG2, F32Op, F32Op>> { struct LOG2_F32 : Sequence<LOG2_F32, I<OPCODE_LOG2, F32Op, F32Op>> {
static __m128 EmulateLog2(void*, __m128 src) { static __m128 EmulateLog2(void*, __m128 src) {
@ -5166,7 +5167,7 @@ struct DOT_PRODUCT_3_V128
: Sequence<DOT_PRODUCT_3_V128, : Sequence<DOT_PRODUCT_3_V128,
I<OPCODE_DOT_PRODUCT_3, F32Op, V128Op, V128Op>> { I<OPCODE_DOT_PRODUCT_3, F32Op, V128Op, V128Op>> {
static void Emit(X64Emitter& e, const EmitArgType& i) { static void Emit(X64Emitter& e, const EmitArgType& i) {
// http://msdn.microsoft.com/en-us/library/bb514054(v=vs.90).aspx // https://msdn.microsoft.com/en-us/library/bb514054(v=vs.90).aspx
EmitCommutativeBinaryXmmOp(e, i, EmitCommutativeBinaryXmmOp(e, i,
[](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) {
// TODO(benvanik): apparently this is very slow // TODO(benvanik): apparently this is very slow
@ -5184,7 +5185,7 @@ struct DOT_PRODUCT_4_V128
: Sequence<DOT_PRODUCT_4_V128, : Sequence<DOT_PRODUCT_4_V128,
I<OPCODE_DOT_PRODUCT_4, F32Op, V128Op, V128Op>> { I<OPCODE_DOT_PRODUCT_4, F32Op, V128Op, V128Op>> {
static void Emit(X64Emitter& e, const EmitArgType& i) { static void Emit(X64Emitter& e, const EmitArgType& i) {
// http://msdn.microsoft.com/en-us/library/bb514054(v=vs.90).aspx // https://msdn.microsoft.com/en-us/library/bb514054(v=vs.90).aspx
EmitCommutativeBinaryXmmOp(e, i, EmitCommutativeBinaryXmmOp(e, i,
[](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) {
// TODO(benvanik): apparently this is very slow // TODO(benvanik): apparently this is very slow
@ -7003,7 +7004,7 @@ struct PACK : Sequence<PACK, I<OPCODE_PACK, V128Op, V128Op, V128Op>> {
} }
static void EmitFLOAT16_2(X64Emitter& e, const EmitArgType& i) { static void EmitFLOAT16_2(X64Emitter& e, const EmitArgType& i) {
assert_true(i.src2.value->IsConstantZero()); assert_true(i.src2.value->IsConstantZero());
// http://blogs.msdn.com/b/chuckw/archive/2012/09/11/directxmath-f16c-and-fma.aspx // https://blogs.msdn.com/b/chuckw/archive/2012/09/11/directxmath-f16c-and-fma.aspx
// dest = [(src1.x | src1.y), 0, 0, 0] // dest = [(src1.x | src1.y), 0, 0, 0]
Xmm src; Xmm src;
@ -7398,10 +7399,10 @@ struct UNPACK : Sequence<UNPACK, I<OPCODE_UNPACK, V128Op, V128Op>> {
// 1 bit sign, 5 bit exponent, 10 bit mantissa // 1 bit sign, 5 bit exponent, 10 bit mantissa
// D3D10 half float format // D3D10 half float format
// TODO(benvanik): // TODO(benvanik):
// http://blogs.msdn.com/b/chuckw/archive/2012/09/11/directxmath-f16c-and-fma.aspx // https://blogs.msdn.com/b/chuckw/archive/2012/09/11/directxmath-f16c-and-fma.aspx
// Use _mm_cvtph_ps -- requires very modern processors (SSE5+) // Use _mm_cvtph_ps -- requires very modern processors (SSE5+)
// Unpacking half floats: // Unpacking half floats:
// http://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/ // https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/
// Packing half floats: https://gist.github.com/rygorous/2156668 // Packing half floats: https://gist.github.com/rygorous/2156668
// Load source, move from tight pack of X16Y16.... to X16...Y16... // Load source, move from tight pack of X16Y16.... to X16...Y16...
// Also zero out the high end. // Also zero out the high end.

View File

@ -489,7 +489,7 @@ int CompareValueUse(const Value::Use* a, const Value::Use* b) {
} // namespace } // namespace
void RegisterAllocationPass::SortUsageList(Value* value) { void RegisterAllocationPass::SortUsageList(Value* value) {
// Modified in-place linked list sort from: // Modified in-place linked list sort from:
// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c // https://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c
if (!value->use_head) { if (!value->use_head) {
return; return;
} }

View File

@ -505,7 +505,7 @@ bool TryDecodeMov(const uint8_t* p, DecodedMov* mov) {
} }
if (p[i] == 0x0F && p[i + 1] == 0x38 && p[i + 2] == 0xF1) { if (p[i] == 0x0F && p[i + 1] == 0x38 && p[i + 2] == 0xF1) {
// MOVBE m32, r32 (store) // MOVBE m32, r32 (store)
// http://www.tptp.cc/mirrors/siyobik.info/instruction/MOVBE.html // https://web.archive.org/web/20170629091435/https://www.tptp.cc/mirrors/siyobik.info/instruction/MOVBE.html
// 44 0f 38 f1 a4 02 00 movbe DWORD PTR [rdx+rax*1+0x0],r12d // 44 0f 38 f1 a4 02 00 movbe DWORD PTR [rdx+rax*1+0x0],r12d
// 42 0f 38 f1 8c 22 00 movbe DWORD PTR [rdx+r12*1+0x0],ecx // 42 0f 38 f1 8c 22 00 movbe DWORD PTR [rdx+r12*1+0x0],ecx
// 0f 38 f1 8c 02 00 00 movbe DWORD PTR [rdx + rax * 1 + 0x0], ecx // 0f 38 f1 8c 02 00 00 movbe DWORD PTR [rdx + rax * 1 + 0x0], ecx
@ -514,7 +514,7 @@ bool TryDecodeMov(const uint8_t* p, DecodedMov* mov) {
i += 3; i += 3;
} else if (p[i] == 0x0F && p[i + 1] == 0x38 && p[i + 2] == 0xF0) { } else if (p[i] == 0x0F && p[i + 1] == 0x38 && p[i + 2] == 0xF0) {
// MOVBE r32, m32 (load) // MOVBE r32, m32 (load)
// http://www.tptp.cc/mirrors/siyobik.info/instruction/MOVBE.html // https://web.archive.org/web/20170629091435/https://www.tptp.cc/mirrors/siyobik.info/instruction/MOVBE.html
// 44 0f 38 f0 a4 02 00 movbe r12d,DWORD PTR [rdx+rax*1+0x0] // 44 0f 38 f0 a4 02 00 movbe r12d,DWORD PTR [rdx+rax*1+0x0]
// 42 0f 38 f0 8c 22 00 movbe ecx,DWORD PTR [rdx+r12*1+0x0] // 42 0f 38 f0 8c 22 00 movbe ecx,DWORD PTR [rdx+r12*1+0x0]
// 46 0f 38 f0 a4 22 00 movbe r12d,DWORD PTR [rdx+r12*1+0x0] // 46 0f 38 f0 a4 22 00 movbe r12d,DWORD PTR [rdx+r12*1+0x0]
@ -525,7 +525,7 @@ bool TryDecodeMov(const uint8_t* p, DecodedMov* mov) {
i += 3; i += 3;
} else if (p[i] == 0x89) { } else if (p[i] == 0x89) {
// MOV m32, r32 (store) // MOV m32, r32 (store)
// http://www.tptp.cc/mirrors/siyobik.info/instruction/MOV.html // https://web.archive.org/web/20170629072136/https://www.tptp.cc/mirrors/siyobik.info/instruction/MOV.html
// 44 89 24 02 mov DWORD PTR[rdx + rax * 1], r12d // 44 89 24 02 mov DWORD PTR[rdx + rax * 1], r12d
// 42 89 0c 22 mov DWORD PTR[rdx + r12 * 1], ecx // 42 89 0c 22 mov DWORD PTR[rdx + r12 * 1], ecx
// 89 0c 02 mov DWORD PTR[rdx + rax * 1], ecx // 89 0c 02 mov DWORD PTR[rdx + rax * 1], ecx
@ -534,7 +534,7 @@ bool TryDecodeMov(const uint8_t* p, DecodedMov* mov) {
++i; ++i;
} else if (p[i] == 0x8B) { } else if (p[i] == 0x8B) {
// MOV r32, m32 (load) // MOV r32, m32 (load)
// http://www.tptp.cc/mirrors/siyobik.info/instruction/MOV.html // https://web.archive.org/web/20170629072136/https://www.tptp.cc/mirrors/siyobik.info/instruction/MOV.html
// 44 8b 24 02 mov r12d, DWORD PTR[rdx + rax * 1] // 44 8b 24 02 mov r12d, DWORD PTR[rdx + rax * 1]
// 42 8b 0c 22 mov ecx, DWORD PTR[rdx + r12 * 1] // 42 8b 0c 22 mov ecx, DWORD PTR[rdx + r12 * 1]
// 46 8b 24 22 mov r12d, DWORD PTR[rdx + r12 * 1] // 46 8b 24 22 mov r12d, DWORD PTR[rdx + r12 * 1]
@ -544,7 +544,7 @@ bool TryDecodeMov(const uint8_t* p, DecodedMov* mov) {
++i; ++i;
} else if (p[i] == 0xC7) { } else if (p[i] == 0xC7) {
// MOV m32, simm32 // MOV m32, simm32
// http://www.asmpedia.org/index.php?title=MOV // https://web.archive.org/web/20161017042413/https://www.asmpedia.org/index.php?title=MOV
// C7 04 02 02 00 00 00 mov dword ptr [rdx+rax],2 // C7 04 02 02 00 00 00 mov dword ptr [rdx+rax],2
mov->is_load = false; mov->is_load = false;
mov->byte_swap = false; mov->byte_swap = false;

View File

@ -31,7 +31,7 @@ Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb);
// Most of this file comes from: // Most of this file comes from:
// http://biallas.net/doc/vmx128/vmx128.txt // http://biallas.net/doc/vmx128/vmx128.txt
// https://github.com/kakaroto/ps3ida/blob/master/plugins/PPCAltivec/src/main.cpp // https://github.com/kakaroto/ps3ida/blob/master/plugins/PPCAltivec/src/main.cpp
// http://sannybuilder.com/forums/viewtopic.php?id=190 // https://sannybuilder.com/forums/viewtopic.php?id=190
#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26) #define OP(x) ((((uint32_t)(x)) & 0x3f) << 26)
#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0)) #define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0))
@ -2068,7 +2068,7 @@ int InstrEmit_vpkd3d128(PPCHIRBuilder& f, const InstrData& i) {
assert_unhandled_case(type); assert_unhandled_case(type);
return 1; return 1;
} }
// http://hlssmod.net/he_code/public/pixelwriter.h // https://hlssmod.net/he_code/public/pixelwriter.h
// control = prev:0123 | new:4567 // control = prev:0123 | new:4567
uint32_t control = kIdentityPermuteMask; // original uint32_t control = kIdentityPermuteMask; // original
switch (pack) { switch (pack) {
@ -2141,7 +2141,8 @@ int InstrEmit_vpkd3d128(PPCHIRBuilder& f, const InstrData& i) {
int InstrEmit_vupkd3d128(PPCHIRBuilder& f, const InstrData& i) { int InstrEmit_vupkd3d128(PPCHIRBuilder& f, const InstrData& i) {
// Can't find many docs on this. Best reference is // Can't find many docs on this. Best reference is
// http://worldcraft.googlecode.com/svn/trunk/src/qylib/math/xmmatrix.inl, // https://code.google.com/archive/p/worldcraft/source/default/source?page=4
// (qylib/math/xmmatrix.inl)
// which shows how it's used in some cases. Since it's all intrinsics, // which shows how it's used in some cases. Since it's all intrinsics,
// finding it in code is pretty easy. // finding it in code is pretty easy.
const uint32_t vd = i.VX128_3.VD128l | (i.VX128_3.VD128h << 5); const uint32_t vd = i.VX128_3.VD128l | (i.VX128_3.VD128h << 5);

View File

@ -26,7 +26,7 @@ using xe::cpu::hir::RoundMode;
using xe::cpu::hir::Value; using xe::cpu::hir::Value;
// Good source of information: // Good source of information:
// http://mamedev.org/source/src/emu/cpu/powerpc/ppc_ops.c // https://github.com/mamedev/historic-mame/blob/master/src/emu/cpu/powerpc/ppc_ops.c
// The correctness of that code is not reflected here yet -_- // The correctness of that code is not reflected here yet -_-
// Enable rounding numbers to single precision as required. // Enable rounding numbers to single precision as required.

View File

@ -48,8 +48,9 @@ DEFINE_double(time_scalar, 1.0,
namespace xe { namespace xe {
Emulator::Emulator(const std::wstring& command_line) Emulator::Emulator(const std::wstring& command_line,
: command_line_(command_line) {} const std::wstring& content_root)
: command_line_(command_line), content_root_(content_root) {}
Emulator::~Emulator() { Emulator::~Emulator() {
// Note that we delete things in the reverse order they were initialized. // Note that we delete things in the reverse order they were initialized.

View File

@ -47,12 +47,16 @@ namespace xe {
// This is responsible for initializing and managing all the various subsystems. // This is responsible for initializing and managing all the various subsystems.
class Emulator { class Emulator {
public: public:
explicit Emulator(const std::wstring& command_line); explicit Emulator(const std::wstring& command_line,
const std::wstring& content_root);
~Emulator(); ~Emulator();
// Full command line used when launching the process. // Full command line used when launching the process.
const std::wstring& command_line() const { return command_line_; } const std::wstring& command_line() const { return command_line_; }
// Folder content is stored in.
const std::wstring& content_root() const { return content_root_; }
// Title of the game in the default language. // Title of the game in the default language.
const std::wstring& game_title() const { return game_title_; } const std::wstring& game_title() const { return game_title_; }
@ -154,6 +158,8 @@ class Emulator {
const std::string& module_path); const std::string& module_path);
std::wstring command_line_; std::wstring command_line_;
std::wstring content_root_;
std::wstring game_title_; std::wstring game_title_;
ui::Window* display_window_; ui::Window* display_window_;

View File

@ -347,8 +347,8 @@ void CommandProcessor::MakeCoherent() {
// some way to check for dest coherency (what all the COHER_DEST_BASE_* // some way to check for dest coherency (what all the COHER_DEST_BASE_*
// registers are for). // registers are for).
// Best docs I've found on this are here: // Best docs I've found on this are here:
// http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/10/R6xx_R7xx_3D.pdf // https://web.archive.org/web/20160711162346/https://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/10/R6xx_R7xx_3D.pdf
// http://cgit.freedesktop.org/xorg/driver/xf86-video-radeonhd/tree/src/r6xx_accel.c?id=3f8b6eccd9dba116cc4801e7f80ce21a879c67d2#n454 // https://cgit.freedesktop.org/xorg/driver/xf86-video-radeonhd/tree/src/r6xx_accel.c?id=3f8b6eccd9dba116cc4801e7f80ce21a879c67d2#n454
RegisterFile* regs = register_file_; RegisterFile* regs = register_file_;
auto status_host = regs->values[XE_GPU_REG_COHER_STATUS_HOST].u32; auto status_host = regs->values[XE_GPU_REG_COHER_STATUS_HOST].u32;
@ -1392,7 +1392,7 @@ bool CommandProcessor::ExecutePacketType3_VIZ_QUERY(RingBuffer* reader,
uint32_t packet, uint32_t packet,
uint32_t count) { uint32_t count) {
// begin/end initiator for viz query extent processing // begin/end initiator for viz query extent processing
// http://www.google.com/patents/US20050195186 // https://www.google.com/patents/US20050195186
assert_true(count == 1); assert_true(count == 1);
uint32_t dword0 = reader->ReadAndSwap<uint32_t>(); uint32_t dword0 = reader->ReadAndSwap<uint32_t>();

View File

@ -131,8 +131,8 @@ struct VertexData {
}; };
)"); )");
// http://www.nvidia.com/object/cube_map_ogl_tutorial.html // https://www.nvidia.com/object/cube_map_ogl_tutorial.html
// http://developer.amd.com/wordpress/media/2012/10/R600_Instruction_Set_Architecture.pdf // https://developer.amd.com/wordpress/media/2012/10/R600_Instruction_Set_Architecture.pdf
// src0 = Rn.zzxy, src1 = Rn.yxzz // src0 = Rn.zzxy, src1 = Rn.yxzz
// dst.W = FaceId; // dst.W = FaceId;
// dst.Z = 2.0f * MajorAxis; // dst.Z = 2.0f * MajorAxis;

View File

@ -26,8 +26,8 @@ namespace gpu {
// Nvidia Optimus/AMD PowerXpress support. // Nvidia Optimus/AMD PowerXpress support.
// These exports force the process to trigger the discrete GPU in multi-GPU // These exports force the process to trigger the discrete GPU in multi-GPU
// systems. // systems.
// http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/OptimusRenderingPolicies.pdf // https://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/OptimusRenderingPolicies.pdf
// http://stackoverflow.com/questions/17458803/amd-equivalent-to-nvoptimusenablement // https://stackoverflow.com/questions/17458803/amd-equivalent-to-nvoptimusenablement
#if XE_PLATFORM_WIN32 #if XE_PLATFORM_WIN32
extern "C" { extern "C" {
__declspec(dllexport) uint32_t NvOptimusEnablement = 0x00000001; __declspec(dllexport) uint32_t NvOptimusEnablement = 0x00000001;
@ -74,7 +74,7 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
"Ensure you have the latest drivers for your GPU and " "Ensure you have the latest drivers for your GPU and "
"that it supports Vulkan.\n" "that it supports Vulkan.\n"
"\n" "\n"
"See http://xenia.jp/faq/ for more information and a list of " "See https://xenia.jp/faq/ for more information and a list of "
"supported GPUs."); "supported GPUs.");
return X_STATUS_UNSUCCESSFUL; return X_STATUS_UNSUCCESSFUL;
} }

View File

@ -40,7 +40,7 @@ using namespace ucode;
// https://github.com/freedreno/freedreno/blob/master/util/disasm-a2xx.c // https://github.com/freedreno/freedreno/blob/master/util/disasm-a2xx.c
// //
// Lots of naming comes from the disassembly spit out by the XNA GS compiler // Lots of naming comes from the disassembly spit out by the XNA GS compiler
// and dumps of d3dcompiler and games: http://pastebin.com/i4kAv7bB // and dumps of d3dcompiler and games: https://pastebin.com/i4kAv7bB
ShaderTranslator::ShaderTranslator() = default; ShaderTranslator::ShaderTranslator() = default;

View File

@ -48,7 +48,7 @@ void CopySwapBlock(Endian endian, void* output, const void* input,
void ConvertTexelCTX1ToR8G8(Endian endian, void* output, const void* input, void ConvertTexelCTX1ToR8G8(Endian endian, void* output, const void* input,
size_t length) { size_t length) {
// http://fileadmin.cs.lth.se/cs/Personal/Michael_Doggett/talks/unc-xenos-doggett.pdf // https://fileadmin.cs.lth.se/cs/Personal/Michael_Doggett/talks/unc-xenos-doggett.pdf
union { union {
uint8_t data[8]; uint8_t data[8];
struct { struct {

View File

@ -26,7 +26,7 @@ using namespace xe::gpu::xenos;
bool TextureInfo::Prepare(const xe_gpu_texture_fetch_t& fetch, bool TextureInfo::Prepare(const xe_gpu_texture_fetch_t& fetch,
TextureInfo* out_info) { TextureInfo* out_info) {
// http://msdn.microsoft.com/en-us/library/windows/desktop/cc308051(v=vs.85).aspx // https://msdn.microsoft.com/en-us/library/windows/desktop/cc308051(v=vs.85).aspx
// a2xx_sq_surfaceformat // a2xx_sq_surfaceformat
std::memset(out_info, 0, sizeof(TextureInfo)); std::memset(out_info, 0, sizeof(TextureInfo));

View File

@ -103,7 +103,7 @@ int TraceDump::Main(const std::vector<std::wstring>& args) {
bool TraceDump::Setup() { bool TraceDump::Setup() {
// Create the emulator but don't initialize so we can setup the window. // Create the emulator but don't initialize so we can setup the window.
emulator_ = std::make_unique<Emulator>(L""); emulator_ = std::make_unique<Emulator>(L"", L"");
X_STATUS result = emulator_->Setup( X_STATUS result = emulator_->Setup(
nullptr, nullptr, [this]() { return CreateGraphicsSystem(); }, nullptr); nullptr, nullptr, [this]() { return CreateGraphicsSystem(); }, nullptr);
if (XFAILED(result)) { if (XFAILED(result)) {

View File

@ -122,7 +122,7 @@ bool TraceViewer::Setup() {
window_->Resize(1920, 1200); window_->Resize(1920, 1200);
// Create the emulator but don't initialize so we can setup the window. // Create the emulator but don't initialize so we can setup the window.
emulator_ = std::make_unique<Emulator>(L""); emulator_ = std::make_unique<Emulator>(L"", L"");
X_STATUS result = X_STATUS result =
emulator_->Setup(window_.get(), nullptr, emulator_->Setup(window_.get(), nullptr,
[this]() { return CreateGraphicsSystem(); }, nullptr); [this]() { return CreateGraphicsSystem(); }, nullptr);

View File

@ -17,7 +17,7 @@
#include "xenia/gpu/xenos.h" #include "xenia/gpu/xenos.h"
// Closest AMD doc: // Closest AMD doc:
// http://developer.amd.com/wordpress/media/2012/10/R600_Instruction_Set_Architecture.pdf // https://developer.amd.com/wordpress/media/2012/10/R600_Instruction_Set_Architecture.pdf
// Microcode format differs, but most fields/enums are the same. // Microcode format differs, but most fields/enums are the same.
// This code comes from the freedreno project: // This code comes from the freedreno project:
@ -701,7 +701,7 @@ static_assert_size(TextureFetchInstruction, 12);
// R600 docs that have a near 1:1 with the instructions available in the xenos // R600 docs that have a near 1:1 with the instructions available in the xenos
// GPU. Some of the behavior has been experimentally verified. Some has been // GPU. Some of the behavior has been experimentally verified. Some has been
// guessed. // guessed.
// Docs: http://www.x.org/docs/AMD/old/r600isa.pdf // Docs: https://www.x.org/docs/AMD/old/r600isa.pdf
// //
// Conventions: // Conventions:
// - All temporary registers are vec4s. // - All temporary registers are vec4s.

View File

@ -660,7 +660,7 @@ bool PipelineCache::SetDynamicState(VkCommandBuffer command_buffer,
} }
// Whether each of the viewport settings are enabled. // Whether each of the viewport settings are enabled.
// http://www.x.org/docs/AMD/old/evergreen_3D_registers_v2.pdf // https://www.x.org/docs/AMD/old/evergreen_3D_registers_v2.pdf
bool vport_xscale_enable = (regs.pa_cl_vte_cntl & (1 << 0)) > 0; bool vport_xscale_enable = (regs.pa_cl_vte_cntl & (1 << 0)) > 0;
bool vport_xoffset_enable = (regs.pa_cl_vte_cntl & (1 << 1)) > 0; bool vport_xoffset_enable = (regs.pa_cl_vte_cntl & (1 << 1)) > 0;
bool vport_yscale_enable = (regs.pa_cl_vte_cntl & (1 << 2)) > 0; bool vport_yscale_enable = (regs.pa_cl_vte_cntl & (1 << 2)) > 0;
@ -865,7 +865,7 @@ bool PipelineCache::SetDynamicState(VkCommandBuffer command_buffer,
push_constants.window_scale[3] = (-1280.f / window_height_scalar) + 0.5f; push_constants.window_scale[3] = (-1280.f / window_height_scalar) + 0.5f;
} }
// http://www.x.org/docs/AMD/old/evergreen_3D_registers_v2.pdf // https://www.x.org/docs/AMD/old/evergreen_3D_registers_v2.pdf
// VTX_XY_FMT = true: the incoming XY have already been multiplied by 1/W0. // VTX_XY_FMT = true: the incoming XY have already been multiplied by 1/W0.
// = false: multiply the X, Y coordinates by 1/W0. // = false: multiply the X, Y coordinates by 1/W0.
// VTX_Z_FMT = true: the incoming Z has already been multiplied by 1/W0. // VTX_Z_FMT = true: the incoming Z has already been multiplied by 1/W0.

View File

@ -786,7 +786,7 @@ bool RenderCache::ParseConfiguration(RenderConfiguration* config) {
config->mode_control = regs.rb_modecontrol.edram_mode; config->mode_control = regs.rb_modecontrol.edram_mode;
// RB_SURFACE_INFO // RB_SURFACE_INFO
// http://fossies.org/dox/MesaLib-10.3.5/fd2__gmem_8c_source.html // https://fossies.org/dox/MesaLib-10.3.5/fd2__gmem_8c_source.html
config->surface_pitch_px = regs.rb_surface_info.surface_pitch; config->surface_pitch_px = regs.rb_surface_info.surface_pitch;
config->surface_msaa = regs.rb_surface_info.msaa_samples; config->surface_msaa = regs.rb_surface_info.msaa_samples;

View File

@ -99,7 +99,7 @@ const TextureConfig texture_configs[64] = {
/* k_16_MPEG_INTERLACED */ ___(UNDEFINED), /* k_16_MPEG_INTERLACED */ ___(UNDEFINED),
/* k_16_16_MPEG_INTERLACED */ ___(UNDEFINED), /* k_16_16_MPEG_INTERLACED */ ___(UNDEFINED),
// http://fileadmin.cs.lth.se/cs/Personal/Michael_Doggett/talks/unc-xenos-doggett.pdf // https://fileadmin.cs.lth.se/cs/Personal/Michael_Doggett/talks/unc-xenos-doggett.pdf
/* k_DXN */ ___(BC5_UNORM_BLOCK), // ? /* k_DXN */ ___(BC5_UNORM_BLOCK), // ?
/* k_8_8_8_8_AS_16_16_16_16 */ ___(R8G8B8A8_UNORM), /* k_8_8_8_8_AS_16_16_16_16 */ ___(R8G8B8A8_UNORM),
@ -116,7 +116,7 @@ const TextureConfig texture_configs[64] = {
/* k_DXT3A */ _c_(BC2_UNORM_BLOCK, ___R), /* k_DXT3A */ _c_(BC2_UNORM_BLOCK, ___R),
/* k_DXT5A */ _c_(BC4_UNORM_BLOCK, RRRR), // ATI1N /* k_DXT5A */ _c_(BC4_UNORM_BLOCK, RRRR), // ATI1N
// http://fileadmin.cs.lth.se/cs/Personal/Michael_Doggett/talks/unc-xenos-doggett.pdf // https://fileadmin.cs.lth.se/cs/Personal/Michael_Doggett/talks/unc-xenos-doggett.pdf
/* k_CTX1 */ ___(R8G8_UINT), /* k_CTX1 */ ___(R8G8_UINT),
/* k_DXT3A_AS_1_1_1_1 */ ___(UNDEFINED), /* k_DXT3A_AS_1_1_1_1 */ ___(UNDEFINED),

View File

@ -916,7 +916,7 @@ bool VulkanCommandProcessor::IssueCopy() {
assert_true(copy_regs->copy_mask == 0); assert_true(copy_regs->copy_mask == 0);
// RB_SURFACE_INFO // RB_SURFACE_INFO
// http://fossies.org/dox/MesaLib-10.3.5/fd2__gmem_8c_source.html // https://fossies.org/dox/MesaLib-10.3.5/fd2__gmem_8c_source.html
uint32_t surface_info = regs[XE_GPU_REG_RB_SURFACE_INFO].u32; uint32_t surface_info = regs[XE_GPU_REG_RB_SURFACE_INFO].u32;
uint32_t surface_pitch = surface_info & 0x3FFF; uint32_t surface_pitch = surface_info & 0x3FFF;
auto surface_msaa = static_cast<MsaaSamples>((surface_info >> 16) & 0x3); auto surface_msaa = static_cast<MsaaSamples>((surface_info >> 16) & 0x3);

View File

@ -68,7 +68,7 @@ enum class TextureSign : uint32_t {
kUnsigned = 0, kUnsigned = 0,
// Two's complement texture data. // Two's complement texture data.
kSigned = 1, kSigned = 1,
// 2*color-1 - http://xboxforums.create.msdn.com/forums/t/107374.aspx // 2*color-1 - https://xboxforums.create.msdn.com/forums/t/107374.aspx
kUnsignedBiased = 2, kUnsignedBiased = 2,
// Linearized when sampled. // Linearized when sampled.
kGamma = 3, kGamma = 3,

View File

@ -70,7 +70,7 @@ struct X_INPUT_CAPABILITIES {
static_assert_size(X_INPUT_CAPABILITIES, static_assert_size(X_INPUT_CAPABILITIES,
sizeof(X_INPUT_GAMEPAD) + sizeof(X_INPUT_VIBRATION) + 4); sizeof(X_INPUT_GAMEPAD) + sizeof(X_INPUT_VIBRATION) + 4);
// http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinput_keystroke(v=vs.85).aspx // https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinput_keystroke(v=vs.85).aspx
struct X_INPUT_KEYSTROKE { struct X_INPUT_KEYSTROKE {
be<uint16_t> virtual_key; be<uint16_t> virtual_key;
be<uint16_t> unicode; be<uint16_t> unicode;

View File

@ -20,33 +20,65 @@ namespace xe {
namespace hid { namespace hid {
namespace xinput { namespace xinput {
// TODO(Triang3l): Find why XInputEnable is deprecated on Windows 10.
#pragma warning(push)
#pragma warning(disable : 4995)
XInputInputDriver::XInputInputDriver(xe::ui::Window* window) XInputInputDriver::XInputInputDriver(xe::ui::Window* window)
: InputDriver(window) { : InputDriver(window),
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8 && _WIN32_WINNT < _WIN32_WINNT_WIN10) module_(nullptr),
// TODO(gibbed): Is this necessary? XInputGetCapabilities_(nullptr),
XInputEnable(TRUE); XInputGetState_(nullptr),
#endif XInputGetKeystroke_(nullptr),
} XInputSetState_(nullptr),
XInputEnable_(nullptr) {}
XInputInputDriver::~XInputInputDriver() { XInputInputDriver::~XInputInputDriver() {
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8 && _WIN32_WINNT < _WIN32_WINNT_WIN10) if (module_) {
// TODO(gibbed): Is this necessary? FreeLibrary((HMODULE)module_);
XInputEnable(FALSE); module_ = nullptr;
#endif XInputGetCapabilities_ = nullptr;
XInputGetState_ = nullptr;
XInputGetKeystroke_ = nullptr;
XInputSetState_ = nullptr;
XInputEnable_ = nullptr;
}
} }
#pragma warning(pop) X_STATUS XInputInputDriver::Setup() {
HMODULE module = LoadLibraryW(L"xinput1_4.dll");
if (!module) {
module = LoadLibraryW(L"xinput1_3.dll");
}
if (!module) {
return X_STATUS_DLL_NOT_FOUND;
}
X_STATUS XInputInputDriver::Setup() { return X_STATUS_SUCCESS; } // Required.
auto xigc = GetProcAddress(module, "XInputGetCapabilities");
auto xigs = GetProcAddress(module, "XInputGetState");
auto xigk = GetProcAddress(module, "XInputGetKeystroke");
auto xiss = GetProcAddress(module, "XInputSetState");
// Not required.
auto xie = GetProcAddress(module, "XInputEnable");
// Only fail when we don't have the bare essentials;
if (!xigc || !xigs || !xigk || !xiss) {
FreeLibrary(module);
return X_STATUS_PROCEDURE_NOT_FOUND;
}
module_ = module;
XInputGetCapabilities_ = xigc;
XInputGetState_ = xigs;
XInputGetKeystroke_ = xigk;
XInputSetState_ = xiss;
XInputEnable_ = xie;
return X_STATUS_SUCCESS;
}
X_RESULT XInputInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags, X_RESULT XInputInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
X_INPUT_CAPABILITIES* out_caps) { X_INPUT_CAPABILITIES* out_caps) {
XINPUT_CAPABILITIES native_caps; XINPUT_CAPABILITIES native_caps;
DWORD result = XInputGetCapabilities(user_index, flags, &native_caps); auto xigc = (decltype(&XInputGetCapabilities))XInputGetCapabilities_;
DWORD result = xigc(user_index, flags, &native_caps);
if (result) { if (result) {
return result; return result;
} }
@ -71,7 +103,8 @@ X_RESULT XInputInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
X_RESULT XInputInputDriver::GetState(uint32_t user_index, X_RESULT XInputInputDriver::GetState(uint32_t user_index,
X_INPUT_STATE* out_state) { X_INPUT_STATE* out_state) {
XINPUT_STATE native_state; XINPUT_STATE native_state;
DWORD result = XInputGetState(user_index, &native_state); auto xigs = (decltype(&XInputGetState))XInputGetState_;
DWORD result = xigs(user_index, &native_state);
if (result) { if (result) {
return result; return result;
} }
@ -93,7 +126,8 @@ X_RESULT XInputInputDriver::SetState(uint32_t user_index,
XINPUT_VIBRATION native_vibration; XINPUT_VIBRATION native_vibration;
native_vibration.wLeftMotorSpeed = vibration->left_motor_speed; native_vibration.wLeftMotorSpeed = vibration->left_motor_speed;
native_vibration.wRightMotorSpeed = vibration->right_motor_speed; native_vibration.wRightMotorSpeed = vibration->right_motor_speed;
DWORD result = XInputSetState(user_index, &native_vibration); auto xiss = (decltype(&XInputSetState))XInputSetState_;
DWORD result = xiss(user_index, &native_vibration);
return result; return result;
} }
@ -105,18 +139,20 @@ X_RESULT XInputInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
// XInputGetKeystroke on Windows has a bug where it will return // XInputGetKeystroke on Windows has a bug where it will return
// ERROR_SUCCESS (0) even if the device is not connected: // ERROR_SUCCESS (0) even if the device is not connected:
// http://stackoverflow.com/questions/23669238/xinputgetkeystroke-returning-error-success-while-controller-is-unplugged // https://stackoverflow.com/questions/23669238/xinputgetkeystroke-returning-error-success-while-controller-is-unplugged
// //
// So we first check if the device is connected via XInputGetCapabilities, so // So we first check if the device is connected via XInputGetCapabilities, so
// we are not passing back an uninitialized X_INPUT_KEYSTROKE structure: // we are not passing back an uninitialized X_INPUT_KEYSTROKE structure:
XINPUT_CAPABILITIES caps; XINPUT_CAPABILITIES caps;
result = XInputGetCapabilities(user_index, 0, &caps); auto xigc = (decltype(&XInputGetCapabilities))XInputGetCapabilities_;
result = xigc(user_index, 0, &caps);
if (result) { if (result) {
return result; return result;
} }
XINPUT_KEYSTROKE native_keystroke; XINPUT_KEYSTROKE native_keystroke;
result = XInputGetKeystroke(user_index, 0, &native_keystroke); auto xigk = (decltype(&XInputGetKeystroke))XInputGetKeystroke_;
result = xigk(user_index, 0, &native_keystroke);
if (result) { if (result) {
return result; return result;
} }

View File

@ -31,6 +31,12 @@ class XInputInputDriver : public InputDriver {
X_INPUT_KEYSTROKE* out_keystroke) override; X_INPUT_KEYSTROKE* out_keystroke) override;
protected: protected:
void* module_;
void* XInputGetCapabilities_;
void* XInputGetState_;
void* XInputGetKeystroke_;
void* XInputSetState_;
void* XInputEnable_;
}; };
} // namespace xinput } // namespace xinput

View File

@ -31,8 +31,6 @@
DEFINE_bool(headless, false, DEFINE_bool(headless, false,
"Don't display any UI, using defaults for prompts as needed."); "Don't display any UI, using defaults for prompts as needed.");
DEFINE_string(content_root, "content",
"Root path for content (save/etc) storage.");
namespace xe { namespace xe {
namespace kernel { namespace kernel {
@ -57,7 +55,7 @@ KernelState::KernelState(Emulator* emulator)
app_manager_ = std::make_unique<xam::AppManager>(); app_manager_ = std::make_unique<xam::AppManager>();
user_profile_ = std::make_unique<xam::UserProfile>(); user_profile_ = std::make_unique<xam::UserProfile>();
auto content_root = xe::to_wstring(FLAGS_content_root); auto content_root = emulator_->content_root();
content_root = xe::to_absolute_path(content_root); content_root = xe::to_absolute_path(content_root);
content_manager_ = std::make_unique<xam::ContentManager>(this, content_root); content_manager_ = std::make_unique<xam::ContentManager>(this, content_root);
@ -581,7 +579,7 @@ void KernelState::RegisterNotifyListener(NotifyListener* listener) {
// Games seem to expect a few notifications on startup, only for the first // Games seem to expect a few notifications on startup, only for the first
// listener. // listener.
// http://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=resident+evil+5&start=375 // https://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=resident+evil+5&start=375
if (!has_notified_startup_ && listener->mask() & 0x00000001) { if (!has_notified_startup_ && listener->mask() & 0x00000001) {
has_notified_startup_ = true; has_notified_startup_ = true;
// XN_SYS_UI (on, off) // XN_SYS_UI (on, off)

View File

@ -19,8 +19,8 @@ namespace xe {
namespace kernel { namespace kernel {
namespace util { namespace util {
// http://freestyledash.googlecode.com/svn/trunk/Freestyle/Tools/XEX/SPA.h // https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.h
// http://freestyledash.googlecode.com/svn/trunk/Freestyle/Tools/XEX/SPA.cpp // https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.cpp
enum class XdbfSection : uint16_t { enum class XdbfSection : uint16_t {
kMetadata = 0x0001, kMetadata = 0x0001,
@ -49,7 +49,7 @@ struct XdbfBlock {
}; };
// Wraps an XBDF (XboxDataBaseFormat) in-memory database. // Wraps an XBDF (XboxDataBaseFormat) in-memory database.
// http://www.free60.org/wiki/XDBF // https://free60project.github.io/wiki/XDBF.html
class XdbfWrapper { class XdbfWrapper {
public: public:
XdbfWrapper(const uint8_t* data, size_t data_size); XdbfWrapper(const uint8_t* data, size_t data_size);

View File

@ -25,7 +25,7 @@ namespace xam {
namespace apps { namespace apps {
// Only source of docs for a lot of these functions: // Only source of docs for a lot of these functions:
// http://freestyledash.googlecode.com/svn-history/r1/trunk/Freestyle/Scenes/Media/Music/ScnMusic.cpp // https://github.com/oukiar/freestyledash/blob/master/Freestyle/Scenes/Media/Music/ScnMusic.cpp
class XmpApp : public App { class XmpApp : public App {
public: public:

View File

@ -23,6 +23,8 @@ namespace xam {
static const wchar_t* kThumbnailFileName = L"__thumbnail.png"; static const wchar_t* kThumbnailFileName = L"__thumbnail.png";
static const wchar_t* kGameUserContentDirName = L"profile";
static int content_device_id_ = 0; static int content_device_id_ = 0;
ContentPackage::ContentPackage(KernelState* kernel_state, std::string root_name, ContentPackage::ContentPackage(KernelState* kernel_state, std::string root_name,
@ -252,6 +254,20 @@ X_RESULT ContentManager::DeleteContent(const XCONTENT_DATA& data) {
} }
} }
std::wstring ContentManager::ResolveGameUserContentPath() {
wchar_t title_id[9] = L"00000000";
std::swprintf(title_id, 9, L"%.8X", kernel_state_->title_id());
auto user_name = xe::to_wstring(kernel_state_->user_profile()->name());
// Per-game per-profile data location:
// content_root/title_id/profile/user_name
auto package_root = xe::join_paths(
root_path_,
xe::join_paths(title_id,
xe::join_paths(kGameUserContentDirName, user_name)));
return package_root + xe::kWPathSeparator;
}
} // namespace xam } // namespace xam
} // namespace kernel } // namespace kernel
} // namespace xe } // namespace xe

View File

@ -84,6 +84,7 @@ class ContentManager {
X_RESULT SetContentThumbnail(const XCONTENT_DATA& data, X_RESULT SetContentThumbnail(const XCONTENT_DATA& data,
std::vector<uint8_t> buffer); std::vector<uint8_t> buffer);
X_RESULT DeleteContent(const XCONTENT_DATA& data); X_RESULT DeleteContent(const XCONTENT_DATA& data);
std::wstring ResolveGameUserContentPath();
private: private:
std::wstring ResolvePackageRoot(uint32_t content_type); std::wstring ResolvePackageRoot(uint32_t content_type);

View File

@ -7,6 +7,10 @@
****************************************************************************** ******************************************************************************
*/ */
#include <sstream>
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/util/shim_utils.h"
#include "xenia/kernel/xam/user_profile.h" #include "xenia/kernel/xam/user_profile.h"
namespace xe { namespace xe {
@ -17,7 +21,7 @@ UserProfile::UserProfile() {
xuid_ = 0xBABEBABEBABEBABE; xuid_ = 0xBABEBABEBABEBABE;
name_ = "User"; name_ = "User";
// http://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=gfwl+live&start=195 // https://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=gfwl+live&start=195
// https://github.com/arkem/py360/blob/master/py360/constants.py // https://github.com/arkem/py360/blob/master/py360/constants.py
// XPROFILE_GAMER_YAXIS_INVERSION // XPROFILE_GAMER_YAXIS_INVERSION
AddSetting(std::make_unique<Int32Setting>(0x10040002, 0)); AddSetting(std::make_unique<Int32Setting>(0x10040002, 0));
@ -87,6 +91,10 @@ void UserProfile::AddSetting(std::unique_ptr<Setting> setting) {
Setting* previous_setting = setting.get(); Setting* previous_setting = setting.get();
std::swap(settings_[setting->setting_id], previous_setting); std::swap(settings_[setting->setting_id], previous_setting);
if (setting->is_set && setting->is_title_specific()) {
SaveSetting(setting.get());
}
if (previous_setting) { if (previous_setting) {
// replace: swap out the old setting from the owning list // replace: swap out the old setting from the owning list
for (auto vec_it = setting_list_.begin(); vec_it != setting_list_.end(); for (auto vec_it = setting_list_.begin(); vec_it != setting_list_.end();
@ -107,7 +115,58 @@ UserProfile::Setting* UserProfile::GetSetting(uint32_t setting_id) {
if (it == settings_.end()) { if (it == settings_.end()) {
return nullptr; return nullptr;
} }
return it->second; UserProfile::Setting* setting = it->second;
if (setting->is_title_specific()) {
// If what we have loaded in memory isn't for the title that is running
// right now, then load it from disk.
if (kernel_state()->title_id() != setting->loaded_title_id) {
LoadSetting(setting);
}
}
return setting;
}
void UserProfile::LoadSetting(UserProfile::Setting* setting) {
if (setting->is_title_specific()) {
auto content_dir =
kernel_state()->content_manager()->ResolveGameUserContentPath();
auto setting_id = xe::format_string(L"%.8X", setting->setting_id);
auto file_path = xe::join_paths(content_dir, setting_id);
auto file = xe::filesystem::OpenFile(file_path, "rb");
if (file) {
fseek(file, 0, SEEK_END);
uint32_t input_file_size = static_cast<uint32_t>(ftell(file));
fseek(file, 0, SEEK_SET);
std::vector<uint8_t> serialized_data(input_file_size);
fread(serialized_data.data(), 1, serialized_data.size(), file);
fclose(file);
setting->Deserialize(serialized_data);
setting->loaded_title_id = kernel_state()->title_id();
}
} else {
// Unsupported for now. Other settings aren't per-game and need to be
// stored some other way.
XELOGW("Attempting to load unsupported profile setting from disk");
}
}
void UserProfile::SaveSetting(UserProfile::Setting* setting) {
if (setting->is_title_specific()) {
auto serialized_setting = setting->Serialize();
auto content_dir =
kernel_state()->content_manager()->ResolveGameUserContentPath();
xe::filesystem::CreateFolder(content_dir);
auto setting_id = xe::format_string(L"%.8X", setting->setting_id);
auto file_path = xe::join_paths(content_dir, setting_id);
auto file = xe::filesystem::OpenFile(file_path, "wb");
fwrite(serialized_setting.data(), 1, serialized_setting.size(), file);
fclose(file);
} else {
// Unsupported for now. Other settings aren't per-game and need to be
// stored some other way.
XELOGW("Attempting to save unsupported profile setting to disk");
}
} }
} // namespace xam } // namespace xam

Some files were not shown because too many files have changed in this diff Show More