2025-01-22 16:18:30 +01:00

460 lines
15 KiB
C++

#include <kinc/graphics4/graphics.h>
#include <kinc/input/gamepad.h>
#include <kinc/input/keyboard.h>
#include <kinc/input/mouse.h>
#include <kinc/system.h>
#include <kinc/threads/thread.h>
#include <kinc/video.h>
#include <kinc/window.h>
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#ifndef XINPUT
#ifdef KINC_WINDOWS
#define XINPUT 1
#endif
#ifdef KINC_WINDOWSAPP
#define XINPUT !(WINAPI_PARTITION_PHONE_APP)
#endif
#endif
#if XINPUT
#include <Xinput.h>
#endif
#include <d3d11_1.h>
#include <d3d11_4.h>
#include <dxgi1_5.h>
#include <wrl.h>
#ifdef KINC_WINDOWSAPP
using namespace ::Microsoft::WRL;
using namespace Windows::UI::Core;
using namespace Windows::Foundation;
#ifdef KINC_HOLOLENS
using namespace Windows::Graphics::Holographic;
using namespace Windows::Graphics::DirectX::Direct3D11;
#endif
#endif
extern "C" IUnknown *kinc_winapp_internal_get_window(void) {
return reinterpret_cast<IUnknown *>(CoreWindow::GetForCurrentThread());
}
extern "C" void kinc_internal_uwp_installed_location_path(char *path) {
Platform::String ^ locationString = Windows::ApplicationModel::Package::Current->InstalledLocation->Path;
WideCharToMultiByte(CP_UTF8, 0, locationString->Begin(), -1, path, 1000, nullptr, nullptr);
}
ref class Win8Application sealed : public Windows::ApplicationModel::Core::IFrameworkView {
public:
Win8Application();
virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView ^ applicationView);
virtual void SetWindow(Windows::UI::Core::CoreWindow ^ window);
virtual void Load(Platform::String ^ entryPoint);
virtual void Run();
virtual void Uninitialize();
protected:
void OnWindowSizeChanged(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::WindowSizeChangedEventArgs ^ args);
// void OnLogicalDpiChanged(Platform::Object^ sender);
void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView ^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs ^ args);
void OnSuspending(Platform::Object ^ sender, Windows::ApplicationModel::SuspendingEventArgs ^ args);
void OnResuming(Platform::Object ^ sender, Platform::Object ^ args);
void OnWindowClosed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::CoreWindowEventArgs ^ args);
void OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args);
void OnPointerReleased(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args);
void OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args);
private:
// CubeRenderer^ m_renderer;
// Windows::ApplicationModel::Core::CoreApplicationView^ view;
bool closed;
void OnKeyDown(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args);
void OnKeyUp(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args);
};
ref class Win8ApplicationSource : Windows::ApplicationModel::Core::IFrameworkViewSource {
public:
virtual Windows::ApplicationModel::Core::IFrameworkView ^ CreateView();
};
namespace {
int mouseX, mouseY;
float axes[12 * 6];
float buttons[12 * 16];
}
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::UI::Core;
using namespace Windows::System;
using namespace Windows::Foundation;
using namespace Windows::Graphics::Display;
const char *kinc_gamepad_vendor(int gamepad) {
return "Microsoft";
}
const char *kinc_gamepad_product_name(int gamepad) {
return "Xbox 360 Controller";
}
bool kinc_internal_handle_messages(void) {
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
#if XINPUT
DWORD dwResult;
for (DWORD i = 0; i < XUSER_MAX_COUNT; ++i) {
XINPUT_STATE state;
ZeroMemory(&state, sizeof(XINPUT_STATE));
dwResult = XInputGetState(i, &state);
if (dwResult == ERROR_SUCCESS) {
float newaxes[6];
newaxes[0] = state.Gamepad.sThumbLX / 32768.0f;
newaxes[1] = state.Gamepad.sThumbLY / 32768.0f;
newaxes[2] = state.Gamepad.sThumbRX / 32768.0f;
newaxes[3] = state.Gamepad.sThumbRY / 32768.0f;
newaxes[4] = state.Gamepad.bLeftTrigger / 255.0f;
newaxes[5] = state.Gamepad.bRightTrigger / 255.0f;
for (int i2 = 0; i2 < 6; ++i2) {
if (axes[i * 6 + i2] != newaxes[i2]) {
kinc_internal_gamepad_trigger_axis(i, i2, newaxes[i2]);
axes[i * 6 + i2] = newaxes[i2];
}
}
float newbuttons[16];
newbuttons[0] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_A) ? 1.0f : 0.0f;
newbuttons[1] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_B) ? 1.0f : 0.0f;
newbuttons[2] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_X) ? 1.0f : 0.0f;
newbuttons[3] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y) ? 1.0f : 0.0f;
newbuttons[4] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? 1.0f : 0.0f;
newbuttons[5] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) ? 1.0f : 0.0f;
newbuttons[6] = state.Gamepad.bLeftTrigger / 255.0f;
newbuttons[7] = state.Gamepad.bRightTrigger / 255.0f;
newbuttons[8] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) ? 1.0f : 0.0f;
newbuttons[9] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_START) ? 1.0f : 0.0f;
newbuttons[10] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) ? 1.0f : 0.0f;
newbuttons[11] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) ? 1.0f : 0.0f;
newbuttons[12] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) ? 1.0f : 0.0f;
newbuttons[13] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) ? 1.0f : 0.0f;
newbuttons[14] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) ? 1.0f : 0.0f;
newbuttons[15] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) ? 1.0f : 0.0f;
for (int i2 = 0; i2 < 16; ++i2) {
if (buttons[i * 16 + i2] != newbuttons[i2]) {
kinc_internal_gamepad_trigger_button(i, i2, newbuttons[i2]);
buttons[i * 16 + i2] = newbuttons[i2];
}
}
}
}
#endif
return true;
}
// Kore::vec2i Kore::System::mousePos() {
// return vec2i(mouseX, mouseY);
//}
#ifdef KINC_KONG
extern "C" void kong_init(void);
#endif
#undef CreateWindow
int kinc_init(const char *name, int width, int height, struct kinc_window_options *win, struct kinc_framebuffer_options *frame) {
kinc_window_options_t defaultWin;
if (win == NULL) {
kinc_window_options_set_defaults(&defaultWin);
win = &defaultWin;
}
win->width = width;
win->height = height;
kinc_framebuffer_options_t defaultFrame;
if (frame == NULL) {
kinc_framebuffer_options_set_defaults(&defaultFrame);
frame = &defaultFrame;
}
kinc_g4_internal_init();
kinc_g4_internal_init_window(0, frame->depth_bits, frame->stencil_bits, true);
#ifdef KINC_KONG
kong_init();
#endif
return 0;
}
void kinc_set_keep_screen_on(bool on) {}
namespace {
bool keyboardshown = false;
char language[3] = {0};
}
void kinc_keyboard_show() {
keyboardshown = true;
}
void kinc_keyboard_hide() {
keyboardshown = false;
}
bool kinc_keyboard_active() {
return keyboardshown;
}
void kinc_load_url(const char *url) {}
void kinc_vibrate(int ms) {}
const char *kinc_language() {
wchar_t wlanguage[3] = {0};
if (GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SISO639LANGNAME, wlanguage, 3)) {
WideCharToMultiByte(CP_UTF8, 0, wlanguage, -1, language, 3, nullptr, nullptr);
return language;
}
return "en";
}
Win8Application::Win8Application() : closed(false) {}
void Win8Application::Initialize(CoreApplicationView ^ applicationView) {
applicationView->Activated += ref new TypedEventHandler<CoreApplicationView ^, IActivatedEventArgs ^>(this, &Win8Application::OnActivated);
CoreApplication::Suspending += ref new EventHandler<SuspendingEventArgs ^>(this, &Win8Application::OnSuspending);
CoreApplication::Resuming += ref new EventHandler<Platform::Object ^>(this, &Win8Application::OnResuming);
// m_renderer = ref new CubeRenderer();
}
void Win8Application::SetWindow(CoreWindow ^ window) {
window->SizeChanged += ref new TypedEventHandler<CoreWindow ^, WindowSizeChangedEventArgs ^>(this, &Win8Application::OnWindowSizeChanged);
window->Closed += ref new TypedEventHandler<CoreWindow ^, CoreWindowEventArgs ^>(this, &Win8Application::OnWindowClosed);
window->PointerPressed += ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &Win8Application::OnPointerPressed);
window->PointerReleased += ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &Win8Application::OnPointerReleased);
window->PointerMoved += ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &Win8Application::OnPointerMoved);
window->KeyDown +=
ref new Windows::Foundation::TypedEventHandler<Windows::UI::Core::CoreWindow ^, Windows::UI::Core::KeyEventArgs ^>(this, &Win8Application::OnKeyDown);
window->KeyUp +=
ref new Windows::Foundation::TypedEventHandler<Windows::UI::Core::CoreWindow ^, Windows::UI::Core::KeyEventArgs ^>(this, &Win8Application::OnKeyUp);
// m_renderer->Initialize(CoreWindow::GetForCurrentThread());
#ifdef KINC_HOLOLENS
// Create holographics space - needs to be created before window is activated
holographicFrameController = std::make_unique<HolographicFrameController>(window);
// create video frame processor
VideoFrameProcessor::createAsync().then([this](std::shared_ptr<VideoFrameProcessor> videoProcessor) { videoFrameProcessor = std::move(videoProcessor); });
#endif
}
void Win8Application::Load(Platform::String ^ entryPoint) {}
void Win8Application::Run() {
// BasicTimer^ timer = ref new BasicTimer();
kickstart(0, nullptr);
// while (!closed) {
// timer->Update();
// m_renderer->Update(timer->Total, timer->Delta);
// m_renderer->Render();
// m_renderer->Present(); // This call is synchronized to the display frame rate.
//}
}
void Win8Application::Uninitialize() {}
int kinc_uwp_window_width;
int kinc_uwp_window_height;
extern "C" void kinc_internal_resize(int window, int width, int height);
void Win8Application::OnWindowSizeChanged(CoreWindow ^ sender, WindowSizeChangedEventArgs ^ args) {
kinc_uwp_window_width = (int)args->Size.Width;
kinc_uwp_window_height = (int)args->Size.Height;
kinc_internal_resize(0, (int)args->Size.Width, (int)args->Size.Height);
}
void Win8Application::OnWindowClosed(CoreWindow ^ sender, CoreWindowEventArgs ^ args) {
closed = true;
}
void Win8Application::OnActivated(CoreApplicationView ^ applicationView, IActivatedEventArgs ^ args) {
CoreWindow::GetForCurrentThread()->Activate();
}
void Win8Application::OnSuspending(Platform::Object ^ sender, SuspendingEventArgs ^ args) {
// SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
// deferral->Complete();
}
void Win8Application::OnResuming(Platform::Object ^ sender, Platform::Object ^ args) {}
void Win8Application::OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
mouseX = static_cast<int>(args->CurrentPoint->Position.X);
mouseY = static_cast<int>(args->CurrentPoint->Position.Y);
kinc_internal_mouse_trigger_press(0, 0, mouseX, mouseY);
}
void Win8Application::OnPointerReleased(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
mouseX = static_cast<int>(args->CurrentPoint->Position.X);
mouseY = static_cast<int>(args->CurrentPoint->Position.Y);
kinc_internal_mouse_trigger_release(0, 0, mouseX, mouseY);
}
void Win8Application::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
mouseX = static_cast<int>(args->CurrentPoint->Position.X);
mouseY = static_cast<int>(args->CurrentPoint->Position.Y);
kinc_internal_mouse_trigger_move(0, mouseX, mouseY);
}
void Win8Application::OnKeyDown(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args) {
switch (args->VirtualKey) {
case Windows::System::VirtualKey::Left:
kinc_internal_keyboard_trigger_key_down(KINC_KEY_LEFT);
break;
case Windows::System::VirtualKey::Right:
kinc_internal_keyboard_trigger_key_down(KINC_KEY_RIGHT);
break;
case Windows::System::VirtualKey::Up:
kinc_internal_keyboard_trigger_key_down(KINC_KEY_UP);
break;
case Windows::System::VirtualKey::Down:
kinc_internal_keyboard_trigger_key_down(KINC_KEY_DOWN);
break;
default:
if (args->VirtualKey >= Windows::System::VirtualKey::A && args->VirtualKey <= Windows::System::VirtualKey::Z) {
kinc_internal_keyboard_trigger_key_down((int)args->VirtualKey);
}
else if (args->VirtualKey >= Windows::System::VirtualKey::Number0 && args->VirtualKey <= Windows::System::VirtualKey::Number9) {
kinc_internal_keyboard_trigger_key_down((int)args->VirtualKey);
}
break;
}
}
void Win8Application::OnKeyUp(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args) {
switch (args->VirtualKey) {
case Windows::System::VirtualKey::Left:
kinc_internal_keyboard_trigger_key_up(KINC_KEY_LEFT);
break;
case Windows::System::VirtualKey::Right:
kinc_internal_keyboard_trigger_key_up(KINC_KEY_RIGHT);
break;
case Windows::System::VirtualKey::Up:
kinc_internal_keyboard_trigger_key_up(KINC_KEY_UP);
break;
case Windows::System::VirtualKey::Down:
kinc_internal_keyboard_trigger_key_up(KINC_KEY_DOWN);
break;
default:
if (args->VirtualKey >= Windows::System::VirtualKey::A && args->VirtualKey <= Windows::System::VirtualKey::Z) {
kinc_internal_keyboard_trigger_key_up((int)args->VirtualKey);
}
else if (args->VirtualKey >= Windows::System::VirtualKey::Number0 && args->VirtualKey <= Windows::System::VirtualKey::Number9) {
kinc_internal_keyboard_trigger_key_up((int)args->VirtualKey);
}
break;
}
}
IFrameworkView ^ Win8ApplicationSource::CreateView() {
return ref new Win8Application;
}
const char *kinc_internal_save_path() {
return "\\";
}
const char *kinc_system_id() {
return "WindowsApp";
}
namespace {
const char *videoFormats[] = {"ogv", nullptr};
}
const char **kinc_video_formats() {
return ::videoFormats;
}
int kinc_window_width(int window_index) {
return kinc_uwp_window_width;
}
int kinc_window_height(int window_index) {
return kinc_uwp_window_height;
}
double kinc_frequency() {
kinc_ticks_t rate;
QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER *>(&rate));
return (double)rate;
}
void kinc_internal_shutdown() {}
static kinc_ticks_t start_stamp;
kinc_ticks_t kinc_timestamp() {
kinc_ticks_t stamp;
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&stamp));
return stamp - start_stamp;
}
void kinc_login() {}
void kinc_unlock_achievement(int id) {}
bool kinc_gamepad_connected(int num) {
return true;
}
void kinc_gamepad_rumble(int gamepad, float left, float right){
}
[Platform::MTAThread] int main(Platform::Array<Platform::String ^> ^) {
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&start_stamp));
CoreApplication::Run(ref new Win8ApplicationSource);
return 0;
}
int kinc_cpu_cores(void) {
SYSTEM_LOGICAL_PROCESSOR_INFORMATION info[1024];
DWORD returnLength = sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) * 1024;
BOOL success = GetLogicalProcessorInformation(&info[0], &returnLength);
int proper_cpu_count = 0;
if (success) {
DWORD byteOffset = 0;
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = &info[0];
while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength) {
if (ptr->Relationship == RelationProcessorCore) {
++proper_cpu_count;
}
byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
++ptr;
}
}
else {
proper_cpu_count = 1;
}
return proper_cpu_count;
}
int kinc_hardware_threads(void) {
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
return sysinfo.dwNumberOfProcessors;
}