Files
Xenia-Canary/src/xenia/ui/main_window.cc
2015-06-14 12:02:52 -05:00

181 lines
4.4 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/ui/main_window.h"
#include "xenia/base/clock.h"
#include "xenia/base/logging.h"
#include "xenia/base/threading.h"
#include "xenia/gpu/graphics_system.h"
#include "xenia/emulator.h"
#include "xenia/profiling.h"
namespace xe {
namespace ui {
const std::wstring kBaseTitle = L"xenia";
MainWindow::MainWindow(Emulator* emulator)
: PlatformWindow(kBaseTitle),
emulator_(emulator),
main_menu_(MenuItem::Type::kNormal),
fullscreen_(false) {}
MainWindow::~MainWindow() = default;
void MainWindow::Start() {
xe::threading::Fence fence;
loop_.Post([&]() {
xe::threading::set_name("Win32 Loop");
xe::Profiler::ThreadEnter("Win32 Loop");
if (!Initialize()) {
XEFATAL("Failed to initialize main window");
exit(1);
}
fence.Signal();
});
fence.Wait();
}
bool MainWindow::Initialize() {
if (!PlatformWindow::Initialize()) {
return false;
}
UpdateTitle();
on_key_down.AddListener([this](KeyEvent& e) {
bool handled = true;
switch (e.key_code()) {
case 0x73: { // VK_F4
emulator()->graphics_system()->RequestFrameTrace();
break;
}
case 0x74: { // VK_F5
emulator()->graphics_system()->ClearCaches();
break;
}
case 0x7A: { // VK_F11
ToggleFullscreen();
break;
}
case 0x1B: { // VK_ESCAPE
// Allow users to escape fullscreen (but not enter it)
if (fullscreen_) {
ToggleFullscreen();
}
}
case 0x6D: { // numpad minus
Clock::set_guest_time_scalar(Clock::guest_time_scalar() / 2.0);
UpdateTitle();
break;
}
case 0x6B: { // numpad plus
Clock::set_guest_time_scalar(Clock::guest_time_scalar() * 2.0);
UpdateTitle();
break;
}
case 0x0D: { // numpad enter
Clock::set_guest_time_scalar(1.0);
UpdateTitle();
break;
}
default: {
handled = false;
break;
}
}
e.set_handled(handled);
});
// Main menu
// FIXME: This code is really messy.
auto file = std::make_unique<PlatformMenu>(MenuItem::Type::kPopup, L"&File");
file->AddChild(std::make_unique<PlatformMenu>(
MenuItem::Type::kString, Commands::IDC_FILE_OPEN, L"&Open"));
main_menu_.AddChild(std::move(file));
// Window submenu
auto window =
std::make_unique<PlatformMenu>(MenuItem::Type::kPopup, L"&Window");
window->AddChild(std::make_unique<PlatformMenu>(
MenuItem::Type::kString, Commands::IDC_WINDOW_FULLSCREEN,
L"Fullscreen\tF11"));
main_menu_.AddChild(std::move(window));
SetMenu(&main_menu_);
Resize(1280, 720);
return true;
}
void MainWindow::UpdateTitle() {
std::wstring title(kBaseTitle);
if (Clock::guest_time_scalar() != 1.0) {
title += L" (@";
title += xe::to_wstring(std::to_string(Clock::guest_time_scalar()));
title += L"x)";
}
set_title(title);
}
void MainWindow::ToggleFullscreen() {
fullscreen_ = !fullscreen_;
SetFullscreen(fullscreen_);
}
void MainWindow::OnClose() {
loop_.Quit();
// TODO(benvanik): proper exit.
XELOGI("User-initiated death!");
exit(1);
}
void MainWindow::OnCommand(int id) {
switch (id) {
// TODO: Setup delegates to MenuItems so we don't have to do this
case IDC_WINDOW_FULLSCREEN: {
ToggleFullscreen();
break;
}
}
}
X_STATUS MainWindow::LaunchPath(std::wstring path) {
X_STATUS result;
// Launch based on file type.
// This is a silly guess based on file extension.
// NOTE: this blocks!
auto file_system_type = emulator_->file_system()->InferType(path);
switch (file_system_type) {
case kernel::fs::FileSystemType::STFS_TITLE:
result = emulator_->LaunchSTFSTitle(path);
break;
case kernel::fs::FileSystemType::XEX_FILE:
result = emulator_->LaunchXexFile(path);
break;
case kernel::fs::FileSystemType::DISC_IMAGE:
result = emulator_->LaunchDiscImage(path);
break;
}
return result;
}
} // namespace ui
} // namespace xe