Lots of Windows fixes; add D3D12; more boo decoupling

This commit is contained in:
Luke Street 2022-02-22 00:53:57 -05:00
parent 54330e43b6
commit c33674b9ab
55 changed files with 380 additions and 261 deletions

View File

@ -605,12 +605,12 @@ void CNESEmulator::ProcessUserInput(const CFinalInput& input, int) {
if (GetPasswordEntryState() != EPasswordEntryState::NotPasswordScreen) {
// Don't swap A/B
inValReads[BUTTON_A] = input.DA() || input.DSpecialKey(boo::ESpecialKey::Enter) ||
input.DMouseButton(boo::EMouseButton::Primary);
inValReads[BUTTON_B] = input.DB() || input.DSpecialKey(boo::ESpecialKey::Esc);
inValReads[BUTTON_A] = input.DA() || input.DSpecialKey(aurora::SpecialKey::Enter) ||
input.DMouseButton(EMouseButton::Primary);
inValReads[BUTTON_B] = input.DB() || input.DSpecialKey(aurora::SpecialKey::Esc);
} else {
// Prime controls (B jumps, A shoots)
inValReads[BUTTON_B] = input.DA() || input.DY() || input.DMouseButton(boo::EMouseButton::Primary);
inValReads[BUTTON_B] = input.DA() || input.DY() || input.DMouseButton(EMouseButton::Primary);
inValReads[BUTTON_A] = input.DB() || input.DX() || input.DKey(' ');
}
@ -619,7 +619,7 @@ void CNESEmulator::ProcessUserInput(const CFinalInput& input, int) {
inValReads[BUTTON_LEFT] = input.DDPLeft() || input.DLALeft();
inValReads[BUTTON_RIGHT] = input.DDPRight() || input.DLARight();
inValReads[BUTTON_SELECT] = input.DZ() || input.DKey('\t');
inValReads[BUTTON_START] = input.DStart() || input.DSpecialKey(boo::ESpecialKey::Esc);
inValReads[BUTTON_START] = input.DStart() || input.DSpecialKey(aurora::SpecialKey::Esc);
}
bool CNESEmulator::CheckForGameOver(const u8* vram, u8* passwordOut) {

View File

@ -490,7 +490,7 @@ void CAutoMapper::ProcessMapRotateInput(const CFinalInput& input, const CStateMa
std::array<float, 4> dirs{};
bool mouseHeld = false;
if (const auto& kbm = input.GetKBM()) {
if (kbm->m_mouseButtons[size_t(boo::EMouseButton::Primary)]) {
if (kbm->m_mouseButtons[size_t(EMouseButton::Primary)]) {
mouseHeld = true;
if (float(m_mouseDelta.x()) < 0.f)
dirs[3] = -m_mouseDelta.x();
@ -662,8 +662,8 @@ void CAutoMapper::ProcessMapPanInput(const CFinalInput& input, const CStateManag
bool mouseHeld = false;
if (const auto& kbm = input.GetKBM()) {
if (kbm->m_mouseButtons[size_t(boo::EMouseButton::Middle)] ||
kbm->m_mouseButtons[size_t(boo::EMouseButton::Secondary)]) {
if (kbm->m_mouseButtons[size_t(EMouseButton::Middle)] ||
kbm->m_mouseButtons[size_t(EMouseButton::Secondary)]) {
mouseHeld = true;
if (float(m_mouseDelta.x()) < 0.f)
right += -m_mouseDelta.x();
@ -789,10 +789,10 @@ void CAutoMapper::SetShouldRotatingSoundBePlaying(bool shouldBePlaying) {
void CAutoMapper::ProcessMapScreenInput(const CFinalInput& input, CStateManager& mgr) {
zeus::CMatrix3f camRot = xa8_renderStates[0].x8_camOrientation.toTransform().buildMatrix3f();
if (x1bc_state == EAutoMapperState::MapScreen) {
if ((input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter)) && x328_ == 0 && HasCurrentMapUniverseWorld())
if ((input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter)) && x328_ == 0 && HasCurrentMapUniverseWorld())
BeginMapperStateTransition(EAutoMapperState::MapScreenUniverse, mgr);
} else if (x1bc_state == EAutoMapperState::MapScreenUniverse &&
(input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter))) {
(input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter))) {
const CMapUniverse::CMapWorldData& mapuWld = x8_mapu->GetMapWorldData(x9c_worldIdx);
zeus::CVector3f pointLocal = mapuWld.GetWorldTransform().inverse() * xa8_renderStates[0].x20_areaPoint;
if (mapuWld.GetWorldAssetId() != g_GameState->CurrentWorldAssetId()) {
@ -807,7 +807,7 @@ void CAutoMapper::ProcessMapScreenInput(const CFinalInput& input, CStateManager&
}
x2f4_aButtonPos = 0;
if (input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter))
if (input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter))
x2f4_aButtonPos = 1;
if (IsInPlayerControlState()) {
@ -1084,7 +1084,7 @@ void CAutoMapper::ProcessControllerInput(const CFinalInput& input, CStateManager
}
}
if (input.PZ() || input.PKey('\t') || input.PB() || input.PSpecialKey(boo::ESpecialKey::Esc)) {
if (input.PZ() || input.PKey('\t') || input.PB() || input.PSpecialKey(aurora::SpecialKey::Esc)) {
if (x328_ == 0) {
if (CanLeaveMapScreenInternal(mgr)) {
LeaveMapScreen(mgr);

View File

@ -181,8 +181,8 @@ private:
std::optional<zeus::CVector2f> m_lastMouseCoord;
zeus::CVector2f m_mouseDelta;
boo::SScrollDelta m_lastAccumScroll;
boo::SScrollDelta m_mapScroll;
SScrollDelta m_lastAccumScroll;
SScrollDelta m_mapScroll;
template <class T>
static void SetResLockState(T& list, bool lock) {

View File

@ -9,8 +9,6 @@
#include "Runtime/Graphics/Shaders/CMapSurfaceShader.hpp"
#include "Runtime/RetroTypes.hpp"
//#include <boo/graphicsdev/IGraphicsDataFactory.hpp>
#include <zeus/CAABox.hpp>
#include <zeus/CVector3f.hpp>

View File

@ -6,10 +6,7 @@
#ifndef _WIN32
#include <sys/stat.h>
#else
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
struct _stat64;
#endif
#include "Runtime/GCNTypes.hpp"

View File

@ -12,11 +12,21 @@
#include <cstring>
#include <ctime>
#ifdef WIN32
#include <windows.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <Windows.h>
#include <nowide/stackstring.hpp>
#ifndef _WIN32_IE
#define _WIN32_IE 0x0400
#endif
#include <shlobj.h>
#include <ShlObj.h>
#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
#endif
#endif
#include "Runtime/CBasics.hpp"
@ -191,7 +201,7 @@ void CBasics::Swap8Bytes(u8* v) {
#if __GNUC__
*val = __builtin_bswap64(*val);
#elif _WIN32
*val = _byteswap_uint64(val);
*val = _byteswap_uint64(*val);
#else
*val = ((val & 0xFF00000000000000ULL) >> 56) | ((val & 0x00FF000000000000ULL) >> 40) |
((val & 0x0000FF0000000000ULL) >> 24) | ((val & 0x000000FF00000000ULL) >> 8) |

View File

@ -446,7 +446,7 @@ void CGameOptions::TryRestoreDefaults(const CFinalInput& input, int category, in
if (options.second[option].option != EGameOption::RestoreDefaults)
return;
if (!forceRestore && !input.PA() && !input.PSpecialKey(boo::ESpecialKey::Enter))
if (!forceRestore && !input.PA() && !input.PSpecialKey(aurora::SpecialKey::Enter))
return;
if (frontend) {

View File

@ -3,6 +3,16 @@
#include <numeric>
#include <iostream>
#ifdef WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <Windows.h>
#endif
#include "logvisor/logvisor.hpp"
#include "ImGuiEngine.hpp"
@ -156,7 +166,7 @@ private:
// m_imguiCallback.resized(rect, sync);
}
void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) override {
void mouseDown(const boo::SWindowCoord& coord, EMouseButton button, boo::EModifierKey mods) override {
// if (!ImGuiWindowCallback::m_mouseCaptured && g_mainMP1) {
// if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) {
// as->mouseDown(coord, button, mods);
@ -165,7 +175,7 @@ private:
// m_imguiCallback.mouseDown(coord, button, mods);
}
void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) override {
void mouseUp(const boo::SWindowCoord& coord, EMouseButton button, boo::EModifierKey mods) override {
if (g_mainMP1) {
if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) {
as->mouseUp(coord, button, mods);
@ -214,23 +224,23 @@ private:
// m_imguiCallback.charKeyUp(charCode, mods);
}
void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat) override {
void specialKeyDown(aurora::SpecialKey key, boo::EModifierKey mods, bool isRepeat) override {
// if (!ImGuiWindowCallback::m_keyboardCaptured && g_mainMP1) {
// if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) {
// as->specialKeyDown(key, mods, isRepeat);
// }
// }
// if (True(mods & boo::EModifierKey::Alt)) {
// if (key == boo::ESpecialKey::Enter) {
// if (key == aurora::SpecialKey::Enter) {
// m_fullscreenToggleRequested = true;
// } else if (key == boo::ESpecialKey::F4) {
// } else if (key == aurora::SpecialKey::F4) {
// m_windowInvalid = true;
// }
// }
// m_imguiCallback.specialKeyDown(key, mods, isRepeat);
}
void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods) override {
void specialKeyUp(aurora::SpecialKey key, boo::EModifierKey mods) override {
// if (g_mainMP1) {
// if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) {
// as->specialKeyUp(key, mods);
@ -272,7 +282,7 @@ public:
Application(FileStoreManager& fileMgr, CVarManager& cvarMgr, CVarCommons& cvarCmns)
: m_fileMgr(fileMgr), m_cvarManager(cvarMgr), m_cvarCommons(cvarCmns), m_imGuiConsole(cvarMgr, cvarCmns) {}
void onAppLaunched() override {
void onAppLaunched() noexcept override {
initialize();
auto backend = static_cast<std::string>(aurora::get_backend_string());

View File

@ -2,11 +2,23 @@
#include "Runtime/GameGlobalObjects.hpp"
#include "Runtime/IMain.hpp"
#include "Runtime/CBasics.hpp"
#include <shlobj.h>
#include <ShlObj.h>
#include <SDL_filesystem.h>
namespace metaforce {
static std::optional<std::string> GetPrefPath(const char* app) {
char* path = SDL_GetPrefPath(nullptr, app);
if (path == nullptr) {
return {};
}
std::string str{path};
SDL_free(path);
return str;
}
#if WINDOWS_STORE
using namespace Windows::Storage;
#endif
@ -53,8 +65,8 @@ std::string CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlot slot) {
path += fmt::format(FMT_STRING("/GC/MemoryCard{}.USA.raw"), slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B');
hecl::Sstat theStat;
if (hecl::Stat(path.c_str(), &theStat) || !S_ISREG(theStat.st_mode))
struct _stat64 theStat{};
if (_stat64(path.c_str(), &theStat) || !S_ISREG(theStat.st_mode))
return {};
return path;
@ -101,26 +113,33 @@ std::string CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot slot, bool do
#endif
path += "/GC";
if (hecl::RecursiveMakeDir(path.c_str()) < 0)
if (CBasics::RecursiveMakeDir(path.c_str()) < 0)
return {};
path += fmt::format(FMT_STRING("/MemoryCard{}.USA.raw"), slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B');
const auto fp = hecl::FopenUnique(path.c_str(), "wb");
const nowide::wstackstring wpath(path);
FILE* fp = _wfopen(wpath.get(), L"wb");
if (fp == nullptr) {
return {};
}
fclose(fp);
return path;
} else {
std::string path = _GetDolphinCardPath(slot);
hecl::SanitizePath(path);
if (path.find('/') == std::string::npos) {
path = hecl::GetcwdStr() + "/" + _GetDolphinCardPath(slot);
auto prefPath = GetPrefPath("Metaforce");
if (!prefPath) {
return {};
}
path = *prefPath + _GetDolphinCardPath(slot);
}
std::string tmpPath = path.substr(0, path.find_last_of("/"));
hecl::RecursiveMakeDir(tmpPath.c_str());
const auto fp = hecl::FopenUnique(path.c_str(), "wb");
std::string tmpPath = path.substr(0, path.find_last_of('/'));
CBasics::RecursiveMakeDir(tmpPath.c_str());
const nowide::wstackstring wpath(path);
FILE* fp = _wfopen(wpath.get(), L"wb");
if (fp) {
fclose(fp);
return path;
}
}

View File

@ -2,7 +2,10 @@
#include "Runtime/CBasics.hpp"
#include "logvisor/logvisor.hpp"
#include <logvisor/logvisor.hpp>
#if _WIN32
#include <nowide/convert.hpp>
#endif
#if _WIN32
#include <ShlObj.h>

View File

@ -15,7 +15,6 @@
#include <algorithm>
#include <array>
#include <boo/System.hpp>
#include <logvisor/logvisor.hpp>
#include <zeus/CColor.hpp>
#include <zeus/CUnitVector.hpp>

View File

@ -9,11 +9,7 @@
#include "GX.hpp"
//#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
//#include <boo/graphicsdev/IGraphicsDataFactory.hpp>
#include "ConsoleVariables/CVar.hpp"
//#include <hecl/Runtime.hpp>
#include <zeus/CColor.hpp>
#include <zeus/CTransform.hpp>

View File

@ -6,11 +6,6 @@
#include "Runtime/rstl.hpp"
#include "Runtime/Graphics/CGraphics.hpp"
//#include <boo/graphicsdev/IGraphicsDataFactory.hpp>
//#include <hecl/UniformBufferPool.hpp>
//#include <hecl/VertexBufferPool.hpp>
#include <zeus/CColor.hpp>
#include <zeus/CVector2f.hpp>
#include <zeus/CVector3f.hpp>

View File

@ -9,8 +9,6 @@
#include "Runtime/Streams/IOStreams.hpp"
#include "Runtime/Graphics/CGraphics.hpp"
//#include <boo/graphicsdev/IGraphicsDataFactory.hpp>
namespace metaforce {
class CVParamTransfer;
class CTextureInfo;

View File

@ -216,7 +216,7 @@ bool CGuiFrame::ProcessMouseInput(const CFinalInput& input, const CGuiWidgetDraw
m_lastMouseOverWidget = hit;
}
if (hit && hit->m_lastScroll) {
boo::SScrollDelta delta = kbm->m_accumScroll - *hit->m_lastScroll;
SScrollDelta delta = kbm->m_accumScroll - *hit->m_lastScroll;
hit->m_lastScroll.emplace(kbm->m_accumScroll);
if (!delta.isZero()) {
hit->m_integerScroll += delta;
@ -226,7 +226,7 @@ bool CGuiFrame::ProcessMouseInput(const CFinalInput& input, const CGuiWidgetDraw
hit->m_integerScroll.delta[1] -= std::trunc(hit->m_integerScroll.delta[1]);
}
}
if (!m_inMouseDown && kbm->m_mouseButtons[size_t(boo::EMouseButton::Primary)]) {
if (!m_inMouseDown && kbm->m_mouseButtons[size_t(EMouseButton::Primary)]) {
m_inMouseDown = true;
m_inCancel = false;
m_mouseDownWidget = hit;
@ -234,7 +234,7 @@ bool CGuiFrame::ProcessMouseInput(const CFinalInput& input, const CGuiWidgetDraw
m_mouseDownCb(hit, false);
if (hit)
return true;
} else if (m_inMouseDown && !kbm->m_mouseButtons[size_t(boo::EMouseButton::Primary)]) {
} else if (m_inMouseDown && !kbm->m_mouseButtons[size_t(EMouseButton::Primary)]) {
m_inMouseDown = false;
m_inCancel = false;
if (m_mouseDownWidget == m_lastMouseOverWidget) {

View File

@ -10,8 +10,6 @@
#include "Runtime/GuiSys/CGuiWidgetIdDB.hpp"
#include "Runtime/GuiSys/CGuiWidget.hpp"
#include <boo/IWindow.hpp>
namespace metaforce {
class CBooModel;
class CGuiCamera;
@ -54,7 +52,7 @@ private:
std::function<void(CGuiWidget*, CGuiWidget*)> m_mouseOverChangeCb;
std::function<void(CGuiWidget*, bool)> m_mouseDownCb;
std::function<void(CGuiWidget*, bool)> m_mouseUpCb;
std::function<void(CGuiWidget*, const boo::SScrollDelta&, int, int)> m_mouseScrollCb;
std::function<void(CGuiWidget*, const SScrollDelta&, int, int)> m_mouseScrollCb;
public:
CGuiFrame(CAssetId id, CGuiSys& sys, int a, int b, int c, CSimplePool* sp);
@ -87,7 +85,7 @@ public:
}
void SetMouseDownCallback(std::function<void(CGuiWidget*, bool)>&& cb) { m_mouseDownCb = std::move(cb); }
void SetMouseUpCallback(std::function<void(CGuiWidget*, bool)>&& cb) { m_mouseUpCb = std::move(cb); }
void SetMouseScrollCallback(std::function<void(CGuiWidget*, const boo::SScrollDelta&, int, int)>&& cb) {
void SetMouseScrollCallback(std::function<void(CGuiWidget*, const SScrollDelta&, int, int)>&& cb) {
m_mouseScrollCb = std::move(cb);
}

View File

@ -67,9 +67,9 @@ bool CGuiSliderGroup::TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVect
}
void CGuiSliderGroup::ProcessUserInput(const CFinalInput& input) {
if (input.DMouseButton(boo::EMouseButton::Primary) && m_mouseInside)
if (input.DMouseButton(EMouseButton::Primary) && m_mouseInside)
m_mouseDown = true;
else if (!input.DMouseButton(boo::EMouseButton::Primary))
else if (!input.DMouseButton(EMouseButton::Primary))
m_mouseDown = false;
if (input.DLALeft()) {
StartDecreasing();

View File

@ -32,9 +32,9 @@ CGuiTableGroup::CGuiTableGroup(const CGuiWidgetParms& parms, int elementCount, i
, xd0_selectWraparound(selectWraparound) {}
void CGuiTableGroup::ProcessUserInput(const CFinalInput& input) {
if (input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter)) {
if (input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter)) {
DoAdvance();
} else if (input.PB() || input.PSpecialKey(boo::ESpecialKey::Esc)) {
} else if (input.PB() || input.PSpecialKey(aurora::SpecialKey::Esc)) {
DoCancel();
} else {
bool decrement;

View File

@ -7,8 +7,7 @@
#include "Runtime/GCNTypes.hpp"
#include "Runtime/Streams/IOStreams.hpp"
#include "Runtime/GuiSys/CGuiObject.hpp"
#include <boo/IWindow.hpp>
#include "Runtime/Input/CKeyboardMouseController.hpp"
#include <zeus/CColor.hpp>
#include <zeus/CTransform.hpp>
@ -84,8 +83,8 @@ protected:
bool xb7_25_ : 1 = true;
bool m_mouseActive : 1 = false;
std::optional<boo::SScrollDelta> m_lastScroll;
boo::SScrollDelta m_integerScroll;
std::optional<SScrollDelta> m_lastScroll;
SScrollDelta m_integerScroll;
std::string m_name;

View File

@ -82,7 +82,7 @@ void CScanDisplay::ProcessInput(const CFinalInput& input) {
return;
if (xc_state == EScanState::DownloadComplete && x1a4_xAlpha == 0.f) {
if (input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter) || input.PMouseButton(boo::EMouseButton::Primary)) {
if (input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary)) {
if (xa8_message->TextSupport().GetCurTime() < xa8_message->TextSupport().GetTotalAnimationTime()) {
xa8_message->TextSupport().SetCurTime(xa8_message->TextSupport().GetTotalAnimationTime());
} else {
@ -94,7 +94,7 @@ void CScanDisplay::ProcessInput(const CFinalInput& input) {
} else if (xc_state == EScanState::ViewingScan) {
int oldCounter = x1ac_pageCounter;
int totalPages = xac_scrollMessage->TextSupport().GetTotalPageCount();
if ((input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter) || input.PMouseButton(boo::EMouseButton::Primary)) &&
if ((input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary)) &&
totalPages != -1) {
CGuiTextSupport& supp = !x1ac_pageCounter ? xa8_message->TextSupport() : xac_scrollMessage->TextSupport();
if (supp.GetCurTime() < supp.GetTotalAnimationTime())

View File

@ -9,11 +9,6 @@
#include "Runtime/GuiSys/CFontImageDef.hpp"
#include "Runtime/GuiSys/CGuiWidget.hpp"
//#include <boo/graphicsdev/IGraphicsDataFactory.hpp>
//
//#include <hecl/UniformBufferPool.hpp>
//#include <hecl/VertexBufferPool.hpp>
#include <zeus/CColor.hpp>
#include <zeus/CMatrix4f.hpp>
#include <zeus/CVector2f.hpp>

View File

@ -6,7 +6,6 @@
#include <amuse/amuse.hpp>
#include <boo/audiodev/IAudioVoiceEngine.hpp>
#include <boo/boo.hpp>
namespace metaforce {
class Console;

View File

@ -74,7 +74,7 @@ struct CFinalInput {
std::optional<CKeyboardMouseControllerData> m_kbm;
std::array<bool, 256> m_PCharKeys{};
std::array<bool, 26> m_PSpecialKeys{};
std::array<bool, size_t(aurora::SpecialKey::MAX)> m_PSpecialKeys{};
std::array<bool, 6> m_PMouseButtons{};
float m_leftMul = 1.f;
@ -173,14 +173,14 @@ struct CFinalInput {
CFinalInput ScaleAnalogueSticks(float leftDiv, float rightDiv) const;
bool PKey(char k) const { return m_kbm && m_PCharKeys[size_t(k)]; }
bool PSpecialKey(boo::ESpecialKey k) const { return m_kbm && m_PSpecialKeys[size_t(k)]; }
bool PMouseButton(boo::EMouseButton k) const { return m_kbm && m_PMouseButtons[size_t(k)]; }
bool PSpecialKey(aurora::SpecialKey k) const { return m_kbm && m_PSpecialKeys[size_t(k)]; }
bool PMouseButton(EMouseButton k) const { return m_kbm && m_PMouseButtons[size_t(k)]; }
bool DKey(char k) const { return m_kbm && m_kbm->m_charKeys[size_t(k)]; }
bool DSpecialKey(boo::ESpecialKey k) const { return m_kbm && m_kbm->m_specialKeys[size_t(k)]; }
bool DMouseButton(boo::EMouseButton k) const { return m_kbm && m_kbm->m_mouseButtons[size_t(k)]; }
bool DSpecialKey(aurora::SpecialKey k) const { return m_kbm && m_kbm->m_specialKeys[size_t(k)]; }
bool DMouseButton(EMouseButton k) const { return m_kbm && m_kbm->m_mouseButtons[size_t(k)]; }
float AKey(char k) const { return DKey(k) ? 1.f : 0.f; }
float ASpecialKey(boo::ESpecialKey k) const { return DSpecialKey(k) ? 1.f : 0.f; }
float AMouseButton(boo::EMouseButton k) const { return DMouseButton(k) ? 1.f : 0.f; }
float ASpecialKey(aurora::SpecialKey k) const { return DSpecialKey(k) ? 1.f : 0.f; }
float AMouseButton(EMouseButton k) const { return DMouseButton(k) ? 1.f : 0.f; }
const std::optional<CKeyboardMouseControllerData>& GetKBM() const { return m_kbm; }
};

View File

@ -2,7 +2,9 @@
#include "Runtime/CArchitectureMessage.hpp"
#include "Runtime/CArchitectureQueue.hpp"
#include "imgui/magic_enum.hpp"
#include <magic_enum.hpp>
namespace metaforce {
void CInputGenerator::Update(float dt, CArchitectureQueue& queue) {
@ -49,8 +51,7 @@ void CInputGenerator::controllerAdded(uint32_t which) noexcept {
}
void CInputGenerator::controllerRemoved(uint32_t which) noexcept {
auto* it =
std::find_if(m_state.begin(), m_state.end(), [&which](const auto& s) { return s.m_which == which; });
auto it = std::find_if(m_state.begin(), m_state.end(), [&which](const auto& s) { return s.m_which == which; });
if (it == m_state.end()) {
return;
}

View File

@ -7,8 +7,6 @@
#include "Runtime/Input/CFinalInput.hpp"
#include "Runtime/Input/CKeyboardMouseController.hpp"
#include <boo/boo.hpp>
namespace metaforce {
class CArchitectureQueue;
@ -58,14 +56,14 @@ public:
* at the start of each frame, invoking these methods. No atomic locking
* is necessary, only absolute state tracking. */
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton button, boo::EModifierKey) {
void mouseDown(const SWindowCoord&, EMouseButton button, EModifierKey) {
m_data.m_mouseButtons[size_t(button)] = true;
}
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton button, boo::EModifierKey) {
void mouseUp(const SWindowCoord&, EMouseButton button, EModifierKey) {
m_data.m_mouseButtons[size_t(button)] = false;
}
void mouseMove(const boo::SWindowCoord& coord) { m_data.m_mouseCoord = coord; }
void scroll(const boo::SWindowCoord&, const boo::SScrollDelta& scroll) { m_data.m_accumScroll += scroll; }
void mouseMove(const SWindowCoord& coord) { m_data.m_mouseCoord = coord; }
void scroll(const SWindowCoord&, const SScrollDelta& scroll) { m_data.m_accumScroll += scroll; }
void charKeyDown(uint8_t charCode, aurora::ModifierKey, bool) {
charCode = tolower(charCode);

View File

@ -3,17 +3,64 @@
#include <array>
#include <aurora/aurora.hpp>
#include <boo/IWindow.hpp>
namespace metaforce {
// TODO: copied from boo; should be rewritten and included from from aurora
enum class EMouseButton { None = 0, Primary = 1, Secondary = 2, Middle = 3, Aux1 = 4, Aux2 = 5 };
enum class EModifierKey {
None = 0,
Ctrl = 1 << 0,
Alt = 1 << 2,
Shift = 1 << 3,
Command = 1 << 4,
CtrlCommand = EModifierKey::Ctrl | EModifierKey::Command
};
ENABLE_BITWISE_ENUM(EModifierKey)
struct SWindowCoord {
std::array<int, 2> pixel;
std::array<int, 2> virtualPixel;
std::array<float, 2> norm;
};
struct SScrollDelta {
std::array<double, 2> delta{};
bool isFine = false; /* Use system-scale fine-scroll (for scrollable-trackpads) */
bool isAccelerated = false; /* System performs acceleration computation */
constexpr SScrollDelta operator+(const SScrollDelta& other) const noexcept {
SScrollDelta ret;
ret.delta[0] = delta[0] + other.delta[0];
ret.delta[1] = delta[1] + other.delta[1];
ret.isFine = isFine || other.isFine;
ret.isAccelerated = isAccelerated || other.isAccelerated;
return ret;
}
constexpr SScrollDelta operator-(const SScrollDelta& other) const noexcept {
SScrollDelta ret;
ret.delta[0] = delta[0] - other.delta[0];
ret.delta[1] = delta[1] - other.delta[1];
ret.isFine = isFine || other.isFine;
ret.isAccelerated = isAccelerated || other.isAccelerated;
return ret;
}
constexpr SScrollDelta& operator+=(const SScrollDelta& other) noexcept {
delta[0] += other.delta[0];
delta[1] += other.delta[1];
isFine |= other.isFine;
isAccelerated |= other.isAccelerated;
return *this;
}
constexpr void zeroOut() noexcept { delta = {}; }
constexpr bool isZero() const noexcept { return delta[0] == 0.0 && delta[1] == 0.0; }
};
struct CKeyboardMouseControllerData {
std::array<bool, 256> m_charKeys{};
std::array<bool, static_cast<size_t>(aurora::SpecialKey::MAX)> m_specialKeys{};
std::array<bool, 6> m_mouseButtons{};
aurora::ModifierKey m_modMask = aurora::ModifierKey::None;
boo::SWindowCoord m_mouseCoord;
boo::SScrollDelta m_accumScroll;
SWindowCoord m_mouseCoord;
SScrollDelta m_accumScroll;
};
} // namespace metaforce

View File

@ -145,75 +145,75 @@ constexpr std::array<FloatReturnFn, 24> skAnalogFuncs{
};
constexpr std::array<ControlMapper::EKBMFunctionList, 70> skKBMMapping{
ControlMapper::EKBMFunctionList::KeyPress + 'w', // Forward,
ControlMapper::EKBMFunctionList::KeyPress + 's', // Backward,
ControlMapper::EKBMFunctionList::KeyPress + 'a', // TurnLeft,
ControlMapper::EKBMFunctionList::KeyPress + 'd', // TurnRight,
ControlMapper::EKBMFunctionList::KeyPress + 'a', // StrafeLeft,
ControlMapper::EKBMFunctionList::KeyPress + 'd', // StrafeRight,
ControlMapper::EKBMFunctionList::KeyPress + 'a', // LookLeft,
ControlMapper::EKBMFunctionList::KeyPress + 'd', // LookRight,
ControlMapper::EKBMFunctionList::KeyPress + 's', // LookUp,
ControlMapper::EKBMFunctionList::KeyPress + 'w', // LookDown,
ControlMapper::EKBMFunctionList::KeyPress + ' ', // JumpOrBoost = 10,
ControlMapper::EKBMFunctionList::MousePress + boo::EMouseButton::Primary, // FireOrBomb = 11,
ControlMapper::EKBMFunctionList::MousePress + boo::EMouseButton::Secondary, // MissileOrPowerBomb = 12,
ControlMapper::EKBMFunctionList::KeyPress + 'c', // Morph,
ControlMapper::EKBMFunctionList::None, // AimUp,
ControlMapper::EKBMFunctionList::None, // AimDown,
ControlMapper::EKBMFunctionList::None, // CycleBeamUp,
ControlMapper::EKBMFunctionList::None, // CycleBeamDown,
ControlMapper::EKBMFunctionList::None, // CycleItem,
ControlMapper::EKBMFunctionList::KeyPress + '1', // PowerBeam,
ControlMapper::EKBMFunctionList::KeyPress + '3', // IceBeam,
ControlMapper::EKBMFunctionList::KeyPress + '2', // WaveBeam,
ControlMapper::EKBMFunctionList::KeyPress + '4', // PlasmaBeam,
ControlMapper::EKBMFunctionList::None, // ToggleHolster = 23,
ControlMapper::EKBMFunctionList::None, // OrbitClose,
ControlMapper::EKBMFunctionList::KeyPress + 'q', // OrbitFar,
ControlMapper::EKBMFunctionList::KeyPress + 'q', // OrbitObject,
ControlMapper::EKBMFunctionList::None, // OrbitSelect,
ControlMapper::EKBMFunctionList::None, // OrbitConfirm,
ControlMapper::EKBMFunctionList::KeyPress + 'a', // OrbitLeft,
ControlMapper::EKBMFunctionList::KeyPress + 'd', // OrbitRight,
ControlMapper::EKBMFunctionList::KeyPress + 'w', // OrbitUp,
ControlMapper::EKBMFunctionList::KeyPress + 's', // OrbitDown,
ControlMapper::EKBMFunctionList::KeyPress + 'e', // LookHold1,
ControlMapper::EKBMFunctionList::None, // LookHold2,
ControlMapper::EKBMFunctionList::None, // LookZoomIn,
ControlMapper::EKBMFunctionList::None, // LookZoomOut,
ControlMapper::EKBMFunctionList::None, // AimHold,
ControlMapper::EKBMFunctionList::KeyPress + 's', // MapCircleUp,
ControlMapper::EKBMFunctionList::KeyPress + 'w', // MapCircleDown,
ControlMapper::EKBMFunctionList::KeyPress + 'a', // MapCircleLeft,
ControlMapper::EKBMFunctionList::KeyPress + 'd', // MapCircleRight,
ControlMapper::EKBMFunctionList::SpecialKeyPress + boo::ESpecialKey::Up, // MapMoveForward,
ControlMapper::EKBMFunctionList::SpecialKeyPress + boo::ESpecialKey::Down, // MapMoveBack,
ControlMapper::EKBMFunctionList::SpecialKeyPress + boo::ESpecialKey::Left, // MapMoveLeft,
ControlMapper::EKBMFunctionList::SpecialKeyPress + boo::ESpecialKey::Right, // MapMoveRight,
ControlMapper::EKBMFunctionList::KeyPress + 'e', // MapZoomIn,
ControlMapper::EKBMFunctionList::KeyPress + 'q', // MapZoomOut,
ControlMapper::EKBMFunctionList::KeyPress + 'e', // SpiderBall,
ControlMapper::EKBMFunctionList::KeyPress + 'q', // ChaseCamera,
ControlMapper::EKBMFunctionList::SpecialKeyPress + boo::ESpecialKey::Right, // XrayVisor = 50,
ControlMapper::EKBMFunctionList::SpecialKeyPress + boo::ESpecialKey::Down, // ThermoVisor = 51,
ControlMapper::EKBMFunctionList::SpecialKeyPress + boo::ESpecialKey::Left, // InviroVisor = 52,
ControlMapper::EKBMFunctionList::SpecialKeyPress + boo::ESpecialKey::Up, // NoVisor = 53,
ControlMapper::EKBMFunctionList::None, // VisorMenu,
ControlMapper::EKBMFunctionList::None, // VisorUp,
ControlMapper::EKBMFunctionList::None, // VisorDown,
ControlMapper::EKBMFunctionList::KeyPress + 'e', // ShowCrosshairs,
ControlMapper::EKBMFunctionList::None, // UNKNOWN
ControlMapper::EKBMFunctionList::None, // UseSheild = 0x3B,
ControlMapper::EKBMFunctionList::KeyPress + 'q', // ScanItem = 0x3C,
ControlMapper::EKBMFunctionList::None, // UNKNOWN
ControlMapper::EKBMFunctionList::None, // UNKNOWN
ControlMapper::EKBMFunctionList::None, // UNKNOWN
ControlMapper::EKBMFunctionList::None, // UNKNOWN
ControlMapper::EKBMFunctionList::KeyPress + 'q', // PreviousPauseScreen = 0x41,
ControlMapper::EKBMFunctionList::KeyPress + 'e', // NextPauseScreen = 0x42,
ControlMapper::EKBMFunctionList::None, // UNKNOWN,
ControlMapper::EKBMFunctionList::None, // None,
ControlMapper::EKBMFunctionList::KeyPress + 'w', // Forward,
ControlMapper::EKBMFunctionList::KeyPress + 's', // Backward,
ControlMapper::EKBMFunctionList::KeyPress + 'a', // TurnLeft,
ControlMapper::EKBMFunctionList::KeyPress + 'd', // TurnRight,
ControlMapper::EKBMFunctionList::KeyPress + 'a', // StrafeLeft,
ControlMapper::EKBMFunctionList::KeyPress + 'd', // StrafeRight,
ControlMapper::EKBMFunctionList::KeyPress + 'a', // LookLeft,
ControlMapper::EKBMFunctionList::KeyPress + 'd', // LookRight,
ControlMapper::EKBMFunctionList::KeyPress + 's', // LookUp,
ControlMapper::EKBMFunctionList::KeyPress + 'w', // LookDown,
ControlMapper::EKBMFunctionList::KeyPress + ' ', // JumpOrBoost = 10,
ControlMapper::EKBMFunctionList::MousePress + EMouseButton::Primary, // FireOrBomb = 11,
ControlMapper::EKBMFunctionList::MousePress + EMouseButton::Secondary, // MissileOrPowerBomb = 12,
ControlMapper::EKBMFunctionList::KeyPress + 'c', // Morph,
ControlMapper::EKBMFunctionList::None, // AimUp,
ControlMapper::EKBMFunctionList::None, // AimDown,
ControlMapper::EKBMFunctionList::None, // CycleBeamUp,
ControlMapper::EKBMFunctionList::None, // CycleBeamDown,
ControlMapper::EKBMFunctionList::None, // CycleItem,
ControlMapper::EKBMFunctionList::KeyPress + '1', // PowerBeam,
ControlMapper::EKBMFunctionList::KeyPress + '3', // IceBeam,
ControlMapper::EKBMFunctionList::KeyPress + '2', // WaveBeam,
ControlMapper::EKBMFunctionList::KeyPress + '4', // PlasmaBeam,
ControlMapper::EKBMFunctionList::None, // ToggleHolster = 23,
ControlMapper::EKBMFunctionList::None, // OrbitClose,
ControlMapper::EKBMFunctionList::KeyPress + 'q', // OrbitFar,
ControlMapper::EKBMFunctionList::KeyPress + 'q', // OrbitObject,
ControlMapper::EKBMFunctionList::None, // OrbitSelect,
ControlMapper::EKBMFunctionList::None, // OrbitConfirm,
ControlMapper::EKBMFunctionList::KeyPress + 'a', // OrbitLeft,
ControlMapper::EKBMFunctionList::KeyPress + 'd', // OrbitRight,
ControlMapper::EKBMFunctionList::KeyPress + 'w', // OrbitUp,
ControlMapper::EKBMFunctionList::KeyPress + 's', // OrbitDown,
ControlMapper::EKBMFunctionList::KeyPress + 'e', // LookHold1,
ControlMapper::EKBMFunctionList::None, // LookHold2,
ControlMapper::EKBMFunctionList::None, // LookZoomIn,
ControlMapper::EKBMFunctionList::None, // LookZoomOut,
ControlMapper::EKBMFunctionList::None, // AimHold,
ControlMapper::EKBMFunctionList::KeyPress + 's', // MapCircleUp,
ControlMapper::EKBMFunctionList::KeyPress + 'w', // MapCircleDown,
ControlMapper::EKBMFunctionList::KeyPress + 'a', // MapCircleLeft,
ControlMapper::EKBMFunctionList::KeyPress + 'd', // MapCircleRight,
ControlMapper::EKBMFunctionList::SpecialKeyPress + aurora::SpecialKey::Up, // MapMoveForward,
ControlMapper::EKBMFunctionList::SpecialKeyPress + aurora::SpecialKey::Down, // MapMoveBack,
ControlMapper::EKBMFunctionList::SpecialKeyPress + aurora::SpecialKey::Left, // MapMoveLeft,
ControlMapper::EKBMFunctionList::SpecialKeyPress + aurora::SpecialKey::Right, // MapMoveRight,
ControlMapper::EKBMFunctionList::KeyPress + 'e', // MapZoomIn,
ControlMapper::EKBMFunctionList::KeyPress + 'q', // MapZoomOut,
ControlMapper::EKBMFunctionList::KeyPress + 'e', // SpiderBall,
ControlMapper::EKBMFunctionList::KeyPress + 'q', // ChaseCamera,
ControlMapper::EKBMFunctionList::SpecialKeyPress + aurora::SpecialKey::Right, // XrayVisor = 50,
ControlMapper::EKBMFunctionList::SpecialKeyPress + aurora::SpecialKey::Down, // ThermoVisor = 51,
ControlMapper::EKBMFunctionList::SpecialKeyPress + aurora::SpecialKey::Left, // InviroVisor = 52,
ControlMapper::EKBMFunctionList::SpecialKeyPress + aurora::SpecialKey::Up, // NoVisor = 53,
ControlMapper::EKBMFunctionList::None, // VisorMenu,
ControlMapper::EKBMFunctionList::None, // VisorUp,
ControlMapper::EKBMFunctionList::None, // VisorDown,
ControlMapper::EKBMFunctionList::KeyPress + 'e', // ShowCrosshairs,
ControlMapper::EKBMFunctionList::None, // UNKNOWN
ControlMapper::EKBMFunctionList::None, // UseSheild = 0x3B,
ControlMapper::EKBMFunctionList::KeyPress + 'q', // ScanItem = 0x3C,
ControlMapper::EKBMFunctionList::None, // UNKNOWN
ControlMapper::EKBMFunctionList::None, // UNKNOWN
ControlMapper::EKBMFunctionList::None, // UNKNOWN
ControlMapper::EKBMFunctionList::None, // UNKNOWN
ControlMapper::EKBMFunctionList::KeyPress + 'q', // PreviousPauseScreen = 0x41,
ControlMapper::EKBMFunctionList::KeyPress + 'e', // NextPauseScreen = 0x42,
ControlMapper::EKBMFunctionList::None, // UNKNOWN,
ControlMapper::EKBMFunctionList::None, // None,
ControlMapper::EKBMFunctionList::None,
};
@ -307,10 +307,10 @@ static float KBToWASDY(const CKeyboardMouseControllerData& data) {
static float KBToArrowsX(const CKeyboardMouseControllerData& data) {
float retval = 0.0;
if (data.m_specialKeys[size_t(boo::ESpecialKey::Left)]) {
if (data.m_specialKeys[size_t(aurora::SpecialKey::Left)]) {
retval -= 1.0;
}
if (data.m_specialKeys[size_t(boo::ESpecialKey::Right)]) {
if (data.m_specialKeys[size_t(aurora::SpecialKey::Right)]) {
retval += 1.0;
}
return retval;
@ -318,10 +318,10 @@ static float KBToArrowsX(const CKeyboardMouseControllerData& data) {
static float KBToArrowsY(const CKeyboardMouseControllerData& data) {
float retval = 0.0;
if (data.m_specialKeys[size_t(boo::ESpecialKey::Down)]) {
if (data.m_specialKeys[size_t(aurora::SpecialKey::Down)]) {
retval -= 1.0;
}
if (data.m_specialKeys[size_t(boo::ESpecialKey::Up)]) {
if (data.m_specialKeys[size_t(aurora::SpecialKey::Up)]) {
retval += 1.0;
}
return retval;

View File

@ -2,7 +2,7 @@
#include <type_traits>
#include <boo/IWindow.hpp>
#include "Input/CKeyboardMouseController.hpp"
namespace metaforce {
struct CFinalInput;
@ -126,12 +126,12 @@ constexpr ControlMapper::EKBMFunctionList operator+(ControlMapper::EKBMFunctionL
return ControlMapper::EKBMFunctionList(static_cast<T>(a) + static_cast<T>(b));
}
constexpr ControlMapper::EKBMFunctionList operator+(ControlMapper::EKBMFunctionList a, boo::ESpecialKey b) {
constexpr ControlMapper::EKBMFunctionList operator+(ControlMapper::EKBMFunctionList a, aurora::SpecialKey b) {
using T = std::underlying_type_t<ControlMapper::EKBMFunctionList>;
return ControlMapper::EKBMFunctionList(static_cast<T>(a) + static_cast<T>(b));
}
constexpr ControlMapper::EKBMFunctionList operator+(ControlMapper::EKBMFunctionList a, boo::EMouseButton b) {
constexpr ControlMapper::EKBMFunctionList operator+(ControlMapper::EKBMFunctionList a, EMouseButton b) {
using T = std::underlying_type_t<ControlMapper::EKBMFunctionList>;
return ControlMapper::EKBMFunctionList(static_cast<T>(a) + static_cast<T>(b));
}

View File

@ -843,11 +843,11 @@ CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::ProcessUserInput(const CFinalInpu
case EUIType::LinkFailed:
case EUIType::LinkCompleteOrLinking:
case EUIType::TurnOffGBA:
if (input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter) || input.PMouseButton(boo::EMouseButton::Primary) ||
if (input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary) ||
tbAction == CFrontEndUITouchBar::EAction::Confirm) {
PlayAdvanceSfx();
SetUIText(NextLinkUI[size_t(x0_uiType)]);
} else if (input.PB() || input.PSpecialKey(boo::ESpecialKey::Esc) ||
} else if (input.PB() || input.PSpecialKey(aurora::SpecialKey::Esc) ||
tbAction == CFrontEndUITouchBar::EAction::Back) {
const EUIType prevUi = PrevLinkUI[size_t(x0_uiType)];
if (prevUi == EUIType::Empty) {
@ -1375,7 +1375,7 @@ void CFrontEndUI::SNesEmulatorFrame::ProcessUserInput(const CFinalInput& input,
switch (x0_mode) {
case EMode::Emulator:
x4_nesEmu->ProcessUserInput(input, 4);
if ((input.ControllerIdx() == 0 && input.PL()) || input.PSpecialKey(boo::ESpecialKey::Esc))
if ((input.ControllerIdx() == 0 && input.PL()) || input.PSpecialKey(aurora::SpecialKey::Esc))
SetMode(EMode::QuitNESMetroid);
break;
case EMode::SaveProgress:
@ -1717,7 +1717,7 @@ bool CFrontEndUI::SOptionsFrontEndFrame::ProcessUserInput(const CFinalInput& inp
if (sui)
sui->ProcessUserInput(input);
if (x1c_loadedFrame && x134_24_visible) {
if ((input.PB() || input.PSpecialKey(boo::ESpecialKey::Esc)) && x24_tablegroup_leftmenu->GetIsActive()) {
if ((input.PB() || input.PSpecialKey(aurora::SpecialKey::Esc)) && x24_tablegroup_leftmenu->GetIsActive()) {
x134_25_exitOptions = true;
CSfxManager::SfxStart(SFXfnt_back, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
} else {
@ -2186,8 +2186,8 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue&
if (x50_curScreen != x54_nextScreen) {
if (x54_nextScreen == EScreen::AttractMovie &&
(input.PStart() || input.PA() || input.PSpecialKey(boo::ESpecialKey::Esc) ||
input.PSpecialKey(boo::ESpecialKey::Enter) || input.PMouseButton(boo::EMouseButton::Primary) ||
(input.PStart() || input.PA() || input.PSpecialKey(aurora::SpecialKey::Esc) ||
input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary) ||
touchBarAction == CFrontEndUITouchBar::EAction::Start)) {
/* Player wants to return to opening credits from attract movie */
SetFadeBlackTimer(std::min(1.f, x58_fadeBlackTimer));
@ -2195,8 +2195,8 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue&
return;
}
if (input.PA() || input.PStart() || input.PSpecialKey(boo::ESpecialKey::Esc) ||
input.PSpecialKey(boo::ESpecialKey::Enter) || input.PMouseButton(boo::EMouseButton::Primary) ||
if (input.PA() || input.PStart() || input.PSpecialKey(aurora::SpecialKey::Esc) ||
input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary) ||
touchBarAction == CFrontEndUITouchBar::EAction::Start) {
if (x50_curScreen == EScreen::OpenCredits && x54_nextScreen == EScreen::Title && x58_fadeBlackTimer > 1.f) {
/* Player is too impatient to view opening credits */
@ -2207,8 +2207,8 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue&
}
} else {
if (x50_curScreen == EScreen::Title) {
if (input.PStart() || input.PA() || input.PSpecialKey(boo::ESpecialKey::Esc) ||
input.PSpecialKey(boo::ESpecialKey::Enter) || input.PMouseButton(boo::EMouseButton::Primary) ||
if (input.PStart() || input.PA() || input.PSpecialKey(aurora::SpecialKey::Esc) ||
input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary) ||
touchBarAction == CFrontEndUITouchBar::EAction::Start) {
if (x58_fadeBlackTimer < 30.f - g_tweakGame->GetPressStartDelay()) {
/* Proceed to file select UI */

View File

@ -132,7 +132,7 @@ void CInventoryScreen::ProcessControllerInput(const CFinalInput& input) {
if (const auto& kbm = input.GetKBM()) {
m_lastMouseCoord = zeus::CVector2f(kbm->m_mouseCoord.norm[0], kbm->m_mouseCoord.norm[1]);
m_lastAccumScroll = kbm->m_accumScroll;
m_dollScroll = boo::SScrollDelta();
m_dollScroll = SScrollDelta();
}
}
}
@ -141,7 +141,7 @@ void CInventoryScreen::ProcessControllerInput(const CFinalInput& input) {
if (input.PStart()) {
x19c_samusDoll->BeginViewInterpolate(false);
x198_26_exitPauseScreen = true;
} else if (input.PB() || input.PSpecialKey(boo::ESpecialKey::Esc)) {
} else if (input.PB() || input.PSpecialKey(aurora::SpecialKey::Esc)) {
x19c_samusDoll->BeginViewInterpolate(false);
}
}
@ -167,8 +167,8 @@ void CInventoryScreen::ProcessControllerInput(const CFinalInput& input) {
m_lastMouseCoord = mouseCoord;
mouseDelta.x() *= g_Viewport.aspect;
mouseDelta *= 100.f;
if (kbm->m_mouseButtons[size_t(boo::EMouseButton::Middle)] ||
kbm->m_mouseButtons[size_t(boo::EMouseButton::Secondary)]) {
if (kbm->m_mouseButtons[size_t(EMouseButton::Middle)] ||
kbm->m_mouseButtons[size_t(EMouseButton::Secondary)]) {
if (float(mouseDelta.x()) < 0.f)
moveRight += -mouseDelta.x();
else if (float(mouseDelta.x()) > 0.f)
@ -178,7 +178,7 @@ void CInventoryScreen::ProcessControllerInput(const CFinalInput& input) {
else if (float(mouseDelta.y()) > 0.f)
moveBack += mouseDelta.y();
}
if (kbm->m_mouseButtons[size_t(boo::EMouseButton::Primary)]) {
if (kbm->m_mouseButtons[size_t(EMouseButton::Primary)]) {
if (float(mouseDelta.x()) < 0.f)
circleRight += -mouseDelta.x();
else if (float(mouseDelta.x()) > 0.f)
@ -220,7 +220,7 @@ void CInventoryScreen::ProcessControllerInput(const CFinalInput& input) {
if (input.PLAUp() || m_bodyUpClicked)
newPage = std::max(oldPage - 1, 0);
else if (input.PLADown() || m_bodyDownClicked ||
((input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter) || m_bodyClicked) && !lastPage))
((input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter) || m_bodyClicked) && !lastPage))
newPage = std::min(oldPage + 1, totalCount - 1);
x174_textpane_body->TextSupport().SetPage(newPage);
if (oldPage != newPage)
@ -233,8 +233,8 @@ void CInventoryScreen::ProcessControllerInput(const CFinalInput& input) {
}
if (!x1ac_textLeaveRequested)
x1ac_textLeaveRequested =
input.PB() || input.PSpecialKey(boo::ESpecialKey::Esc) ||
((input.PA() || m_bodyClicked || input.PSpecialKey(boo::ESpecialKey::Enter)) && lastPage);
input.PB() || input.PSpecialKey(aurora::SpecialKey::Esc) ||
((input.PA() || m_bodyClicked || input.PSpecialKey(aurora::SpecialKey::Enter)) && lastPage);
x1ad_textViewing = !x1ac_textLeaveRequested;
} else {
x198_29_pulseTextArrowBottom = false;

View File

@ -24,8 +24,8 @@ class CInventoryScreen : public CPauseScreenBase {
bool x1ad_textViewing;
zeus::CVector2f m_lastMouseCoord;
boo::SScrollDelta m_lastAccumScroll;
boo::SScrollDelta m_dollScroll;
SScrollDelta m_lastAccumScroll;
SScrollDelta m_dollScroll;
void UpdateSamusDollPulses();
bool HasLeftInventoryItem(int idx) const;

View File

@ -338,7 +338,7 @@ void CLogBookScreen::ProcessControllerInput(const CFinalInput& input) {
if (input.PLAUp() || m_bodyUpClicked)
newPage = std::max(oldPage - 1, 0);
else if (input.PLADown() || m_bodyDownClicked ||
((input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter) || m_bodyClicked) && !lastPage))
((input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter) || m_bodyClicked) && !lastPage))
newPage = std::min(oldPage + 1, pageCount - 1);
x174_textpane_body->TextSupport().SetPage(newPage);
if (oldPage != newPage)
@ -352,8 +352,8 @@ void CLogBookScreen::ProcessControllerInput(const CFinalInput& input) {
if (!x260_26_exitTextScroll)
x260_26_exitTextScroll =
input.PB() || input.PSpecialKey(boo::ESpecialKey::Esc) ||
((input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter) || m_bodyClicked) && lastPage);
input.PB() || input.PSpecialKey(aurora::SpecialKey::Esc) ||
((input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter) || m_bodyClicked) && lastPage);
if (g_tweakGui->GetLatchArticleText())
x260_25_inTextScroll = !x260_26_exitTextScroll;

View File

@ -125,7 +125,7 @@ CIOWin::EMessageReturn CMFGame::OnMessage(const CArchitectureMessage& msg, CArch
if (input.ControllerIdx() == 0) {
const CEntity* cam = x14_stateManager->GetCameraManager()->GetCurrentCamera(*x14_stateManager);
TCastToConstPtr<CCinematicCamera> cineCam = cam;
if (input.PStart() || input.PSpecialKey(boo::ESpecialKey::Esc)) {
if (input.PStart() || input.PSpecialKey(aurora::SpecialKey::Esc)) {
if (cineCam && x14_stateManager->GetSkipCinematicSpecialFunction() != kInvalidUniqueId) {
CMidiManager::StopAll();
x28_skippedCineCam = cineCam->GetUniqueId();

View File

@ -18,7 +18,7 @@ CMessageScreen::CMessageScreen(CAssetId msg, float delayTime) : x74_delayTime(de
void CMessageScreen::ProcessControllerInput(const CFinalInput& input) {
if (!x18_loadedMsgScreen || x74_delayTime > 0.f ||
!(input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter) || input.PMouseButton(boo::EMouseButton::Primary)))
!(input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary)))
return;
if (x1c_textpane_message->TextSupport().GetCurTime() < x1c_textpane_message->TextSupport().GetTotalAnimationTime()) {

View File

@ -153,7 +153,7 @@ void COptionsScreen::ProcessControllerInput(const CFinalInput& input) {
CGameOptions::TryRestoreDefaults(input, x70_tablegroup_leftlog->GetUserSelection(), x1c_rightSel, false,
rightClicked);
if (x70_tablegroup_leftlog->GetUserSelection() == 4 &&
(input.PA() || leftClicked || input.PSpecialKey(boo::ESpecialKey::Enter)))
(input.PA() || leftClicked || input.PSpecialKey(aurora::SpecialKey::Enter)))
x19c_quitGame = std::make_unique<CQuitGameScreen>(EQuitType::QuitGame);
} else {
CPauseScreenBase::ResetMouseState();

View File

@ -202,7 +202,7 @@ void CPauseScreen::ProcessControllerInput(const CStateManager& mgr, const CFinal
if (InputEnabled()) {
bool invalid = x8_curSubscreen == ESubScreen::ToGame;
if (useInput.PStart() || ((useInput.PB() || useInput.PSpecialKey(boo::ESpecialKey::Esc)) && bExits) ||
if (useInput.PStart() || ((useInput.PB() || useInput.PSpecialKey(aurora::SpecialKey::Esc)) && bExits) ||
(x7c_screens[x78_activeIdx] && x7c_screens[x78_activeIdx]->ShouldExitPauseScreen())) {
CSfxManager::SfxStart(SFXui_pause_screen_exit, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
StartTransition(0.5f, mgr, ESubScreen::ToGame, 2);

View File

@ -169,7 +169,7 @@ void CPauseScreenBase::InitializeFrameGlue() {
x194_tablegroup_triple->SetMenuSelectionChangeCallback({});
x8_frame.SetMouseUpCallback([this](CGuiWidget* widget, bool cancel) { OnWidgetMouseUp(widget, cancel); });
x8_frame.SetMouseScrollCallback([this](CGuiWidget* widget, const boo::SScrollDelta& delta, int accumX, int accumY) {
x8_frame.SetMouseScrollCallback([this](CGuiWidget* widget, const SScrollDelta& delta, int accumX, int accumY) {
OnWidgetScroll(widget, delta, accumX, accumY);
});
}
@ -493,7 +493,7 @@ void CPauseScreenBase::OnWidgetMouseUp(CGuiWidget* widget, bool cancel) {
}
}
void CPauseScreenBase::OnWidgetScroll(CGuiWidget* widget, const boo::SScrollDelta& delta, int accumX, int accumY) {
void CPauseScreenBase::OnWidgetScroll(CGuiWidget* widget, const SScrollDelta& delta, int accumX, int accumY) {
if (!widget || accumY == 0)
return;
if (widget->GetParent() == x84_tablegroup_rightlog) {

View File

@ -99,7 +99,7 @@ protected:
void OnRightTableCancel(CGuiTableGroup* caller);
void OnWidgetMouseUp(CGuiWidget* widget, bool cancel);
void OnWidgetScroll(CGuiWidget* widget, const boo::SScrollDelta& delta, int accumX, int accumY);
void OnWidgetScroll(CGuiWidget* widget, const SScrollDelta& delta, int accumX, int accumY);
public:
static std::string GetImagePaneName(size_t i);

View File

@ -106,7 +106,7 @@ void CQuitGameScreen::ProcessUserInput(const CFinalInput& input) {
x10_loadedFrame->ProcessMouseInput(
input, CGuiWidgetDrawParms{1.f, zeus::CVector3f{0.f, 0.f, VerticalOffsets[size_t(x0_type)]}});
x10_loadedFrame->ProcessUserInput(input);
if ((input.PB() || input.PSpecialKey(boo::ESpecialKey::Esc)) && x0_type != EQuitType::ContinueFromLastSave) {
if ((input.PB() || input.PSpecialKey(aurora::SpecialKey::Esc)) && x0_type != EQuitType::ContinueFromLastSave) {
x18_action = EQuitAction::No;
}
}

View File

@ -76,6 +76,29 @@
#include <discord_rpc.h>
#endif
#if _WIN32
inline void* memmem(const void* haystack, size_t hlen, const void* needle, size_t nlen) {
int needle_first;
const uint8_t* p = static_cast<const uint8_t*>(haystack);
size_t plen = hlen;
if (!nlen)
return NULL;
needle_first = *(unsigned char*)needle;
while (plen >= nlen && (p = static_cast<const uint8_t*>(memchr(p, needle_first, plen - nlen + 1)))) {
if (!memcmp(p, needle, nlen))
return (void*)p;
p++;
plen = hlen - (p - static_cast<const uint8_t*>(haystack));
}
return NULL;
}
#endif
namespace metaforce::MP1 {
namespace {
struct AudioGroupInfo {

View File

@ -1,9 +1,5 @@
#pragma once
#ifndef MP1_USE_BOO
#define MP1_USE_BOO 0
#endif
#include "Runtime/IMain.hpp"
#include "Runtime/MP1/CTweaks.hpp"
#include "Runtime/MP1/CPlayMovie.hpp"
@ -114,12 +110,7 @@ public:
}
};
#if MP1_USE_BOO
class CGameArchitectureSupport : public boo::IWindowCallback
#else
class CGameArchitectureSupport
#endif
{
class CGameArchitectureSupport {
friend class CMain;
CMain& m_parent;
CArchitectureQueue x4_archQueue;
@ -133,12 +124,12 @@ class CGameArchitectureSupport
EAudioLoadStatus x88_audioLoadStatus = EAudioLoadStatus::Uninitialized;
std::vector<TToken<CAudioGroupSet>> x8c_pendingAudioGroups;
boo::SWindowRect m_windowRect;
aurora::WindowSize m_windowRect;
bool m_rectIsDirty = false;
void destroyed() { x4_archQueue.Push(MakeMsg::CreateRemoveAllIOWins(EArchMsgTarget::IOWinManager)); }
void resized(const boo::SWindowRect& rect) {
void resized(const aurora::WindowSize& rect) {
m_windowRect = rect;
m_rectIsDirty = true;
}
@ -147,17 +138,15 @@ public:
CGameArchitectureSupport(CMain& parent, boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend);
~CGameArchitectureSupport();
void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) {
void mouseDown(const SWindowCoord& coord, EMouseButton button, EModifierKey mods) {
x30_inputGenerator.mouseDown(coord, button, mods);
}
void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) {
void mouseUp(const SWindowCoord& coord, EMouseButton button, EModifierKey mods) {
x30_inputGenerator.mouseUp(coord, button, mods);
}
void mouseMove(const boo::SWindowCoord& coord) { x30_inputGenerator.mouseMove(coord); }
void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) {
x30_inputGenerator.scroll(coord, scroll);
}
void charKeyDown(uint8_t charCode, aurora::ModifierKey mods, bool isRepeat);
void mouseMove(const SWindowCoord& coord) { x30_inputGenerator.mouseMove(coord); }
void scroll(const SWindowCoord& coord, const SScrollDelta& scroll) { x30_inputGenerator.scroll(coord, scroll); }
void charKeyDown(uint8_t charCode, aurora::ModifierKey mods, bool isRepeat);
void charKeyUp(uint8_t charCode, aurora::ModifierKey mods) { x30_inputGenerator.charKeyUp(charCode, mods); }
void specialKeyDown(aurora::SpecialKey key, aurora::ModifierKey mods, bool isRepeat);
@ -173,7 +162,7 @@ public:
void Draw();
bool isRectDirty() const { return m_rectIsDirty; }
const boo::SWindowRect& getWindowRect() {
const aurora::WindowSize& getWindowRect() {
m_rectIsDirty = false;
return m_windowRect;
}
@ -181,25 +170,9 @@ public:
CIOWinManager& GetIOWinManager() { return x58_ioWinManager; }
};
#if MP1_USE_BOO
class CMain : public boo::IApplicationCallback,
public IMain
#else
class CMain : public IMain
#endif
{
class CMain : public IMain {
friend class CGameArchitectureSupport;
#if MP1_USE_BOO
boo::IWindow* mainWindow;
int appMain(boo::IApplication* app);
void appQuitting(boo::IApplication*) { xe8_b24_finished = true; }
void appFilesOpen(boo::IApplication*, const std::vector<std::string>& paths) {
fmt::print(stderr, FMT_STRING("OPENING: "));
for (const std::string& path : paths)
fprintf(stderr, "%s ", path.c_str());
fprintf(stderr, "\n");
}
#endif
private:
struct BooSetter {
BooSetter();
@ -279,8 +252,8 @@ public:
// int RsMain(int argc, char** argv, boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator&
// backend);
void Init(const FileStoreManager& storeMgr, CVarManager* cvarManager,
boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend) override;
void Init(const FileStoreManager& storeMgr, CVarManager* cvarManager, boo::IAudioVoiceEngine* voiceEngine,
amuse::IBackendVoiceAllocator& backend) override;
void WarmupShaders() override;
bool Proc(float dt) override;
void Draw() override;

View File

@ -6,7 +6,8 @@
namespace metaforce {
class COutputStream {
friend class coutput_stream_helper;
template <typename T>
friend void coutput_stream_helper(const T& t, COutputStream& out);
u32 x4_position = 0;
u32 x8_bufLen = 0;
u8* xc_ptr = nullptr;
@ -16,9 +17,9 @@ class COutputStream {
u8 x1c_scratch[96]{};
protected:
void DoFlush();
void DoPut(const u8* ptr, u32 len);
public:
COutputStream(u8* ptr, s32 unk);
virtual ~COutputStream();
@ -85,4 +86,4 @@ template <>
void coutput_stream_helper(const double& t, COutputStream& out);
template <>
void coutput_stream_helper(const std::string& t, COutputStream& out);
}
} // namespace metaforce

View File

@ -1,3 +1,6 @@
if (WIN32)
set(SDL_LIBC ON CACHE BOOL "Use the system C library" FORCE)
endif ()
add_subdirectory(../extern/SDL SDL2 EXCLUDE_FROM_ALL)
if (NOT MSVC)
target_compile_options(SDL2-static PRIVATE -Wno-implicit-fallthrough)
@ -35,6 +38,11 @@ if (APPLE)
target_compile_definitions(aurora PRIVATE DAWN_ENABLE_BACKEND_METAL)
target_sources(aurora PRIVATE lib/dawn/MetalBinding.mm)
set_source_files_properties(lib/dawn/MetalBinding.mm PROPERTIES COMPILE_FLAGS -fobjc-arc)
elseif (WIN32)
target_compile_definitions(aurora PRIVATE
DAWN_ENABLE_BACKEND_D3D12
DAWN_ENABLE_BACKEND_VULKAN)
target_sources(aurora PRIVATE lib/dawn/D3D12Binding.cpp lib/dawn/VulkanBinding.cpp)
else ()
target_compile_definitions(aurora PRIVATE
DAWN_ENABLE_BACKEND_VULKAN

View File

@ -0,0 +1,37 @@
#include "BackendBinding.hpp"
#include <SDL_syswm.h>
#include <dawn/native/D3D12Backend.h>
namespace aurora::gpu::utils {
class D3D12Binding : public BackendBinding {
public:
D3D12Binding(SDL_Window* window, WGPUDevice device) : BackendBinding(window, device) {}
uint64_t GetSwapChainImplementation() override {
if (m_swapChainImpl.userData == nullptr) {
CreateSwapChainImpl();
}
return reinterpret_cast<uint64_t>(&m_swapChainImpl);
}
WGPUTextureFormat GetPreferredSwapChainTextureFormat() override {
if (m_swapChainImpl.userData == nullptr) {
CreateSwapChainImpl();
}
return dawn::native::d3d12::GetNativeSwapChainPreferredFormat(&m_swapChainImpl);
}
private:
DawnSwapChainImplementation m_swapChainImpl{};
void CreateSwapChainImpl() {
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(m_window, &wmInfo);
m_swapChainImpl = dawn::native::d3d12::CreateNativeSwapChainImpl(m_device, wmInfo.info.win.window);
}
};
BackendBinding* CreateD3D12Binding(SDL_Window* window, WGPUDevice device) { return new D3D12Binding(window, device); }
} // namespace aurora::gpu::utils

View File

@ -268,6 +268,14 @@ void shutdown() {
g_pipelineThreadEnd = true;
g_pipelineCv.notify_all();
g_pipelineThread.join();
g_cachedBindGroups.clear();
g_pipelines.clear();
g_vertexBuffer = {};
g_uniformBuffer = {};
g_indexBuffer = {};
g_state = {};
}
void render(const wgpu::RenderPassEncoder& pass) {

View File

@ -9,6 +9,8 @@
#include "dawn/BackendBinding.hpp"
// TODO this hack doesn't link on Windows?
#ifndef _WIN32
// TODO HACK: dawn doesn't expose device toggles
#include "../extern/dawn/src/dawn/native/Toggles.h"
namespace dawn::native {
@ -17,6 +19,7 @@ public:
void SetToggle(Toggle toggle, bool isEnabled);
};
} // namespace dawn::native
#endif
namespace aurora::gpu {
static logvisor::Module Log("aurora::gpu");
@ -148,9 +151,11 @@ void initialize(SDL_Window* window) {
};
g_device = wgpu::Device::Acquire(g_Adapter.CreateDevice(&deviceDescriptor));
g_device.SetUncapturedErrorCallback(&error_callback, nullptr);
#ifndef _WIN32
// TODO HACK: dawn doesn't expose device toggles
static_cast<dawn::native::DeviceBase*>(static_cast<void*>(g_device.Get()))
->SetToggle(dawn::native::Toggle::UseUserDefinedLabelsInBackend, true);
#endif
}
g_queue = g_device.GetQueue();
@ -192,6 +197,9 @@ void initialize(SDL_Window* window) {
}
void shutdown() {
g_frameBuffer = {};
g_frameBufferResolved = {};
g_depthBuffer = {};
wgpuSwapChainRelease(g_swapChain.Release());
wgpuQueueRelease(g_queue.Release());
g_BackendBinding.reset();

View File

@ -31,7 +31,9 @@ struct TextureWithSampler {
wgpu::Sampler sampler;
};
#ifdef DAWN_ENABLE_BACKEND_VULKAN
#ifdef DAWN_ENABLE_BACKEND_D3D12
static const wgpu::BackendType preferredBackendType = wgpu::BackendType::D3D12;
#elif DAWN_ENABLE_BACKEND_VULKAN
static const wgpu::BackendType preferredBackendType = wgpu::BackendType::Vulkan;
#elif DAWN_ENABLE_BACKEND_METAL
static const wgpu::BackendType preferredBackendType = wgpu::BackendType::Metal;

2
extern/amuse vendored

@ -1 +1 @@
Subproject commit 89986bdd650685261311a87b37f504baee342eff
Subproject commit 101746f2688f0b8f66b574cd492ab41c0f7eec4f

2
extern/athena vendored

@ -1 +1 @@
Subproject commit e13b498266d69d12883f36d35d284cd3dbfa53c1
Subproject commit f27a63f312ba15b986e186b993d9d201d63a118b

2
extern/boo vendored

@ -1 +1 @@
Subproject commit e458d1999cb613c5dc221c9805c81cf7e8a24fb6
Subproject commit 94d11cb32884cfc90a0f13f6ff98a1c7637f8312

2
extern/dawn vendored

@ -1 +1 @@
Subproject commit 883681cafb2563de3b8af270726e30e83f240721
Subproject commit 5772c54b9935f5e294c522ef5741ce888f33457c

2
extern/kabufuda vendored

@ -1 +1 @@
Subproject commit 2252e6c3c391dc162ed1245a5d348c1f9a587a4b
Subproject commit 32090b4d4ab70dbfa07f1f2994964f983ab43a69

2
extern/nod vendored

@ -1 +1 @@
Subproject commit 30697375adee818e9c14015584c6629e12d27ab4
Subproject commit 72893dcacb02ebff11b354832c55f3763ab523b7

View File

@ -6,13 +6,6 @@
#include <thread>
#include <vector>
#if _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#endif
namespace hecl {
class MultiProgressPrinter {
@ -22,7 +15,7 @@ class MultiProgressPrinter {
struct TermInfo {
#if _WIN32
HANDLE console;
void* console;
#endif
int width;
bool xtermColor = false;

View File

@ -13,6 +13,10 @@
#if _WIN32
#define FOREGROUND_WHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#endif
namespace hecl {