| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- #include "EABase/eabase.h"
- #if (defined(EA_PLATFORM_MICROSOFT) && !defined(CS_UNDEFINED_STRING) && !EA_WINAPI_FAMILY_PARTITION(EA_WINAPI_PARTITION_DESKTOP))
- #include <EAAssert/eaassert.h>
- #include <EAMain/EAMain.h>
- #include <EAStdC/EASprintf.h>
- #include <EAStdC/EAString.h>
- EA_DISABLE_ALL_VC_WARNINGS()
- #pragma warning(disable: 4472 4355) // additional warnings generated by XDK with VS2015
- #include <memory>
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
- #endif
- #include <Windows.h>
- #if defined EA_PLATFORM_CAPILANO
- #if defined EAMAIN_CAPILANO_DX12
- #include <d3d12_x.h>
- #else
- #include <d3d11_x.h>
- #endif
- #endif
- EA_RESTORE_ALL_VC_WARNINGS()
- namespace EA
- {
- namespace EAMain
- {
- // Application - implements the required functionality for a application
- ref class ApplicationView sealed : public Windows::ApplicationModel::Core::IFrameworkView
- {
- public:
- // IFrameworkView Methods
- virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
- virtual void SetWindow(Windows::UI::Core::CoreWindow^ window) {}
- virtual void Load(Platform::String^ entryPoint);
- virtual void Run();
- virtual void Uninitialize();
- private:
- char *mCommandLine;
- #if EA_PLATFORM_CAPILANO
- #if defined EAMAIN_CAPILANO_DX12
- ID3D12CommandQueue* mpCommandQueue;
- #else
- ID3DXboxPerformanceContext* mpD3DXboxPerfContext;
- #endif
- #endif
- void CreateDeviceResources();
- void OnActivated( Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args );
- };
- // ApplicationSource - responsible for creating the Application instance and passing it back to the system
- ref class ApplicationViewSource : Windows::ApplicationModel::Core::IFrameworkViewSource
- {
- public:
- virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView()
- {
- return ref new ApplicationView();
- }
- };
- void OutputAppTransition(const char* transition, const wchar_t* sender, const wchar_t* args)
- {
- char msg[1024];
- EA::StdC::Snprintf(msg, EAArrayCount(msg), "****\n app is %s.\n sender: ", transition);
- EA::StdC::Strlcat(msg, sender, EAArrayCount(msg));
- EA::StdC::Strlcat(msg, "\n args: ", EAArrayCount(msg));
- EA::StdC::Strlcat(msg, args, EAArrayCount(msg));
- EA::StdC::Strlcat(msg, "\n****\n", EAArrayCount(msg));
- OutputDebugStringA(msg);
- }
- void ApplicationView::CreateDeviceResources()
- {
- #if defined EA_PLATFORM_CAPILANO
- #if defined EAMAIN_CAPILANO_DX12
- ID3D12Device* pD3DDevice;
- HRESULT hr = D3D12CreateDevice(
- nullptr, // specify null to use the default adapter
- D3D_FEATURE_LEVEL_11_0,
- __uuidof(ID3D12Device),
- (void**)&pD3DDevice
- );
- if (FAILED(hr))
- {
- OutputDebugStringA("Failed to create device. Suspending will not work for this application.");
- return;
- }
- D3D12XBOX_COMMAND_QUEUE_DESC queueDesc = {};
- queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
- queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
- queueDesc.EngineOrPipeIndex = 0;
- queueDesc.QueueIndex = 0;
- hr = pD3DDevice->CreateCommandQueueX(&queueDesc, __uuidof(ID3D12CommandQueue), (void**)&mpCommandQueue);
- if (FAILED(hr))
- {
- OutputDebugStringA("Failed to create command queue. Suspending will not work for this application.");
- }
- if (pD3DDevice) { pD3DDevice->Release(); pD3DDevice = NULL; }
- #else
- // This flag adds support for surfaces with a different color channel ordering than the API default.
- // It is recommended usage, and is required for compatibility with Direct2D.
- UINT creationFlags = D3D11_CREATE_DEVICE_INSTRUMENTED;
- // This array defines the set of DirectX hardware feature levels this app will support.
- // Note the ordering should be preserved.
- // Don't forget to declare your application's minimum required feature level in its
- // description. All applications are assumed to support 9.1 unless otherwise stated.
- D3D_FEATURE_LEVEL featureLevels[] =
- {
- D3D_FEATURE_LEVEL_11_0
- };
- // Create the DX11 API device object, and get a corresponding context.
- ID3D11Device* pD3DDevice;
- ID3D11DeviceContext* pD3DDeviceContext;
- HRESULT hr = D3D11CreateDevice(
- nullptr, // specify null to use the default adapter
- D3D_DRIVER_TYPE_HARDWARE,
- nullptr, // leave as nullptr unless software device
- creationFlags, // optionally set debug and Direct2D compatibility flags
- featureLevels, // list of feature levels this app can support
- ARRAYSIZE(featureLevels), // number of entries in above list
- D3D11_SDK_VERSION, // always set this to D3D11_SDK_VERSION
- &pD3DDevice, // returns the Direct3D device created
- NULL, // returns feature level of device created
- &pD3DDeviceContext // returns the device immediate context
- );
- if (FAILED(hr))
- {
- OutputDebugStringA("Failed to create device. Suspending will not work for this application.");
- return;
- }
- hr = pD3DDevice->QueryInterface(__uuidof(mpD3DXboxPerfContext), (void **)&mpD3DXboxPerfContext);
- if (FAILED(hr))
- {
- OutputDebugStringA("Failed to get perfcontext. Suspending will not work for this application.");
- }
- if (pD3DDevice) { pD3DDevice->Release(); pD3DDevice = NULL; }
- if (pD3DDeviceContext) { pD3DDeviceContext->Release(); pD3DDeviceContext = NULL; }
- #endif
- #else
- // Do nothing
- #endif
- }
- // Called by the system. Perform application initialization here,
- // hooking application wide events, etc.
- void ApplicationView::Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView)
- {
- using namespace Platform;
- using namespace Windows::Foundation;
- using namespace Windows::ApplicationModel;
- using namespace Windows::ApplicationModel::Core;
- using namespace Windows::ApplicationModel::Activation;
- // Creates any resources required by the platform to run an application / enable a particular feature set (like GPU profiling or suspend/resume)
- CreateDeviceResources();
- #pragma warning(push)
- // Disables warning for MS class 'Windows::Foundation::TypedEventHandler<TSender,TResult>::{ctor}::__abi_PointerToMemberCapture'
- // "layout of class may have changed from a previous version of the compiler due to better packing of member 'Windows::Foundation::TypedEventHandler<TSender,TResult>::{ctor}::__abi_PointerToMemberCapture::member'"
- #pragma warning(disable:4371)
- applicationView->Activated += ref new Windows::Foundation::TypedEventHandler< CoreApplicationView^, IActivatedEventArgs^ >( this, &ApplicationView::OnActivated );
- #pragma warning(pop)
- CoreApplication::Suspending += ref new EventHandler<SuspendingEventArgs^>([this](Object^ sender, SuspendingEventArgs^ args) {
- OutputAppTransition("suspending", sender ? sender->ToString()->Data() : L"NULL", args ? args->ToString()->Data() : L"NULL");
- #if defined EA_PLATFORM_CAPILANO
- #if defined EAMAIN_CAPILANO_DX12
- mpCommandQueue->SuspendX(0);
- #else
- mpD3DXboxPerfContext->Suspend(0);
- #endif
- #endif
- });
- CoreApplication::Resuming += ref new EventHandler<Object^>([this](Object^ sender, Object^ args) {
- OutputAppTransition("resuming", sender ? sender->ToString()->Data() : L"NULL", args ? args->ToString()->Data() : L"NULL");
- #if defined EA_PLATFORM_CAPILANO
- #if defined EAMAIN_CAPILANO_DX12
- mpCommandQueue->ResumeX();
- #else
- mpD3DXboxPerfContext->Resume();
- #endif
- #endif
- });
- CoreApplication::Exiting += ref new EventHandler<Object^>([](Object^ sender, Object^ args) {
- OutputAppTransition("exiting", sender ? sender->ToString()->Data() : L"NULL", args ? args->ToString()->Data() : L"NULL");
- });
- }
- static char *ConvertLaunchArgsToMultibyte(LPCWSTR rawArgumentString, int rawArgumentStringLength)
- {
- int bufferSize = WideCharToMultiByte(
- CP_UTF8,
- 0,
- rawArgumentString,
- rawArgumentStringLength,
- NULL,
- 0,
- NULL,
- NULL);
- char *commandLine = static_cast<char *>(calloc(bufferSize + 1, 1));
- int rv = WideCharToMultiByte(
- CP_UTF8,
- 0,
- rawArgumentString,
- rawArgumentStringLength,
- commandLine,
- bufferSize + 1,
- NULL,
- NULL);
- commandLine[bufferSize] = 0;
- EA_ASSERT(rv == bufferSize);
- EA_UNUSED(rv); // avoids warnings in opt builds regarding unused variables
- return commandLine;
- }
- static char *ReadArgsFromFile()
- {
- FILE *fp = fopen("EAMainArgsFile.txt", "rb");
- if (fp == NULL)
- {
- goto error_return;
- }
- size_t fileSize;
- fseek(fp, 0, SEEK_END);
- fileSize = static_cast<size_t>(ftell(fp));
- fseek(fp, 0, SEEK_SET);
- char *argsBuffer = static_cast<char *>(calloc(fileSize + 1, 1));
- if (fread(argsBuffer, 1, fileSize, fp) != fileSize)
- {
- goto error_return_free_buffer;
- }
- return argsBuffer;
- error_return_free_buffer:
- free(argsBuffer);
- fclose(fp);
- error_return:
- return static_cast<char *>(calloc(1, 1));
- }
- void ApplicationView::OnActivated( Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args )
- {
- if (args->Kind == Windows::ApplicationModel::Activation::ActivationKind::Launch)
- {
- Windows::ApplicationModel::Activation::LaunchActivatedEventArgs ^launchArgs = (Windows::ApplicationModel::Activation::LaunchActivatedEventArgs ^) args;
- Platform::String ^argumentString = launchArgs->Arguments;
- LPCWSTR rawArgumentString = argumentString->Data();
- int rawArgumentStringLength = argumentString->Length();
- if (rawArgumentString == NULL || wcslen(rawArgumentString) == 0)
- {
- mCommandLine = ReadArgsFromFile();
- }
- else
- {
- mCommandLine = ConvertLaunchArgsToMultibyte(rawArgumentString, rawArgumentStringLength);
- }
- }
- Windows::UI::Core::CoreWindow::GetForCurrentThread()->Activate();
- }
- void ApplicationView::Load(Platform::String^ entryPoint)
- {
- }
- // Called by the system after initialization is complete. This implements the traditional game loop.
- void ApplicationView::Run()
- {
- using namespace EA::EAMain;
- std::unique_ptr<IWinRTRunner> winRTRunner(CreateWinRTRunner());
- CommandLine commandline(mCommandLine, CommandLine::FLAG_NO_PROGRAM_NAME);
- winRTRunner->Run(commandline.Argc(),commandline.Argv());
- do
- {
- // ProcessEvents will throw if the process is exiting, allowing us to
- // break out of the loop. This will be cleaned up when we get proper
- // process lifetime management online in a future release.
- Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(Windows::UI::Core::CoreProcessEventsOption::ProcessAllIfPresent);
- } while(!winRTRunner->IsFinished());
- winRTRunner->ReportResult();
- Windows::ApplicationModel::Core::CoreApplication::Exit();
- free(mCommandLine);
- mCommandLine = nullptr;
- }
- void ApplicationView::Uninitialize()
- {
- }
- namespace Internal
- {
- EAMAIN_API void StartWinRtApplication()
- {
- // To do: store args so they can be passed to EAEntryPointMain.
- Windows::ApplicationModel::Core::CoreApplication::Run(ref new ApplicationViewSource());
- }
- } // namespace Internal
- } // namespace EAMain
- } // namespace EA
- #endif
|