Merge branch 'master' into vulkan

This commit is contained in:
Triang3l
2021-09-14 22:29:51 +03:00
22 changed files with 563 additions and 168 deletions

View File

@@ -0,0 +1,54 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2021 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/ui/window_android.h"
#include <memory>
#include <utility>
#include "xenia/base/assert.h"
#include "xenia/ui/windowed_app_context_android.h"
namespace xe {
namespace ui {
std::unique_ptr<Window> Window::Create(WindowedAppContext& app_context,
const std::string& title) {
// The window is a proxy between the main activity and Xenia, so there can be
// only one for an activity.
AndroidWindowedAppContext& android_app_context =
static_cast<AndroidWindowedAppContext&>(app_context);
AndroidWindow* current_activity_window =
android_app_context.GetActivityWindow();
assert_null(current_activity_window);
if (current_activity_window) {
return nullptr;
}
auto window = std::make_unique<AndroidWindow>(app_context, title);
android_app_context.SetActivityWindow(window.get());
return std::move(window);
}
AndroidWindow::~AndroidWindow() {
AndroidWindowedAppContext& android_app_context =
static_cast<AndroidWindowedAppContext&>(app_context());
if (android_app_context.GetActivityWindow() == this) {
android_app_context.SetActivityWindow(nullptr);
}
}
std::unique_ptr<ui::MenuItem> MenuItem::Create(Type type,
const std::string& text,
const std::string& hotkey,
std::function<void()> callback) {
return std::make_unique<AndroidMenuItem>(type, text, hotkey, callback);
}
} // namespace ui
} // namespace xe

View File

@@ -0,0 +1,64 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2021 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_UI_WINDOW_ANDROID_H_
#define XENIA_UI_WINDOW_ANDROID_H_
#include "xenia/ui/menu_item.h"
#include "xenia/ui/window.h"
namespace xe {
namespace ui {
class AndroidWindow : public Window {
public:
// Many functions are left unimplemented because the layout is configured from
// XML and Java.
AndroidWindow(WindowedAppContext& app_context, const std::string& title)
: Window(app_context, title) {}
~AndroidWindow();
NativePlatformHandle native_platform_handle() const override {
return nullptr;
}
// TODO(Triang3l): ANativeWindow for Vulkan surface creation.
NativeWindowHandle native_handle() const override { return nullptr; }
void EnableMainMenu() override {}
void DisableMainMenu() override {}
bool SetIcon(const void* buffer, size_t size) override { return false; }
bool CaptureMouse() override { return false; }
bool ReleaseMouse() override { return false; }
int get_medium_dpi() const override { return 160; }
// TODO(Triang3l): Call the close event, which may finish the activity.
void Close() override {}
};
// Dummy for the menu item - menus are controlled by the layout.
// TODO(Triang3l): Make something like MenuItem work as the basic common action
// interface for Java buttons.
class AndroidMenuItem final : public MenuItem {
public:
AndroidMenuItem(Type type, const std::string& text, const std::string& hotkey,
std::function<void()> callback)
: MenuItem(type, text, hotkey, callback) {}
void EnableMenuItem(Window& window) override {}
void DisableMenuItem(Window& window) override {}
};
} // namespace ui
} // namespace xe
#endif // XENIA_UI_WINDOW_ANDROID_H_

View File

@@ -9,9 +9,12 @@
#include "xenia/ui/windowed_app_context_android.h"
#include <android/configuration.h>
#include <android/native_activity.h>
#include <cstdint>
#include "xenia/base/assert.h"
#include "xenia/base/main_android.h"
#include "xenia/ui/windowed_app.h"
namespace xe {
@@ -22,6 +25,8 @@ void AndroidWindowedAppContext::StartAppOnNativeActivityCreate(
[[maybe_unused]] size_t saved_state_size,
std::unique_ptr<WindowedApp> (*app_creator)(
WindowedAppContext& app_context)) {
// TODO(Triang3l): Pass the launch options from the Intent or the saved
// instance state.
AndroidWindowedAppContext* app_context =
new AndroidWindowedAppContext(activity);
// The pointer is now held by the Activity as its ANativeActivity::instance,
@@ -35,6 +40,8 @@ void AndroidWindowedAppContext::StartAppOnNativeActivityCreate(
AndroidWindowedAppContext::~AndroidWindowedAppContext() {
// TODO(Triang3l): Unregister activity callbacks.
activity_->instance = nullptr;
xe::ShutdownAndroidAppFromMainThread();
}
void AndroidWindowedAppContext::NotifyUILoopOfPendingFunctions() {
@@ -42,11 +49,21 @@ void AndroidWindowedAppContext::NotifyUILoopOfPendingFunctions() {
}
void AndroidWindowedAppContext::PlatformQuitFromUIThread() {
ANativeActivity_finish(activity);
ANativeActivity_finish(activity_);
}
AndroidWindowedAppContext::AndroidWindowedAppContext(ANativeActivity* activity)
: activity_(activity) {
int32_t api_level;
{
AConfiguration* configuration = AConfiguration_new();
AConfiguration_fromAssetManager(configuration, activity->assetManager);
api_level = AConfiguration_getSdkVersion(configuration);
AConfiguration_delete(configuration);
}
xe::InitializeAndroidAppFromMainThread(api_level);
activity_->instance = this;
// TODO(Triang3l): Register activity callbacks.
}
@@ -54,7 +71,7 @@ AndroidWindowedAppContext::AndroidWindowedAppContext(ANativeActivity* activity)
bool AndroidWindowedAppContext::InitializeApp(std::unique_ptr<WindowedApp> (
*app_creator)(WindowedAppContext& app_context)) {
assert_null(app_);
app_ = app_creator(this);
app_ = app_creator(*this);
if (!app_->OnInitialize()) {
app_->InvokeOnDestroy();
app_.reset();

View File

@@ -18,6 +18,7 @@
namespace xe {
namespace ui {
class AndroidWindow;
class WindowedApp;
class AndroidWindowedAppContext final : public WindowedAppContext {
@@ -39,6 +40,13 @@ class AndroidWindowedAppContext final : public WindowedAppContext {
void PlatformQuitFromUIThread() override;
// The single Window instance that will be receiving window callbacks.
// Multiple windows cannot be created as one activity or fragment can have
// only one layout. This window acts purely as a proxy between the activity
// and the Xenia logic.
AndroidWindow* GetActivityWindow() const { return activity_window_; }
void SetActivityWindow(AndroidWindow* window) { activity_window_ = window; }
private:
explicit AndroidWindowedAppContext(ANativeActivity* activity);
bool InitializeApp(std::unique_ptr<WindowedApp> (*app_creator)(
@@ -50,6 +58,8 @@ class AndroidWindowedAppContext final : public WindowedAppContext {
ANativeActivity* activity_;
std::unique_ptr<WindowedApp> app_;
AndroidWindow* activity_window_ = nullptr;
// TODO(Triang3l): The rest of the context, including quit handler (and the
// destructor) calling `finish` on the activity, UI looper notification
// posting, etc.

View File

@@ -0,0 +1,10 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2021 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
// Not needed - no single entry point, the event loop is polled by the OS.