mirror of
https://github.com/encounter/boo.git
synced 2026-07-09 18:18:49 -07:00
New code style refactor
This commit is contained in:
+7
-11
@@ -5,17 +5,13 @@
|
||||
#include "boo/inputdev/XInputPad.hpp"
|
||||
#include "boo/inputdev/NintendoPowerA.hpp"
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
|
||||
const DeviceSignature BOO_DEVICE_SIGS[] =
|
||||
{
|
||||
DEVICE_SIG(DolphinSmashAdapter, 0x57e, 0x337, DeviceType::USB),
|
||||
DEVICE_SIG(DualshockPad, 0x54c, 0x268, DeviceType::HID),
|
||||
DEVICE_SIG(GenericPad, 0, 0, DeviceType::HID),
|
||||
DEVICE_SIG(NintendoPowerA, 0x20D6, 0xA711, DeviceType::USB),
|
||||
DEVICE_SIG(XInputPad, 0, 0, DeviceType::XInput),
|
||||
DEVICE_SIG_SENTINEL()
|
||||
};
|
||||
const DeviceSignature BOO_DEVICE_SIGS[] = {DEVICE_SIG(DolphinSmashAdapter, 0x57e, 0x337, DeviceType::USB),
|
||||
DEVICE_SIG(DualshockPad, 0x54c, 0x268, DeviceType::HID),
|
||||
DEVICE_SIG(GenericPad, 0, 0, DeviceType::HID),
|
||||
DEVICE_SIG(NintendoPowerA, 0x20D6, 0xA711, DeviceType::USB),
|
||||
DEVICE_SIG(XInputPad, 0, 0, DeviceType::XInput),
|
||||
DEVICE_SIG_SENTINEL()};
|
||||
|
||||
}
|
||||
|
||||
+68
-38
@@ -4,50 +4,80 @@
|
||||
#include <mutex>
|
||||
#include "nxstl/mutex"
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
|
||||
class IObj {
|
||||
std::atomic_int m_refCount = {0};
|
||||
|
||||
class IObj
|
||||
{
|
||||
std::atomic_int m_refCount = {0};
|
||||
protected:
|
||||
virtual ~IObj() = default;
|
||||
virtual ~IObj() = default;
|
||||
|
||||
public:
|
||||
virtual std::unique_lock<std::recursive_mutex> destructorLock()=0;
|
||||
void increment() { m_refCount++; }
|
||||
void decrement()
|
||||
{
|
||||
if (m_refCount.fetch_sub(1) == 1)
|
||||
{
|
||||
auto lk = destructorLock();
|
||||
delete this;
|
||||
}
|
||||
virtual std::unique_lock<std::recursive_mutex> destructorLock() = 0;
|
||||
void increment() { m_refCount++; }
|
||||
void decrement() {
|
||||
if (m_refCount.fetch_sub(1) == 1) {
|
||||
auto lk = destructorLock();
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class SubCls>
|
||||
class ObjToken
|
||||
{
|
||||
SubCls* m_obj = nullptr;
|
||||
template <class SubCls>
|
||||
class ObjToken {
|
||||
SubCls* m_obj = nullptr;
|
||||
|
||||
public:
|
||||
ObjToken() = default;
|
||||
ObjToken(SubCls* obj) : m_obj(obj) { if (m_obj) m_obj->increment(); }
|
||||
ObjToken(const ObjToken& other) : m_obj(other.m_obj) { if (m_obj) m_obj->increment(); }
|
||||
ObjToken(ObjToken&& other) : m_obj(other.m_obj) { other.m_obj = nullptr; }
|
||||
ObjToken& operator=(SubCls* obj)
|
||||
{ if (m_obj) m_obj->decrement(); m_obj = obj; if (m_obj) m_obj->increment(); return *this; }
|
||||
ObjToken& operator=(const ObjToken& other)
|
||||
{ if (m_obj) m_obj->decrement(); m_obj = other.m_obj; if (m_obj) m_obj->increment(); return *this; }
|
||||
ObjToken& operator=(ObjToken&& other)
|
||||
{ if (m_obj) m_obj->decrement(); m_obj = other.m_obj; other.m_obj = nullptr; return *this; }
|
||||
~ObjToken() { if (m_obj) m_obj->decrement(); }
|
||||
SubCls* get() const { return m_obj; }
|
||||
SubCls* operator->() const { return m_obj; }
|
||||
SubCls& operator*() const { return *m_obj; }
|
||||
template<class T> T* cast() const { return static_cast<T*>(m_obj); }
|
||||
operator bool() const { return m_obj != nullptr; }
|
||||
void reset() { if (m_obj) m_obj->decrement(); m_obj = nullptr; }
|
||||
ObjToken() = default;
|
||||
ObjToken(SubCls* obj) : m_obj(obj) {
|
||||
if (m_obj)
|
||||
m_obj->increment();
|
||||
}
|
||||
ObjToken(const ObjToken& other) : m_obj(other.m_obj) {
|
||||
if (m_obj)
|
||||
m_obj->increment();
|
||||
}
|
||||
ObjToken(ObjToken&& other) : m_obj(other.m_obj) { other.m_obj = nullptr; }
|
||||
ObjToken& operator=(SubCls* obj) {
|
||||
if (m_obj)
|
||||
m_obj->decrement();
|
||||
m_obj = obj;
|
||||
if (m_obj)
|
||||
m_obj->increment();
|
||||
return *this;
|
||||
}
|
||||
ObjToken& operator=(const ObjToken& other) {
|
||||
if (m_obj)
|
||||
m_obj->decrement();
|
||||
m_obj = other.m_obj;
|
||||
if (m_obj)
|
||||
m_obj->increment();
|
||||
return *this;
|
||||
}
|
||||
ObjToken& operator=(ObjToken&& other) {
|
||||
if (m_obj)
|
||||
m_obj->decrement();
|
||||
m_obj = other.m_obj;
|
||||
other.m_obj = nullptr;
|
||||
return *this;
|
||||
}
|
||||
~ObjToken() {
|
||||
if (m_obj)
|
||||
m_obj->decrement();
|
||||
}
|
||||
SubCls* get() const { return m_obj; }
|
||||
SubCls* operator->() const { return m_obj; }
|
||||
SubCls& operator*() const { return *m_obj; }
|
||||
template <class T>
|
||||
T* cast() const {
|
||||
return static_cast<T*>(m_obj);
|
||||
}
|
||||
operator bool() const { return m_obj != nullptr; }
|
||||
void reset() {
|
||||
if (m_obj)
|
||||
m_obj->decrement();
|
||||
m_obj = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -5,269 +5,242 @@
|
||||
#include <condition_variable>
|
||||
#include "nxstl/condition_variable"
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
|
||||
template <class Receiver>
|
||||
struct DeferredWindowEvents : public IWindowCallback
|
||||
{
|
||||
Receiver& m_rec;
|
||||
std::mutex m_mt;
|
||||
std::condition_variable m_resizeCv;
|
||||
DeferredWindowEvents(Receiver& rec) : m_rec(rec) {}
|
||||
struct DeferredWindowEvents : public IWindowCallback {
|
||||
Receiver& m_rec;
|
||||
std::mutex m_mt;
|
||||
std::condition_variable m_resizeCv;
|
||||
DeferredWindowEvents(Receiver& rec) : m_rec(rec) {}
|
||||
|
||||
bool m_destroyed = false;
|
||||
void destroyed()
|
||||
{
|
||||
m_destroyed = true;
|
||||
bool m_destroyed = false;
|
||||
void destroyed() { m_destroyed = true; }
|
||||
|
||||
bool m_hasResize = false;
|
||||
SWindowRect m_latestResize;
|
||||
void resized(const SWindowRect& rect, bool sync) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_latestResize = rect;
|
||||
m_hasResize = true;
|
||||
if (sync)
|
||||
m_resizeCv.wait_for(lk, std::chrono::milliseconds(500));
|
||||
}
|
||||
|
||||
struct Command {
|
||||
enum class Type {
|
||||
MouseDown,
|
||||
MouseUp,
|
||||
MouseMove,
|
||||
MouseEnter,
|
||||
MouseLeave,
|
||||
Scroll,
|
||||
TouchDown,
|
||||
TouchUp,
|
||||
TouchMove,
|
||||
CharKeyDown,
|
||||
CharKeyUp,
|
||||
SpecialKeyDown,
|
||||
SpecialKeyUp,
|
||||
ModKeyDown,
|
||||
ModKeyUp
|
||||
} m_type;
|
||||
|
||||
SWindowCoord m_coord;
|
||||
EMouseButton m_button;
|
||||
EModifierKey m_mods;
|
||||
SScrollDelta m_scroll;
|
||||
STouchCoord m_tCoord;
|
||||
uintptr_t m_tid;
|
||||
unsigned long m_charcode;
|
||||
ESpecialKey m_special;
|
||||
bool m_isRepeat;
|
||||
|
||||
void dispatch(Receiver& rec) const {
|
||||
switch (m_type) {
|
||||
case Type::MouseDown:
|
||||
rec.mouseDown(m_coord, m_button, m_mods);
|
||||
break;
|
||||
case Type::MouseUp:
|
||||
rec.mouseUp(m_coord, m_button, m_mods);
|
||||
break;
|
||||
case Type::MouseMove:
|
||||
rec.mouseMove(m_coord);
|
||||
break;
|
||||
case Type::MouseEnter:
|
||||
rec.mouseEnter(m_coord);
|
||||
break;
|
||||
case Type::MouseLeave:
|
||||
rec.mouseLeave(m_coord);
|
||||
break;
|
||||
case Type::Scroll:
|
||||
rec.scroll(m_coord, m_scroll);
|
||||
break;
|
||||
case Type::TouchDown:
|
||||
rec.touchDown(m_tCoord, m_tid);
|
||||
break;
|
||||
case Type::TouchUp:
|
||||
rec.touchUp(m_tCoord, m_tid);
|
||||
break;
|
||||
case Type::TouchMove:
|
||||
rec.touchMove(m_tCoord, m_tid);
|
||||
break;
|
||||
case Type::CharKeyDown:
|
||||
rec.charKeyDown(m_charcode, m_mods, m_isRepeat);
|
||||
break;
|
||||
case Type::CharKeyUp:
|
||||
rec.charKeyUp(m_charcode, m_mods);
|
||||
break;
|
||||
case Type::SpecialKeyDown:
|
||||
rec.specialKeyDown(m_special, m_mods, m_isRepeat);
|
||||
break;
|
||||
case Type::SpecialKeyUp:
|
||||
rec.specialKeyUp(m_special, m_mods);
|
||||
break;
|
||||
case Type::ModKeyDown:
|
||||
rec.modKeyDown(m_mods, m_isRepeat);
|
||||
break;
|
||||
case Type::ModKeyUp:
|
||||
rec.modKeyUp(m_mods);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool m_hasResize = false;
|
||||
SWindowRect m_latestResize;
|
||||
void resized(const SWindowRect& rect, bool sync)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_latestResize = rect;
|
||||
m_hasResize = true;
|
||||
if (sync)
|
||||
m_resizeCv.wait_for(lk, std::chrono::milliseconds(500));
|
||||
Command(Type tp) : m_type(tp) {}
|
||||
};
|
||||
std::vector<Command> m_cmds;
|
||||
|
||||
void mouseDown(const SWindowCoord& coord, EMouseButton button, EModifierKey mods) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::MouseDown);
|
||||
m_cmds.back().m_coord = coord;
|
||||
m_cmds.back().m_button = button;
|
||||
m_cmds.back().m_mods = mods;
|
||||
}
|
||||
|
||||
void mouseUp(const SWindowCoord& coord, EMouseButton button, EModifierKey mods) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::MouseUp);
|
||||
m_cmds.back().m_coord = coord;
|
||||
m_cmds.back().m_button = button;
|
||||
m_cmds.back().m_mods = mods;
|
||||
}
|
||||
|
||||
void mouseMove(const SWindowCoord& coord) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::MouseMove);
|
||||
m_cmds.back().m_coord = coord;
|
||||
}
|
||||
|
||||
void mouseEnter(const SWindowCoord& coord) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::MouseEnter);
|
||||
m_cmds.back().m_coord = coord;
|
||||
}
|
||||
|
||||
void mouseLeave(const SWindowCoord& coord) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::MouseLeave);
|
||||
m_cmds.back().m_coord = coord;
|
||||
}
|
||||
|
||||
void scroll(const SWindowCoord& coord, const SScrollDelta& scroll) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::Scroll);
|
||||
m_cmds.back().m_coord = coord;
|
||||
m_cmds.back().m_scroll = scroll;
|
||||
}
|
||||
|
||||
void touchDown(const STouchCoord& coord, uintptr_t tid) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::TouchDown);
|
||||
m_cmds.back().m_tCoord = coord;
|
||||
m_cmds.back().m_tid = tid;
|
||||
}
|
||||
|
||||
void touchUp(const STouchCoord& coord, uintptr_t tid) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::TouchUp);
|
||||
m_cmds.back().m_tCoord = coord;
|
||||
m_cmds.back().m_tid = tid;
|
||||
}
|
||||
|
||||
void touchMove(const STouchCoord& coord, uintptr_t tid) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::TouchMove);
|
||||
m_cmds.back().m_tCoord = coord;
|
||||
m_cmds.back().m_tid = tid;
|
||||
}
|
||||
|
||||
void charKeyDown(unsigned long charCode, EModifierKey mods, bool isRepeat) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::CharKeyDown);
|
||||
m_cmds.back().m_charcode = charCode;
|
||||
m_cmds.back().m_mods = mods;
|
||||
m_cmds.back().m_isRepeat = isRepeat;
|
||||
}
|
||||
|
||||
void charKeyUp(unsigned long charCode, EModifierKey mods) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::CharKeyUp);
|
||||
m_cmds.back().m_charcode = charCode;
|
||||
m_cmds.back().m_mods = mods;
|
||||
}
|
||||
|
||||
void specialKeyDown(ESpecialKey key, EModifierKey mods, bool isRepeat) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::SpecialKeyDown);
|
||||
m_cmds.back().m_special = key;
|
||||
m_cmds.back().m_mods = mods;
|
||||
m_cmds.back().m_isRepeat = isRepeat;
|
||||
}
|
||||
|
||||
void specialKeyUp(ESpecialKey key, EModifierKey mods) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::SpecialKeyUp);
|
||||
m_cmds.back().m_special = key;
|
||||
m_cmds.back().m_mods = mods;
|
||||
}
|
||||
|
||||
void modKeyDown(EModifierKey mod, bool isRepeat) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::ModKeyDown);
|
||||
m_cmds.back().m_mods = mod;
|
||||
m_cmds.back().m_isRepeat = isRepeat;
|
||||
}
|
||||
|
||||
void modKeyUp(EModifierKey mod) {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::ModKeyUp);
|
||||
m_cmds.back().m_mods = mod;
|
||||
}
|
||||
|
||||
ITextInputCallback* getTextInputCallback() { return m_rec.getTextInputCallback(); }
|
||||
|
||||
void dispatchEvents() {
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
bool destroyed = m_destroyed;
|
||||
bool hasResize = m_hasResize;
|
||||
if (hasResize)
|
||||
m_hasResize = false;
|
||||
SWindowRect latestResize = m_latestResize;
|
||||
std::vector<Command> cmds;
|
||||
m_cmds.swap(cmds);
|
||||
lk.unlock();
|
||||
|
||||
if (destroyed) {
|
||||
m_rec.destroyed();
|
||||
return;
|
||||
}
|
||||
|
||||
struct Command
|
||||
{
|
||||
enum class Type
|
||||
{
|
||||
MouseDown,
|
||||
MouseUp,
|
||||
MouseMove,
|
||||
MouseEnter,
|
||||
MouseLeave,
|
||||
Scroll,
|
||||
TouchDown,
|
||||
TouchUp,
|
||||
TouchMove,
|
||||
CharKeyDown,
|
||||
CharKeyUp,
|
||||
SpecialKeyDown,
|
||||
SpecialKeyUp,
|
||||
ModKeyDown,
|
||||
ModKeyUp
|
||||
} m_type;
|
||||
if (hasResize)
|
||||
m_rec.resized(latestResize, false);
|
||||
|
||||
SWindowCoord m_coord;
|
||||
EMouseButton m_button;
|
||||
EModifierKey m_mods;
|
||||
SScrollDelta m_scroll;
|
||||
STouchCoord m_tCoord;
|
||||
uintptr_t m_tid;
|
||||
unsigned long m_charcode;
|
||||
ESpecialKey m_special;
|
||||
bool m_isRepeat;
|
||||
|
||||
void dispatch(Receiver& rec) const
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case Type::MouseDown:
|
||||
rec.mouseDown(m_coord, m_button, m_mods);
|
||||
break;
|
||||
case Type::MouseUp:
|
||||
rec.mouseUp(m_coord, m_button, m_mods);
|
||||
break;
|
||||
case Type::MouseMove:
|
||||
rec.mouseMove(m_coord);
|
||||
break;
|
||||
case Type::MouseEnter:
|
||||
rec.mouseEnter(m_coord);
|
||||
break;
|
||||
case Type::MouseLeave:
|
||||
rec.mouseLeave(m_coord);
|
||||
break;
|
||||
case Type::Scroll:
|
||||
rec.scroll(m_coord, m_scroll);
|
||||
break;
|
||||
case Type::TouchDown:
|
||||
rec.touchDown(m_tCoord, m_tid);
|
||||
break;
|
||||
case Type::TouchUp:
|
||||
rec.touchUp(m_tCoord, m_tid);
|
||||
break;
|
||||
case Type::TouchMove:
|
||||
rec.touchMove(m_tCoord, m_tid);
|
||||
break;
|
||||
case Type::CharKeyDown:
|
||||
rec.charKeyDown(m_charcode, m_mods, m_isRepeat);
|
||||
break;
|
||||
case Type::CharKeyUp:
|
||||
rec.charKeyUp(m_charcode, m_mods);
|
||||
break;
|
||||
case Type::SpecialKeyDown:
|
||||
rec.specialKeyDown(m_special, m_mods, m_isRepeat);
|
||||
break;
|
||||
case Type::SpecialKeyUp:
|
||||
rec.specialKeyUp(m_special, m_mods);
|
||||
break;
|
||||
case Type::ModKeyDown:
|
||||
rec.modKeyDown(m_mods, m_isRepeat);
|
||||
break;
|
||||
case Type::ModKeyUp:
|
||||
rec.modKeyUp(m_mods);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
Command(Type tp) : m_type(tp) {}
|
||||
};
|
||||
std::vector<Command> m_cmds;
|
||||
|
||||
void mouseDown(const SWindowCoord& coord, EMouseButton button, EModifierKey mods)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::MouseDown);
|
||||
m_cmds.back().m_coord = coord;
|
||||
m_cmds.back().m_button = button;
|
||||
m_cmds.back().m_mods = mods;
|
||||
}
|
||||
|
||||
void mouseUp(const SWindowCoord& coord, EMouseButton button, EModifierKey mods)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::MouseUp);
|
||||
m_cmds.back().m_coord = coord;
|
||||
m_cmds.back().m_button = button;
|
||||
m_cmds.back().m_mods = mods;
|
||||
}
|
||||
|
||||
void mouseMove(const SWindowCoord& coord)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::MouseMove);
|
||||
m_cmds.back().m_coord = coord;
|
||||
}
|
||||
|
||||
void mouseEnter(const SWindowCoord& coord)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::MouseEnter);
|
||||
m_cmds.back().m_coord = coord;
|
||||
}
|
||||
|
||||
void mouseLeave(const SWindowCoord& coord)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::MouseLeave);
|
||||
m_cmds.back().m_coord = coord;
|
||||
}
|
||||
|
||||
void scroll(const SWindowCoord& coord, const SScrollDelta& scroll)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::Scroll);
|
||||
m_cmds.back().m_coord = coord;
|
||||
m_cmds.back().m_scroll = scroll;
|
||||
}
|
||||
|
||||
void touchDown(const STouchCoord& coord, uintptr_t tid)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::TouchDown);
|
||||
m_cmds.back().m_tCoord = coord;
|
||||
m_cmds.back().m_tid = tid;
|
||||
}
|
||||
|
||||
void touchUp(const STouchCoord& coord, uintptr_t tid)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::TouchUp);
|
||||
m_cmds.back().m_tCoord = coord;
|
||||
m_cmds.back().m_tid = tid;
|
||||
}
|
||||
|
||||
void touchMove(const STouchCoord& coord, uintptr_t tid)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::TouchMove);
|
||||
m_cmds.back().m_tCoord = coord;
|
||||
m_cmds.back().m_tid = tid;
|
||||
}
|
||||
|
||||
void charKeyDown(unsigned long charCode, EModifierKey mods, bool isRepeat)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::CharKeyDown);
|
||||
m_cmds.back().m_charcode = charCode;
|
||||
m_cmds.back().m_mods = mods;
|
||||
m_cmds.back().m_isRepeat = isRepeat;
|
||||
}
|
||||
|
||||
void charKeyUp(unsigned long charCode, EModifierKey mods)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::CharKeyUp);
|
||||
m_cmds.back().m_charcode = charCode;
|
||||
m_cmds.back().m_mods = mods;
|
||||
}
|
||||
|
||||
void specialKeyDown(ESpecialKey key, EModifierKey mods, bool isRepeat)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::SpecialKeyDown);
|
||||
m_cmds.back().m_special = key;
|
||||
m_cmds.back().m_mods = mods;
|
||||
m_cmds.back().m_isRepeat = isRepeat;
|
||||
}
|
||||
|
||||
void specialKeyUp(ESpecialKey key, EModifierKey mods)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::SpecialKeyUp);
|
||||
m_cmds.back().m_special = key;
|
||||
m_cmds.back().m_mods = mods;
|
||||
}
|
||||
|
||||
void modKeyDown(EModifierKey mod, bool isRepeat)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::ModKeyDown);
|
||||
m_cmds.back().m_mods = mod;
|
||||
m_cmds.back().m_isRepeat = isRepeat;
|
||||
}
|
||||
|
||||
void modKeyUp(EModifierKey mod)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_cmds.emplace_back(Command::Type::ModKeyUp);
|
||||
m_cmds.back().m_mods = mod;
|
||||
}
|
||||
|
||||
ITextInputCallback* getTextInputCallback() { return m_rec.getTextInputCallback(); }
|
||||
|
||||
void dispatchEvents()
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
bool destroyed = m_destroyed;
|
||||
bool hasResize = m_hasResize;
|
||||
if (hasResize)
|
||||
m_hasResize = false;
|
||||
SWindowRect latestResize = m_latestResize;
|
||||
std::vector<Command> cmds;
|
||||
m_cmds.swap(cmds);
|
||||
lk.unlock();
|
||||
|
||||
if (destroyed)
|
||||
{
|
||||
m_rec.destroyed();
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasResize)
|
||||
m_rec.resized(latestResize, false);
|
||||
|
||||
for (const Command& cmd : cmds)
|
||||
cmd.dispatch(m_rec);
|
||||
}
|
||||
for (const Command& cmd : cmds)
|
||||
cmd.dispatch(m_rec);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -7,88 +7,68 @@
|
||||
#include "IWindow.hpp"
|
||||
#include "inputdev/DeviceFinder.hpp"
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
class IApplication;
|
||||
|
||||
struct IApplicationCallback
|
||||
{
|
||||
virtual int appMain(IApplication*)=0;
|
||||
virtual void appQuitting(IApplication*)=0;
|
||||
virtual void appFilesOpen(IApplication*, const std::vector<SystemString>&) {}
|
||||
struct IApplicationCallback {
|
||||
virtual int appMain(IApplication*) = 0;
|
||||
virtual void appQuitting(IApplication*) = 0;
|
||||
virtual void appFilesOpen(IApplication*, const std::vector<SystemString>&) {}
|
||||
};
|
||||
|
||||
class IApplication
|
||||
{
|
||||
friend class WindowCocoa;
|
||||
friend class WindowWayland;
|
||||
friend class WindowXlib;
|
||||
friend class WindowWin32;
|
||||
virtual void _deletedWindow(IWindow* window)=0;
|
||||
class IApplication {
|
||||
friend class WindowCocoa;
|
||||
friend class WindowWayland;
|
||||
friend class WindowXlib;
|
||||
friend class WindowWin32;
|
||||
virtual void _deletedWindow(IWindow* window) = 0;
|
||||
|
||||
public:
|
||||
virtual ~IApplication() = default;
|
||||
|
||||
enum class EPlatformType
|
||||
{
|
||||
Auto = 0,
|
||||
Wayland = 1,
|
||||
Xlib = 2,
|
||||
Android = 3,
|
||||
Cocoa = 4,
|
||||
CocoaTouch = 5,
|
||||
Win32 = 6,
|
||||
UWP = 7,
|
||||
Revolution = 8,
|
||||
Cafe = 9,
|
||||
NX = 10,
|
||||
Qt = 11
|
||||
};
|
||||
virtual EPlatformType getPlatformType() const=0;
|
||||
|
||||
virtual int run()=0;
|
||||
virtual SystemStringView getUniqueName() const=0;
|
||||
virtual SystemStringView getFriendlyName() const=0;
|
||||
virtual SystemStringView getProcessName() const=0;
|
||||
virtual const std::vector<SystemString>& getArgs() const=0;
|
||||
|
||||
/* Constructors/initializers for sub-objects */
|
||||
virtual std::shared_ptr<IWindow> newWindow(SystemStringView title)=0;
|
||||
virtual ~IApplication() = default;
|
||||
|
||||
enum class EPlatformType {
|
||||
Auto = 0,
|
||||
Wayland = 1,
|
||||
Xlib = 2,
|
||||
Android = 3,
|
||||
Cocoa = 4,
|
||||
CocoaTouch = 5,
|
||||
Win32 = 6,
|
||||
UWP = 7,
|
||||
Revolution = 8,
|
||||
Cafe = 9,
|
||||
NX = 10,
|
||||
Qt = 11
|
||||
};
|
||||
virtual EPlatformType getPlatformType() const = 0;
|
||||
|
||||
virtual int run() = 0;
|
||||
virtual SystemStringView getUniqueName() const = 0;
|
||||
virtual SystemStringView getFriendlyName() const = 0;
|
||||
virtual SystemStringView getProcessName() const = 0;
|
||||
virtual const std::vector<SystemString>& getArgs() const = 0;
|
||||
|
||||
/* Constructors/initializers for sub-objects */
|
||||
virtual std::shared_ptr<IWindow> newWindow(SystemStringView title) = 0;
|
||||
};
|
||||
|
||||
int
|
||||
ApplicationRun(IApplication::EPlatformType platform,
|
||||
IApplicationCallback& cb,
|
||||
SystemStringView uniqueName,
|
||||
SystemStringView friendlyName,
|
||||
SystemStringView pname,
|
||||
const std::vector<SystemString>& args,
|
||||
std::string_view gfxApi = {},
|
||||
uint32_t samples = 1,
|
||||
uint32_t anisotropy = 1,
|
||||
bool deepColor = false,
|
||||
bool singleInstance=true);
|
||||
int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb, SystemStringView uniqueName,
|
||||
SystemStringView friendlyName, SystemStringView pname, const std::vector<SystemString>& args,
|
||||
std::string_view gfxApi = {}, uint32_t samples = 1, uint32_t anisotropy = 1, bool deepColor = false,
|
||||
bool singleInstance = true);
|
||||
extern IApplication* APP;
|
||||
|
||||
static inline int
|
||||
ApplicationRun(IApplication::EPlatformType platform,
|
||||
IApplicationCallback& cb,
|
||||
SystemStringView uniqueName,
|
||||
SystemStringView friendlyName,
|
||||
int argc, const SystemChar** argv,
|
||||
std::string_view gfxApi = {},
|
||||
uint32_t samples = 1,
|
||||
uint32_t anisotropy = 1,
|
||||
bool deepColor = false,
|
||||
bool singleInstance=true)
|
||||
{
|
||||
if (APP)
|
||||
return 1;
|
||||
std::vector<SystemString> args;
|
||||
for (int i=1 ; i<argc ; ++i)
|
||||
args.push_back(argv[i]);
|
||||
return ApplicationRun(platform, cb, uniqueName, friendlyName, argv[0], args,
|
||||
gfxApi, samples, anisotropy, deepColor, singleInstance);
|
||||
}
|
||||
|
||||
|
||||
static inline int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb,
|
||||
SystemStringView uniqueName, SystemStringView friendlyName, int argc,
|
||||
const SystemChar** argv, std::string_view gfxApi = {}, uint32_t samples = 1,
|
||||
uint32_t anisotropy = 1, bool deepColor = false, bool singleInstance = true) {
|
||||
if (APP)
|
||||
return 1;
|
||||
std::vector<SystemString> args;
|
||||
for (int i = 1; i < argc; ++i)
|
||||
args.push_back(argv[i]);
|
||||
return ApplicationRun(platform, cb, uniqueName, friendlyName, argv[0], args, gfxApi, samples, anisotropy, deepColor,
|
||||
singleInstance);
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -3,61 +3,55 @@
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
struct IGraphicsCommandQueue;
|
||||
struct IGraphicsDataFactory;
|
||||
|
||||
class IGraphicsContext
|
||||
{
|
||||
friend class WindowCocoa;
|
||||
friend class WindowXCB;
|
||||
virtual void _setCallback(class IWindowCallback* cb) {(void)cb;}
|
||||
class IGraphicsContext {
|
||||
friend class WindowCocoa;
|
||||
friend class WindowXCB;
|
||||
virtual void _setCallback(class IWindowCallback* cb) { (void)cb; }
|
||||
|
||||
public:
|
||||
|
||||
enum class EGraphicsAPI
|
||||
{
|
||||
None = 0,
|
||||
OpenGL3_3 = 1,
|
||||
OpenGL4_2 = 2,
|
||||
Vulkan = 3,
|
||||
D3D11 = 4,
|
||||
Metal = 6,
|
||||
GX = 7,
|
||||
GX2 = 8,
|
||||
NX = 9
|
||||
};
|
||||
|
||||
enum class EPixelFormat
|
||||
{
|
||||
None = 0,
|
||||
RGBA8 = 1, /* Default */
|
||||
RGBA16 = 2,
|
||||
RGBA8_Z24 = 3,
|
||||
RGBAF32 = 4,
|
||||
RGBAF32_Z24 = 5
|
||||
};
|
||||
|
||||
virtual ~IGraphicsContext() = default;
|
||||
|
||||
virtual EGraphicsAPI getAPI() const=0;
|
||||
virtual EPixelFormat getPixelFormat() const=0;
|
||||
virtual void setPixelFormat(EPixelFormat pf)=0;
|
||||
virtual bool initializeContext(void* handle)=0;
|
||||
virtual void makeCurrent()=0;
|
||||
virtual void postInit()=0;
|
||||
virtual void present()=0;
|
||||
enum class EGraphicsAPI {
|
||||
None = 0,
|
||||
OpenGL3_3 = 1,
|
||||
OpenGL4_2 = 2,
|
||||
Vulkan = 3,
|
||||
D3D11 = 4,
|
||||
Metal = 6,
|
||||
GX = 7,
|
||||
GX2 = 8,
|
||||
NX = 9
|
||||
};
|
||||
|
||||
virtual IGraphicsCommandQueue* getCommandQueue()=0;
|
||||
virtual IGraphicsDataFactory* getDataFactory()=0;
|
||||
enum class EPixelFormat {
|
||||
None = 0,
|
||||
RGBA8 = 1, /* Default */
|
||||
RGBA16 = 2,
|
||||
RGBA8_Z24 = 3,
|
||||
RGBAF32 = 4,
|
||||
RGBAF32_Z24 = 5
|
||||
};
|
||||
|
||||
/* Creates a new context on current thread!! Call from main client thread */
|
||||
virtual IGraphicsDataFactory* getMainContextDataFactory()=0;
|
||||
virtual ~IGraphicsContext() = default;
|
||||
|
||||
/* Creates a new context on current thread!! Call from client loading thread */
|
||||
virtual IGraphicsDataFactory* getLoadContextDataFactory()=0;
|
||||
virtual EGraphicsAPI getAPI() const = 0;
|
||||
virtual EPixelFormat getPixelFormat() const = 0;
|
||||
virtual void setPixelFormat(EPixelFormat pf) = 0;
|
||||
virtual bool initializeContext(void* handle) = 0;
|
||||
virtual void makeCurrent() = 0;
|
||||
virtual void postInit() = 0;
|
||||
virtual void present() = 0;
|
||||
|
||||
virtual IGraphicsCommandQueue* getCommandQueue() = 0;
|
||||
virtual IGraphicsDataFactory* getDataFactory() = 0;
|
||||
|
||||
/* Creates a new context on current thread!! Call from main client thread */
|
||||
virtual IGraphicsDataFactory* getMainContextDataFactory() = 0;
|
||||
|
||||
/* Creates a new context on current thread!! Call from client loading thread */
|
||||
virtual IGraphicsDataFactory* getLoadContextDataFactory() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
+238
-267
File diff suppressed because it is too large
Load Diff
+44
-48
@@ -14,68 +14,65 @@
|
||||
template <class T>
|
||||
using ComPtr = Microsoft::WRL::ComPtr<T>;
|
||||
template <class T>
|
||||
static inline ComPtr<T>* ReferenceComPtr(ComPtr<T>& ptr)
|
||||
{ return reinterpret_cast<ComPtr<T>*>(ptr.GetAddressOf()); }
|
||||
static inline ComPtr<T>* ReferenceComPtr(ComPtr<T>& ptr) {
|
||||
return reinterpret_cast<ComPtr<T>*>(ptr.GetAddressOf());
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#ifndef ENABLE_BITWISE_ENUM
|
||||
#define ENABLE_BITWISE_ENUM(type)\
|
||||
constexpr type operator|(type a, type b)\
|
||||
{\
|
||||
using T = std::underlying_type_t<type>;\
|
||||
return type(static_cast<T>(a) | static_cast<T>(b));\
|
||||
}\
|
||||
constexpr type operator&(type a, type b)\
|
||||
{\
|
||||
using T = std::underlying_type_t<type>;\
|
||||
return type(static_cast<T>(a) & static_cast<T>(b));\
|
||||
}\
|
||||
inline type& operator|=(type& a, const type& b)\
|
||||
{\
|
||||
using T = std::underlying_type_t<type>;\
|
||||
a = type(static_cast<T>(a) | static_cast<T>(b));\
|
||||
return a;\
|
||||
}\
|
||||
inline type& operator&=(type& a, const type& b)\
|
||||
{\
|
||||
using T = std::underlying_type_t<type>;\
|
||||
a = type(static_cast<T>(a) & static_cast<T>(b));\
|
||||
return a;\
|
||||
}\
|
||||
inline type operator~(const type& key)\
|
||||
{\
|
||||
using T = std::underlying_type_t<type>;\
|
||||
return type(~static_cast<T>(key));\
|
||||
}
|
||||
#define ENABLE_BITWISE_ENUM(type) \
|
||||
constexpr type operator|(type a, type b) { \
|
||||
using T = std::underlying_type_t<type>; \
|
||||
return type(static_cast<T>(a) | static_cast<T>(b)); \
|
||||
} \
|
||||
constexpr type operator&(type a, type b) { \
|
||||
using T = std::underlying_type_t<type>; \
|
||||
return type(static_cast<T>(a) & static_cast<T>(b)); \
|
||||
} \
|
||||
inline type& operator|=(type& a, const type& b) { \
|
||||
using T = std::underlying_type_t<type>; \
|
||||
a = type(static_cast<T>(a) | static_cast<T>(b)); \
|
||||
return a; \
|
||||
} \
|
||||
inline type& operator&=(type& a, const type& b) { \
|
||||
using T = std::underlying_type_t<type>; \
|
||||
a = type(static_cast<T>(a) & static_cast<T>(b)); \
|
||||
return a; \
|
||||
} \
|
||||
inline type operator~(const type& key) { \
|
||||
using T = std::underlying_type_t<type>; \
|
||||
return type(~static_cast<T>(key)); \
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
|
||||
#ifdef _WIN32
|
||||
using SystemString = std::wstring;
|
||||
using SystemStringView = std::wstring_view;
|
||||
using SystemChar = wchar_t;
|
||||
# ifndef _SYS_STR
|
||||
# define _SYS_STR(val) L ## val
|
||||
# endif
|
||||
using SystemString = std::wstring;
|
||||
using SystemStringView = std::wstring_view;
|
||||
using SystemChar = wchar_t;
|
||||
#ifndef _SYS_STR
|
||||
#define _SYS_STR(val) L##val
|
||||
#endif
|
||||
#else
|
||||
using SystemString = std::string;
|
||||
using SystemStringView = std::string_view;
|
||||
using SystemChar = char;
|
||||
# ifndef _SYS_STR
|
||||
# define _SYS_STR(val) val
|
||||
# endif
|
||||
using SystemString = std::string;
|
||||
using SystemStringView = std::string_view;
|
||||
using SystemChar = char;
|
||||
#ifndef _SYS_STR
|
||||
#define _SYS_STR(val) val
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define __BooTraceArgs , const char* file, int line
|
||||
#define __BooTraceArgs , const char *file, int line
|
||||
#define __BooTraceArgsUse , file, line
|
||||
#define __BooTraceInitializer , m_file(file), m_line(line)
|
||||
#define __BooTraceFields const char* m_file; int m_line;
|
||||
#define __BooTraceFields \
|
||||
const char* m_file; \
|
||||
int m_line;
|
||||
#define BooTrace , __FILE__, __LINE__
|
||||
#else
|
||||
#define __BooTraceArgs
|
||||
@@ -85,5 +82,4 @@ namespace boo
|
||||
#define BooTrace
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -9,25 +9,25 @@
|
||||
|
||||
/** Multiplatform TLS-pointer wrapper (for compilers without proper thread_local support) */
|
||||
template <class T>
|
||||
class ThreadLocalPtr
|
||||
{
|
||||
class ThreadLocalPtr {
|
||||
#if _WIN32
|
||||
DWORD m_key;
|
||||
DWORD m_key;
|
||||
|
||||
public:
|
||||
ThreadLocalPtr() {m_key = TlsAlloc();}
|
||||
~ThreadLocalPtr() {TlsFree(m_key);}
|
||||
T* get() const {return static_cast<T*>(TlsGetValue(m_key));}
|
||||
void reset(T* v=nullptr) {TlsSetValue(m_key, LPVOID(v));}
|
||||
ThreadLocalPtr() { m_key = TlsAlloc(); }
|
||||
~ThreadLocalPtr() { TlsFree(m_key); }
|
||||
T* get() const { return static_cast<T*>(TlsGetValue(m_key)); }
|
||||
void reset(T* v = nullptr) { TlsSetValue(m_key, LPVOID(v)); }
|
||||
#else
|
||||
pthread_key_t m_key;
|
||||
pthread_key_t m_key;
|
||||
|
||||
public:
|
||||
ThreadLocalPtr() {pthread_key_create(&m_key, nullptr);}
|
||||
~ThreadLocalPtr() {pthread_key_delete(m_key);}
|
||||
T* get() const {return static_cast<T*>(pthread_getspecific(m_key));}
|
||||
void reset(T* v=nullptr) {pthread_setspecific(m_key, v);}
|
||||
ThreadLocalPtr() { pthread_key_create(&m_key, nullptr); }
|
||||
~ThreadLocalPtr() { pthread_key_delete(m_key); }
|
||||
T* get() const { return static_cast<T*>(pthread_getspecific(m_key)); }
|
||||
void reset(T* v = nullptr) { pthread_setspecific(m_key, v); }
|
||||
#endif
|
||||
T* operator->() {return get();}
|
||||
T* operator->() { return get(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2,43 +2,37 @@
|
||||
|
||||
#include "IApplication.hpp"
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
|
||||
#if WINDOWS_STORE
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
|
||||
ref struct ViewProvider sealed : IFrameworkViewSource
|
||||
{
|
||||
internal:
|
||||
ViewProvider(boo::IApplicationCallback& appCb,
|
||||
SystemStringView uniqueName,
|
||||
SystemStringView friendlyName,
|
||||
SystemStringView pname,
|
||||
Platform::Array<Platform::String^>^ params,
|
||||
bool singleInstance)
|
||||
: m_appCb(appCb), m_uniqueName(uniqueName), m_friendlyName(friendlyName),
|
||||
m_pname(pname), m_singleInstance(singleInstance)
|
||||
{
|
||||
SystemChar selfPath[1024];
|
||||
GetModuleFileNameW(nullptr, selfPath, 1024);
|
||||
m_args.reserve(params->Length + 1);
|
||||
m_args.emplace_back(selfPath);
|
||||
for (Platform::String^ str : params)
|
||||
m_args.emplace_back(str->Data());
|
||||
}
|
||||
public:
|
||||
virtual IFrameworkView^ CreateView();
|
||||
ref struct ViewProvider sealed : IFrameworkViewSource {
|
||||
internal : ViewProvider(boo::IApplicationCallback& appCb, SystemStringView uniqueName, SystemStringView friendlyName,
|
||||
SystemStringView pname, Platform::Array<Platform::String ^> ^ params, bool singleInstance)
|
||||
: m_appCb(appCb)
|
||||
, m_uniqueName(uniqueName)
|
||||
, m_friendlyName(friendlyName)
|
||||
, m_pname(pname)
|
||||
, m_singleInstance(singleInstance) {
|
||||
SystemChar selfPath[1024];
|
||||
GetModuleFileNameW(nullptr, selfPath, 1024);
|
||||
m_args.reserve(params->Length + 1);
|
||||
m_args.emplace_back(selfPath);
|
||||
for (Platform::String ^ str : params)
|
||||
m_args.emplace_back(str->Data());
|
||||
}
|
||||
|
||||
internal:
|
||||
boo::IApplicationCallback& m_appCb;
|
||||
SystemString m_uniqueName;
|
||||
SystemString m_friendlyName;
|
||||
SystemString m_pname;
|
||||
std::vector<SystemString> m_args;
|
||||
bool m_singleInstance;
|
||||
public:
|
||||
virtual IFrameworkView ^ CreateView();
|
||||
|
||||
internal : boo::IApplicationCallback& m_appCb;
|
||||
SystemString m_uniqueName;
|
||||
SystemString m_friendlyName;
|
||||
SystemString m_pname;
|
||||
std::vector<SystemString> m_args;
|
||||
bool m_singleInstance;
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -5,51 +5,39 @@
|
||||
#include <memory>
|
||||
#include "boo/BooObject.hpp"
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
struct IAudioVoice;
|
||||
struct IAudioVoiceCallback;
|
||||
struct ChannelMap;
|
||||
struct IAudioSubmixCallback;
|
||||
|
||||
enum class SubmixFormat
|
||||
{
|
||||
Int16,
|
||||
Int32,
|
||||
Float
|
||||
enum class SubmixFormat { Int16, Int32, Float };
|
||||
|
||||
struct IAudioSubmix : IObj {
|
||||
/** Reset channel-levels to silence; unbind all submixes */
|
||||
virtual void resetSendLevels() = 0;
|
||||
|
||||
/** Set channel-levels for target submix (AudioChannel enum for array index) */
|
||||
virtual void setSendLevel(IAudioSubmix* submix, float level, bool slew) = 0;
|
||||
|
||||
/** Gets fixed sample rate of submix this way */
|
||||
virtual double getSampleRate() const = 0;
|
||||
|
||||
/** Gets fixed sample format of submix this way */
|
||||
virtual SubmixFormat getSampleFormat() const = 0;
|
||||
};
|
||||
|
||||
struct IAudioSubmix : IObj
|
||||
{
|
||||
/** Reset channel-levels to silence; unbind all submixes */
|
||||
virtual void resetSendLevels()=0;
|
||||
struct IAudioSubmixCallback {
|
||||
/** Client-provided claim to implement / is ready to call applyEffect() */
|
||||
virtual bool canApplyEffect() const = 0;
|
||||
|
||||
/** Set channel-levels for target submix (AudioChannel enum for array index) */
|
||||
virtual void setSendLevel(IAudioSubmix* submix, float level, bool slew)=0;
|
||||
/** Client-provided effect solution for interleaved, master sample-rate audio */
|
||||
virtual void applyEffect(int16_t* audio, size_t frameCount, const ChannelMap& chanMap, double sampleRate) const = 0;
|
||||
virtual void applyEffect(int32_t* audio, size_t frameCount, const ChannelMap& chanMap, double sampleRate) const = 0;
|
||||
virtual void applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap, double sampleRate) const = 0;
|
||||
|
||||
/** Gets fixed sample rate of submix this way */
|
||||
virtual double getSampleRate() const=0;
|
||||
|
||||
/** Gets fixed sample format of submix this way */
|
||||
virtual SubmixFormat getSampleFormat() const=0;
|
||||
/** Notify of output sample rate changes (for instance, changing the default audio device on Windows) */
|
||||
virtual void resetOutputSampleRate(double sampleRate) = 0;
|
||||
};
|
||||
|
||||
struct IAudioSubmixCallback
|
||||
{
|
||||
/** Client-provided claim to implement / is ready to call applyEffect() */
|
||||
virtual bool canApplyEffect() const=0;
|
||||
|
||||
/** Client-provided effect solution for interleaved, master sample-rate audio */
|
||||
virtual void applyEffect(int16_t* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate) const=0;
|
||||
virtual void applyEffect(int32_t* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate) const=0;
|
||||
virtual void applyEffect(float* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate) const=0;
|
||||
|
||||
/** Notify of output sample rate changes (for instance, changing the default audio device on Windows) */
|
||||
virtual void resetOutputSampleRate(double sampleRate)=0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -5,106 +5,89 @@
|
||||
#include <cstring>
|
||||
#include "boo/BooObject.hpp"
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
struct IAudioSubmix;
|
||||
|
||||
enum class AudioChannelSet
|
||||
{
|
||||
Stereo,
|
||||
Quad,
|
||||
Surround51,
|
||||
Surround71,
|
||||
Unknown = 0xff
|
||||
enum class AudioChannelSet { Stereo, Quad, Surround51, Surround71, Unknown = 0xff };
|
||||
|
||||
enum class AudioChannel {
|
||||
FrontLeft,
|
||||
FrontRight,
|
||||
RearLeft,
|
||||
RearRight,
|
||||
FrontCenter,
|
||||
LFE,
|
||||
SideLeft,
|
||||
SideRight,
|
||||
Unknown = 0xff
|
||||
};
|
||||
|
||||
enum class AudioChannel
|
||||
{
|
||||
FrontLeft,
|
||||
FrontRight,
|
||||
RearLeft,
|
||||
RearRight,
|
||||
FrontCenter,
|
||||
LFE,
|
||||
SideLeft,
|
||||
SideRight,
|
||||
Unknown = 0xff
|
||||
struct ChannelMap {
|
||||
unsigned m_channelCount = 0;
|
||||
AudioChannel m_channels[8] = {};
|
||||
};
|
||||
|
||||
struct ChannelMap
|
||||
{
|
||||
unsigned m_channelCount = 0;
|
||||
AudioChannel m_channels[8] = {};
|
||||
};
|
||||
|
||||
static inline unsigned ChannelCount(AudioChannelSet layout)
|
||||
{
|
||||
switch (layout)
|
||||
{
|
||||
case AudioChannelSet::Stereo:
|
||||
return 2;
|
||||
case AudioChannelSet::Quad:
|
||||
return 4;
|
||||
case AudioChannelSet::Surround51:
|
||||
return 6;
|
||||
case AudioChannelSet::Surround71:
|
||||
return 8;
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
static inline unsigned ChannelCount(AudioChannelSet layout) {
|
||||
switch (layout) {
|
||||
case AudioChannelSet::Stereo:
|
||||
return 2;
|
||||
case AudioChannelSet::Quad:
|
||||
return 4;
|
||||
case AudioChannelSet::Surround51:
|
||||
return 6;
|
||||
case AudioChannelSet::Surround71:
|
||||
return 8;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct IAudioVoice : IObj
|
||||
{
|
||||
/** Set sample rate into voice (may result in audio discontinuities) */
|
||||
virtual void resetSampleRate(double sampleRate)=0;
|
||||
struct IAudioVoice : IObj {
|
||||
/** Set sample rate into voice (may result in audio discontinuities) */
|
||||
virtual void resetSampleRate(double sampleRate) = 0;
|
||||
|
||||
/** Reset channel-levels to silence; unbind all submixes */
|
||||
virtual void resetChannelLevels()=0;
|
||||
/** Reset channel-levels to silence; unbind all submixes */
|
||||
virtual void resetChannelLevels() = 0;
|
||||
|
||||
/** Set channel-levels for mono audio source (AudioChannel enum for array index) */
|
||||
virtual void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew)=0;
|
||||
/** Set channel-levels for mono audio source (AudioChannel enum for array index) */
|
||||
virtual void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew) = 0;
|
||||
|
||||
/** Set channel-levels for stereo audio source (AudioChannel enum for array index) */
|
||||
virtual void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew)=0;
|
||||
/** Set channel-levels for stereo audio source (AudioChannel enum for array index) */
|
||||
virtual void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew) = 0;
|
||||
|
||||
/** Called by client to dynamically adjust the pitch of voices with dynamic pitch enabled */
|
||||
virtual void setPitchRatio(double ratio, bool slew)=0;
|
||||
/** Called by client to dynamically adjust the pitch of voices with dynamic pitch enabled */
|
||||
virtual void setPitchRatio(double ratio, bool slew) = 0;
|
||||
|
||||
/** Instructs platform to begin consuming sample data; invoking callback as needed */
|
||||
virtual void start()=0;
|
||||
/** Instructs platform to begin consuming sample data; invoking callback as needed */
|
||||
virtual void start() = 0;
|
||||
|
||||
/** Instructs platform to stop consuming sample data */
|
||||
virtual void stop()=0;
|
||||
/** Instructs platform to stop consuming sample data */
|
||||
virtual void stop() = 0;
|
||||
};
|
||||
|
||||
struct IAudioVoiceCallback
|
||||
{
|
||||
/** boo calls this on behalf of the audio platform to proactively invoke potential
|
||||
* pitch or panning changes before processing samples */
|
||||
virtual void preSupplyAudio(boo::IAudioVoice& voice, double dt)=0;
|
||||
struct IAudioVoiceCallback {
|
||||
/** boo calls this on behalf of the audio platform to proactively invoke potential
|
||||
* pitch or panning changes before processing samples */
|
||||
virtual void preSupplyAudio(boo::IAudioVoice& voice, double dt) = 0;
|
||||
|
||||
/** boo calls this on behalf of the audio platform to request more audio
|
||||
* frames from the client */
|
||||
virtual size_t supplyAudio(IAudioVoice& voice, size_t frames, int16_t* data)=0;
|
||||
/** boo calls this on behalf of the audio platform to request more audio
|
||||
* frames from the client */
|
||||
virtual size_t supplyAudio(IAudioVoice& voice, size_t frames, int16_t* data) = 0;
|
||||
|
||||
/** after resampling, boo calls this for each submix that this voice targets;
|
||||
* client performs volume processing and bus-routing this way */
|
||||
virtual void routeAudio(size_t frames, size_t channels, double dt, int busId, int16_t* in, int16_t* out)
|
||||
{
|
||||
memmove(out, in, frames * channels * 2);
|
||||
}
|
||||
/** after resampling, boo calls this for each submix that this voice targets;
|
||||
* client performs volume processing and bus-routing this way */
|
||||
virtual void routeAudio(size_t frames, size_t channels, double dt, int busId, int16_t* in, int16_t* out) {
|
||||
memmove(out, in, frames * channels * 2);
|
||||
}
|
||||
|
||||
virtual void routeAudio(size_t frames, size_t channels, double dt, int busId, int32_t* in, int32_t* out)
|
||||
{
|
||||
memmove(out, in, frames * channels * 4);
|
||||
}
|
||||
virtual void routeAudio(size_t frames, size_t channels, double dt, int busId, int32_t* in, int32_t* out) {
|
||||
memmove(out, in, frames * channels * 4);
|
||||
}
|
||||
|
||||
virtual void routeAudio(size_t frames, size_t channels, double dt, int busId, float* in, float* out)
|
||||
{
|
||||
memmove(out, in, frames * channels * 4);
|
||||
}
|
||||
virtual void routeAudio(size_t frames, size_t channels, double dt, int busId, float* in, float* out) {
|
||||
memmove(out, in, frames * channels * 4);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -7,100 +7,95 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
struct IAudioVoiceEngine;
|
||||
|
||||
/** Time-sensitive event callback for synchronizing the client with rendered audio waveform */
|
||||
struct IAudioVoiceEngineCallback
|
||||
{
|
||||
/** All mixing occurs in virtual 5ms intervals;
|
||||
* this is called at the start of each interval for all mixable entities */
|
||||
virtual void on5MsInterval(IAudioVoiceEngine& engine, double dt) {}
|
||||
struct IAudioVoiceEngineCallback {
|
||||
/** All mixing occurs in virtual 5ms intervals;
|
||||
* this is called at the start of each interval for all mixable entities */
|
||||
virtual void on5MsInterval(IAudioVoiceEngine& engine, double dt) {}
|
||||
|
||||
/** When a pumping cycle is complete this is called to allow the client to
|
||||
* perform periodic cleanup tasks */
|
||||
virtual void onPumpCycleComplete(IAudioVoiceEngine& engine) {}
|
||||
/** When a pumping cycle is complete this is called to allow the client to
|
||||
* perform periodic cleanup tasks */
|
||||
virtual void onPumpCycleComplete(IAudioVoiceEngine& engine) {}
|
||||
};
|
||||
|
||||
/** Mixing and sample-rate-conversion system. Allocates voices and mixes them
|
||||
* before sending the final samples to an OS-supplied audio-queue */
|
||||
struct IAudioVoiceEngine
|
||||
{
|
||||
virtual ~IAudioVoiceEngine() = default;
|
||||
struct IAudioVoiceEngine {
|
||||
virtual ~IAudioVoiceEngine() = default;
|
||||
|
||||
/** Client calls this to request allocation of new mixer-voice.
|
||||
* Returns empty unique_ptr if necessary resources aren't available.
|
||||
* ChannelLayout automatically reduces to maximum-supported layout by HW.
|
||||
*
|
||||
* Client must be prepared to supply audio frames via the callback when this is called;
|
||||
* the backing audio-buffers are primed with initial data for low-latency playback start
|
||||
*/
|
||||
virtual ObjToken<IAudioVoice> allocateNewMonoVoice(double sampleRate,
|
||||
IAudioVoiceCallback* cb,
|
||||
bool dynamicPitch=false)=0;
|
||||
/** Client calls this to request allocation of new mixer-voice.
|
||||
* Returns empty unique_ptr if necessary resources aren't available.
|
||||
* ChannelLayout automatically reduces to maximum-supported layout by HW.
|
||||
*
|
||||
* Client must be prepared to supply audio frames via the callback when this is called;
|
||||
* the backing audio-buffers are primed with initial data for low-latency playback start
|
||||
*/
|
||||
virtual ObjToken<IAudioVoice> allocateNewMonoVoice(double sampleRate, IAudioVoiceCallback* cb,
|
||||
bool dynamicPitch = false) = 0;
|
||||
|
||||
/** Same as allocateNewMonoVoice, but source audio is stereo-interleaved */
|
||||
virtual ObjToken<IAudioVoice> allocateNewStereoVoice(double sampleRate,
|
||||
IAudioVoiceCallback* cb,
|
||||
bool dynamicPitch=false)=0;
|
||||
/** Same as allocateNewMonoVoice, but source audio is stereo-interleaved */
|
||||
virtual ObjToken<IAudioVoice> allocateNewStereoVoice(double sampleRate, IAudioVoiceCallback* cb,
|
||||
bool dynamicPitch = false) = 0;
|
||||
|
||||
/** Client calls this to allocate a Submix for gathering audio together for effects processing */
|
||||
virtual ObjToken<IAudioSubmix> allocateNewSubmix(bool mainOut, IAudioSubmixCallback* cb, int busId)=0;
|
||||
/** Client calls this to allocate a Submix for gathering audio together for effects processing */
|
||||
virtual ObjToken<IAudioSubmix> allocateNewSubmix(bool mainOut, IAudioSubmixCallback* cb, int busId) = 0;
|
||||
|
||||
/** Client can register for key callback events from the mixing engine this way */
|
||||
virtual void setCallbackInterface(IAudioVoiceEngineCallback* cb)=0;
|
||||
/** Client can register for key callback events from the mixing engine this way */
|
||||
virtual void setCallbackInterface(IAudioVoiceEngineCallback* cb) = 0;
|
||||
|
||||
/** Client may use this to determine current speaker-setup */
|
||||
virtual AudioChannelSet getAvailableSet()=0;
|
||||
/** Client may use this to determine current speaker-setup */
|
||||
virtual AudioChannelSet getAvailableSet() = 0;
|
||||
|
||||
/** Ensure backing platform buffer is filled as much as possible with mixed samples */
|
||||
virtual void pumpAndMixVoices()=0;
|
||||
/** Ensure backing platform buffer is filled as much as possible with mixed samples */
|
||||
virtual void pumpAndMixVoices() = 0;
|
||||
|
||||
/** Set total volume of engine */
|
||||
virtual void setVolume(float vol)=0;
|
||||
/** Set total volume of engine */
|
||||
virtual void setVolume(float vol) = 0;
|
||||
|
||||
/** Enable or disable Lt/Rt surround encoding. If successful, getAvailableSet() will return Surround51 */
|
||||
virtual bool enableLtRt(bool enable)=0;
|
||||
/** Enable or disable Lt/Rt surround encoding. If successful, getAvailableSet() will return Surround51 */
|
||||
virtual bool enableLtRt(bool enable) = 0;
|
||||
|
||||
/** Get current Audio output in use */
|
||||
virtual std::string getCurrentAudioOutput() const=0;
|
||||
/** Get current Audio output in use */
|
||||
virtual std::string getCurrentAudioOutput() const = 0;
|
||||
|
||||
/** Set current Audio output to use */
|
||||
virtual bool setCurrentAudioOutput(const char* name)=0;
|
||||
/** Set current Audio output to use */
|
||||
virtual bool setCurrentAudioOutput(const char* name) = 0;
|
||||
|
||||
/** Get list of Audio output devices found on system */
|
||||
virtual std::vector<std::pair<std::string, std::string>> enumerateAudioOutputs() const=0;
|
||||
/** Get list of Audio output devices found on system */
|
||||
virtual std::vector<std::pair<std::string, std::string>> enumerateAudioOutputs() const = 0;
|
||||
|
||||
/** Get list of MIDI input devices found on system */
|
||||
virtual std::vector<std::pair<std::string, std::string>> enumerateMIDIInputs() const=0;
|
||||
/** Get list of MIDI input devices found on system */
|
||||
virtual std::vector<std::pair<std::string, std::string>> enumerateMIDIInputs() const = 0;
|
||||
|
||||
/** Query if system supports creating a virtual MIDI input */
|
||||
virtual bool supportsVirtualMIDIIn() const=0;
|
||||
/** Query if system supports creating a virtual MIDI input */
|
||||
virtual bool supportsVirtualMIDIIn() const = 0;
|
||||
|
||||
/** Create ad-hoc MIDI in port and register with system */
|
||||
virtual std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver)=0;
|
||||
/** Create ad-hoc MIDI in port and register with system */
|
||||
virtual std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) = 0;
|
||||
|
||||
/** Create ad-hoc MIDI out port and register with system */
|
||||
virtual std::unique_ptr<IMIDIOut> newVirtualMIDIOut()=0;
|
||||
/** Create ad-hoc MIDI out port and register with system */
|
||||
virtual std::unique_ptr<IMIDIOut> newVirtualMIDIOut() = 0;
|
||||
|
||||
/** Create ad-hoc MIDI in/out port and register with system */
|
||||
virtual std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver)=0;
|
||||
/** Create ad-hoc MIDI in/out port and register with system */
|
||||
virtual std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) = 0;
|
||||
|
||||
/** Open named MIDI in port, name format depends on OS */
|
||||
virtual std::unique_ptr<IMIDIIn> newRealMIDIIn(const char* name, ReceiveFunctor&& receiver)=0;
|
||||
/** Open named MIDI in port, name format depends on OS */
|
||||
virtual std::unique_ptr<IMIDIIn> newRealMIDIIn(const char* name, ReceiveFunctor&& receiver) = 0;
|
||||
|
||||
/** Open named MIDI out port, name format depends on OS */
|
||||
virtual std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name)=0;
|
||||
/** Open named MIDI out port, name format depends on OS */
|
||||
virtual std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) = 0;
|
||||
|
||||
/** Open named MIDI in/out port, name format depends on OS */
|
||||
virtual std::unique_ptr<IMIDIInOut> newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver)=0;
|
||||
/** Open named MIDI in/out port, name format depends on OS */
|
||||
virtual std::unique_ptr<IMIDIInOut> newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver) = 0;
|
||||
|
||||
/** If this returns true, MIDI callbacks are assumed to be *not* thread-safe; need protection via mutex */
|
||||
virtual bool useMIDILock() const=0;
|
||||
/** If this returns true, MIDI callbacks are assumed to be *not* thread-safe; need protection via mutex */
|
||||
virtual bool useMIDILock() const = 0;
|
||||
|
||||
/** Get canonical count of frames for each 5ms output block */
|
||||
virtual size_t get5MsFrames() const=0;
|
||||
/** Get canonical count of frames for each 5ms output block */
|
||||
virtual size_t get5MsFrames() const = 0;
|
||||
};
|
||||
|
||||
/** Construct host platform's voice engine */
|
||||
@@ -112,5 +107,4 @@ std::unique_ptr<IAudioVoiceEngine> NewWAVAudioVoiceEngine(const char* path, doub
|
||||
std::unique_ptr<IAudioVoiceEngine> NewWAVAudioVoiceEngine(const wchar_t* path, double sampleRate, int numChans);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -5,58 +5,56 @@
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
struct IAudioVoiceEngine;
|
||||
using ReceiveFunctor = std::function<void(std::vector<uint8_t>&&, double time)>;
|
||||
|
||||
class IMIDIPort
|
||||
{
|
||||
bool m_virtual;
|
||||
class IMIDIPort {
|
||||
bool m_virtual;
|
||||
|
||||
protected:
|
||||
IAudioVoiceEngine* m_parent;
|
||||
IMIDIPort(IAudioVoiceEngine* parent, bool virt) : m_virtual(virt), m_parent(parent) {}
|
||||
IAudioVoiceEngine* m_parent;
|
||||
IMIDIPort(IAudioVoiceEngine* parent, bool virt) : m_virtual(virt), m_parent(parent) {}
|
||||
|
||||
public:
|
||||
virtual ~IMIDIPort();
|
||||
bool isVirtual() const {return m_virtual;}
|
||||
virtual std::string description() const=0;
|
||||
void _disown() { m_parent = nullptr; }
|
||||
virtual ~IMIDIPort();
|
||||
bool isVirtual() const { return m_virtual; }
|
||||
virtual std::string description() const = 0;
|
||||
void _disown() { m_parent = nullptr; }
|
||||
};
|
||||
|
||||
class IMIDIReceiver
|
||||
{
|
||||
class IMIDIReceiver {
|
||||
public:
|
||||
ReceiveFunctor m_receiver;
|
||||
IMIDIReceiver(ReceiveFunctor&& receiver) : m_receiver(std::move(receiver)) {}
|
||||
ReceiveFunctor m_receiver;
|
||||
IMIDIReceiver(ReceiveFunctor&& receiver) : m_receiver(std::move(receiver)) {}
|
||||
};
|
||||
|
||||
class IMIDIIn : public IMIDIPort, public IMIDIReceiver
|
||||
{
|
||||
class IMIDIIn : public IMIDIPort, public IMIDIReceiver {
|
||||
protected:
|
||||
IMIDIIn(IAudioVoiceEngine* parent, bool virt, ReceiveFunctor&& receiver)
|
||||
: IMIDIPort(parent, virt), IMIDIReceiver(std::move(receiver)) {}
|
||||
IMIDIIn(IAudioVoiceEngine* parent, bool virt, ReceiveFunctor&& receiver)
|
||||
: IMIDIPort(parent, virt), IMIDIReceiver(std::move(receiver)) {}
|
||||
|
||||
public:
|
||||
virtual ~IMIDIIn();
|
||||
virtual ~IMIDIIn();
|
||||
};
|
||||
|
||||
class IMIDIOut : public IMIDIPort
|
||||
{
|
||||
class IMIDIOut : public IMIDIPort {
|
||||
protected:
|
||||
IMIDIOut(IAudioVoiceEngine* parent, bool virt) : IMIDIPort(parent, virt) {}
|
||||
IMIDIOut(IAudioVoiceEngine* parent, bool virt) : IMIDIPort(parent, virt) {}
|
||||
|
||||
public:
|
||||
virtual ~IMIDIOut();
|
||||
virtual size_t send(const void* buf, size_t len) const=0;
|
||||
virtual ~IMIDIOut();
|
||||
virtual size_t send(const void* buf, size_t len) const = 0;
|
||||
};
|
||||
|
||||
class IMIDIInOut : public IMIDIPort, public IMIDIReceiver
|
||||
{
|
||||
class IMIDIInOut : public IMIDIPort, public IMIDIReceiver {
|
||||
protected:
|
||||
IMIDIInOut(IAudioVoiceEngine* parent, bool virt, ReceiveFunctor&& receiver)
|
||||
: IMIDIPort(parent, virt), IMIDIReceiver(std::move(receiver)) {}
|
||||
IMIDIInOut(IAudioVoiceEngine* parent, bool virt, ReceiveFunctor&& receiver)
|
||||
: IMIDIPort(parent, virt), IMIDIReceiver(std::move(receiver)) {}
|
||||
|
||||
public:
|
||||
virtual ~IMIDIInOut();
|
||||
virtual size_t send(const void* buf, size_t len) const=0;
|
||||
virtual ~IMIDIInOut();
|
||||
virtual size_t send(const void* buf, size_t len) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -3,39 +3,36 @@
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
|
||||
class IMIDIReader
|
||||
{
|
||||
class IMIDIReader {
|
||||
public:
|
||||
virtual void noteOff(uint8_t chan, uint8_t key, uint8_t velocity)=0;
|
||||
virtual void noteOn(uint8_t chan, uint8_t key, uint8_t velocity)=0;
|
||||
virtual void notePressure(uint8_t chan, uint8_t key, uint8_t pressure)=0;
|
||||
virtual void controlChange(uint8_t chan, uint8_t control, uint8_t value)=0;
|
||||
virtual void programChange(uint8_t chan, uint8_t program)=0;
|
||||
virtual void channelPressure(uint8_t chan, uint8_t pressure)=0;
|
||||
virtual void pitchBend(uint8_t chan, int16_t pitch)=0;
|
||||
virtual void noteOff(uint8_t chan, uint8_t key, uint8_t velocity) = 0;
|
||||
virtual void noteOn(uint8_t chan, uint8_t key, uint8_t velocity) = 0;
|
||||
virtual void notePressure(uint8_t chan, uint8_t key, uint8_t pressure) = 0;
|
||||
virtual void controlChange(uint8_t chan, uint8_t control, uint8_t value) = 0;
|
||||
virtual void programChange(uint8_t chan, uint8_t program) = 0;
|
||||
virtual void channelPressure(uint8_t chan, uint8_t pressure) = 0;
|
||||
virtual void pitchBend(uint8_t chan, int16_t pitch) = 0;
|
||||
|
||||
virtual void allSoundOff(uint8_t chan)=0;
|
||||
virtual void resetAllControllers(uint8_t chan)=0;
|
||||
virtual void localControl(uint8_t chan, bool on)=0;
|
||||
virtual void allNotesOff(uint8_t chan)=0;
|
||||
virtual void omniMode(uint8_t chan, bool on)=0;
|
||||
virtual void polyMode(uint8_t chan, bool on)=0;
|
||||
virtual void allSoundOff(uint8_t chan) = 0;
|
||||
virtual void resetAllControllers(uint8_t chan) = 0;
|
||||
virtual void localControl(uint8_t chan, bool on) = 0;
|
||||
virtual void allNotesOff(uint8_t chan) = 0;
|
||||
virtual void omniMode(uint8_t chan, bool on) = 0;
|
||||
virtual void polyMode(uint8_t chan, bool on) = 0;
|
||||
|
||||
virtual void sysex(const void* data, size_t len)=0;
|
||||
virtual void timeCodeQuarterFrame(uint8_t message, uint8_t value)=0;
|
||||
virtual void songPositionPointer(uint16_t pointer)=0;
|
||||
virtual void songSelect(uint8_t song)=0;
|
||||
virtual void tuneRequest()=0;
|
||||
virtual void sysex(const void* data, size_t len) = 0;
|
||||
virtual void timeCodeQuarterFrame(uint8_t message, uint8_t value) = 0;
|
||||
virtual void songPositionPointer(uint16_t pointer) = 0;
|
||||
virtual void songSelect(uint8_t song) = 0;
|
||||
virtual void tuneRequest() = 0;
|
||||
|
||||
virtual void startSeq()=0;
|
||||
virtual void continueSeq()=0;
|
||||
virtual void stopSeq()=0;
|
||||
virtual void startSeq() = 0;
|
||||
virtual void continueSeq() = 0;
|
||||
virtual void stopSeq() = 0;
|
||||
|
||||
virtual void reset()=0;
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -5,22 +5,18 @@
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
|
||||
class MIDIDecoder {
|
||||
IMIDIReader& m_out;
|
||||
uint8_t m_status = 0;
|
||||
bool _readContinuedValue(std::vector<uint8_t>::const_iterator& it, std::vector<uint8_t>::const_iterator end,
|
||||
uint32_t& valOut);
|
||||
|
||||
class MIDIDecoder
|
||||
{
|
||||
IMIDIReader& m_out;
|
||||
uint8_t m_status = 0;
|
||||
bool _readContinuedValue(std::vector<uint8_t>::const_iterator& it,
|
||||
std::vector<uint8_t>::const_iterator end,
|
||||
uint32_t& valOut);
|
||||
public:
|
||||
MIDIDecoder(IMIDIReader& out) : m_out(out) {}
|
||||
std::vector<uint8_t>::const_iterator
|
||||
receiveBytes(std::vector<uint8_t>::const_iterator begin,
|
||||
std::vector<uint8_t>::const_iterator end);
|
||||
MIDIDecoder(IMIDIReader& out) : m_out(out) {}
|
||||
std::vector<uint8_t>::const_iterator receiveBytes(std::vector<uint8_t>::const_iterator begin,
|
||||
std::vector<uint8_t>::const_iterator end);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -3,46 +3,44 @@
|
||||
#include "boo/audiodev/IMIDIReader.hpp"
|
||||
#include "boo/audiodev/IMIDIPort.hpp"
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
|
||||
template <class Sender>
|
||||
class MIDIEncoder : public IMIDIReader
|
||||
{
|
||||
Sender& m_sender;
|
||||
uint8_t m_status = 0;
|
||||
void _sendMessage(const uint8_t* data, size_t len);
|
||||
void _sendContinuedValue(uint32_t val);
|
||||
class MIDIEncoder : public IMIDIReader {
|
||||
Sender& m_sender;
|
||||
uint8_t m_status = 0;
|
||||
void _sendMessage(const uint8_t* data, size_t len);
|
||||
void _sendContinuedValue(uint32_t val);
|
||||
|
||||
public:
|
||||
MIDIEncoder(Sender& sender) : m_sender(sender) {}
|
||||
MIDIEncoder(Sender& sender) : m_sender(sender) {}
|
||||
|
||||
void noteOff(uint8_t chan, uint8_t key, uint8_t velocity);
|
||||
void noteOn(uint8_t chan, uint8_t key, uint8_t velocity);
|
||||
void notePressure(uint8_t chan, uint8_t key, uint8_t pressure);
|
||||
void controlChange(uint8_t chan, uint8_t control, uint8_t value);
|
||||
void programChange(uint8_t chan, uint8_t program);
|
||||
void channelPressure(uint8_t chan, uint8_t pressure);
|
||||
void pitchBend(uint8_t chan, int16_t pitch);
|
||||
void noteOff(uint8_t chan, uint8_t key, uint8_t velocity);
|
||||
void noteOn(uint8_t chan, uint8_t key, uint8_t velocity);
|
||||
void notePressure(uint8_t chan, uint8_t key, uint8_t pressure);
|
||||
void controlChange(uint8_t chan, uint8_t control, uint8_t value);
|
||||
void programChange(uint8_t chan, uint8_t program);
|
||||
void channelPressure(uint8_t chan, uint8_t pressure);
|
||||
void pitchBend(uint8_t chan, int16_t pitch);
|
||||
|
||||
void allSoundOff(uint8_t chan);
|
||||
void resetAllControllers(uint8_t chan);
|
||||
void localControl(uint8_t chan, bool on);
|
||||
void allNotesOff(uint8_t chan);
|
||||
void omniMode(uint8_t chan, bool on);
|
||||
void polyMode(uint8_t chan, bool on);
|
||||
void allSoundOff(uint8_t chan);
|
||||
void resetAllControllers(uint8_t chan);
|
||||
void localControl(uint8_t chan, bool on);
|
||||
void allNotesOff(uint8_t chan);
|
||||
void omniMode(uint8_t chan, bool on);
|
||||
void polyMode(uint8_t chan, bool on);
|
||||
|
||||
void sysex(const void* data, size_t len);
|
||||
void timeCodeQuarterFrame(uint8_t message, uint8_t value);
|
||||
void songPositionPointer(uint16_t pointer);
|
||||
void songSelect(uint8_t song);
|
||||
void tuneRequest();
|
||||
void sysex(const void* data, size_t len);
|
||||
void timeCodeQuarterFrame(uint8_t message, uint8_t value);
|
||||
void songPositionPointer(uint16_t pointer);
|
||||
void songSelect(uint8_t song);
|
||||
void tuneRequest();
|
||||
|
||||
void startSeq();
|
||||
void continueSeq();
|
||||
void stopSeq();
|
||||
void startSeq();
|
||||
void continueSeq();
|
||||
void stopSeq();
|
||||
|
||||
void reset();
|
||||
void reset();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -10,4 +10,3 @@
|
||||
#include "graphicsdev/IGraphicsCommandQueue.hpp"
|
||||
#include "graphicsdev/IGraphicsDataFactory.hpp"
|
||||
#include "DeferredWindowEvents.hpp"
|
||||
|
||||
|
||||
@@ -9,70 +9,61 @@
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
typedef HRESULT (WINAPI *pD3DCreateBlob)
|
||||
(SIZE_T Size,
|
||||
ID3DBlob** ppBlob);
|
||||
typedef HRESULT(WINAPI* pD3DCreateBlob)(SIZE_T Size, ID3DBlob** ppBlob);
|
||||
extern pD3DCreateBlob D3DCreateBlobPROC;
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
struct BaseGraphicsData;
|
||||
|
||||
class D3D11DataFactory : public IGraphicsDataFactory
|
||||
{
|
||||
class D3D11DataFactory : public IGraphicsDataFactory {
|
||||
public:
|
||||
virtual ~D3D11DataFactory() = default;
|
||||
virtual ~D3D11DataFactory() = default;
|
||||
|
||||
Platform platform() const {return Platform::D3D11;}
|
||||
const SystemChar* platformName() const {return _SYS_STR("D3D11");}
|
||||
Platform platform() const { return Platform::D3D11; }
|
||||
const SystemChar* platformName() const { return _SYS_STR("D3D11"); }
|
||||
|
||||
class Context final : public IGraphicsDataFactory::Context
|
||||
{
|
||||
friend class D3D11DataFactoryImpl;
|
||||
D3D11DataFactory& m_parent;
|
||||
boo::ObjToken<BaseGraphicsData> m_data;
|
||||
Context(D3D11DataFactory& parent __BooTraceArgs);
|
||||
~Context();
|
||||
public:
|
||||
Platform platform() const {return Platform::D3D11;}
|
||||
const SystemChar* platformName() const {return _SYS_STR("D3D11");}
|
||||
class Context final : public IGraphicsDataFactory::Context {
|
||||
friend class D3D11DataFactoryImpl;
|
||||
D3D11DataFactory& m_parent;
|
||||
boo::ObjToken<BaseGraphicsData> m_data;
|
||||
Context(D3D11DataFactory& parent __BooTraceArgs);
|
||||
~Context();
|
||||
|
||||
boo::ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
|
||||
boo::ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count);
|
||||
public:
|
||||
Platform platform() const { return Platform::D3D11; }
|
||||
const SystemChar* platformName() const { return _SYS_STR("D3D11"); }
|
||||
|
||||
boo::ObjToken<ITextureS> newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||
TextureClampMode clampMode, const void* data, size_t sz);
|
||||
boo::ObjToken<ITextureSA> newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
|
||||
TextureFormat fmt, TextureClampMode clampMode,
|
||||
const void* data, size_t sz);
|
||||
boo::ObjToken<ITextureD> newDynamicTexture(size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode);
|
||||
boo::ObjToken<ITextureR> newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
|
||||
size_t colorBindCount, size_t depthBindCount);
|
||||
boo::ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
|
||||
boo::ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count);
|
||||
|
||||
ObjToken<IShaderStage>
|
||||
newShaderStage(const uint8_t* data, size_t size, PipelineStage stage);
|
||||
boo::ObjToken<ITextureS> newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||
TextureClampMode clampMode, const void* data, size_t sz);
|
||||
boo::ObjToken<ITextureSA> newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
|
||||
TextureFormat fmt, TextureClampMode clampMode, const void* data,
|
||||
size_t sz);
|
||||
boo::ObjToken<ITextureD> newDynamicTexture(size_t width, size_t height, TextureFormat fmt,
|
||||
TextureClampMode clampMode);
|
||||
boo::ObjToken<ITextureR> newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
|
||||
size_t colorBindCount, size_t depthBindCount);
|
||||
|
||||
ObjToken<IShaderPipeline>
|
||||
newShaderPipeline(ObjToken<IShaderStage> vertex, ObjToken<IShaderStage> fragment,
|
||||
ObjToken<IShaderStage> geometry, ObjToken<IShaderStage> control,
|
||||
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
|
||||
const AdditionalPipelineInfo& additionalInfo);
|
||||
ObjToken<IShaderStage> newShaderStage(const uint8_t* data, size_t size, PipelineStage stage);
|
||||
|
||||
boo::ObjToken<IShaderDataBinding>
|
||||
newShaderDataBinding(const boo::ObjToken<IShaderPipeline>& pipeline,
|
||||
const boo::ObjToken<IGraphicsBuffer>& vbo,
|
||||
const boo::ObjToken<IGraphicsBuffer>& instVbo,
|
||||
const boo::ObjToken<IGraphicsBuffer>& ibo,
|
||||
size_t ubufCount, const boo::ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages,
|
||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||
size_t texCount, const boo::ObjToken<ITexture>* texs,
|
||||
const int* bindIdxs, const bool* bindDepth,
|
||||
size_t baseVert = 0, size_t baseInst = 0);
|
||||
};
|
||||
ObjToken<IShaderPipeline> newShaderPipeline(ObjToken<IShaderStage> vertex, ObjToken<IShaderStage> fragment,
|
||||
ObjToken<IShaderStage> geometry, ObjToken<IShaderStage> control,
|
||||
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
|
||||
const AdditionalPipelineInfo& additionalInfo);
|
||||
|
||||
static std::vector<uint8_t> CompileHLSL(const char* source, PipelineStage stage);
|
||||
boo::ObjToken<IShaderDataBinding> newShaderDataBinding(
|
||||
const boo::ObjToken<IShaderPipeline>& pipeline, const boo::ObjToken<IGraphicsBuffer>& vbo,
|
||||
const boo::ObjToken<IGraphicsBuffer>& instVbo, const boo::ObjToken<IGraphicsBuffer>& ibo, size_t ubufCount,
|
||||
const boo::ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages, const size_t* ubufOffs,
|
||||
const size_t* ubufSizes, size_t texCount, const boo::ObjToken<ITexture>* texs, const int* bindIdxs,
|
||||
const bool* bindDepth, size_t baseVert = 0, size_t baseInst = 0);
|
||||
};
|
||||
|
||||
static std::vector<uint8_t> CompileHLSL(const char* source, PipelineStage stage);
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace boo
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -6,64 +6,56 @@
|
||||
#include "boo/IGraphicsContext.hpp"
|
||||
#include "GLSLMacros.hpp"
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
struct BaseGraphicsData;
|
||||
|
||||
struct GLContext
|
||||
{
|
||||
uint32_t m_sampleCount = 1;
|
||||
uint32_t m_anisotropy = 1;
|
||||
bool m_deepColor = false;
|
||||
struct GLContext {
|
||||
uint32_t m_sampleCount = 1;
|
||||
uint32_t m_anisotropy = 1;
|
||||
bool m_deepColor = false;
|
||||
};
|
||||
|
||||
class GLDataFactory : public IGraphicsDataFactory
|
||||
{
|
||||
class GLDataFactory : public IGraphicsDataFactory {
|
||||
public:
|
||||
class Context final : public IGraphicsDataFactory::Context
|
||||
{
|
||||
friend class GLDataFactoryImpl;
|
||||
GLDataFactory& m_parent;
|
||||
ObjToken<BaseGraphicsData> m_data;
|
||||
Context(GLDataFactory& parent __BooTraceArgs);
|
||||
~Context();
|
||||
public:
|
||||
Platform platform() const { return Platform::OpenGL; }
|
||||
const SystemChar* platformName() const { return _SYS_STR("OpenGL"); }
|
||||
class Context final : public IGraphicsDataFactory::Context {
|
||||
friend class GLDataFactoryImpl;
|
||||
GLDataFactory& m_parent;
|
||||
ObjToken<BaseGraphicsData> m_data;
|
||||
Context(GLDataFactory& parent __BooTraceArgs);
|
||||
~Context();
|
||||
|
||||
ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
|
||||
ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count);
|
||||
public:
|
||||
Platform platform() const { return Platform::OpenGL; }
|
||||
const SystemChar* platformName() const { return _SYS_STR("OpenGL"); }
|
||||
|
||||
ObjToken<ITextureS> newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||
TextureClampMode clampMode, const void* data, size_t sz);
|
||||
ObjToken<ITextureSA> newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
|
||||
TextureFormat fmt, TextureClampMode clampMode, const void* data, size_t sz);
|
||||
ObjToken<ITextureD> newDynamicTexture(size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode);
|
||||
ObjToken<ITextureR> newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
|
||||
size_t colorBindingCount, size_t depthBindingCount);
|
||||
ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
|
||||
ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count);
|
||||
|
||||
ObjToken<IShaderStage>
|
||||
newShaderStage(const uint8_t* data, size_t size, PipelineStage stage);
|
||||
ObjToken<ITextureS> newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||
TextureClampMode clampMode, const void* data, size_t sz);
|
||||
ObjToken<ITextureSA> newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
|
||||
TextureFormat fmt, TextureClampMode clampMode, const void* data,
|
||||
size_t sz);
|
||||
ObjToken<ITextureD> newDynamicTexture(size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode);
|
||||
ObjToken<ITextureR> newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
|
||||
size_t colorBindingCount, size_t depthBindingCount);
|
||||
|
||||
ObjToken<IShaderPipeline>
|
||||
newShaderPipeline(ObjToken<IShaderStage> vertex, ObjToken<IShaderStage> fragment,
|
||||
ObjToken<IShaderStage> geometry, ObjToken<IShaderStage> control,
|
||||
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
|
||||
const AdditionalPipelineInfo& additionalInfo);
|
||||
ObjToken<IShaderStage> newShaderStage(const uint8_t* data, size_t size, PipelineStage stage);
|
||||
|
||||
ObjToken<IShaderDataBinding>
|
||||
newShaderDataBinding(const ObjToken<IShaderPipeline>& pipeline,
|
||||
const ObjToken<IGraphicsBuffer>& vbo,
|
||||
const ObjToken<IGraphicsBuffer>& instVbo,
|
||||
const ObjToken<IGraphicsBuffer>& ibo,
|
||||
size_t ubufCount, const ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages,
|
||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||
size_t texCount, const ObjToken<ITexture>* texs,
|
||||
const int* texBindIdx, const bool* depthBind,
|
||||
size_t baseVert = 0, size_t baseInst = 0);
|
||||
};
|
||||
ObjToken<IShaderPipeline> newShaderPipeline(ObjToken<IShaderStage> vertex, ObjToken<IShaderStage> fragment,
|
||||
ObjToken<IShaderStage> geometry, ObjToken<IShaderStage> control,
|
||||
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
|
||||
const AdditionalPipelineInfo& additionalInfo);
|
||||
|
||||
ObjToken<IShaderDataBinding> newShaderDataBinding(
|
||||
const ObjToken<IShaderPipeline>& pipeline, const ObjToken<IGraphicsBuffer>& vbo,
|
||||
const ObjToken<IGraphicsBuffer>& instVbo, const ObjToken<IGraphicsBuffer>& ibo, size_t ubufCount,
|
||||
const ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages, const size_t* ubufOffs,
|
||||
const size_t* ubufSizes, size_t texCount, const ObjToken<ITexture>* texs, const int* texBindIdx,
|
||||
const bool* depthBind, size_t baseVert = 0, size_t baseInst = 0);
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace boo
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,48 +3,47 @@
|
||||
#define BOO_GLSL_MAX_UNIFORM_COUNT 8
|
||||
#define BOO_GLSL_MAX_TEXTURE_COUNT 8
|
||||
|
||||
#define BOO_GLSL_BINDING_HEAD \
|
||||
"#ifdef VULKAN\n" \
|
||||
"#define gl_VertexID gl_VertexIndex\n" \
|
||||
"#extension GL_ARB_separate_shader_objects: enable\n" \
|
||||
"#define SBINDING(idx) layout(location=idx)\n" \
|
||||
"#else\n" \
|
||||
"#define SBINDING(idx)\n" \
|
||||
"#endif\n" \
|
||||
"#extension GL_ARB_shading_language_420pack: enable\n" \
|
||||
"#ifdef GL_ARB_shading_language_420pack\n" \
|
||||
"#define UBINDING0 layout(binding=0)\n" \
|
||||
"#define UBINDING1 layout(binding=1)\n" \
|
||||
"#define UBINDING2 layout(binding=2)\n" \
|
||||
"#define UBINDING3 layout(binding=3)\n" \
|
||||
"#define UBINDING4 layout(binding=4)\n" \
|
||||
"#define UBINDING5 layout(binding=5)\n" \
|
||||
"#define UBINDING6 layout(binding=6)\n" \
|
||||
"#define UBINDING7 layout(binding=7)\n" \
|
||||
"#define TBINDING0 layout(binding=8)\n" \
|
||||
"#define TBINDING1 layout(binding=9)\n" \
|
||||
"#define TBINDING2 layout(binding=10)\n" \
|
||||
"#define TBINDING3 layout(binding=11)\n" \
|
||||
"#define TBINDING4 layout(binding=12)\n" \
|
||||
"#define TBINDING5 layout(binding=13)\n" \
|
||||
"#define TBINDING6 layout(binding=14)\n" \
|
||||
"#define TBINDING7 layout(binding=15)\n" \
|
||||
"#else\n" \
|
||||
"#define UBINDING0\n" \
|
||||
"#define UBINDING1\n" \
|
||||
"#define UBINDING2\n" \
|
||||
"#define UBINDING3\n" \
|
||||
"#define UBINDING4\n" \
|
||||
"#define UBINDING5\n" \
|
||||
"#define UBINDING6\n" \
|
||||
"#define UBINDING7\n" \
|
||||
"#define TBINDING0\n" \
|
||||
"#define TBINDING1\n" \
|
||||
"#define TBINDING2\n" \
|
||||
"#define TBINDING3\n" \
|
||||
"#define TBINDING4\n" \
|
||||
"#define TBINDING5\n" \
|
||||
"#define TBINDING6\n" \
|
||||
"#define TBINDING7\n" \
|
||||
"#endif\n"
|
||||
|
||||
#define BOO_GLSL_BINDING_HEAD \
|
||||
"#ifdef VULKAN\n" \
|
||||
"#define gl_VertexID gl_VertexIndex\n" \
|
||||
"#extension GL_ARB_separate_shader_objects: enable\n" \
|
||||
"#define SBINDING(idx) layout(location=idx)\n" \
|
||||
"#else\n" \
|
||||
"#define SBINDING(idx)\n" \
|
||||
"#endif\n" \
|
||||
"#extension GL_ARB_shading_language_420pack: enable\n" \
|
||||
"#ifdef GL_ARB_shading_language_420pack\n" \
|
||||
"#define UBINDING0 layout(binding=0)\n" \
|
||||
"#define UBINDING1 layout(binding=1)\n" \
|
||||
"#define UBINDING2 layout(binding=2)\n" \
|
||||
"#define UBINDING3 layout(binding=3)\n" \
|
||||
"#define UBINDING4 layout(binding=4)\n" \
|
||||
"#define UBINDING5 layout(binding=5)\n" \
|
||||
"#define UBINDING6 layout(binding=6)\n" \
|
||||
"#define UBINDING7 layout(binding=7)\n" \
|
||||
"#define TBINDING0 layout(binding=8)\n" \
|
||||
"#define TBINDING1 layout(binding=9)\n" \
|
||||
"#define TBINDING2 layout(binding=10)\n" \
|
||||
"#define TBINDING3 layout(binding=11)\n" \
|
||||
"#define TBINDING4 layout(binding=12)\n" \
|
||||
"#define TBINDING5 layout(binding=13)\n" \
|
||||
"#define TBINDING6 layout(binding=14)\n" \
|
||||
"#define TBINDING7 layout(binding=15)\n" \
|
||||
"#else\n" \
|
||||
"#define UBINDING0\n" \
|
||||
"#define UBINDING1\n" \
|
||||
"#define UBINDING2\n" \
|
||||
"#define UBINDING3\n" \
|
||||
"#define UBINDING4\n" \
|
||||
"#define UBINDING5\n" \
|
||||
"#define UBINDING6\n" \
|
||||
"#define UBINDING7\n" \
|
||||
"#define TBINDING0\n" \
|
||||
"#define TBINDING1\n" \
|
||||
"#define TBINDING2\n" \
|
||||
"#define TBINDING3\n" \
|
||||
"#define TBINDING4\n" \
|
||||
"#define TBINDING5\n" \
|
||||
"#define TBINDING6\n" \
|
||||
"#define TBINDING7\n" \
|
||||
"#endif\n"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user