Compare commits
23 Commits
647fedfa19
...
3aa20a3a32
Author | SHA1 | Date |
---|---|---|
|
3aa20a3a32 | |
|
de7c3d3d29 | |
|
3f89df338e | |
|
c7f89c9b77 | |
|
a107e463e8 | |
|
7a5cfe1728 | |
|
7ad3f967db | |
|
d1c814cf9d | |
|
72f85dce2b | |
|
f5bbcc017c | |
|
2980173c8e | |
|
a84c348045 | |
|
d845ecc811 | |
|
064d9009a2 | |
|
b6aa5bdfab | |
|
a3bdf0456e | |
|
e3ecf05866 | |
|
6240374dd1 | |
|
e17ee831a7 | |
|
aef9bd6357 | |
|
8857227a35 | |
|
937250c681 | |
|
66d3a1d025 |
|
@ -497,13 +497,13 @@ namespace Kernel
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PageTable::reserve_page(vaddr_t vaddr, bool only_free)
|
bool PageTable::reserve_page(vaddr_t vaddr, bool only_free, bool send_smp_message)
|
||||||
{
|
{
|
||||||
SpinLockGuard _(m_lock);
|
SpinLockGuard _(m_lock);
|
||||||
ASSERT(vaddr % PAGE_SIZE == 0);
|
ASSERT(vaddr % PAGE_SIZE == 0);
|
||||||
if (only_free && !is_page_free(vaddr))
|
if (only_free && !is_page_free(vaddr))
|
||||||
return false;
|
return false;
|
||||||
map_page_at(0, vaddr, Flags::Reserved);
|
map_page_at(0, vaddr, Flags::Reserved, MemoryType::Normal, send_smp_message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,7 +517,14 @@ namespace Kernel
|
||||||
if (only_free && !is_range_free(vaddr, bytes))
|
if (only_free && !is_range_free(vaddr, bytes))
|
||||||
return false;
|
return false;
|
||||||
for (size_t offset = 0; offset < bytes; offset += PAGE_SIZE)
|
for (size_t offset = 0; offset < bytes; offset += PAGE_SIZE)
|
||||||
reserve_page(vaddr + offset);
|
reserve_page(vaddr + offset, true, false);
|
||||||
|
Processor::broadcast_smp_message({
|
||||||
|
.type = Processor::SMPMessage::Type::FlushTLB,
|
||||||
|
.flush_tlb = {
|
||||||
|
.vaddr = vaddr,
|
||||||
|
.page_count = bytes / PAGE_SIZE,
|
||||||
|
}
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -814,13 +814,13 @@ namespace Kernel
|
||||||
return page_data & s_page_addr_mask;
|
return page_data & s_page_addr_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PageTable::reserve_page(vaddr_t vaddr, bool only_free)
|
bool PageTable::reserve_page(vaddr_t vaddr, bool only_free, bool send_smp_message)
|
||||||
{
|
{
|
||||||
SpinLockGuard _(m_lock);
|
SpinLockGuard _(m_lock);
|
||||||
ASSERT(vaddr % PAGE_SIZE == 0);
|
ASSERT(vaddr % PAGE_SIZE == 0);
|
||||||
if (only_free && !is_page_free(vaddr))
|
if (only_free && !is_page_free(vaddr))
|
||||||
return false;
|
return false;
|
||||||
map_page_at(0, vaddr, Flags::Reserved);
|
map_page_at(0, vaddr, Flags::Reserved, MemoryType::Normal, send_smp_message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,7 +834,14 @@ namespace Kernel
|
||||||
if (only_free && !is_range_free(vaddr, bytes))
|
if (only_free && !is_range_free(vaddr, bytes))
|
||||||
return false;
|
return false;
|
||||||
for (size_t offset = 0; offset < bytes; offset += PAGE_SIZE)
|
for (size_t offset = 0; offset < bytes; offset += PAGE_SIZE)
|
||||||
reserve_page(vaddr + offset);
|
reserve_page(vaddr + offset, true, false);
|
||||||
|
Processor::broadcast_smp_message({
|
||||||
|
.type = Processor::SMPMessage::Type::FlushTLB,
|
||||||
|
.flush_tlb = {
|
||||||
|
.vaddr = vaddr,
|
||||||
|
.page_count = bytes / PAGE_SIZE,
|
||||||
|
}
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace Kernel
|
||||||
BAN::ErrorOr<void> initialize_bld();
|
BAN::ErrorOr<void> initialize_bld();
|
||||||
BAN::ErrorOr<void> initialize_interrupts();
|
BAN::ErrorOr<void> initialize_interrupts();
|
||||||
|
|
||||||
void queue_samples_to_bld();
|
bool queue_samples_to_bld();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t m_bdl_entries = 32;
|
static constexpr size_t m_bdl_entries = 32;
|
||||||
|
|
|
@ -112,7 +112,7 @@ namespace Kernel
|
||||||
bool is_page_free(vaddr_t) const;
|
bool is_page_free(vaddr_t) const;
|
||||||
bool is_range_free(vaddr_t, size_t bytes) const;
|
bool is_range_free(vaddr_t, size_t bytes) const;
|
||||||
|
|
||||||
bool reserve_page(vaddr_t, bool only_free = true);
|
bool reserve_page(vaddr_t, bool only_free = true, bool send_smp_message = true);
|
||||||
bool reserve_range(vaddr_t, size_t bytes, bool only_free = true);
|
bool reserve_range(vaddr_t, size_t bytes, bool only_free = true);
|
||||||
|
|
||||||
vaddr_t reserve_free_page(vaddr_t first_address, vaddr_t last_address = UINTPTR_MAX);
|
vaddr_t reserve_free_page(vaddr_t first_address, vaddr_t last_address = UINTPTR_MAX);
|
||||||
|
|
|
@ -35,7 +35,9 @@ namespace Kernel
|
||||||
// FIXME: kernel stack does NOT have to be this big, but my recursive AML interpreter
|
// FIXME: kernel stack does NOT have to be this big, but my recursive AML interpreter
|
||||||
// stack overflows on some machines with 8 page stack
|
// stack overflows on some machines with 8 page stack
|
||||||
static constexpr size_t kernel_stack_size { PAGE_SIZE * 16 };
|
static constexpr size_t kernel_stack_size { PAGE_SIZE * 16 };
|
||||||
static constexpr size_t userspace_stack_size { PAGE_SIZE * 128 };
|
|
||||||
|
// TODO: userspace stack is hard limited to 32 MiB, maybe make this dynamic?
|
||||||
|
static constexpr size_t userspace_stack_size { 32 << 20 };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static BAN::ErrorOr<Thread*> create_kernel(entry_t, void*);
|
static BAN::ErrorOr<Thread*> create_kernel(entry_t, void*);
|
||||||
|
|
|
@ -927,42 +927,79 @@ acpi_release_global_lock:
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define FIND_GPE(idx) \
|
||||||
|
BAN::Optional<GAS> gpe##idx; \
|
||||||
|
{ \
|
||||||
|
const uint8_t null[sizeof(GAS)] {}; \
|
||||||
|
if (fadt().length > offsetof(FADT, x_gpe##idx##_blk) \
|
||||||
|
&& memcmp(fadt().x_gpe##idx##_blk, null, sizeof(GAS)) == 0) { \
|
||||||
|
auto gas = *reinterpret_cast<GAS*>(fadt().x_gpe##idx##_blk); \
|
||||||
|
if (!gas.read().is_error()) \
|
||||||
|
gpe0 = gas; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (!gpe##idx.has_value() && fadt().gpe##idx##_blk) { \
|
||||||
|
gpe##idx = GAS { \
|
||||||
|
.address_space_id = GAS::AddressSpaceID::SystemIO, \
|
||||||
|
.register_bit_width = 8, \
|
||||||
|
.register_bit_offset = 0, \
|
||||||
|
.access_size = 1, \
|
||||||
|
.address = fadt().gpe##idx##_blk, \
|
||||||
|
}; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
FIND_GPE(0);
|
||||||
|
FIND_GPE(1);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
uint16_t sts_port;
|
uint16_t sts_port;
|
||||||
uint16_t pending;
|
uint16_t pending;
|
||||||
|
|
||||||
sts_port = fadt().pm1a_evt_blk;
|
const auto read_gpe = [this](GAS gpe, uint8_t gpe_blk_len, uint32_t base) -> bool {
|
||||||
if (pending = get_fixed_event(sts_port); pending)
|
for (uint8_t i = 0; i < gpe_blk_len / 2; i++)
|
||||||
goto handle_event;
|
|
||||||
|
|
||||||
sts_port = fadt().pm1b_evt_blk;
|
|
||||||
if (pending = get_fixed_event(sts_port); pending)
|
|
||||||
goto handle_event;
|
|
||||||
|
|
||||||
{
|
|
||||||
bool handled_event = false;
|
|
||||||
uint8_t gpe0_bytes = fadt().gpe0_blk_len / 2;
|
|
||||||
for (uint8_t i = 0; i < gpe0_bytes; i++)
|
|
||||||
{
|
{
|
||||||
uint8_t sts = IO::inb(fadt().gpe0_blk + i);
|
auto status = ({ auto tmp = gpe; tmp.address += i; tmp; });
|
||||||
uint8_t en = IO::inb(fadt().gpe0_blk + gpe0_bytes + i);
|
auto enabled = ({ auto tmp = gpe; tmp.address += (gpe_blk_len / 2) + i; tmp; });
|
||||||
pending = sts & en;
|
const uint8_t pending = MUST(status.read()) & MUST(enabled.read());
|
||||||
if (pending == 0)
|
if (pending == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto index = i * 8 + (pending & ~(pending - 1));
|
for (size_t bit = 0; bit < 8; bit++)
|
||||||
if (m_gpe_methods[index])
|
{
|
||||||
if (auto ret = AML::method_call(m_gpe_scope, m_gpe_methods[index]->node, BAN::Array<AML::Reference*, 7>{}); ret.is_error())
|
if (!(pending & (1 << bit)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto index = base + i * 8 + bit;
|
||||||
|
if (auto* method = m_gpe_methods[index]; method == nullptr)
|
||||||
|
dwarnln("No handler for _GPE {}", index);
|
||||||
|
else if (auto ret = AML::method_call(m_gpe_scope, method->node, BAN::Array<AML::Reference*, 7>{}); ret.is_error())
|
||||||
dwarnln("Failed to evaluate _GPE {}: ", index, ret.error());
|
dwarnln("Failed to evaluate _GPE {}: ", index, ret.error());
|
||||||
|
else
|
||||||
|
dprintln("handled _GPE {}", index);
|
||||||
|
}
|
||||||
|
|
||||||
handled_event = true;
|
MUST(status.write(pending));
|
||||||
IO::outb(fadt().gpe0_blk + i, 1 << index);
|
return true;
|
||||||
}
|
}
|
||||||
if (handled_event)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
sts_port = fadt().pm1a_evt_blk;
|
||||||
|
if ((pending = get_fixed_event(sts_port)))
|
||||||
|
goto handle_event;
|
||||||
|
|
||||||
|
sts_port = fadt().pm1b_evt_blk;
|
||||||
|
if ((pending = get_fixed_event(sts_port)))
|
||||||
|
goto handle_event;
|
||||||
|
|
||||||
|
if (gpe0.has_value() && read_gpe(gpe0.value(), fadt().gpe0_blk_len, 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (gpe1.has_value() && read_gpe(gpe1.value(), fadt().gpe1_blk_len, fadt().gpe1_base))
|
||||||
|
continue;
|
||||||
|
|
||||||
// FIXME: this can cause missing of event if it happens between
|
// FIXME: this can cause missing of event if it happens between
|
||||||
// reading the status and blocking
|
// reading the status and blocking
|
||||||
|
|
|
@ -185,14 +185,10 @@ namespace Kernel
|
||||||
void AC97AudioController::handle_new_data()
|
void AC97AudioController::handle_new_data()
|
||||||
{
|
{
|
||||||
ASSERT(m_spinlock.current_processor_has_lock());
|
ASSERT(m_spinlock.current_processor_has_lock());
|
||||||
|
|
||||||
if (m_bdl_head != m_bdl_tail)
|
|
||||||
return;
|
|
||||||
|
|
||||||
queue_samples_to_bld();
|
queue_samples_to_bld();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AC97AudioController::queue_samples_to_bld()
|
bool AC97AudioController::queue_samples_to_bld()
|
||||||
{
|
{
|
||||||
ASSERT(m_spinlock.current_processor_has_lock());
|
ASSERT(m_spinlock.current_processor_has_lock());
|
||||||
|
|
||||||
|
@ -228,7 +224,7 @@ namespace Kernel
|
||||||
|
|
||||||
// if head was not updated, no data was queued
|
// if head was not updated, no data was queued
|
||||||
if (lvi == m_bdl_head)
|
if (lvi == m_bdl_head)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
m_sample_data_blocker.unblock();
|
m_sample_data_blocker.unblock();
|
||||||
|
|
||||||
|
@ -238,6 +234,8 @@ namespace Kernel
|
||||||
const uint8_t control = m_bus_master->read8(BusMasterRegister::PO_CR);
|
const uint8_t control = m_bus_master->read8(BusMasterRegister::PO_CR);
|
||||||
if (!(control & RDBM))
|
if (!(control & RDBM))
|
||||||
m_bus_master->write8(BusMasterRegister::PO_CR, control | RDBM);
|
m_bus_master->write8(BusMasterRegister::PO_CR, control | RDBM);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AC97AudioController::handle_irq()
|
void AC97AudioController::handle_irq()
|
||||||
|
@ -249,17 +247,18 @@ namespace Kernel
|
||||||
|
|
||||||
SpinLockGuard _(m_spinlock);
|
SpinLockGuard _(m_spinlock);
|
||||||
|
|
||||||
if (status & LVBCI)
|
bool did_enqueue = false;
|
||||||
|
if (status & BCIS)
|
||||||
|
{
|
||||||
|
m_bdl_tail = (m_bdl_tail + 1) % m_bdl_entries;
|
||||||
|
did_enqueue = queue_samples_to_bld();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status & LVBCI) && !did_enqueue)
|
||||||
{
|
{
|
||||||
const uint8_t control = m_bus_master->read8(BusMasterRegister::PO_CR);
|
const uint8_t control = m_bus_master->read8(BusMasterRegister::PO_CR);
|
||||||
m_bus_master->write8(BusMasterRegister::PO_CR, control & ~RDBM);
|
m_bus_master->write8(BusMasterRegister::PO_CR, control & ~RDBM);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & BCIS)
|
|
||||||
{
|
|
||||||
m_bdl_tail = (m_bdl_tail + 1) % m_bdl_entries;
|
|
||||||
queue_samples_to_bld();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,9 @@ namespace Kernel
|
||||||
|
|
||||||
if (file_type == DIRTYPE)
|
if (file_type == DIRTYPE)
|
||||||
{
|
{
|
||||||
if (auto ret = parent_inode->create_directory(file_name_sv, file_mode, file_uid, file_gid); ret.is_error())
|
if (file_name_sv == "."_sv)
|
||||||
|
; // NOTE: don't create "." (root)
|
||||||
|
else if (auto ret = parent_inode->create_directory(file_name_sv, file_mode, file_uid, file_gid); ret.is_error())
|
||||||
dwarnln("failed to create directory '{}': {}", file_name_sv, ret.error());
|
dwarnln("failed to create directory '{}': {}", file_name_sv, ret.error());
|
||||||
}
|
}
|
||||||
else if (file_type == LNKTYPE)
|
else if (file_type == LNKTYPE)
|
||||||
|
|
|
@ -207,26 +207,6 @@ namespace Kernel
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if stack is OOB
|
|
||||||
if (ARCH(i686) && !GDT::is_user_segment(interrupt_stack->cs))
|
|
||||||
; // 32 bit does not push stack pointer when no CPL change happens
|
|
||||||
else if (thread.userspace_stack_bottom() < interrupt_stack->sp && interrupt_stack->sp <= thread.userspace_stack_top())
|
|
||||||
; // using userspace stack
|
|
||||||
else if (thread.kernel_stack_bottom() < interrupt_stack->sp && interrupt_stack->sp <= thread.kernel_stack_top())
|
|
||||||
; // using kernel stack
|
|
||||||
else
|
|
||||||
{
|
|
||||||
derrorln("Stack pointer out of bounds!");
|
|
||||||
derrorln("rip {H}", interrupt_stack->ip);
|
|
||||||
derrorln("rsp {H}, userspace stack {H}->{H}, kernel stack {H}->{H}",
|
|
||||||
interrupt_stack->sp,
|
|
||||||
thread.userspace_stack_bottom(), thread.userspace_stack_top(),
|
|
||||||
thread.kernel_stack_bottom(), thread.kernel_stack_top()
|
|
||||||
);
|
|
||||||
Thread::current().handle_signal(SIGKILL);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,12 @@ namespace Kernel
|
||||||
last_event.move_event.rel_y += curr_event.move_event.rel_y;
|
last_event.move_event.rel_y += curr_event.move_event.rel_y;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (last_event.type == LibInput::MouseEventType::MouseMoveAbsEvent && curr_event.type == LibInput::MouseEventType::MouseMoveAbsEvent)
|
||||||
|
{
|
||||||
|
last_event.move_abs_event.abs_x = curr_event.move_abs_event.abs_x;
|
||||||
|
last_event.move_abs_event.abs_y = curr_event.move_abs_event.abs_y;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (last_event.type == LibInput::MouseEventType::MouseScrollEvent && curr_event.type == LibInput::MouseEventType::MouseScrollEvent)
|
if (last_event.type == LibInput::MouseEventType::MouseScrollEvent && curr_event.type == LibInput::MouseEventType::MouseScrollEvent)
|
||||||
{
|
{
|
||||||
last_event.scroll_event.scroll += curr_event.scroll_event.scroll;
|
last_event.scroll_event.scroll += curr_event.scroll_event.scroll;
|
||||||
|
|
|
@ -143,7 +143,7 @@ namespace Kernel
|
||||||
BAN::ErrorOr<bool> VirtualRange::allocate_page_for_demand_paging(vaddr_t vaddr)
|
BAN::ErrorOr<bool> VirtualRange::allocate_page_for_demand_paging(vaddr_t vaddr)
|
||||||
{
|
{
|
||||||
ASSERT(contains(vaddr));
|
ASSERT(contains(vaddr));
|
||||||
ASSERT(&PageTable::current() == &m_page_table);
|
vaddr &= PAGE_ADDR_MASK;
|
||||||
|
|
||||||
if (m_preallocated)
|
if (m_preallocated)
|
||||||
return false;
|
return false;
|
||||||
|
@ -158,8 +158,11 @@ namespace Kernel
|
||||||
if (m_paddrs[index] == 0)
|
if (m_paddrs[index] == 0)
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
|
|
||||||
|
PageTable::with_fast_page(m_paddrs[index], []{
|
||||||
|
memset(PageTable::fast_page_as_ptr(), 0x00, PAGE_SIZE);
|
||||||
|
});
|
||||||
|
|
||||||
m_page_table.map_page_at(m_paddrs[index], vaddr, m_flags);
|
m_page_table.map_page_at(m_paddrs[index], vaddr, m_flags);
|
||||||
memset(reinterpret_cast<void*>(vaddr), 0, PAGE_SIZE);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ namespace Kernel
|
||||||
stack_addr_start, USERSPACE_END,
|
stack_addr_start, USERSPACE_END,
|
||||||
userspace_stack_size,
|
userspace_stack_size,
|
||||||
PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
||||||
true, true
|
false, true
|
||||||
));
|
));
|
||||||
|
|
||||||
thread_deleter.disable();
|
thread_deleter.disable();
|
||||||
|
@ -217,6 +217,7 @@ namespace Kernel
|
||||||
save_sse();
|
save_sse();
|
||||||
memcpy(thread->m_sse_storage, m_sse_storage, sizeof(m_sse_storage));
|
memcpy(thread->m_sse_storage, m_sse_storage, sizeof(m_sse_storage));
|
||||||
|
|
||||||
|
TRY(thread->userspace_stack().allocate_page_for_demand_paging(thread->userspace_stack_top() - PAGE_SIZE));
|
||||||
PageTable::with_fast_page(thread->userspace_stack().paddr_of(thread->userspace_stack_top() - PAGE_SIZE), [=] {
|
PageTable::with_fast_page(thread->userspace_stack().paddr_of(thread->userspace_stack_top() - PAGE_SIZE), [=] {
|
||||||
PageTable::fast_page_as<void*>(PAGE_SIZE - sizeof(uintptr_t)) = arg;
|
PageTable::fast_page_as<void*>(PAGE_SIZE - sizeof(uintptr_t)) = arg;
|
||||||
});
|
});
|
||||||
|
@ -299,6 +300,10 @@ namespace Kernel
|
||||||
|
|
||||||
vaddr_t vaddr = userspace_stack_top() - needed_size;
|
vaddr_t vaddr = userspace_stack_top() - needed_size;
|
||||||
|
|
||||||
|
const size_t page_count = BAN::Math::div_round_up(needed_size, PAGE_SIZE);
|
||||||
|
for (size_t i = 0; i < page_count; i++)
|
||||||
|
TRY(m_userspace_stack->allocate_page_for_demand_paging(vaddr + i * PAGE_SIZE));
|
||||||
|
|
||||||
const auto stack_copy_buf =
|
const auto stack_copy_buf =
|
||||||
[this](BAN::ConstByteSpan buffer, vaddr_t vaddr) -> void
|
[this](BAN::ConstByteSpan buffer, vaddr_t vaddr) -> void
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,25 +1,22 @@
|
||||||
#!/bin/bash ../install.sh
|
#!/bin/bash ../install.sh
|
||||||
|
|
||||||
NAME='SDL2'
|
NAME='SDL2'
|
||||||
VERSION='2.30.11'
|
VERSION='2.32.8'
|
||||||
DOWNLOAD_URL="https://github.com/libsdl-org/SDL/archive/refs/tags/release-$VERSION.tar.gz#cc6136dd964854e8846c679703322f3e2a341d27a06a53f8b3f642c26f1b0cfd"
|
DOWNLOAD_URL="https://github.com/libsdl-org/SDL/releases/download/release-$VERSION/SDL2-$VERSION.tar.gz#0ca83e9c9b31e18288c7ec811108e58bac1f1bb5ec6577ad386830eac51c787e"
|
||||||
TAR_CONTENT="SDL-release-$VERSION"
|
|
||||||
DEPENDENCIES=('mesa')
|
DEPENDENCIES=('mesa')
|
||||||
|
|
||||||
configure() {
|
configure() {
|
||||||
$BANAN_CMAKE \
|
$BANAN_CMAKE --fresh -S . -B build -G Ninja \
|
||||||
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
|
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
|
||||||
--fresh -GNinja -S . -B build \
|
|
||||||
-DCMAKE_INSTALL_PREFIX='/usr' \
|
-DCMAKE_INSTALL_PREFIX='/usr' \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DBANAN_OS=true \
|
|
||||||
-DUNIX=true \
|
|
||||||
-DSDL_LIBSAMPLERATE=OFF \
|
-DSDL_LIBSAMPLERATE=OFF \
|
||||||
-DSDL_PTHREADS_SEM=OFF
|
-DSDL_PTHREADS_SEM=OFF \
|
||||||
|
|| exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
$BANAN_CMAKE --build build --config Release || exit 1
|
$BANAN_CMAKE --build build || exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
install() {
|
install() {
|
||||||
|
|
|
@ -1,7 +1,28 @@
|
||||||
diff -ruN SDL-release-2.30.11/CMakeLists.txt SDL2-2.30.11-banan_os/CMakeLists.txt
|
diff -ruN SDL2-2.32.8/cmake/sdlplatform.cmake SDL2-2.32.8-banan_os/cmake/sdlplatform.cmake
|
||||||
--- SDL-release-2.30.11/CMakeLists.txt 2025-01-01 19:09:38.000000000 +0200
|
--- SDL2-2.32.8/cmake/sdlplatform.cmake 2024-08-14 13:35:43.000000000 +0300
|
||||||
+++ SDL2-2.30.11-banan_os/CMakeLists.txt 2025-08-03 14:04:09.894244781 +0300
|
+++ SDL2-2.32.8-banan_os/cmake/sdlplatform.cmake 2025-08-06 02:07:18.347821313 +0300
|
||||||
@@ -1452,7 +1452,7 @@
|
@@ -28,6 +28,8 @@
|
||||||
|
set(SDL_CMAKE_PLATFORM AIX)
|
||||||
|
elseif(CMAKE_SYSTEM_NAME MATCHES "Minix.*")
|
||||||
|
set(SDL_CMAKE_PLATFORM MINIX)
|
||||||
|
+ elseif(CMAKE_SYSTEM_NAME MATCHES "banan-os")
|
||||||
|
+ set(SDL_CMAKE_PLATFORM BANAN_OS)
|
||||||
|
elseif(CMAKE_SYSTEM_NAME MATCHES "QNX")
|
||||||
|
set(SDL_CMAKE_PLATFORM QNX)
|
||||||
|
endif()
|
||||||
|
diff -ruN SDL2-2.32.8/CMakeLists.txt SDL2-2.32.8-banan_os/CMakeLists.txt
|
||||||
|
--- SDL2-2.32.8/CMakeLists.txt 2025-06-03 02:00:39.000000000 +0300
|
||||||
|
+++ SDL2-2.32.8-banan_os/CMakeLists.txt 2025-08-06 02:19:44.864415796 +0300
|
||||||
|
@@ -14,7 +14,7 @@
|
||||||
|
set(SDL2_SUBPROJECT ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
-if (HAIKU)
|
||||||
|
+if (HAIKU OR BANAN_OS)
|
||||||
|
enable_language(CXX)
|
||||||
|
set(LINKER_LANGUAGE CXX)
|
||||||
|
endif()
|
||||||
|
@@ -1462,7 +1462,7 @@
|
||||||
CheckPTHREAD()
|
CheckPTHREAD()
|
||||||
CheckLibUnwind()
|
CheckLibUnwind()
|
||||||
|
|
||||||
|
@ -10,7 +31,7 @@ diff -ruN SDL-release-2.30.11/CMakeLists.txt SDL2-2.30.11-banan_os/CMakeLists.tx
|
||||||
if(SDL_AUDIO)
|
if(SDL_AUDIO)
|
||||||
if(SYSV5 OR SOLARIS OR HPUX)
|
if(SYSV5 OR SOLARIS OR HPUX)
|
||||||
set(SDL_AUDIO_DRIVER_SUNAUDIO 1)
|
set(SDL_AUDIO_DRIVER_SUNAUDIO 1)
|
||||||
@@ -2422,6 +2422,49 @@
|
@@ -2459,6 +2459,57 @@
|
||||||
CheckPTHREAD()
|
CheckPTHREAD()
|
||||||
list(APPEND EXTRA_LIBS root be media game device textencoding)
|
list(APPEND EXTRA_LIBS root be media game device textencoding)
|
||||||
|
|
||||||
|
@ -21,8 +42,16 @@ diff -ruN SDL-release-2.30.11/CMakeLists.txt SDL2-2.30.11-banan_os/CMakeLists.tx
|
||||||
+ set(HAVE_SDL_MISC TRUE)
|
+ set(HAVE_SDL_MISC TRUE)
|
||||||
+ endif()
|
+ endif()
|
||||||
+
|
+
|
||||||
|
+ if(SDL_AUDIO)
|
||||||
|
+ set(SDL_AUDIO_DRIVER_BANANOS 1)
|
||||||
|
+ file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/banan_os/*.cpp)
|
||||||
|
+ list(APPEND SOURCE_FILES ${AUDIO_SOURCES})
|
||||||
|
+ set(HAVE_SDL_AUDIO TRUE)
|
||||||
|
+ list(APPEND EXTRA_LIBS audio)
|
||||||
|
+ endif()
|
||||||
|
+
|
||||||
+ if(SDL_VIDEO)
|
+ if(SDL_VIDEO)
|
||||||
+ set(SDL_VIDEO_DRIVER_BANAN_OS 1)
|
+ set(SDL_VIDEO_DRIVER_BANANOS 1)
|
||||||
+ file(GLOB VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/banan_os/*.cpp)
|
+ file(GLOB VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/banan_os/*.cpp)
|
||||||
+ list(APPEND SOURCE_FILES ${VIDEO_SOURCES})
|
+ list(APPEND SOURCE_FILES ${VIDEO_SOURCES})
|
||||||
+ set(HAVE_SDL_VIDEO TRUE)
|
+ set(HAVE_SDL_VIDEO TRUE)
|
||||||
|
@ -30,7 +59,7 @@ diff -ruN SDL-release-2.30.11/CMakeLists.txt SDL2-2.30.11-banan_os/CMakeLists.tx
|
||||||
+
|
+
|
||||||
+ if(SDL_OPENGL)
|
+ if(SDL_OPENGL)
|
||||||
+ set(SDL_VIDEO_OPENGL 1)
|
+ set(SDL_VIDEO_OPENGL 1)
|
||||||
+ set(SDL_VIDEO_OPENGL_BANAN_OS 1)
|
+ set(SDL_VIDEO_OPENGL_BANANOS 1)
|
||||||
+ set(SDL_VIDEO_RENDER_OGL 1)
|
+ set(SDL_VIDEO_RENDER_OGL 1)
|
||||||
+ list(APPEND EXTRA_LIBS OSMesa)
|
+ list(APPEND EXTRA_LIBS OSMesa)
|
||||||
+ set(HAVE_OPENGL TRUE)
|
+ set(HAVE_OPENGL TRUE)
|
||||||
|
@ -60,20 +89,28 @@ diff -ruN SDL-release-2.30.11/CMakeLists.txt SDL2-2.30.11-banan_os/CMakeLists.tx
|
||||||
elseif(RISCOS)
|
elseif(RISCOS)
|
||||||
if(SDL_MISC)
|
if(SDL_MISC)
|
||||||
file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/riscos/*.c)
|
file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/riscos/*.c)
|
||||||
diff -ruN SDL-release-2.30.11/include/SDL_config.h.cmake SDL2-2.30.11-banan_os/include/SDL_config.h.cmake
|
diff -ruN SDL2-2.32.8/include/SDL_config.h.cmake SDL2-2.32.8-banan_os/include/SDL_config.h.cmake
|
||||||
--- SDL-release-2.30.11/include/SDL_config.h.cmake 2025-01-01 19:09:38.000000000 +0200
|
--- SDL2-2.32.8/include/SDL_config.h.cmake 2025-01-01 17:47:53.000000000 +0200
|
||||||
+++ SDL2-2.30.11-banan_os/include/SDL_config.h.cmake 2025-08-03 14:04:09.894803585 +0300
|
+++ SDL2-2.32.8-banan_os/include/SDL_config.h.cmake 2025-08-06 02:01:21.085539504 +0300
|
||||||
@@ -406,6 +406,7 @@
|
@@ -307,6 +307,7 @@
|
||||||
|
#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND @SDL_AUDIO_DRIVER_FUSIONSOUND@
|
||||||
|
#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC @SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC@
|
||||||
|
#cmakedefine SDL_AUDIO_DRIVER_HAIKU @SDL_AUDIO_DRIVER_HAIKU@
|
||||||
|
+#cmakedefine SDL_AUDIO_DRIVER_BANANOS @SDL_AUDIO_DRIVER_BANANOS@
|
||||||
|
#cmakedefine SDL_AUDIO_DRIVER_JACK @SDL_AUDIO_DRIVER_JACK@
|
||||||
|
#cmakedefine SDL_AUDIO_DRIVER_JACK_DYNAMIC @SDL_AUDIO_DRIVER_JACK_DYNAMIC@
|
||||||
|
#cmakedefine SDL_AUDIO_DRIVER_NAS @SDL_AUDIO_DRIVER_NAS@
|
||||||
|
@@ -406,6 +407,7 @@
|
||||||
#cmakedefine SDL_VIDEO_DRIVER_ANDROID @SDL_VIDEO_DRIVER_ANDROID@
|
#cmakedefine SDL_VIDEO_DRIVER_ANDROID @SDL_VIDEO_DRIVER_ANDROID@
|
||||||
#cmakedefine SDL_VIDEO_DRIVER_EMSCRIPTEN @SDL_VIDEO_DRIVER_EMSCRIPTEN@
|
#cmakedefine SDL_VIDEO_DRIVER_EMSCRIPTEN @SDL_VIDEO_DRIVER_EMSCRIPTEN@
|
||||||
#cmakedefine SDL_VIDEO_DRIVER_HAIKU @SDL_VIDEO_DRIVER_HAIKU@
|
#cmakedefine SDL_VIDEO_DRIVER_HAIKU @SDL_VIDEO_DRIVER_HAIKU@
|
||||||
+#cmakedefine SDL_VIDEO_DRIVER_BANAN_OS @SDL_VIDEO_DRIVER_BANAN_OS@
|
+#cmakedefine SDL_VIDEO_DRIVER_BANANOS @SDL_VIDEO_DRIVER_BANANOS@
|
||||||
#cmakedefine SDL_VIDEO_DRIVER_COCOA @SDL_VIDEO_DRIVER_COCOA@
|
#cmakedefine SDL_VIDEO_DRIVER_COCOA @SDL_VIDEO_DRIVER_COCOA@
|
||||||
#cmakedefine SDL_VIDEO_DRIVER_UIKIT @SDL_VIDEO_DRIVER_UIKIT@
|
#cmakedefine SDL_VIDEO_DRIVER_UIKIT @SDL_VIDEO_DRIVER_UIKIT@
|
||||||
#cmakedefine SDL_VIDEO_DRIVER_DIRECTFB @SDL_VIDEO_DRIVER_DIRECTFB@
|
#cmakedefine SDL_VIDEO_DRIVER_DIRECTFB @SDL_VIDEO_DRIVER_DIRECTFB@
|
||||||
diff -ruN SDL-release-2.30.11/include/SDL_platform.h SDL2-2.30.11-banan_os/include/SDL_platform.h
|
diff -ruN SDL2-2.32.8/include/SDL_platform.h SDL2-2.32.8-banan_os/include/SDL_platform.h
|
||||||
--- SDL-release-2.30.11/include/SDL_platform.h 2025-01-01 19:09:38.000000000 +0200
|
--- SDL2-2.32.8/include/SDL_platform.h 2025-01-01 17:47:53.000000000 +0200
|
||||||
+++ SDL2-2.30.11-banan_os/include/SDL_platform.h 2025-08-03 14:04:09.895022748 +0300
|
+++ SDL2-2.32.8-banan_os/include/SDL_platform.h 2025-08-06 02:01:21.085701327 +0300
|
||||||
@@ -36,6 +36,10 @@
|
@@ -36,6 +36,10 @@
|
||||||
#undef __HAIKU__
|
#undef __HAIKU__
|
||||||
#define __HAIKU__ 1
|
#define __HAIKU__ 1
|
||||||
|
@ -85,9 +122,225 @@ diff -ruN SDL-release-2.30.11/include/SDL_platform.h SDL2-2.30.11-banan_os/inclu
|
||||||
#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__)
|
#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__)
|
||||||
#undef __BSDI__
|
#undef __BSDI__
|
||||||
#define __BSDI__ 1
|
#define __BSDI__ 1
|
||||||
diff -ruN SDL-release-2.30.11/src/misc/banan_os/SDL_sysurl.cpp SDL2-2.30.11-banan_os/src/misc/banan_os/SDL_sysurl.cpp
|
diff -ruN SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.cpp SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.cpp
|
||||||
--- SDL-release-2.30.11/src/misc/banan_os/SDL_sysurl.cpp 1970-01-01 02:00:00.000000000 +0200
|
--- SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.cpp 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ SDL2-2.30.11-banan_os/src/misc/banan_os/SDL_sysurl.cpp 2025-08-03 14:04:09.895198889 +0300
|
+++ SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.cpp 2025-08-06 02:01:21.085876490 +0300
|
||||||
|
@@ -0,0 +1,150 @@
|
||||||
|
+/*
|
||||||
|
+ Simple DirectMedia Layer
|
||||||
|
+ Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
+
|
||||||
|
+ This software is provided 'as-is', without any express or implied
|
||||||
|
+ warranty. In no event will the authors be held liable for any damages
|
||||||
|
+ arising from the use of this software.
|
||||||
|
+
|
||||||
|
+ Permission is granted to anyone to use this software for any purpose,
|
||||||
|
+ including commercial applications, and to alter it and redistribute it
|
||||||
|
+ freely, subject to the following restrictions:
|
||||||
|
+
|
||||||
|
+ 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
+ claim that you wrote the original software. If you use this software
|
||||||
|
+ in a product, an acknowledgment in the product documentation would be
|
||||||
|
+ appreciated but is not required.
|
||||||
|
+ 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
+ misrepresented as being the original software.
|
||||||
|
+ 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
+*/
|
||||||
|
+#include "../../SDL_internal.h"
|
||||||
|
+
|
||||||
|
+#if SDL_AUDIO_DRIVER_BANANOS
|
||||||
|
+
|
||||||
|
+extern "C" {
|
||||||
|
+#include "SDL_audio.h"
|
||||||
|
+#include "../SDL_audio_c.h"
|
||||||
|
+#include "../SDL_sysaudio.h"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include "SDL_banan_os_audio.h"
|
||||||
|
+
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+#define DUMP_FUNCTIONS 0
|
||||||
|
+
|
||||||
|
+#if DUMP_FUNCTIONS
|
||||||
|
+# define DUMP_FUNCTION() dprintln(__FUNCTION__)
|
||||||
|
+#else
|
||||||
|
+# define DUMP_FUNCTION()
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+static void BANANOS_CloseDevice(_THIS)
|
||||||
|
+{
|
||||||
|
+ DUMP_FUNCTION();
|
||||||
|
+
|
||||||
|
+ if (!_this->hidden)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (_this->hidden->mixbuf)
|
||||||
|
+ SDL_free(_this->hidden->mixbuf);
|
||||||
|
+
|
||||||
|
+ delete _this->hidden;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int BANANOS_OpenDevice(_THIS, char const*)
|
||||||
|
+{
|
||||||
|
+ DUMP_FUNCTION();
|
||||||
|
+
|
||||||
|
+ // TODO: try to accept already existing spec
|
||||||
|
+ _this->spec.freq = 44100;
|
||||||
|
+ _this->spec.format = AUDIO_S16LSB;
|
||||||
|
+ _this->spec.channels = 2;
|
||||||
|
+ _this->spec.samples = 2048;
|
||||||
|
+ SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
+
|
||||||
|
+ auto audio_or_error = LibAudio::Audio::create(_this->spec.channels, _this->spec.freq, 0x1000);
|
||||||
|
+ if (audio_or_error.is_error())
|
||||||
|
+ return SDL_SetError("failed to create audio device: %s", audio_or_error.error().get_message());
|
||||||
|
+
|
||||||
|
+ void* mixbuf = SDL_malloc(_this->spec.size);
|
||||||
|
+ if (mixbuf == nullptr)
|
||||||
|
+ return SDL_OutOfMemory();
|
||||||
|
+
|
||||||
|
+ _this->hidden = new SDL_PrivateAudioData(audio_or_error.release_value(), mixbuf);
|
||||||
|
+ if (!_this->hidden)
|
||||||
|
+ return SDL_OutOfMemory();
|
||||||
|
+ MUST(_this->hidden->audio.start());
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void BANANOS_PlayDevice(_THIS)
|
||||||
|
+{
|
||||||
|
+ DUMP_FUNCTION();
|
||||||
|
+
|
||||||
|
+ const bool should_play = SDL_AtomicGet(&_this->enabled) && !SDL_AtomicGet(&_this->paused);
|
||||||
|
+ _this->hidden->audio.set_paused(!should_play);
|
||||||
|
+ if (!should_play)
|
||||||
|
+ {
|
||||||
|
+ usleep(100);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static_assert(BAN::is_same_v<LibAudio::AudioBuffer::sample_t, double>);
|
||||||
|
+
|
||||||
|
+ const auto convert_sample = [](int16_t input) {
|
||||||
|
+ return (static_cast<double>(input) - BAN::numeric_limits<int16_t>::min()) / BAN::numeric_limits<int16_t>::max() * 2.0 - 1.0;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ const size_t input_samples = _this->spec.size / sizeof(int16_t);
|
||||||
|
+ size_t samples_queued = 0;
|
||||||
|
+
|
||||||
|
+ const int16_t* mixbuf = static_cast<const int16_t*>(_this->hidden->mixbuf);
|
||||||
|
+ while (samples_queued < input_samples)
|
||||||
|
+ {
|
||||||
|
+ const size_t to_convert = BAN::Math::min(_this->hidden->conversion.size(), input_samples - samples_queued);
|
||||||
|
+ for (size_t i = 0; i < to_convert; i++)
|
||||||
|
+ _this->hidden->conversion[i] = convert_sample(mixbuf[samples_queued + i]);
|
||||||
|
+
|
||||||
|
+ auto sample_span = _this->hidden->conversion.span();
|
||||||
|
+ while (!sample_span.empty())
|
||||||
|
+ {
|
||||||
|
+ const size_t queued = _this->hidden->audio.queue_samples(sample_span);
|
||||||
|
+ if (queued == 0)
|
||||||
|
+ usleep(100);
|
||||||
|
+ sample_span = sample_span.slice(queued);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ samples_queued += to_convert;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static Uint8* BANANOS_GetDeviceBuf(_THIS)
|
||||||
|
+{
|
||||||
|
+ DUMP_FUNCTION();
|
||||||
|
+
|
||||||
|
+ return static_cast<Uint8*>(_this->hidden->mixbuf);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static SDL_bool BANANOS_Init(SDL_AudioDriverImpl* impl)
|
||||||
|
+{
|
||||||
|
+ impl->OpenDevice = BANANOS_OpenDevice;
|
||||||
|
+ impl->CloseDevice = BANANOS_CloseDevice;
|
||||||
|
+ impl->PlayDevice = BANANOS_PlayDevice;
|
||||||
|
+ impl->GetDeviceBuf = BANANOS_GetDeviceBuf;
|
||||||
|
+
|
||||||
|
+ impl->ProvidesOwnCallbackThread = SDL_FALSE;
|
||||||
|
+ impl->HasCaptureSupport = SDL_FALSE;
|
||||||
|
+ impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||||
|
+ impl->SupportsNonPow2Samples = SDL_TRUE;
|
||||||
|
+
|
||||||
|
+ return SDL_TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+AudioBootStrap BANANOSAUDIO_bootstrap = {
|
||||||
|
+ "banan-os", "banan-os AudioServer", BANANOS_Init, SDL_FALSE
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff -ruN SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.h SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.h
|
||||||
|
--- SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
|
+++ SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.h 2025-08-06 02:01:21.085937043 +0300
|
||||||
|
@@ -0,0 +1,34 @@
|
||||||
|
+/*
|
||||||
|
+ Simple DirectMedia Layer
|
||||||
|
+ Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
+
|
||||||
|
+ This software is provided 'as-is', without any express or implied
|
||||||
|
+ warranty. In no event will the authors be held liable for any damages
|
||||||
|
+ arising from the use of this software.
|
||||||
|
+
|
||||||
|
+ Permission is granted to anyone to use this software for any purpose,
|
||||||
|
+ including commercial applications, and to alter it and redistribute it
|
||||||
|
+ freely, subject to the following restrictions:
|
||||||
|
+
|
||||||
|
+ 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
+ claim that you wrote the original software. If you use this software
|
||||||
|
+ in a product, an acknowledgment in the product documentation would be
|
||||||
|
+ appreciated but is not required.
|
||||||
|
+ 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
+ misrepresented as being the original software.
|
||||||
|
+ 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
+*/
|
||||||
|
+#include "../../SDL_internal.h"
|
||||||
|
+
|
||||||
|
+#pragma once
|
||||||
|
+
|
||||||
|
+#include <LibAudio/Audio.h>
|
||||||
|
+#include <BAN/Array.h>
|
||||||
|
+
|
||||||
|
+#define _THIS SDL_AudioDevice* _this
|
||||||
|
+
|
||||||
|
+struct SDL_PrivateAudioData {
|
||||||
|
+ LibAudio::Audio audio;
|
||||||
|
+ void* mixbuf { nullptr };
|
||||||
|
+ BAN::Array<LibAudio::AudioBuffer::sample_t, 4096> conversion;
|
||||||
|
+};
|
||||||
|
diff -ruN SDL2-2.32.8/src/audio/SDL_audio.c SDL2-2.32.8-banan_os/src/audio/SDL_audio.c
|
||||||
|
--- SDL2-2.32.8/src/audio/SDL_audio.c 2025-01-01 17:47:53.000000000 +0200
|
||||||
|
+++ SDL2-2.32.8-banan_os/src/audio/SDL_audio.c 2025-08-06 02:01:21.086082872 +0300
|
||||||
|
@@ -87,6 +87,9 @@
|
||||||
|
#ifdef SDL_AUDIO_DRIVER_HAIKU
|
||||||
|
&HAIKUAUDIO_bootstrap,
|
||||||
|
#endif
|
||||||
|
+#ifdef SDL_AUDIO_DRIVER_BANANOS
|
||||||
|
+ &BANANOSAUDIO_bootstrap,
|
||||||
|
+#endif
|
||||||
|
#ifdef SDL_AUDIO_DRIVER_COREAUDIO
|
||||||
|
&COREAUDIO_bootstrap,
|
||||||
|
#endif
|
||||||
|
diff -ruN SDL2-2.32.8/src/audio/SDL_sysaudio.h SDL2-2.32.8-banan_os/src/audio/SDL_sysaudio.h
|
||||||
|
--- SDL2-2.32.8/src/audio/SDL_sysaudio.h 2025-01-01 17:47:53.000000000 +0200
|
||||||
|
+++ SDL2-2.32.8-banan_os/src/audio/SDL_sysaudio.h 2025-08-06 02:01:21.086309718 +0300
|
||||||
|
@@ -196,6 +196,7 @@
|
||||||
|
extern AudioBootStrap WINMM_bootstrap;
|
||||||
|
extern AudioBootStrap PAUDIO_bootstrap;
|
||||||
|
extern AudioBootStrap HAIKUAUDIO_bootstrap;
|
||||||
|
+extern AudioBootStrap BANANOSAUDIO_bootstrap;
|
||||||
|
extern AudioBootStrap COREAUDIO_bootstrap;
|
||||||
|
extern AudioBootStrap DISKAUDIO_bootstrap;
|
||||||
|
extern AudioBootStrap DUMMYAUDIO_bootstrap;
|
||||||
|
diff -ruN SDL2-2.32.8/src/misc/banan_os/SDL_sysurl.cpp SDL2-2.32.8-banan_os/src/misc/banan_os/SDL_sysurl.cpp
|
||||||
|
--- SDL2-2.32.8/src/misc/banan_os/SDL_sysurl.cpp 1970-01-01 02:00:00.000000000 +0200
|
||||||
|
+++ SDL2-2.32.8-banan_os/src/misc/banan_os/SDL_sysurl.cpp 2025-08-06 02:01:21.086457363 +0300
|
||||||
@@ -0,0 +1,30 @@
|
@@ -0,0 +1,30 @@
|
||||||
+/*
|
+/*
|
||||||
+ Simple DirectMedia Layer
|
+ Simple DirectMedia Layer
|
||||||
|
@ -119,9 +372,9 @@ diff -ruN SDL-release-2.30.11/src/misc/banan_os/SDL_sysurl.cpp SDL2-2.30.11-bana
|
||||||
+
|
+
|
||||||
+/* vi: set ts=4 sw=4 expandtab: */
|
+/* vi: set ts=4 sw=4 expandtab: */
|
||||||
+
|
+
|
||||||
diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_message_box.cpp SDL2-2.30.11-banan_os/src/video/banan_os/SDL_banan_os_message_box.cpp
|
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.cpp SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.cpp
|
||||||
--- SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_message_box.cpp 1970-01-01 02:00:00.000000000 +0200
|
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.cpp 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ SDL2-2.30.11-banan_os/src/video/banan_os/SDL_banan_os_message_box.cpp 2025-08-03 14:04:09.895299391 +0300
|
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.cpp 2025-08-06 02:01:21.086557935 +0300
|
||||||
@@ -0,0 +1,60 @@
|
@@ -0,0 +1,60 @@
|
||||||
+/*
|
+/*
|
||||||
+ Simple DirectMedia Layer
|
+ Simple DirectMedia Layer
|
||||||
|
@ -147,7 +400,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_message_box.cpp SD
|
||||||
+
|
+
|
||||||
+#include "../../SDL_internal.h"
|
+#include "../../SDL_internal.h"
|
||||||
+
|
+
|
||||||
+#ifdef SDL_VIDEO_DRIVER_BANAN_OS
|
+#ifdef SDL_VIDEO_DRIVER_BANANOS
|
||||||
+
|
+
|
||||||
+#include "SDL_messagebox.h"
|
+#include "SDL_messagebox.h"
|
||||||
+
|
+
|
||||||
|
@ -156,7 +409,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_message_box.cpp SD
|
||||||
+#include <BAN/Debug.h>
|
+#include <BAN/Debug.h>
|
||||||
+#include <LibGUI/MessageBox.h>
|
+#include <LibGUI/MessageBox.h>
|
||||||
+
|
+
|
||||||
+int BANAN_OS_ShowMessageBox(const SDL_MessageBoxData* messageboxdata, int* buttonid)
|
+int BANANOS_ShowMessageBox(const SDL_MessageBoxData* messageboxdata, int* buttonid)
|
||||||
+{
|
+{
|
||||||
+ BAN::Vector<BAN::StringView> buttons;
|
+ BAN::Vector<BAN::StringView> buttons;
|
||||||
+ for (int i = 0; i < messageboxdata->numbuttons; i++) {
|
+ for (int i = 0; i < messageboxdata->numbuttons; i++) {
|
||||||
|
@ -180,12 +433,12 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_message_box.cpp SD
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+#endif /* SDL_VIDEO_DRIVER_BANAN_OS */
|
+#endif /* SDL_VIDEO_DRIVER_BANANOS */
|
||||||
+
|
+
|
||||||
+/* vi: set ts=4 sw=4 expandtab: */
|
+/* vi: set ts=4 sw=4 expandtab: */
|
||||||
diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_message_box.h SDL2-2.30.11-banan_os/src/video/banan_os/SDL_banan_os_message_box.h
|
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.h SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.h
|
||||||
--- SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_message_box.h 1970-01-01 02:00:00.000000000 +0200
|
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ SDL2-2.30.11-banan_os/src/video/banan_os/SDL_banan_os_message_box.h 2025-08-03 14:04:09.895347931 +0300
|
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.h 2025-08-06 02:01:21.086603053 +0300
|
||||||
@@ -0,0 +1,45 @@
|
@@ -0,0 +1,45 @@
|
||||||
+/*
|
+/*
|
||||||
+ Simple DirectMedia Layer
|
+ Simple DirectMedia Layer
|
||||||
|
@ -209,33 +462,33 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_message_box.h SDL2
|
||||||
+ 3. This notice may not be removed or altered from any source distribution.
|
+ 3. This notice may not be removed or altered from any source distribution.
|
||||||
+*/
|
+*/
|
||||||
+
|
+
|
||||||
+#ifndef SDL_BANAN_OS_MESSAGEBOX_H
|
+#ifndef SDL_BANANOS_MESSAGEBOX_H
|
||||||
+#define SDL_BANAN_OS_MESSAGEBOX_H
|
+#define SDL_BANANOS_MESSAGEBOX_H
|
||||||
+
|
+
|
||||||
+#include "../../SDL_internal.h"
|
+#include "../../SDL_internal.h"
|
||||||
+
|
+
|
||||||
+#ifdef SDL_VIDEO_DRIVER_BANAN_OS
|
+#ifdef SDL_VIDEO_DRIVER_BANANOS
|
||||||
+
|
+
|
||||||
+#ifdef __cplusplus
|
+#ifdef __cplusplus
|
||||||
+extern "C" {
|
+extern "C" {
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
+extern int
|
+extern int
|
||||||
+BANAN_OS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
|
+BANANOS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
|
||||||
+
|
+
|
||||||
+#ifdef __cplusplus
|
+#ifdef __cplusplus
|
||||||
+}
|
+}
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
+#endif /* SDL_BANAN_OS_MESSAGEBOX_H */
|
+#endif /* SDL_BANANOS_MESSAGEBOX_H */
|
||||||
+
|
+
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
+/* vi: set ts=4 sw=4 expandtab: */
|
+/* vi: set ts=4 sw=4 expandtab: */
|
||||||
diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.30.11-banan_os/src/video/banan_os/SDL_banan_os_video.cpp
|
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_video.cpp
|
||||||
--- SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp 1970-01-01 02:00:00.000000000 +0200
|
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_video.cpp 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ SDL2-2.30.11-banan_os/src/video/banan_os/SDL_banan_os_video.cpp 2025-08-04 14:57:50.844360579 +0300
|
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_video.cpp 2025-08-06 02:01:21.086666679 +0300
|
||||||
@@ -0,0 +1,719 @@
|
@@ -0,0 +1,718 @@
|
||||||
+/*
|
+/*
|
||||||
+ Simple DirectMedia Layer
|
+ Simple DirectMedia Layer
|
||||||
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
@ -256,10 +509,9 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ misrepresented as being the original software.
|
+ misrepresented as being the original software.
|
||||||
+ 3. This notice may not be removed or altered from any source distribution.
|
+ 3. This notice may not be removed or altered from any source distribution.
|
||||||
+*/
|
+*/
|
||||||
+
|
|
||||||
+#include "../../SDL_internal.h"
|
+#include "../../SDL_internal.h"
|
||||||
+
|
+
|
||||||
+#ifdef SDL_VIDEO_DRIVER_BANAN_OS
|
+#ifdef SDL_VIDEO_DRIVER_BANANOS
|
||||||
+
|
+
|
||||||
+extern "C" {
|
+extern "C" {
|
||||||
+#include "../SDL_sysvideo.h"
|
+#include "../SDL_sysvideo.h"
|
||||||
|
@ -422,7 +674,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+};
|
+};
|
||||||
+static Keymap s_keymap;
|
+static Keymap s_keymap;
|
||||||
+
|
+
|
||||||
+static int BANAN_OS_mouse_button_to_sdl(LibInput::MouseButton button)
|
+static int BANANOS_mouse_button_to_sdl(LibInput::MouseButton button)
|
||||||
+{
|
+{
|
||||||
+ switch (button) {
|
+ switch (button) {
|
||||||
+#define BUTTON_CASE(my, sdl) case LibInput::MouseButton::my: return SDL_BUTTON_##sdl
|
+#define BUTTON_CASE(my, sdl) case LibInput::MouseButton::my: return SDL_BUTTON_##sdl
|
||||||
|
@ -438,7 +690,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+
|
+
|
||||||
+static SDL_VideoDevice* s_video_device = nullptr;
|
+static SDL_VideoDevice* s_video_device = nullptr;
|
||||||
+
|
+
|
||||||
+static SDL_Cursor* BANAN_OS_CreateSystemCursor(SDL_SystemCursor id)
|
+static SDL_Cursor* BANANOS_CreateSystemCursor(SDL_SystemCursor id)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -453,7 +705,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ return cursor;
|
+ return cursor;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_FreeCursor(SDL_Cursor* cursor)
|
+static void BANANOS_FreeCursor(SDL_Cursor* cursor)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -461,7 +713,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ SDL_free(cursor);
|
+ SDL_free(cursor);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int BANAN_OS_ShowCursor(SDL_Cursor* cursor)
|
+static int BANANOS_ShowCursor(SDL_Cursor* cursor)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -475,7 +727,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int BANAN_OS_SetRelativeMouseMode(SDL_bool enabled)
|
+static int BANANOS_SetRelativeMouseMode(SDL_bool enabled)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -490,24 +742,24 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_InitMouse(_THIS)
|
+static void BANANOS_InitMouse(_THIS)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
+ auto* mouse = SDL_GetMouse();
|
+ auto* mouse = SDL_GetMouse();
|
||||||
+ mouse->ShowCursor = BANAN_OS_ShowCursor;
|
+ mouse->ShowCursor = BANANOS_ShowCursor;
|
||||||
+ mouse->SetRelativeMouseMode = BANAN_OS_SetRelativeMouseMode;
|
+ mouse->SetRelativeMouseMode = BANANOS_SetRelativeMouseMode;
|
||||||
+ mouse->CreateSystemCursor = BANAN_OS_CreateSystemCursor;
|
+ mouse->CreateSystemCursor = BANANOS_CreateSystemCursor;
|
||||||
+ mouse->FreeCursor = BANAN_OS_FreeCursor;
|
+ mouse->FreeCursor = BANANOS_FreeCursor;
|
||||||
+
|
+
|
||||||
+ SDL_SetDefaultCursor(BANAN_OS_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW));
|
+ SDL_SetDefaultCursor(BANANOS_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW));
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int BANAN_OS_VideoInit(_THIS)
|
+static int BANANOS_VideoInit(_THIS)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
+ BANAN_OS_InitMouse(_this);
|
+ BANANOS_InitMouse(_this);
|
||||||
+
|
+
|
||||||
+ int fb_fd = open("/dev/fb0", O_RDONLY);
|
+ int fb_fd = open("/dev/fb0", O_RDONLY);
|
||||||
+ if (fb_fd == -1) {
|
+ if (fb_fd == -1) {
|
||||||
|
@ -543,7 +795,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_VideoQuit(_THIS)
|
+static void BANANOS_VideoQuit(_THIS)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -551,14 +803,14 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ s_video_device = nullptr;
|
+ s_video_device = nullptr;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_free(_THIS)
|
+static void BANANOS_free(_THIS)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+ delete static_cast<banan_os_video_device_data*>(_this->driverdata);
|
+ delete static_cast<banan_os_video_device_data*>(_this->driverdata);
|
||||||
+ SDL_free(_this);
|
+ SDL_free(_this);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int BANAN_OS_CreateSDLWindow(_THIS, SDL_Window* window)
|
+static int BANANOS_CreateSDLWindow(_THIS, SDL_Window* window)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -600,7 +852,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ [window, ban_window](LibGUI::EventPacket::MouseButtonEvent::event_t event) {
|
+ [window, ban_window](LibGUI::EventPacket::MouseButtonEvent::event_t event) {
|
||||||
+ const int state = event.pressed ? SDL_PRESSED : SDL_RELEASED;
|
+ const int state = event.pressed ? SDL_PRESSED : SDL_RELEASED;
|
||||||
+ SDL_SendMouseMotion(window, 0, ban_window->relative, event.x, event.y);
|
+ SDL_SendMouseMotion(window, 0, ban_window->relative, event.x, event.y);
|
||||||
+ SDL_SendMouseButton(window, 0, state, BANAN_OS_mouse_button_to_sdl(event.button));
|
+ SDL_SendMouseButton(window, 0, state, BANANOS_mouse_button_to_sdl(event.button));
|
||||||
+ }
|
+ }
|
||||||
+ );
|
+ );
|
||||||
+
|
+
|
||||||
|
@ -651,7 +903,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_DestroyWindow(_THIS, SDL_Window* window)
|
+static void BANANOS_DestroyWindow(_THIS, SDL_Window* window)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -667,7 +919,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ window->driverdata = nullptr;
|
+ window->driverdata = nullptr;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_ShowWindow(_THIS, SDL_Window* window)
|
+static void BANANOS_ShowWindow(_THIS, SDL_Window* window)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -681,7 +933,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ ban_window.window->set_attributes(attributes);
|
+ ban_window.window->set_attributes(attributes);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_HideWindow(_THIS, SDL_Window* window)
|
+static void BANANOS_HideWindow(_THIS, SDL_Window* window)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -695,7 +947,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ ban_window.window->set_attributes(attributes);
|
+ ban_window.window->set_attributes(attributes);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_SetWindowTitle(_THIS, SDL_Window* window)
|
+static void BANANOS_SetWindowTitle(_THIS, SDL_Window* window)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -703,7 +955,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ ban_window.window->set_title(window->title);
|
+ ban_window.window->set_title(window->title);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_SetWindowPosition(_THIS, SDL_Window* window)
|
+static void BANANOS_SetWindowPosition(_THIS, SDL_Window* window)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -711,7 +963,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ ban_window.window->set_position(window->x, window->y);
|
+ ban_window.window->set_position(window->x, window->y);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_SetWindowSize(_THIS, SDL_Window* window)
|
+static void BANANOS_SetWindowSize(_THIS, SDL_Window* window)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -719,7 +971,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ ban_window.window->request_resize(window->w, window->h);
|
+ ban_window.window->request_resize(window->w, window->h);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_SetWindowMinimumSize(_THIS, SDL_Window* window)
|
+static void BANANOS_SetWindowMinimumSize(_THIS, SDL_Window* window)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -727,7 +979,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ ban_window.window->set_min_size(window->min_w, window->min_h);
|
+ ban_window.window->set_min_size(window->min_w, window->min_h);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_SetWindowMaximumSize(_THIS, SDL_Window* window)
|
+static void BANANOS_SetWindowMaximumSize(_THIS, SDL_Window* window)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -735,12 +987,12 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ ban_window.window->set_max_size(window->min_w, window->min_h);
|
+ ban_window.window->set_max_size(window->min_w, window->min_h);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
|
+static void BANANOS_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
|
+static void BANANOS_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -751,7 +1003,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
+static void BANANOS_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -759,7 +1011,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ ban_window.window->set_fullscreen(fullscreen);
|
+ ban_window.window->set_fullscreen(fullscreen);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int BANAN_OS_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format, void** pixels, int* pitch)
|
+static int BANANOS_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format, void** pixels, int* pitch)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -783,7 +1035,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int BANAN_OS_UpdateWindowFramebuffer(_THIS, SDL_Window* window, const SDL_Rect* rects, int numrects)
|
+static int BANANOS_UpdateWindowFramebuffer(_THIS, SDL_Window* window, const SDL_Rect* rects, int numrects)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -795,12 +1047,12 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_DestroyWindowFramebuffer(_THIS, SDL_Window* window)
|
+static void BANANOS_DestroyWindowFramebuffer(_THIS, SDL_Window* window)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_PumpEvents(_THIS)
|
+static void BANANOS_PumpEvents(_THIS)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -809,7 +1061,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ window->window->poll_events();
|
+ window->window->poll_events();
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int BANAN_OS_GL_LoadLibrary(_THIS, const char* path)
|
+static int BANANOS_GL_LoadLibrary(_THIS, const char* path)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -822,14 +1074,14 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void* BANAN_OS_GL_GetProcAddress(_THIS, const char* proc)
|
+static void* BANANOS_GL_GetProcAddress(_THIS, const char* proc)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
+ return reinterpret_cast<void*>(OSMesaGetProcAddress(proc));
|
+ return reinterpret_cast<void*>(OSMesaGetProcAddress(proc));
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static SDL_GLContext BANAN_OS_GL_CreateContext(_THIS, SDL_Window* window)
|
+static SDL_GLContext BANANOS_GL_CreateContext(_THIS, SDL_Window* window)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -853,7 +1105,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ return gl_context;
|
+ return gl_context;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void BANAN_OS_GL_DeleteContext(_THIS, SDL_GLContext context)
|
+static void BANANOS_GL_DeleteContext(_THIS, SDL_GLContext context)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -861,7 +1113,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ OSMesaDestroyContext(gl_context);
|
+ OSMesaDestroyContext(gl_context);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int BANAN_OS_GL_MakeCurrent(_THIS, SDL_Window* window, SDL_GLContext context)
|
+static int BANANOS_GL_MakeCurrent(_THIS, SDL_Window* window, SDL_GLContext context)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -880,7 +1132,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int BANAN_OS_GL_SwapWindow(_THIS, SDL_Window* window)
|
+static int BANANOS_GL_SwapWindow(_THIS, SDL_Window* window)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -895,7 +1147,7 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static SDL_VideoDevice* BANAN_OS_CreateDevice(void)
|
+static SDL_VideoDevice* BANANOS_CreateDevice(void)
|
||||||
+{
|
+{
|
||||||
+ DUMP_FUNCTION();
|
+ DUMP_FUNCTION();
|
||||||
+
|
+
|
||||||
|
@ -911,70 +1163,70 @@ diff -ruN SDL-release-2.30.11/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.3
|
||||||
+ return nullptr;
|
+ return nullptr;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ device->VideoInit = BANAN_OS_VideoInit;
|
+ device->VideoInit = BANANOS_VideoInit;
|
||||||
+ device->VideoQuit = BANAN_OS_VideoQuit;
|
+ device->VideoQuit = BANANOS_VideoQuit;
|
||||||
+
|
+
|
||||||
+ device->CreateSDLWindow = BANAN_OS_CreateSDLWindow;
|
+ device->CreateSDLWindow = BANANOS_CreateSDLWindow;
|
||||||
+ device->DestroyWindow = BANAN_OS_DestroyWindow;
|
+ device->DestroyWindow = BANANOS_DestroyWindow;
|
||||||
+ device->ShowWindow = BANAN_OS_ShowWindow;
|
+ device->ShowWindow = BANANOS_ShowWindow;
|
||||||
+ device->HideWindow = BANAN_OS_HideWindow;
|
+ device->HideWindow = BANANOS_HideWindow;
|
||||||
+
|
+
|
||||||
+ device->SetWindowTitle = BANAN_OS_SetWindowTitle;
|
+ device->SetWindowTitle = BANANOS_SetWindowTitle;
|
||||||
+ device->SetWindowPosition = BANAN_OS_SetWindowPosition;
|
+ device->SetWindowPosition = BANANOS_SetWindowPosition;
|
||||||
+ device->SetWindowSize = BANAN_OS_SetWindowSize;
|
+ device->SetWindowSize = BANANOS_SetWindowSize;
|
||||||
+ device->SetWindowMinimumSize = BANAN_OS_SetWindowMinimumSize;
|
+ device->SetWindowMinimumSize = BANANOS_SetWindowMinimumSize;
|
||||||
+ device->SetWindowMaximumSize = BANAN_OS_SetWindowMaximumSize;
|
+ device->SetWindowMaximumSize = BANANOS_SetWindowMaximumSize;
|
||||||
+ device->SetWindowBordered = BANAN_OS_SetWindowBordered;
|
+ device->SetWindowBordered = BANANOS_SetWindowBordered;
|
||||||
+ device->SetWindowResizable = BANAN_OS_SetWindowResizable;
|
+ device->SetWindowResizable = BANANOS_SetWindowResizable;
|
||||||
+ device->SetWindowFullscreen = BANAN_OS_SetWindowFullscreen;
|
+ device->SetWindowFullscreen = BANANOS_SetWindowFullscreen;
|
||||||
+
|
+
|
||||||
+ device->CreateWindowFramebuffer = BANAN_OS_CreateWindowFramebuffer;
|
+ device->CreateWindowFramebuffer = BANANOS_CreateWindowFramebuffer;
|
||||||
+ device->UpdateWindowFramebuffer = BANAN_OS_UpdateWindowFramebuffer;
|
+ device->UpdateWindowFramebuffer = BANANOS_UpdateWindowFramebuffer;
|
||||||
+ device->DestroyWindowFramebuffer = BANAN_OS_DestroyWindowFramebuffer;
|
+ device->DestroyWindowFramebuffer = BANANOS_DestroyWindowFramebuffer;
|
||||||
+
|
+
|
||||||
+ device->PumpEvents = BANAN_OS_PumpEvents;
|
+ device->PumpEvents = BANANOS_PumpEvents;
|
||||||
+
|
+
|
||||||
+ device->GL_LoadLibrary = BANAN_OS_GL_LoadLibrary;
|
+ device->GL_LoadLibrary = BANANOS_GL_LoadLibrary;
|
||||||
+ device->GL_GetProcAddress = BANAN_OS_GL_GetProcAddress;
|
+ device->GL_GetProcAddress = BANANOS_GL_GetProcAddress;
|
||||||
+ device->GL_CreateContext = BANAN_OS_GL_CreateContext;
|
+ device->GL_CreateContext = BANANOS_GL_CreateContext;
|
||||||
+ device->GL_DeleteContext = BANAN_OS_GL_DeleteContext;
|
+ device->GL_DeleteContext = BANANOS_GL_DeleteContext;
|
||||||
+ device->GL_MakeCurrent = BANAN_OS_GL_MakeCurrent;
|
+ device->GL_MakeCurrent = BANANOS_GL_MakeCurrent;
|
||||||
+ device->GL_SwapWindow = BANAN_OS_GL_SwapWindow;
|
+ device->GL_SwapWindow = BANANOS_GL_SwapWindow;
|
||||||
+
|
+
|
||||||
+ device->free = BANAN_OS_free;
|
+ device->free = BANANOS_free;
|
||||||
+
|
+
|
||||||
+ return device;
|
+ return device;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+VideoBootStrap BANAN_OS_bootstrap = {
|
+VideoBootStrap BANANOS_bootstrap = {
|
||||||
+ "banan-os", "banan-os graphics",
|
+ "banan-os", "banan-os graphics",
|
||||||
+ BANAN_OS_CreateDevice,
|
+ BANANOS_CreateDevice,
|
||||||
+ BANAN_OS_ShowMessageBox
|
+ BANANOS_ShowMessageBox
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+#endif /* SDL_VIDEO_DRIVER_BANAN_OS */
|
+#endif /* SDL_VIDEO_DRIVER_BANANOS */
|
||||||
+
|
+
|
||||||
+/* vi: set ts=4 sw=4 expandtab: */
|
+/* vi: set ts=4 sw=4 expandtab: */
|
||||||
diff -ruN SDL-release-2.30.11/src/video/SDL_sysvideo.h SDL2-2.30.11-banan_os/src/video/SDL_sysvideo.h
|
diff -ruN SDL2-2.32.8/src/video/SDL_sysvideo.h SDL2-2.32.8-banan_os/src/video/SDL_sysvideo.h
|
||||||
--- SDL-release-2.30.11/src/video/SDL_sysvideo.h 2025-01-01 19:09:38.000000000 +0200
|
--- SDL2-2.32.8/src/video/SDL_sysvideo.h 2025-05-20 00:24:41.000000000 +0300
|
||||||
+++ SDL2-2.30.11-banan_os/src/video/SDL_sysvideo.h 2025-08-03 14:04:09.895655165 +0300
|
+++ SDL2-2.32.8-banan_os/src/video/SDL_sysvideo.h 2025-08-06 02:01:21.086873550 +0300
|
||||||
@@ -462,6 +462,7 @@
|
@@ -462,6 +462,7 @@
|
||||||
extern VideoBootStrap WINDOWS_bootstrap;
|
extern VideoBootStrap WINDOWS_bootstrap;
|
||||||
extern VideoBootStrap WINRT_bootstrap;
|
extern VideoBootStrap WINRT_bootstrap;
|
||||||
extern VideoBootStrap HAIKU_bootstrap;
|
extern VideoBootStrap HAIKU_bootstrap;
|
||||||
+extern VideoBootStrap BANAN_OS_bootstrap;
|
+extern VideoBootStrap BANANOS_bootstrap;
|
||||||
extern VideoBootStrap PND_bootstrap;
|
extern VideoBootStrap PND_bootstrap;
|
||||||
extern VideoBootStrap UIKIT_bootstrap;
|
extern VideoBootStrap UIKIT_bootstrap;
|
||||||
extern VideoBootStrap Android_bootstrap;
|
extern VideoBootStrap Android_bootstrap;
|
||||||
diff -ruN SDL-release-2.30.11/src/video/SDL_video.c SDL2-2.30.11-banan_os/src/video/SDL_video.c
|
diff -ruN SDL2-2.32.8/src/video/SDL_video.c SDL2-2.32.8-banan_os/src/video/SDL_video.c
|
||||||
--- SDL-release-2.30.11/src/video/SDL_video.c 2025-01-01 19:09:38.000000000 +0200
|
--- SDL2-2.32.8/src/video/SDL_video.c 2025-05-20 00:24:41.000000000 +0300
|
||||||
+++ SDL2-2.30.11-banan_os/src/video/SDL_video.c 2025-08-03 14:04:09.896007237 +0300
|
+++ SDL2-2.32.8-banan_os/src/video/SDL_video.c 2025-08-06 02:01:21.087224294 +0300
|
||||||
@@ -94,6 +94,9 @@
|
@@ -96,6 +96,9 @@
|
||||||
#ifdef SDL_VIDEO_DRIVER_HAIKU
|
#ifdef SDL_VIDEO_DRIVER_HAIKU
|
||||||
&HAIKU_bootstrap,
|
&HAIKU_bootstrap,
|
||||||
#endif
|
#endif
|
||||||
+#ifdef SDL_VIDEO_DRIVER_BANAN_OS
|
+#ifdef SDL_VIDEO_DRIVER_BANANOS
|
||||||
+ &BANAN_OS_bootstrap,
|
+ &BANANOS_bootstrap,
|
||||||
+#endif
|
+#endif
|
||||||
#ifdef SDL_VIDEO_DRIVER_PANDORA
|
#ifdef SDL_VIDEO_DRIVER_PANDORA
|
||||||
&PND_bootstrap,
|
&PND_bootstrap,
|
||||||
|
|
|
@ -59,7 +59,7 @@ config_sub_update() {
|
||||||
|
|
||||||
config_sub_path="$BANAN_PORT_DIR/config.sub"
|
config_sub_path="$BANAN_PORT_DIR/config.sub"
|
||||||
|
|
||||||
if [ $(find $config_sub_path -mtime +1) ]; then
|
if [ ! -f "$config_sub_path" ] || [ $(find "$config_sub_path" -mtime +1) ]; then
|
||||||
wget -O "$config_sub_path" 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'
|
wget -O "$config_sub_path" 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
set(USERSPACE_LIBRARIES
|
set(USERSPACE_LIBRARIES
|
||||||
LibAudio
|
LibAudio
|
||||||
LibC
|
LibC
|
||||||
|
LibDL
|
||||||
LibELF
|
LibELF
|
||||||
LibFont
|
LibFont
|
||||||
LibGUI
|
LibGUI
|
||||||
|
|
|
@ -12,6 +12,17 @@
|
||||||
namespace LibAudio
|
namespace LibAudio
|
||||||
{
|
{
|
||||||
|
|
||||||
|
BAN::ErrorOr<Audio> Audio::create(uint32_t channels, uint32_t sample_rate, uint32_t sample_frames)
|
||||||
|
{
|
||||||
|
Audio result;
|
||||||
|
TRY(result.initialize((sample_frames + 10) * channels));
|
||||||
|
|
||||||
|
result.m_audio_buffer->sample_rate = sample_rate;
|
||||||
|
result.m_audio_buffer->channels = channels;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<Audio> Audio::load(BAN::StringView path)
|
BAN::ErrorOr<Audio> Audio::load(BAN::StringView path)
|
||||||
{
|
{
|
||||||
Audio result(TRY(AudioLoader::load(path)));
|
Audio result(TRY(AudioLoader::load(path)));
|
||||||
|
@ -69,18 +80,6 @@ namespace LibAudio
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> Audio::start()
|
|
||||||
{
|
|
||||||
ASSERT(m_server_fd != -1);
|
|
||||||
|
|
||||||
const ssize_t nsend = send(m_server_fd, &m_smo_key, sizeof(m_smo_key), 0);
|
|
||||||
if (nsend == -1)
|
|
||||||
return BAN::Error::from_errno(errno);
|
|
||||||
ASSERT(nsend == sizeof(m_smo_key));
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<void> Audio::initialize(uint32_t total_samples)
|
BAN::ErrorOr<void> Audio::initialize(uint32_t total_samples)
|
||||||
{
|
{
|
||||||
m_smo_size = sizeof(AudioBuffer) + total_samples * sizeof(AudioBuffer::sample_t);
|
m_smo_size = sizeof(AudioBuffer) + total_samples * sizeof(AudioBuffer::sample_t);
|
||||||
|
@ -118,11 +117,58 @@ namespace LibAudio
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> Audio::start()
|
||||||
|
{
|
||||||
|
ASSERT(m_server_fd != -1);
|
||||||
|
|
||||||
|
const ssize_t nsend = send(m_server_fd, &m_smo_key, sizeof(m_smo_key), 0);
|
||||||
|
if (nsend == -1)
|
||||||
|
return BAN::Error::from_errno(errno);
|
||||||
|
ASSERT(nsend == sizeof(m_smo_key));
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void Audio::set_paused(bool paused)
|
||||||
|
{
|
||||||
|
ASSERT(m_server_fd != -1);
|
||||||
|
|
||||||
|
if (m_audio_buffer->paused == paused)
|
||||||
|
return;
|
||||||
|
m_audio_buffer->paused = paused;
|
||||||
|
|
||||||
|
long dummy = 0;
|
||||||
|
send(m_server_fd, &dummy, sizeof(dummy), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Audio::queue_samples(BAN::Span<const AudioBuffer::sample_t> samples)
|
||||||
|
{
|
||||||
|
size_t samples_queued = 0;
|
||||||
|
|
||||||
|
uint32_t head = m_audio_buffer->head;
|
||||||
|
while (samples_queued < samples.size())
|
||||||
|
{
|
||||||
|
const uint32_t next_head = (head + 1) % m_audio_buffer->capacity;
|
||||||
|
if (next_head == m_audio_buffer->tail)
|
||||||
|
break;
|
||||||
|
m_audio_buffer->samples[head] = samples[samples_queued++];
|
||||||
|
head = next_head;
|
||||||
|
if (samples_queued % 128 == 0)
|
||||||
|
m_audio_buffer->head = head;
|
||||||
|
}
|
||||||
|
if (samples_queued % 128 != 0)
|
||||||
|
m_audio_buffer->head = head;
|
||||||
|
return samples_queued;
|
||||||
|
}
|
||||||
|
|
||||||
void Audio::update()
|
void Audio::update()
|
||||||
{
|
{
|
||||||
if (!m_audio_loader)
|
if (!m_audio_loader)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!m_audio_loader->samples_remaining() && !is_playing())
|
||||||
|
return set_paused(true);
|
||||||
|
|
||||||
while (m_audio_loader->samples_remaining())
|
while (m_audio_loader->samples_remaining())
|
||||||
{
|
{
|
||||||
const uint32_t next_head = (m_audio_buffer->head + 1) % m_audio_buffer->capacity;
|
const uint32_t next_head = (m_audio_buffer->head + 1) % m_audio_buffer->capacity;
|
||||||
|
|
|
@ -18,6 +18,8 @@ namespace LibAudio
|
||||||
uint32_t sample_rate;
|
uint32_t sample_rate;
|
||||||
uint32_t channels;
|
uint32_t channels;
|
||||||
|
|
||||||
|
BAN::Atomic<bool> paused { false };
|
||||||
|
|
||||||
uint32_t capacity;
|
uint32_t capacity;
|
||||||
BAN::Atomic<uint32_t> tail { 0 };
|
BAN::Atomic<uint32_t> tail { 0 };
|
||||||
BAN::Atomic<uint32_t> head { 0 };
|
BAN::Atomic<uint32_t> head { 0 };
|
||||||
|
@ -29,6 +31,7 @@ namespace LibAudio
|
||||||
BAN_NON_COPYABLE(Audio);
|
BAN_NON_COPYABLE(Audio);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static BAN::ErrorOr<Audio> create(uint32_t channels, uint32_t sample_rate, uint32_t sample_frames);
|
||||||
static BAN::ErrorOr<Audio> load(BAN::StringView path);
|
static BAN::ErrorOr<Audio> load(BAN::StringView path);
|
||||||
static BAN::ErrorOr<Audio> random(uint32_t samples);
|
static BAN::ErrorOr<Audio> random(uint32_t samples);
|
||||||
~Audio() { clear(); }
|
~Audio() { clear(); }
|
||||||
|
@ -37,9 +40,13 @@ namespace LibAudio
|
||||||
Audio& operator=(Audio&& other);
|
Audio& operator=(Audio&& other);
|
||||||
|
|
||||||
BAN::ErrorOr<void> start();
|
BAN::ErrorOr<void> start();
|
||||||
|
void update();
|
||||||
|
|
||||||
|
void set_paused(bool paused);
|
||||||
|
|
||||||
bool is_playing() const { return m_audio_buffer->tail != m_audio_buffer->head; }
|
bool is_playing() const { return m_audio_buffer->tail != m_audio_buffer->head; }
|
||||||
void update();
|
|
||||||
|
size_t queue_samples(BAN::Span<const AudioBuffer::sample_t> samples);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Audio() = default;
|
Audio() = default;
|
||||||
|
|
|
@ -12,6 +12,7 @@ set(LIBC_SOURCES
|
||||||
fenv.cpp
|
fenv.cpp
|
||||||
ftw.cpp
|
ftw.cpp
|
||||||
grp.cpp
|
grp.cpp
|
||||||
|
ifaddrs.cpp
|
||||||
inttypes.cpp
|
inttypes.cpp
|
||||||
langinfo.cpp
|
langinfo.cpp
|
||||||
libgen.cpp
|
libgen.cpp
|
||||||
|
@ -19,6 +20,7 @@ set(LIBC_SOURCES
|
||||||
locale.cpp
|
locale.cpp
|
||||||
malloc.cpp
|
malloc.cpp
|
||||||
math.cpp
|
math.cpp
|
||||||
|
net/if.cpp
|
||||||
netdb.cpp
|
netdb.cpp
|
||||||
netinet/in.cpp
|
netinet/in.cpp
|
||||||
poll.cpp
|
poll.cpp
|
||||||
|
@ -27,6 +29,7 @@ set(LIBC_SOURCES
|
||||||
pwd.cpp
|
pwd.cpp
|
||||||
scanf_impl.cpp
|
scanf_impl.cpp
|
||||||
sched.cpp
|
sched.cpp
|
||||||
|
semaphore.cpp
|
||||||
setjmp.cpp
|
setjmp.cpp
|
||||||
signal.cpp
|
signal.cpp
|
||||||
stdio.cpp
|
stdio.cpp
|
||||||
|
@ -45,6 +48,7 @@ set(LIBC_SOURCES
|
||||||
sys/stat.cpp
|
sys/stat.cpp
|
||||||
sys/statvfs.cpp
|
sys/statvfs.cpp
|
||||||
sys/time.cpp
|
sys/time.cpp
|
||||||
|
sys/times.cpp
|
||||||
sys/uio.cpp
|
sys/uio.cpp
|
||||||
sys/utsname.cpp
|
sys/utsname.cpp
|
||||||
sys/wait.cpp
|
sys/wait.cpp
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
|
||||||
|
#include <BAN/Assert.h>
|
||||||
|
|
||||||
|
int getifaddrs(struct ifaddrs** ifap)
|
||||||
|
{
|
||||||
|
(void)ifap;
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeifaddrs(struct ifaddrs* ifa)
|
||||||
|
{
|
||||||
|
(void)ifa;
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef _IFADDRS_H
|
||||||
|
#define _IFADDRS_H 1
|
||||||
|
|
||||||
|
// https://man7.org/linux/man-pages/man3/getifaddrs.3.html
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
struct ifaddrs
|
||||||
|
{
|
||||||
|
struct ifaddrs* ifa_next; /* Next item in list */
|
||||||
|
char* ifa_name; /* Name of interface */
|
||||||
|
unsigned int ifa_flags; /* Flags from SIOCGIFFLAGS */
|
||||||
|
struct sockaddr* ifa_addr; /* Address of interface */
|
||||||
|
struct sockaddr* ifa_netmask; /* Netmask of interface */
|
||||||
|
union {
|
||||||
|
struct sockaddr* ifu_broadaddr; /* Broadcast address of interface */
|
||||||
|
struct sockaddr* ifu_dstaddr; /* Point-to-point destination address */
|
||||||
|
} ifa_ifu;
|
||||||
|
void* ifa_data; /* Address-specific data */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ifa_broadaddr ifa_ifu.ifu_broadaddr
|
||||||
|
#define ifa_dstaddr ifa_ifu.ifu_dstaddr
|
||||||
|
|
||||||
|
int getifaddrs(struct ifaddrs **ifap);
|
||||||
|
void freeifaddrs(struct ifaddrs *ifa);
|
||||||
|
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,71 @@
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static int selector(const dirent* dirent)
|
||||||
|
{
|
||||||
|
if (strcmp(dirent->d_name, "lo") == 0)
|
||||||
|
return 1;
|
||||||
|
if (strncmp(dirent->d_name, "eth", 3) == 0)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int comparator(const dirent** d1, const dirent** d2)
|
||||||
|
{
|
||||||
|
if (strcmp((*d1)->d_name, "lo"))
|
||||||
|
return -1;
|
||||||
|
if (strcmp((*d2)->d_name, "lo"))
|
||||||
|
return +1;
|
||||||
|
return alphasort(d1, d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* if_indextoname(unsigned ifindex, char* ifname)
|
||||||
|
{
|
||||||
|
if (ifindex == 0)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
dirent** namelist;
|
||||||
|
|
||||||
|
const int count = scandir("/dev", &namelist, selector, comparator);
|
||||||
|
if (count == -1)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
char* result = nullptr;
|
||||||
|
if (ifindex - 1 < static_cast<unsigned>(count))
|
||||||
|
{
|
||||||
|
strcpy(ifname, namelist[ifindex - 1]->d_name);
|
||||||
|
result = ifname;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
free(namelist[i]);
|
||||||
|
free(namelist);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned if_nametoindex(const char* ifname)
|
||||||
|
{
|
||||||
|
dirent** namelist;
|
||||||
|
|
||||||
|
const int count = scandir("/dev", &namelist, selector, comparator);
|
||||||
|
if (count == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
unsigned result = 0;
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(ifname, namelist[i]->d_name) != 0)
|
||||||
|
continue;
|
||||||
|
result = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
free(namelist[i]);
|
||||||
|
free(namelist);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -311,3 +311,11 @@ error_close_socket:
|
||||||
close(socket);
|
close(socket);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <BAN/Debug.h>
|
||||||
|
|
||||||
|
struct servent* getservbyname(const char* name, const char* proto)
|
||||||
|
{
|
||||||
|
dwarnln("TODO: getservbyname(\"{}\", \"{}\")", name, proto);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include <BAN/Debug.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
|
int sem_destroy(sem_t* sem)
|
||||||
|
{
|
||||||
|
(void)sem;
|
||||||
|
dwarnln("TODO: sem_destroy");
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_init(sem_t* sem, int pshared, unsigned value)
|
||||||
|
{
|
||||||
|
(void)sem;
|
||||||
|
(void)pshared;
|
||||||
|
(void)value;
|
||||||
|
dwarnln("TODO: sem_init");
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_post(sem_t* sem)
|
||||||
|
{
|
||||||
|
(void)sem;
|
||||||
|
dwarnln("TODO: sem_post");
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_trywait(sem_t* sem)
|
||||||
|
{
|
||||||
|
(void)sem;
|
||||||
|
dwarnln("TODO: sem_trywait");
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_wait(sem_t* sem)
|
||||||
|
{
|
||||||
|
(void)sem;
|
||||||
|
dwarnln("TODO: sem_wait");
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -45,8 +45,28 @@ int posix_madvise(void* addr, size_t len, int advice)
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <BAN/Assert.h>
|
#include <BAN/Assert.h>
|
||||||
|
#include <BAN/Debug.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
int mlock(const void*, size_t)
|
int mlock(const void*, size_t)
|
||||||
{
|
{
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int shm_open(const char* name, int oflag, mode_t mode)
|
||||||
|
{
|
||||||
|
(void)name;
|
||||||
|
(void)oflag;
|
||||||
|
(void)mode;
|
||||||
|
dwarnln("TODO: shm_open");
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int shm_unlink(const char* name)
|
||||||
|
{
|
||||||
|
(void)name;
|
||||||
|
dwarnln("TODO: shm_unlink");
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -69,6 +69,13 @@ int setrlimit(int resource, const struct rlimit* rlp)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getpriority(int which, id_t who)
|
||||||
|
{
|
||||||
|
dwarnln("TODO: getpriority({}, {}, {})", which, who);
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int setpriority(int which, id_t who, int value)
|
int setpriority(int which, id_t who, int value)
|
||||||
{
|
{
|
||||||
dwarnln("TODO: setpriority({}, {}, {})", which, who, value);
|
dwarnln("TODO: setpriority({}, {}, {})", which, who, value);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <BAN/Assert.h>
|
#include <BAN/Assert.h>
|
||||||
|
#include <BAN/Debug.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -54,6 +55,34 @@ int mkdir(const char* path, mode_t mode)
|
||||||
return syscall(SYS_CREATE_DIR, path, __UMASKED_MODE(mode));
|
return syscall(SYS_CREATE_DIR, path, __UMASKED_MODE(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mkfifo(const char* path, mode_t mode)
|
||||||
|
{
|
||||||
|
(void)path; (void)mode;
|
||||||
|
dwarnln("TODO: mkfifo");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mkfifoat(int fd, const char* path, mode_t mode)
|
||||||
|
{
|
||||||
|
(void)fd; (void)path; (void)mode;
|
||||||
|
dwarnln("TODO: mkfifoat");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mknod(const char* path, mode_t mode, dev_t dev)
|
||||||
|
{
|
||||||
|
(void)path; (void)mode; (void)dev;
|
||||||
|
dwarnln("TODO: mknod");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mknodat(int fd, const char* path, mode_t mode, dev_t dev)
|
||||||
|
{
|
||||||
|
(void)fd; (void)path; (void)mode; (void)dev;
|
||||||
|
dwarnln("TODO: mknodat");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int futimens(int fd, const struct timespec times[2])
|
int futimens(int fd, const struct timespec times[2])
|
||||||
{
|
{
|
||||||
return utimensat(fd, nullptr, times, 0);
|
return utimensat(fd, nullptr, times, 0);
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include <sys/times.h>
|
||||||
|
|
||||||
|
#include <BAN/Assert.h>
|
||||||
|
|
||||||
|
clock_t times(struct tms* buffer)
|
||||||
|
{
|
||||||
|
(void)buffer;
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
|
@ -19,6 +19,15 @@ int clock_gettime(clockid_t clock_id, struct timespec* tp)
|
||||||
return syscall(SYS_CLOCK_GETTIME, clock_id, tp);
|
return syscall(SYS_CLOCK_GETTIME, clock_id, tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int clock_getres(clockid_t clock_id, struct timespec* res)
|
||||||
|
{
|
||||||
|
(void)clock_id;
|
||||||
|
res->tv_sec = 0;
|
||||||
|
res->tv_nsec = 10;
|
||||||
|
dprintln("TODO: clock_getres");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int nanosleep(const struct timespec* rqtp, struct timespec* rmtp)
|
int nanosleep(const struct timespec* rqtp, struct timespec* rmtp)
|
||||||
{
|
{
|
||||||
pthread_testcancel();
|
pthread_testcancel();
|
||||||
|
|
|
@ -24,6 +24,10 @@ int wcwidth(wchar_t wc)
|
||||||
return wc != '\0';
|
return wc != '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wchar_t* wcstok(wchar_t* __restrict, const wchar_t* __restrict, wchar_t** __restrict) { ASSERT_NOT_REACHED(); }
|
||||||
|
long wcstol(const wchar_t* __restrict, wchar_t** __restrict, int) { ASSERT_NOT_REACHED(); }
|
||||||
|
int swprintf(wchar_t* __restrict, size_t, const wchar_t* __restrict, ...) { ASSERT_NOT_REACHED(); }
|
||||||
|
|
||||||
size_t wcrtomb(char* __restrict s, wchar_t ws, mbstate_t* __restrict ps)
|
size_t wcrtomb(char* __restrict s, wchar_t ws, mbstate_t* __restrict ps)
|
||||||
{
|
{
|
||||||
(void)ps;
|
(void)ps;
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
set(SOURCES
|
||||||
|
dummy.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(libdl-static STATIC ${SOURCES})
|
||||||
|
add_library(libdl-shared SHARED ${SOURCES})
|
||||||
|
|
||||||
|
target_link_options(libdl-static PRIVATE -nolibc)
|
||||||
|
target_link_options(libdl-shared PRIVATE -nolibc)
|
||||||
|
|
||||||
|
banan_link_library(libdl-static libc)
|
||||||
|
banan_link_library(libdl-shared libc)
|
||||||
|
|
||||||
|
set_target_properties(libdl-static PROPERTIES OUTPUT_NAME libdl)
|
||||||
|
set_target_properties(libdl-shared PROPERTIES OUTPUT_NAME libdl)
|
||||||
|
|
||||||
|
install(TARGETS libdl-static OPTIONAL)
|
||||||
|
install(TARGETS libdl-shared OPTIONAL)
|
|
@ -40,6 +40,13 @@ bool AudioServer::on_client_packet(int fd, long smo_key)
|
||||||
{
|
{
|
||||||
auto& audio_buffer = m_audio_buffers[fd];
|
auto& audio_buffer = m_audio_buffers[fd];
|
||||||
|
|
||||||
|
if (smo_key == 0)
|
||||||
|
{
|
||||||
|
if (audio_buffer.buffer)
|
||||||
|
reset_kernel_buffer();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
audio_buffer.buffer = static_cast<LibAudio::AudioBuffer*>(smo_map(smo_key));
|
audio_buffer.buffer = static_cast<LibAudio::AudioBuffer*>(smo_map(smo_key));
|
||||||
audio_buffer.sample_frames_queued = 0;
|
audio_buffer.sample_frames_queued = 0;
|
||||||
if (audio_buffer.buffer == nullptr)
|
if (audio_buffer.buffer == nullptr)
|
||||||
|
@ -53,8 +60,11 @@ bool AudioServer::on_client_packet(int fd, long smo_key)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioServer::update()
|
uint64_t AudioServer::update()
|
||||||
{
|
{
|
||||||
|
// FIXME: get this from the kernel
|
||||||
|
static constexpr uint64_t kernel_buffer_ms = 50;
|
||||||
|
|
||||||
uint32_t kernel_buffer_size;
|
uint32_t kernel_buffer_size;
|
||||||
if (ioctl(m_audio_device_fd, SND_GET_BUFFERSZ, &kernel_buffer_size) == -1)
|
if (ioctl(m_audio_device_fd, SND_GET_BUFFERSZ, &kernel_buffer_size) == -1)
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
|
@ -72,14 +82,17 @@ void AudioServer::update()
|
||||||
const size_t max_sample_frames = (m_samples.capacity() - m_samples.size()) / m_channels;
|
const size_t max_sample_frames = (m_samples.capacity() - m_samples.size()) / m_channels;
|
||||||
const size_t queued_samples_end = m_samples.size();
|
const size_t queued_samples_end = m_samples.size();
|
||||||
if (max_sample_frames == 0)
|
if (max_sample_frames == 0)
|
||||||
return;
|
return kernel_buffer_ms;
|
||||||
|
|
||||||
|
size_t max_sample_frames_to_queue = max_sample_frames;
|
||||||
|
|
||||||
|
bool anyone_playing = false;
|
||||||
for (auto& [_, buffer] : m_audio_buffers)
|
for (auto& [_, buffer] : m_audio_buffers)
|
||||||
{
|
{
|
||||||
if (buffer.buffer == nullptr)
|
if (buffer.buffer == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const double sample_ratio = buffer.buffer->sample_rate / static_cast<double>(m_sample_rate);
|
const sample_t sample_ratio = buffer.buffer->sample_rate / static_cast<sample_t>(m_sample_rate);
|
||||||
|
|
||||||
if (buffer.sample_frames_queued)
|
if (buffer.sample_frames_queued)
|
||||||
{
|
{
|
||||||
|
@ -91,13 +104,38 @@ void AudioServer::update()
|
||||||
buffer.sample_frames_queued -= buffer_sample_frames_played;
|
buffer.sample_frames_queued -= buffer_sample_frames_played;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buffer.buffer->paused)
|
||||||
|
continue;
|
||||||
|
anyone_playing = true;
|
||||||
|
|
||||||
|
const uint32_t buffer_total_sample_frames = ((buffer.buffer->capacity + buffer.buffer->head - buffer.buffer->tail) % buffer.buffer->capacity) / buffer.buffer->channels;
|
||||||
|
const uint32_t buffer_sample_frames_available = (buffer_total_sample_frames - buffer.sample_frames_queued) / sample_ratio;
|
||||||
|
max_sample_frames_to_queue = BAN::Math::min<size_t>(max_sample_frames_to_queue, buffer_sample_frames_available);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!anyone_playing)
|
||||||
|
return 60'000;
|
||||||
|
|
||||||
|
// FIXME: this works but if any client stops producing audio samples
|
||||||
|
// the whole audio server halts
|
||||||
|
const uint32_t samples_per_10ms = m_sample_rate / 100;
|
||||||
|
if (max_sample_frames_to_queue < samples_per_10ms)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for (auto& [_, buffer] : m_audio_buffers)
|
||||||
|
{
|
||||||
|
if (buffer.buffer == nullptr || buffer.buffer->paused)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const sample_t sample_ratio = buffer.buffer->sample_rate / static_cast<sample_t>(m_sample_rate);
|
||||||
|
|
||||||
const uint32_t buffer_total_sample_frames = ((buffer.buffer->capacity + buffer.buffer->head - buffer.buffer->tail) % buffer.buffer->capacity) / buffer.buffer->channels;
|
const uint32_t buffer_total_sample_frames = ((buffer.buffer->capacity + buffer.buffer->head - buffer.buffer->tail) % buffer.buffer->capacity) / buffer.buffer->channels;
|
||||||
const uint32_t buffer_sample_frames_available = (buffer_total_sample_frames - buffer.sample_frames_queued) / sample_ratio;
|
const uint32_t buffer_sample_frames_available = (buffer_total_sample_frames - buffer.sample_frames_queued) / sample_ratio;
|
||||||
if (buffer_sample_frames_available == 0)
|
if (buffer_sample_frames_available == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const size_t sample_frames_to_queue = BAN::Math::min<size_t>(max_sample_frames, buffer_sample_frames_available);
|
const size_t sample_frames_to_queue = BAN::Math::min<size_t>(max_sample_frames_to_queue, buffer_sample_frames_available);
|
||||||
if (sample_frames_to_queue == 0)
|
if (sample_frames_to_queue < samples_per_10ms)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
while (m_samples.size() < queued_samples_end + sample_frames_to_queue * m_channels)
|
while (m_samples.size() < queued_samples_end + sample_frames_to_queue * m_channels)
|
||||||
|
@ -113,10 +151,17 @@ void AudioServer::update()
|
||||||
m_samples[queued_samples_end + i * m_channels + j] += buffer.buffer->samples[(buffer_tail + buffer_frame * buffer.buffer->channels + j) % buffer.buffer->capacity];
|
m_samples[queued_samples_end + i * m_channels + j] += buffer.buffer->samples[(buffer_tail + buffer_frame * buffer.buffer->channels + j) % buffer.buffer->capacity];
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.sample_frames_queued += sample_frames_to_queue * sample_ratio;
|
buffer.sample_frames_queued += BAN::Math::min<uint32_t>(
|
||||||
|
buffer_total_sample_frames,
|
||||||
|
BAN::Math::ceil(sample_frames_to_queue * sample_ratio)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
send_samples();
|
send_samples();
|
||||||
|
|
||||||
|
const double play_ms = 1000.0 * m_samples_sent / m_channels / m_sample_rate;
|
||||||
|
const uint64_t wake_ms = BAN::Math::max<uint64_t>(play_ms, kernel_buffer_ms) - kernel_buffer_ms;
|
||||||
|
return wake_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioServer::reset_kernel_buffer()
|
void AudioServer::reset_kernel_buffer()
|
||||||
|
|
|
@ -19,7 +19,7 @@ public:
|
||||||
void on_client_disconnect(int fd);
|
void on_client_disconnect(int fd);
|
||||||
bool on_client_packet(int fd, long smo_key);
|
bool on_client_packet(int fd, long smo_key);
|
||||||
|
|
||||||
void update();
|
uint64_t update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ClientInfo
|
struct ClientInfo
|
||||||
|
@ -28,6 +28,8 @@ private:
|
||||||
size_t sample_frames_queued { 0 };
|
size_t sample_frames_queued { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using sample_t = LibAudio::AudioBuffer::sample_t;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class AddOrRemove { Add, Remove };
|
enum class AddOrRemove { Add, Remove };
|
||||||
|
|
||||||
|
@ -42,7 +44,7 @@ private:
|
||||||
|
|
||||||
size_t m_samples_sent { 0 };
|
size_t m_samples_sent { 0 };
|
||||||
BAN::Array<uint8_t, 1024> m_send_buffer;
|
BAN::Array<uint8_t, 1024> m_send_buffer;
|
||||||
BAN::CircularQueue<double, 64 * 1024> m_samples;
|
BAN::CircularQueue<sample_t, 64 * 1024> m_samples;
|
||||||
|
|
||||||
BAN::HashMap<int, ClientInfo> m_audio_buffers;
|
BAN::HashMap<int, ClientInfo> m_audio_buffers;
|
||||||
};
|
};
|
||||||
|
|
|
@ -96,8 +96,7 @@ int main()
|
||||||
|
|
||||||
dprintln("AudioServer started");
|
dprintln("AudioServer started");
|
||||||
|
|
||||||
constexpr uint64_t update_interval_ms = 100;
|
uint64_t next_update_ms = get_current_ms();
|
||||||
uint64_t next_update_ms = get_current_ms() + update_interval_ms;
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
@ -113,11 +112,7 @@ int main()
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint64_t current_ms = get_current_ms();
|
const uint64_t current_ms = get_current_ms();
|
||||||
if (current_ms >= next_update_ms)
|
next_update_ms = current_ms + audio_server->update();
|
||||||
{
|
|
||||||
audio_server->update();
|
|
||||||
next_update_ms = current_ms + update_interval_ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint64_t timeout_ms = next_update_ms - current_ms;
|
const uint64_t timeout_ms = next_update_ms - current_ms;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
struct config_t
|
struct config_t
|
||||||
|
@ -37,6 +38,9 @@ struct full_entry_t
|
||||||
BAN::String full_name;
|
BAN::String full_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool g_stdout_terminal { false };
|
||||||
|
winsize g_terminal_size {};
|
||||||
|
|
||||||
const char* entry_color(mode_t mode)
|
const char* entry_color(mode_t mode)
|
||||||
{
|
{
|
||||||
// TODO: handle suid, sgid, sticky
|
// TODO: handle suid, sgid, sticky
|
||||||
|
@ -116,6 +120,37 @@ BAN::String build_time_string(BAN::Time time)
|
||||||
return MUST(BAN::String::formatted("{2}:{2}", time.hour, time.minute));
|
return MUST(BAN::String::formatted("{2}:{2}", time.hour, time.minute));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::Vector<size_t> resolve_column_widths(const BAN::Vector<simple_entry_t>& entries, size_t columns)
|
||||||
|
{
|
||||||
|
BAN::Vector<size_t> widths;
|
||||||
|
MUST(widths.resize(columns));
|
||||||
|
|
||||||
|
const size_t rows = BAN::Math::div_round_up(entries.size(), columns);
|
||||||
|
for (size_t i = 0; i < entries.size(); i++)
|
||||||
|
widths[i / rows] = BAN::Math::max(widths[i / rows], entries[i].name.size());
|
||||||
|
|
||||||
|
size_t full_width = (columns - 1);
|
||||||
|
for (auto width : widths)
|
||||||
|
{
|
||||||
|
if (width == 0)
|
||||||
|
return {};
|
||||||
|
full_width += width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (full_width <= g_terminal_size.ws_col)
|
||||||
|
return widths;
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Vector<size_t> resolve_layout(const BAN::Vector<simple_entry_t>& entries)
|
||||||
|
{
|
||||||
|
for (size_t columns = entries.size(); columns > 1; columns--)
|
||||||
|
if (auto widths = resolve_column_widths(entries, columns); !widths.empty())
|
||||||
|
return widths;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
int list_directory(const BAN::String& path, config_t config)
|
int list_directory(const BAN::String& path, config_t config)
|
||||||
{
|
{
|
||||||
static char link_buffer[PATH_MAX];
|
static char link_buffer[PATH_MAX];
|
||||||
|
@ -198,14 +233,59 @@ int list_directory(const BAN::String& path, config_t config)
|
||||||
|
|
||||||
if (!config.list)
|
if (!config.list)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < entries.size(); i++)
|
if (!g_stdout_terminal)
|
||||||
{
|
{
|
||||||
if (i > 0)
|
for (const auto& entry : entries)
|
||||||
printf(" ");
|
printf("%s\n", entry.name.data());
|
||||||
const char* format = entries[i].name.sv().contains(' ') ? "'%s%s\e[m'" : "%s%s\e[m";
|
return ret;
|
||||||
printf(format, entry_color(entries[i].st.st_mode), entries[i].name.data());
|
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
bool should_quote = false;
|
||||||
|
for (size_t i = 0; i < entries.size() && !should_quote; i++)
|
||||||
|
should_quote = entries[i].name.sv().contains(' ');
|
||||||
|
if (!should_quote)
|
||||||
|
for (auto& entry : entries)
|
||||||
|
MUST(entry.name.push_back(' '));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto& entry : entries)
|
||||||
|
{
|
||||||
|
const char ch = entry.name.sv().contains(' ') ? '\'' : ' ';
|
||||||
|
MUST(entry.name.insert(ch, 0));
|
||||||
|
MUST(entry.name.push_back(ch));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto layout = resolve_layout(entries);
|
||||||
|
|
||||||
|
if (layout.empty())
|
||||||
|
for (const auto& entry : entries)
|
||||||
|
printf("%s%s\e[m\n", entry_color(entry.st.st_mode), entry.name.data());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const size_t cols = layout.size();
|
||||||
|
const size_t rows = BAN::Math::div_round_up(entries.size(), cols);
|
||||||
|
|
||||||
|
for (size_t row = 0; row < rows; row++)
|
||||||
|
{
|
||||||
|
for (size_t col = 0; col < cols; col++)
|
||||||
|
{
|
||||||
|
const size_t i = col * rows + row;
|
||||||
|
if (i >= entries.size())
|
||||||
|
break;
|
||||||
|
|
||||||
|
char format[32];
|
||||||
|
sprintf(format, "%%s%%-%zus\e[m", layout[col]);
|
||||||
|
|
||||||
|
if (col != 0)
|
||||||
|
printf(" ");
|
||||||
|
printf(format, entry_color(entries[i].st.st_mode), entries[i].name.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,6 +406,8 @@ int main(int argc, const char* argv[])
|
||||||
else for (; i < argc; i++)
|
else for (; i < argc; i++)
|
||||||
MUST(files.emplace_back(BAN::StringView(argv[i])));
|
MUST(files.emplace_back(BAN::StringView(argv[i])));
|
||||||
|
|
||||||
|
g_stdout_terminal = isatty(STDOUT_FILENO) && ioctl(STDOUT_FILENO, TIOCGWINSZ, &g_terminal_size) == 0;
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
for (size_t i = 0; i < files.size(); i++)
|
for (size_t i = 0; i < files.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue