Compare commits
8 Commits
06015d006d
...
bad3b8b3e2
Author | SHA1 | Date |
---|---|---|
|
bad3b8b3e2 | |
|
0b81bb9b10 | |
|
f61c78efd5 | |
|
6b2307ab22 | |
|
9ccb381c31 | |
|
71133236f8 | |
|
e5786fe435 | |
|
ef6ee78fd1 |
|
@ -20,6 +20,6 @@ namespace Kernel::ELF
|
|||
BAN::Vector<BAN::UniqPtr<MemoryRegion>> regions;
|
||||
};
|
||||
|
||||
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode>, const Credentials&, PageTable&);
|
||||
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> root, BAN::RefPtr<Inode> inode, const Credentials&, PageTable&);
|
||||
|
||||
}
|
||||
|
|
|
@ -71,13 +71,13 @@ namespace Kernel
|
|||
|
||||
File root_file()
|
||||
{
|
||||
return File(root_inode(), "/"_sv);
|
||||
return File { root_inode(), "/"_sv };
|
||||
}
|
||||
|
||||
BAN::ErrorOr<File> file_from_relative_path(const File& parent, const Credentials&, BAN::StringView, int);
|
||||
BAN::ErrorOr<File> file_from_absolute_path(const Credentials& credentials, BAN::StringView path, int flags)
|
||||
BAN::ErrorOr<File> file_from_relative_path(BAN::RefPtr<Inode> root_inode, const File& parent, const Credentials&, BAN::StringView, int);
|
||||
BAN::ErrorOr<File> file_from_absolute_path(BAN::RefPtr<Inode> root_inode, const Credentials& credentials, BAN::StringView path, int flags)
|
||||
{
|
||||
return file_from_relative_path(root_file(), credentials, path, flags);
|
||||
return file_from_relative_path(root_inode, File { root_inode, "/"_sv }, credentials, path, flags);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <BAN/WeakPtr.h>
|
||||
#include <kernel/FS/Socket.h>
|
||||
#include <kernel/FS/TmpFS/Inode.h>
|
||||
#include <kernel/FS/VirtualFileSystem.h>
|
||||
#include <kernel/Lock/SpinLock.h>
|
||||
|
||||
namespace Kernel
|
||||
|
@ -39,8 +40,8 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> add_packet(BAN::ConstByteSpan);
|
||||
|
||||
bool is_bound() const { return !m_bound_path.empty(); }
|
||||
bool is_bound_to_unused() const { return m_bound_path == "X"_sv; }
|
||||
bool is_bound() const { return !m_bound_file.canonical_path.empty(); }
|
||||
bool is_bound_to_unused() const { return !m_bound_file.inode; }
|
||||
|
||||
bool is_streaming() const;
|
||||
|
||||
|
@ -63,7 +64,7 @@ namespace Kernel
|
|||
|
||||
private:
|
||||
const Socket::Type m_socket_type;
|
||||
BAN::String m_bound_path;
|
||||
VirtualFileSystem::File m_bound_file;
|
||||
|
||||
BAN::Variant<ConnectionInfo, ConnectionlessInfo> m_info;
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ namespace Kernel
|
|||
BAN::ErrorOr<long> sys_getcwd(char* buffer, size_t size);
|
||||
BAN::ErrorOr<long> sys_chdir(const char* path);
|
||||
BAN::ErrorOr<long> sys_fchdir(int fildes);
|
||||
BAN::ErrorOr<long> sys_chroot(const char* path);
|
||||
|
||||
BAN::ErrorOr<long> sys_setuid(uid_t);
|
||||
BAN::ErrorOr<long> sys_setgid(gid_t);
|
||||
|
@ -234,6 +235,7 @@ namespace Kernel
|
|||
static void update_alarm_queue();
|
||||
|
||||
const VirtualFileSystem::File& working_directory() const { return m_working_directory; }
|
||||
const VirtualFileSystem::File& root_file() const { return m_root_file; }
|
||||
|
||||
private:
|
||||
Process(const Credentials&, pid_t pid, pid_t parent, pid_t sid, pid_t pgrp);
|
||||
|
@ -313,6 +315,7 @@ namespace Kernel
|
|||
mutable Mutex m_process_lock;
|
||||
|
||||
VirtualFileSystem::File m_working_directory;
|
||||
VirtualFileSystem::File m_root_file;
|
||||
|
||||
BAN::Vector<Thread*> m_threads;
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ namespace Kernel::ELF
|
|||
return BAN::move(program_headers);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> inode, const Credentials& credentials, PageTable& page_table)
|
||||
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> root, BAN::RefPtr<Inode> inode, const Credentials& credentials, PageTable& page_table)
|
||||
{
|
||||
auto file_header = TRY(read_and_validate_file_header(inode));
|
||||
auto program_headers = TRY(read_program_headers(inode, file_header));
|
||||
|
@ -143,7 +143,7 @@ namespace Kernel::ELF
|
|||
|
||||
if (!interpreter.empty())
|
||||
{
|
||||
auto interpreter_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(credentials, interpreter, O_EXEC)).inode;
|
||||
auto interpreter_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(root, credentials, interpreter, O_EXEC)).inode;
|
||||
auto interpreter_file_header = TRY(read_and_validate_file_header(interpreter_inode));
|
||||
auto interpreter_program_headers = TRY(read_program_headers(interpreter_inode, interpreter_file_header));
|
||||
|
||||
|
|
|
@ -186,7 +186,8 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, BAN::StringView block_device_path, BAN::StringView target)
|
||||
{
|
||||
auto block_device_file = TRY(file_from_absolute_path(credentials, block_device_path, true));
|
||||
// TODO: allow custom root
|
||||
auto block_device_file = TRY(file_from_absolute_path(root_inode(), credentials, block_device_path, true));
|
||||
if (!block_device_file.inode->is_device())
|
||||
return BAN::Error::from_errno(ENOTBLK);
|
||||
|
||||
|
@ -200,7 +201,8 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, BAN::RefPtr<FileSystem> file_system, BAN::StringView path)
|
||||
{
|
||||
auto file = TRY(file_from_absolute_path(credentials, path, true));
|
||||
// TODO: allow custom root
|
||||
auto file = TRY(file_from_absolute_path(root_inode(), credentials, path, true));
|
||||
if (!file.inode->mode().ifdir())
|
||||
return BAN::Error::from_errno(ENOTDIR);
|
||||
|
||||
|
@ -227,7 +229,7 @@ namespace Kernel
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_relative_path(const File& parent, const Credentials& credentials, BAN::StringView path, int flags)
|
||||
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_relative_path(BAN::RefPtr<Inode> root_inode, const File& parent, const Credentials& credentials, BAN::StringView path, int flags)
|
||||
{
|
||||
LockGuard _(m_mutex);
|
||||
|
||||
|
@ -269,6 +271,8 @@ namespace Kernel
|
|||
auto orig = inode;
|
||||
|
||||
// resolve file name
|
||||
{
|
||||
if (!(inode == root_inode && path_part == ".."_sv))
|
||||
{
|
||||
auto parent_inode = inode;
|
||||
if (path_part == ".."_sv)
|
||||
|
@ -277,6 +281,7 @@ namespace Kernel
|
|||
if (!parent_inode->can_access(credentials, O_SEARCH))
|
||||
return BAN::Error::from_errno(EACCES);
|
||||
inode = TRY(parent_inode->find_inode(path_part));
|
||||
}
|
||||
|
||||
if (path_part == ".."_sv)
|
||||
{
|
||||
|
@ -310,7 +315,7 @@ namespace Kernel
|
|||
|
||||
if (link_target.front() == '/')
|
||||
{
|
||||
inode = root_inode();
|
||||
inode = root_inode;
|
||||
canonical_path.clear();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -13,7 +13,15 @@
|
|||
namespace Kernel
|
||||
{
|
||||
|
||||
static BAN::HashMap<BAN::String, BAN::WeakPtr<UnixDomainSocket>> s_bound_sockets;
|
||||
struct UnixSocketHash
|
||||
{
|
||||
BAN::hash_t operator()(const BAN::RefPtr<Inode>& socket)
|
||||
{
|
||||
return BAN::hash<const Inode*>{}(socket.ptr());
|
||||
}
|
||||
};
|
||||
|
||||
static BAN::HashMap<BAN::RefPtr<Inode>, BAN::WeakPtr<UnixDomainSocket>, UnixSocketHash> s_bound_sockets;
|
||||
static SpinLock s_bound_socket_lock;
|
||||
|
||||
static constexpr size_t s_packet_buffer_size = 10 * PAGE_SIZE;
|
||||
|
@ -57,9 +65,7 @@ namespace Kernel
|
|||
if (is_bound() && !is_bound_to_unused())
|
||||
{
|
||||
SpinLockGuard _(s_bound_socket_lock);
|
||||
auto it = s_bound_sockets.find(m_bound_path);
|
||||
if (it != s_bound_sockets.end())
|
||||
s_bound_sockets.remove(it);
|
||||
s_bound_sockets.remove(m_bound_file.inode);
|
||||
}
|
||||
if (m_info.has<ConnectionInfo>())
|
||||
{
|
||||
|
@ -117,17 +123,22 @@ namespace Kernel
|
|||
return_inode = reinterpret_cast<UnixDomainSocket*>(return_inode_tmp.ptr());
|
||||
}
|
||||
|
||||
TRY(return_inode->m_bound_path.push_back('X'));
|
||||
TRY(return_inode->m_bound_file.canonical_path.push_back('X'));
|
||||
return_inode->m_info.get<ConnectionInfo>().connection = TRY(pending->get_weak_ptr());
|
||||
pending->m_info.get<ConnectionInfo>().connection = TRY(return_inode->get_weak_ptr());
|
||||
pending->m_info.get<ConnectionInfo>().connection_done = true;
|
||||
|
||||
if (address && address_len && !is_bound_to_unused())
|
||||
{
|
||||
size_t copy_len = BAN::Math::min<size_t>(*address_len, sizeof(sockaddr) + m_bound_path.size() + 1);
|
||||
auto& sockaddr_un = *reinterpret_cast<struct sockaddr_un*>(address);
|
||||
sockaddr_un.sun_family = AF_UNIX;
|
||||
strncpy(sockaddr_un.sun_path, pending->m_bound_path.data(), copy_len);
|
||||
sockaddr_un sa_un {
|
||||
.sun_family = AF_UNIX,
|
||||
.sun_path {},
|
||||
};
|
||||
strcpy(sa_un.sun_path, pending->m_bound_file.canonical_path.data());
|
||||
|
||||
const size_t to_copy = BAN::Math::min<size_t>(*address_len, sizeof(sockaddr_un));
|
||||
memcpy(address, &sa_un, to_copy);
|
||||
*address_len = to_copy;
|
||||
}
|
||||
|
||||
return TRY(Process::current().open_inode(VirtualFileSystem::File(return_inode, "<unix socket>"_sv), O_RDWR | flags));
|
||||
|
@ -141,10 +152,11 @@ namespace Kernel
|
|||
if (sockaddr_un.sun_family != AF_UNIX)
|
||||
return BAN::Error::from_errno(EAFNOSUPPORT);
|
||||
if (!is_bound())
|
||||
TRY(m_bound_path.push_back('X'));
|
||||
TRY(m_bound_file.canonical_path.push_back('X'));
|
||||
|
||||
auto absolute_path = TRY(Process::current().absolute_path_of(sockaddr_un.sun_path));
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(
|
||||
Process::current().root_file().inode,
|
||||
Process::current().credentials(),
|
||||
absolute_path,
|
||||
O_RDWR
|
||||
|
@ -154,7 +166,7 @@ namespace Kernel
|
|||
|
||||
{
|
||||
SpinLockGuard _(s_bound_socket_lock);
|
||||
auto it = s_bound_sockets.find(file.canonical_path);
|
||||
auto it = s_bound_sockets.find(file.inode);
|
||||
if (it == s_bound_sockets.end())
|
||||
return BAN::Error::from_errno(ECONNREFUSED);
|
||||
target = it->value.lock();
|
||||
|
@ -236,7 +248,7 @@ namespace Kernel
|
|||
|
||||
// FIXME: This feels sketchy
|
||||
auto parent_file = bind_path.front() == '/'
|
||||
? VirtualFileSystem::get().root_file()
|
||||
? TRY(Process::current().root_file().clone())
|
||||
: TRY(Process::current().working_directory().clone());
|
||||
if (auto ret = Process::current().create_file_or_dir(AT_FDCWD, bind_path.data(), 0755 | S_IFSOCK); ret.is_error())
|
||||
{
|
||||
|
@ -245,6 +257,7 @@ namespace Kernel
|
|||
return ret.release_error();
|
||||
}
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_relative_path(
|
||||
Process::current().root_file().inode,
|
||||
parent_file,
|
||||
Process::current().credentials(),
|
||||
bind_path,
|
||||
|
@ -252,10 +265,10 @@ namespace Kernel
|
|||
));
|
||||
|
||||
SpinLockGuard _(s_bound_socket_lock);
|
||||
if (s_bound_sockets.contains(file.canonical_path))
|
||||
if (s_bound_sockets.contains(file.inode))
|
||||
return BAN::Error::from_errno(EADDRINUSE);
|
||||
TRY(s_bound_sockets.emplace(file.canonical_path, TRY(get_weak_ptr())));
|
||||
m_bound_path = BAN::move(file.canonical_path);
|
||||
TRY(s_bound_sockets.emplace(file.inode, TRY(get_weak_ptr())));
|
||||
m_bound_file = BAN::move(file);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -354,14 +367,21 @@ namespace Kernel
|
|||
}
|
||||
else
|
||||
{
|
||||
BAN::String canonical_path;
|
||||
BAN::RefPtr<Inode> target_inode;
|
||||
|
||||
if (!address)
|
||||
{
|
||||
auto& connectionless_info = m_info.get<ConnectionlessInfo>();
|
||||
if (connectionless_info.peer_address.empty())
|
||||
return BAN::Error::from_errno(EDESTADDRREQ);
|
||||
TRY(canonical_path.append(connectionless_info.peer_address));
|
||||
|
||||
auto absolute_path = TRY(Process::current().absolute_path_of(connectionless_info.peer_address));
|
||||
target_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(
|
||||
Process::current().root_file().inode,
|
||||
Process::current().credentials(),
|
||||
absolute_path,
|
||||
O_RDWR
|
||||
)).inode;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -372,17 +392,16 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(EAFNOSUPPORT);
|
||||
|
||||
auto absolute_path = TRY(Process::current().absolute_path_of(sockaddr_un.sun_path));
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(
|
||||
target_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(
|
||||
Process::current().root_file().inode,
|
||||
Process::current().credentials(),
|
||||
absolute_path,
|
||||
O_WRONLY
|
||||
));
|
||||
|
||||
canonical_path = BAN::move(file.canonical_path);
|
||||
)).inode;
|
||||
}
|
||||
|
||||
SpinLockGuard _(s_bound_socket_lock);
|
||||
auto it = s_bound_sockets.find(canonical_path);
|
||||
auto it = s_bound_sockets.find(target_inode);
|
||||
if (it == s_bound_sockets.end())
|
||||
return BAN::Error::from_errno(EDESTADDRREQ);
|
||||
auto target = it->value.lock();
|
||||
|
@ -449,20 +468,11 @@ namespace Kernel
|
|||
if (!connection)
|
||||
return BAN::Error::from_errno(ENOTCONN);
|
||||
|
||||
sockaddr_un sa_un;
|
||||
sa_un.sun_family = AF_UNIX;
|
||||
sa_un.sun_path[0] = 0;
|
||||
|
||||
{
|
||||
SpinLockGuard _(s_bound_socket_lock);
|
||||
for (auto& [path, socket] : s_bound_sockets)
|
||||
{
|
||||
if (socket.lock() != connection)
|
||||
continue;
|
||||
strcpy(sa_un.sun_path, path.data());
|
||||
break;
|
||||
}
|
||||
}
|
||||
sockaddr_un sa_un {
|
||||
.sun_family = AF_UNIX,
|
||||
.sun_path = {},
|
||||
};
|
||||
strcpy(sa_un.sun_path, connection->m_bound_file.canonical_path.data());
|
||||
|
||||
const size_t to_copy = BAN::Math::min<socklen_t>(sizeof(sockaddr_un), *address_len);
|
||||
memcpy(address, &sa_un, to_copy);
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<int> OpenFileDescriptorSet::open(BAN::StringView absolute_path, int flags)
|
||||
{
|
||||
return open(TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, flags)), flags);
|
||||
return open(TRY(VirtualFileSystem::get().file_from_absolute_path(Process::current().root_file().inode, m_credentials, absolute_path, flags)), flags);
|
||||
}
|
||||
|
||||
struct SocketInfo
|
||||
|
|
|
@ -103,6 +103,8 @@ namespace Kernel
|
|||
auto* process = create_process(credentials, 0);
|
||||
|
||||
process->m_working_directory = VirtualFileSystem::get().root_file();
|
||||
process->m_root_file = VirtualFileSystem::get().root_file();
|
||||
|
||||
process->m_page_table = BAN::UniqPtr<PageTable>::adopt(MUST(PageTable::create_userspace()));
|
||||
|
||||
TRY(process->m_cmdline.emplace_back());
|
||||
|
@ -118,7 +120,7 @@ namespace Kernel
|
|||
auto executable_file = TRY(process->find_file(AT_FDCWD, path.data(), O_EXEC));
|
||||
auto executable_inode = executable_file.inode;
|
||||
|
||||
auto executable = TRY(ELF::load_from_inode(executable_inode, process->m_credentials, process->page_table()));
|
||||
auto executable = TRY(ELF::load_from_inode(process->m_root_file.inode, executable_inode, process->m_credentials, process->page_table()));
|
||||
process->m_mapped_regions = BAN::move(executable.regions);
|
||||
|
||||
if (executable_inode->mode().mode & +Inode::Mode::ISUID)
|
||||
|
@ -456,7 +458,7 @@ namespace Kernel
|
|||
|
||||
auto parent_file = TRY(find_relative_parent(fd, path));
|
||||
auto file = path
|
||||
? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags))
|
||||
? TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, parent_file, m_credentials, path, flags))
|
||||
: BAN::move(parent_file);
|
||||
|
||||
return file;
|
||||
|
@ -480,7 +482,7 @@ namespace Kernel
|
|||
|
||||
if (auto index = path_sv.rfind('/'); index.has_value())
|
||||
{
|
||||
parent = TRY(VirtualFileSystem::get().file_from_relative_path(relative_parent, m_credentials, path_sv.substring(0, index.value()), flags));
|
||||
parent = TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, relative_parent, m_credentials, path_sv.substring(0, index.value()), flags));
|
||||
file_name = path_sv.substring(index.value() + 1);
|
||||
}
|
||||
else
|
||||
|
@ -510,7 +512,7 @@ namespace Kernel
|
|||
ASSERT(m_process_lock.is_locked());
|
||||
|
||||
if (path && path[0] == '/')
|
||||
return VirtualFileSystem::get().root_file();
|
||||
return TRY(m_root_file.clone());
|
||||
|
||||
if (fd == AT_FDCWD)
|
||||
return TRY(m_working_directory.clone());
|
||||
|
@ -582,6 +584,7 @@ namespace Kernel
|
|||
}
|
||||
|
||||
auto working_directory = TRY(m_working_directory.clone());
|
||||
auto root_file = TRY(m_root_file.clone());
|
||||
|
||||
BAN::Vector<BAN::String> cmdline;
|
||||
TRY(cmdline.resize(m_cmdline.size()));
|
||||
|
@ -604,6 +607,7 @@ namespace Kernel
|
|||
Process* forked = create_process(m_credentials, m_pid, m_sid, m_pgrp);
|
||||
forked->m_controlling_terminal = m_controlling_terminal;
|
||||
forked->m_working_directory = BAN::move(working_directory);
|
||||
forked->m_root_file = BAN::move(root_file);
|
||||
forked->m_cmdline = BAN::move(cmdline);
|
||||
forked->m_environ = BAN::move(environ);
|
||||
forked->m_page_table = BAN::move(page_table);
|
||||
|
@ -656,7 +660,7 @@ namespace Kernel
|
|||
auto executable_file = TRY(find_file(AT_FDCWD, path, O_EXEC));
|
||||
auto executable_inode = executable_file.inode;
|
||||
|
||||
auto executable = TRY(ELF::load_from_inode(executable_inode, m_credentials, *new_page_table));
|
||||
auto executable = TRY(ELF::load_from_inode(m_root_file.inode, executable_inode, m_credentials, *new_page_table));
|
||||
auto new_mapped_regions = BAN::move(executable.regions);
|
||||
|
||||
BAN::Vector<LibELF::AuxiliaryVector> auxiliary_vector;
|
||||
|
@ -1044,7 +1048,7 @@ namespace Kernel
|
|||
TRY(validate_string_access(path));
|
||||
|
||||
auto [parent, file_name] = TRY(find_parent_file(fd, path, O_RDONLY));
|
||||
auto file_or_error = VirtualFileSystem::get().file_from_relative_path(parent, m_credentials, file_name, flags);
|
||||
auto file_or_error = VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, parent, m_credentials, file_name, flags);
|
||||
|
||||
VirtualFileSystem::File file;
|
||||
if (file_or_error.is_error())
|
||||
|
@ -1054,7 +1058,7 @@ namespace Kernel
|
|||
|
||||
// FIXME: There is a race condition between next two lines
|
||||
TRY(parent.inode->create_file(file_name, (mode & 0777) | Inode::Mode::IFREG, m_credentials.euid(), m_credentials.egid()));
|
||||
file = TRY(VirtualFileSystem::get().file_from_relative_path(parent, m_credentials, file_name, flags & ~O_RDWR));
|
||||
file = TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, parent, m_credentials, file_name, flags & ~O_RDWR));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1135,7 +1139,7 @@ namespace Kernel
|
|||
credentials.set_egid(credentials.rgid());
|
||||
|
||||
auto relative_parent = TRY(find_relative_parent(AT_FDCWD, path));
|
||||
TRY(VirtualFileSystem::get().file_from_relative_path(relative_parent, credentials, path, flags));
|
||||
TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, relative_parent, credentials, path, flags));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1258,6 +1262,7 @@ namespace Kernel
|
|||
flag = O_NOFOLLOW;
|
||||
|
||||
LockGuard _(m_process_lock);
|
||||
TRY(validate_string_access(path));
|
||||
|
||||
auto inode = TRY(find_file(fd, path, flag)).inode;
|
||||
|
||||
|
@ -1280,6 +1285,7 @@ namespace Kernel
|
|||
flag = O_NOFOLLOW;
|
||||
|
||||
LockGuard _(m_process_lock);
|
||||
TRY(validate_string_access(path));
|
||||
|
||||
auto inode = TRY(find_file(fd, path, flag)).inode;
|
||||
|
||||
|
@ -2095,22 +2101,25 @@ namespace Kernel
|
|||
BAN::ErrorOr<long> Process::sys_chdir(const char* path)
|
||||
{
|
||||
LockGuard _(m_process_lock);
|
||||
|
||||
TRY(validate_string_access(path));
|
||||
|
||||
auto file = TRY(find_file(AT_FDCWD, path, O_SEARCH));
|
||||
m_working_directory = BAN::move(file);
|
||||
|
||||
m_working_directory = TRY(find_file(AT_FDCWD, path, O_SEARCH));
|
||||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_fchdir(int fildes)
|
||||
{
|
||||
LockGuard _(m_process_lock);
|
||||
m_working_directory = TRY(m_open_file_descriptors.file_of(fildes));
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto file = TRY(m_open_file_descriptors.file_of(fildes));
|
||||
m_working_directory = BAN::move(file);
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_chroot(const char* path)
|
||||
{
|
||||
LockGuard _(m_process_lock);
|
||||
TRY(validate_string_access(path));
|
||||
if (!m_credentials.is_superuser())
|
||||
return BAN::Error::from_errno(EACCES);
|
||||
m_root_file = TRY(find_file(AT_FDCWD, path, O_SEARCH));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,8 +121,8 @@ namespace Kernel
|
|||
void TTY::keyboard_task(void*)
|
||||
{
|
||||
BAN::RefPtr<Inode> keyboard_inode;
|
||||
if (auto ret = VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, "/dev/keyboard"_sv, O_RDONLY); !ret.is_error())
|
||||
keyboard_inode = ret.value().inode;
|
||||
if (auto ret = DevFileSystem::get().root_inode()->find_inode("keyboard"_sv); !ret.is_error())
|
||||
keyboard_inode = ret.release_value();
|
||||
else
|
||||
{
|
||||
dprintln("could not open keyboard device: {}", ret.error());
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='SDL2_mixer'
|
||||
VERSION='2.8.1'
|
||||
DOWNLOAD_URL="https://github.com/libsdl-org/SDL_mixer/releases/download/release-$VERSION/SDL2_mixer-$VERSION.tar.gz#cb760211b056bfe44f4a1e180cc7cb201137e4d1572f2002cc1be728efd22660"
|
||||
DEPENDENCIES=('SDL2')
|
||||
|
||||
configure() {
|
||||
$BANAN_CMAKE --fresh -S . -B build -G Ninja \
|
||||
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
|
||||
-DCMAKE_INSTALL_PREFIX='/usr' \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DSDL2MIXER_WAVPACK=OFF \
|
||||
-DSDL2MIXER_MIDI=OFF \
|
||||
-DSDL2MIXER_OPUS=OFF \
|
||||
-DSDL2MIXER_MOD=OFF \
|
||||
|| exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
$BANAN_CMAKE --build build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
$BANAN_CMAKE --install build || exit 1
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
NAME='binutils'
|
||||
VERSION='2.44'
|
||||
DOWNLOAD_URL="https://ftp.gnu.org/gnu/binutils/binutils-$VERSION.tar.gz#0cdd76777a0dfd3dd3a63f215f030208ddb91c2361d2bcc02acec0f1c16b6a2e"
|
||||
DEPENDENCIES=('zlib')
|
||||
DEPENDENCIES=('zlib' 'zstd')
|
||||
MAKE_INSTALL_TARGETS=('install-strip')
|
||||
CONFIGURE_OPTIONS=(
|
||||
"--target=$BANAN_TOOLCHAIN_TRIPLE"
|
||||
|
@ -16,6 +16,13 @@ CONFIGURE_OPTIONS=(
|
|||
'--disable-werror'
|
||||
)
|
||||
|
||||
pre_configure() {
|
||||
unset PKG_CONFIG_DIR
|
||||
unset PKG_CONFIG_SYSROOT_DIR
|
||||
unset PKG_CONFIG_LIBDIR
|
||||
unset PKG_CONFIG_PATH
|
||||
}
|
||||
|
||||
post_install() {
|
||||
# remove libtool files
|
||||
rm -f $BANAN_SYSROOT/usr/lib/libbfd.la
|
||||
|
|
|
@ -2,20 +2,22 @@
|
|||
|
||||
NAME='doom'
|
||||
VERSION='git'
|
||||
DOWNLOAD_URL="https://github.com/ozkl/doomgeneric.git#613f870b6fa83ede448a247de5a2571092fa729d"
|
||||
DOWNLOAD_URL="https://github.com/ozkl/doomgeneric.git#5041246e859052e2e258ca6edb4e1e9bbd98fcf5"
|
||||
DEPENDENCIES=('SDL2' 'SDL2_mixer' 'timidity')
|
||||
|
||||
configure() {
|
||||
make --directory doomgeneric clean
|
||||
rm -rf doomgeneric/build
|
||||
}
|
||||
|
||||
build() {
|
||||
if [ ! -f ../doom1.wad ]; then
|
||||
wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad -O ../doom1.wad || exit 1
|
||||
fi
|
||||
make --directory doomgeneric --file Makefile.banan_os -j$(nproc) || exit 1
|
||||
|
||||
CFLAGS='-std=c11' make --directory doomgeneric --file Makefile.sdl CC="$CC" SDL_PATH="$BANAN_SYSROOT/usr/bin/" || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
cp doomgeneric/build/doom "${BANAN_SYSROOT}/bin/" || exit 1
|
||||
cp doomgeneric/doomgeneric "${BANAN_SYSROOT}/bin/doom" || exit 1
|
||||
cp ../doom1.wad "$BANAN_SYSROOT/home/user/" || exit 1
|
||||
}
|
||||
|
|
|
@ -1,224 +0,0 @@
|
|||
From 0f37d9f2df042eb8ba021dd91b898c1f07d86b58 Mon Sep 17 00:00:00 2001
|
||||
From: Bananymous <bananymousosq@gmail.com>
|
||||
Date: Fri, 18 Oct 2024 03:44:10 +0300
|
||||
Subject: [PATCH] Add support for banan-os
|
||||
|
||||
---
|
||||
doomgeneric/Makefile.banan_os | 57 +++++++++++
|
||||
doomgeneric/doomgeneric_banan_os.cpp | 138 +++++++++++++++++++++++++++
|
||||
2 files changed, 200 insertions(+)
|
||||
create mode 100644 doomgeneric/Makefile.banan_os
|
||||
create mode 100644 doomgeneric/doomgeneric_banan_os.cpp
|
||||
|
||||
diff --git a/doomgeneric/Makefile.banan_os b/doomgeneric/Makefile.banan_os
|
||||
new file mode 100644
|
||||
index 0000000..0878148
|
||||
--- /dev/null
|
||||
+++ b/doomgeneric/Makefile.banan_os
|
||||
@@ -0,0 +1,57 @@
|
||||
+################################################################
|
||||
+#
|
||||
+# $Id:$
|
||||
+#
|
||||
+# $Log:$
|
||||
+#
|
||||
+
|
||||
+ifeq ($(V),1)
|
||||
+ VB=''
|
||||
+else
|
||||
+ VB=@
|
||||
+endif
|
||||
+
|
||||
+CC=$(BANAN_ARCH)-pc-banan_os-gcc
|
||||
+CXX=$(BANAN_ARCH)-pc-banan_os-g++
|
||||
+CFLAGS+=-O3 -std=c11 -Wall -DNORMALUNIX -DLINUX -DSNDSERV -D_DEFAULT_SOURCE
|
||||
+CXXFLAGS+=$(CFLAGS) --std=c++20
|
||||
+LDFLAGS+=
|
||||
+LIBS+=-lgui -linput -lstdc++
|
||||
+
|
||||
+# subdirectory for objects
|
||||
+OBJDIR=build
|
||||
+OUTPUT=$(OBJDIR)/doom
|
||||
+
|
||||
+SRC_DOOM = dummy.o am_map.o doomdef.o doomstat.o dstrings.o d_event.o d_items.o d_iwad.o d_loop.o d_main.o d_mode.o d_net.o f_finale.o f_wipe.o g_game.o hu_lib.o hu_stuff.o info.o i_cdmus.o i_endoom.o i_joystick.o i_scale.o i_sound.o i_system.o i_timer.o memio.o m_argv.o m_bbox.o m_cheat.o m_config.o m_controls.o m_fixed.o m_menu.o m_misc.o m_random.o p_ceilng.o p_doors.o p_enemy.o p_floor.o p_inter.o p_lights.o p_map.o p_maputl.o p_mobj.o p_plats.o p_pspr.o p_saveg.o p_setup.o p_sight.o p_spec.o p_switch.o p_telept.o p_tick.o p_user.o r_bsp.o r_data.o r_draw.o r_main.o r_plane.o r_segs.o r_sky.o r_things.o sha1.o sounds.o statdump.o st_lib.o st_stuff.o s_sound.o tables.o v_video.o wi_stuff.o w_checksum.o w_file.o w_main.o w_wad.o z_zone.o w_file_stdc.o i_input.o i_video.o doomgeneric.o doomgeneric_banan_os.o
|
||||
+OBJS += $(addprefix $(OBJDIR)/, $(SRC_DOOM))
|
||||
+
|
||||
+all: $(OUTPUT)
|
||||
+
|
||||
+clean:
|
||||
+ rm -rf $(OBJDIR)
|
||||
+ rm -f $(OUTPUT)
|
||||
+ rm -f $(OUTPUT).gdb
|
||||
+ rm -f $(OUTPUT).map
|
||||
+
|
||||
+$(OUTPUT): $(OBJS)
|
||||
+ @echo [Linking $@]
|
||||
+ $(VB)$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) \
|
||||
+ -o $(OUTPUT) $(LIBS) -Wl,-Map,$(OUTPUT).map
|
||||
+ @echo [Size]
|
||||
+ -$(CROSS_COMPILE)size $(OUTPUT)
|
||||
+
|
||||
+$(OBJS): | $(OBJDIR)
|
||||
+
|
||||
+$(OBJDIR):
|
||||
+ mkdir -p $(OBJDIR)
|
||||
+
|
||||
+$(OBJDIR)/%.o: %.c
|
||||
+ @echo [Compiling $<]
|
||||
+ $(VB)$(CC) $(CFLAGS) -c $< -o $@
|
||||
+
|
||||
+$(OBJDIR)/%.o: %.cpp
|
||||
+ @echo [Compiling $<]
|
||||
+ $(VB)$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
+
|
||||
+print:
|
||||
+ @echo OBJS: $(OBJS)
|
||||
\ No newline at end of file
|
||||
diff --git a/doomgeneric/doomgeneric_banan_os.cpp b/doomgeneric/doomgeneric_banan_os.cpp
|
||||
new file mode 100644
|
||||
index 0000000..9161771
|
||||
--- /dev/null
|
||||
+++ b/doomgeneric/doomgeneric_banan_os.cpp
|
||||
@@ -0,0 +1,139 @@
|
||||
+extern "C"
|
||||
+{
|
||||
+#include "doomgeneric.h"
|
||||
+#include "doomkeys.h"
|
||||
+}
|
||||
+
|
||||
+#include <assert.h>
|
||||
+#include <ctype.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <stdint.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/banan-os.h>
|
||||
+#include <sys/framebuffer.h>
|
||||
+#include <sys/mman.h>
|
||||
+#include <time.h>
|
||||
+
|
||||
+#include <LibGUI/Window.h>
|
||||
+
|
||||
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
+
|
||||
+static BAN::UniqPtr<LibGUI::Window> s_window;
|
||||
+
|
||||
+static constexpr size_t s_key_queue_size = 16;
|
||||
+static unsigned short s_key_queue[s_key_queue_size];
|
||||
+static size_t s_key_read_index = 0;
|
||||
+static size_t s_key_write_index = 0;
|
||||
+
|
||||
+extern "C"
|
||||
+{
|
||||
+
|
||||
+void DG_Init()
|
||||
+{
|
||||
+ s_window = MUST(LibGUI::Window::create(DOOMGENERIC_RESX, DOOMGENERIC_RESY, "DOOM"_sv));
|
||||
+ s_window->set_key_event_callback(
|
||||
+ [](LibGUI::EventPacket::KeyEvent::event_t event)
|
||||
+ {
|
||||
+ unsigned short doom_key = 0;
|
||||
+ switch (event.key)
|
||||
+ {
|
||||
+ case LibInput::Key::Enter:
|
||||
+ doom_key = KEY_ENTER;
|
||||
+ break;
|
||||
+ case LibInput::Key::Escape:
|
||||
+ doom_key = KEY_ESCAPE;
|
||||
+ break;
|
||||
+ case LibInput::Key::ArrowLeft:
|
||||
+ doom_key = KEY_LEFTARROW;
|
||||
+ break;
|
||||
+ case LibInput::Key::ArrowUp:
|
||||
+ doom_key = KEY_UPARROW;
|
||||
+ break;
|
||||
+ case LibInput::Key::ArrowRight:
|
||||
+ doom_key = KEY_RIGHTARROW;
|
||||
+ break;
|
||||
+ case LibInput::Key::ArrowDown:
|
||||
+ doom_key = KEY_DOWNARROW;
|
||||
+ break;
|
||||
+ case LibInput::Key::LeftCtrl:
|
||||
+ case LibInput::Key::RightCtrl:
|
||||
+ doom_key = KEY_FIRE;
|
||||
+ break;
|
||||
+ case LibInput::Key::Space:
|
||||
+ doom_key = KEY_USE;
|
||||
+ break;
|
||||
+ case LibInput::Key::RightShift:
|
||||
+ doom_key = KEY_RSHIFT;
|
||||
+ break;
|
||||
+ default:
|
||||
+ {
|
||||
+ const char* utf8 = LibInput::key_to_utf8(event.key, event.modifier);
|
||||
+ if (utf8 && strlen(utf8) == 1 && isalpha(*utf8))
|
||||
+ doom_key = tolower(*utf8);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (doom_key == 0)
|
||||
+ return;
|
||||
+
|
||||
+ s_key_queue[s_key_write_index] = doom_key | (int)event.pressed() << 8;
|
||||
+ s_key_write_index = (s_key_write_index + 1) % s_key_queue_size;
|
||||
+ }
|
||||
+ );
|
||||
+}
|
||||
+
|
||||
+void DG_DrawFrame()
|
||||
+{
|
||||
+ auto& texture = s_window->texture();
|
||||
+ for (size_t y = 0; y < DOOMGENERIC_RESY; y++)
|
||||
+ for (size_t x = 0; x < DOOMGENERIC_RESX; x++)
|
||||
+ texture.set_pixel(x, y, 0xFF000000 | DG_ScreenBuffer[y * DOOMGENERIC_RESX + x]);
|
||||
+ s_window->invalidate();
|
||||
+ s_window->poll_events();
|
||||
+}
|
||||
+
|
||||
+void DG_SleepMs(uint32_t ms)
|
||||
+{
|
||||
+ struct timespec ts;
|
||||
+ ts.tv_sec = ms / 1000;
|
||||
+ ts.tv_nsec = (ms % 1000) * 1000000;
|
||||
+ nanosleep(&ts, NULL);
|
||||
+}
|
||||
+
|
||||
+uint32_t DG_GetTicksMs()
|
||||
+{
|
||||
+ struct timespec ts;
|
||||
+ clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
+ return (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
|
||||
+}
|
||||
+
|
||||
+int DG_GetKey(int* pressed, unsigned char* doomKey)
|
||||
+{
|
||||
+ if (s_key_read_index == s_key_write_index)
|
||||
+ return 0;
|
||||
+
|
||||
+ unsigned short key_data = s_key_queue[s_key_read_index];
|
||||
+ s_key_read_index = (s_key_read_index + 1) % s_key_queue_size;
|
||||
+
|
||||
+ *pressed = key_data >> 8;
|
||||
+ *doomKey = key_data & 0xFF;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+void DG_SetWindowTitle(const char* title)
|
||||
+{
|
||||
+ (void)title;
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char** argv)
|
||||
+{
|
||||
+ doomgeneric_Create(argc, argv);
|
||||
+
|
||||
+ for (;;)
|
||||
+ doomgeneric_Tick();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+}
|
||||
--
|
||||
2.45.2
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
From a4e6b807885a7cb4a507b4e114743aa0004376ad Mon Sep 17 00:00:00 2001
|
||||
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
|
||||
Date: Sun, 10 Aug 2025 01:57:38 +0300
|
||||
Subject: [PATCH] add support for custom SDL path
|
||||
|
||||
---
|
||||
doomgeneric/Makefile.sdl | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/doomgeneric/Makefile.sdl b/doomgeneric/Makefile.sdl
|
||||
index 38402da..8c2f84e 100644
|
||||
--- a/doomgeneric/Makefile.sdl
|
||||
+++ b/doomgeneric/Makefile.sdl
|
||||
@@ -12,8 +12,8 @@ else
|
||||
endif
|
||||
|
||||
|
||||
-SDL_CFLAGS = `sdl2-config --cflags`
|
||||
-SDL_LIBS = `sdl2-config --cflags --libs` -lSDL2_mixer
|
||||
+SDL_CFLAGS = `$(SDL_PATH)sdl2-config --cflags`
|
||||
+SDL_LIBS = `$(SDL_PATH)sdl2-config --cflags --libs` -lSDL2_mixer
|
||||
|
||||
|
||||
CC=clang # gcc or g++
|
||||
--
|
||||
2.50.1
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
From c28fd460c15a3d4cc5aac35d1ea5744f1722cab4 Mon Sep 17 00:00:00 2001
|
||||
From: Bananymous <bananymousosq@gmail.com>
|
||||
Date: Wed, 3 Apr 2024 21:39:22 +0300
|
||||
Subject: [PATCH] Call exit() on I_Quit() and I_Error()
|
||||
|
||||
---
|
||||
doomgeneric/i_system.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/doomgeneric/i_system.c b/doomgeneric/i_system.c
|
||||
index 5d00091..bfb204f 100644
|
||||
--- a/doomgeneric/i_system.c
|
||||
+++ b/doomgeneric/i_system.c
|
||||
@@ -257,6 +257,8 @@ void I_Quit (void)
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
+ exit(0);
|
||||
+
|
||||
#if ORIGCODE
|
||||
SDL_Quit();
|
||||
|
||||
@@ -403,6 +405,8 @@ void I_Error (char *error, ...)
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
+ exit(1);
|
||||
+
|
||||
exit_gui_popup = !M_ParmExists("-nogui");
|
||||
|
||||
// Pop up a GUI dialog box to show the error message, if the
|
||||
--
|
||||
2.47.1
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
From fd5308b45021ca18e7703d810e2e2ba86c174669 Mon Sep 17 00:00:00 2001
|
||||
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
|
||||
Date: Sun, 10 Aug 2025 01:56:26 +0300
|
||||
Subject: [PATCH] set timidity config path
|
||||
|
||||
---
|
||||
doomgeneric/i_sdlmusic.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/doomgeneric/i_sdlmusic.c b/doomgeneric/i_sdlmusic.c
|
||||
index f56392f..80b9021 100644
|
||||
--- a/doomgeneric/i_sdlmusic.c
|
||||
+++ b/doomgeneric/i_sdlmusic.c
|
||||
@@ -110,7 +110,7 @@ static boolean sdl_was_initialized = false;
|
||||
static boolean musicpaused = false;
|
||||
static int current_music_volume;
|
||||
|
||||
-char *timidity_cfg_path = "";
|
||||
+char *timidity_cfg_path = "/etc/timidity.cfg";
|
||||
|
||||
static char *temp_timidity_cfg = NULL;
|
||||
|
||||
--
|
||||
2.50.1
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
From 70c235938f0b64c4f08a478d3107e5254ad904c6 Mon Sep 17 00:00:00 2001
|
||||
From: Bananymous <bananymousosq@gmail.com>
|
||||
Date: Wed, 27 Nov 2024 13:28:42 +0200
|
||||
Subject: [PATCH] Remove unnecessary copy from framebuffer
|
||||
|
||||
---
|
||||
doomgeneric/doomgeneric.c | 2 --
|
||||
doomgeneric/doomgeneric_banan_os.cpp | 6 +++---
|
||||
2 files changed, 3 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/doomgeneric/doomgeneric.c b/doomgeneric/doomgeneric.c
|
||||
index 782a7e7..f4eb63e 100644
|
||||
--- a/doomgeneric/doomgeneric.c
|
||||
+++ b/doomgeneric/doomgeneric.c
|
||||
@@ -18,8 +18,6 @@ void doomgeneric_Create(int argc, char **argv)
|
||||
|
||||
M_FindResponseFile();
|
||||
|
||||
- DG_ScreenBuffer = malloc(DOOMGENERIC_RESX * DOOMGENERIC_RESY * 4);
|
||||
-
|
||||
DG_Init();
|
||||
|
||||
D_DoomMain ();
|
||||
diff --git a/doomgeneric/doomgeneric_banan_os.cpp b/doomgeneric/doomgeneric_banan_os.cpp
|
||||
index d00c30d..9d13b43 100644
|
||||
--- a/doomgeneric/doomgeneric_banan_os.cpp
|
||||
+++ b/doomgeneric/doomgeneric_banan_os.cpp
|
||||
@@ -80,14 +80,13 @@ void DG_Init()
|
||||
s_key_write_index = (s_key_write_index + 1) % s_key_queue_size;
|
||||
}
|
||||
);
|
||||
+
|
||||
+ ASSERT(DG_ScreenBuffer == nullptr);
|
||||
+ DG_ScreenBuffer = s_window->texture().pixels().data();
|
||||
}
|
||||
|
||||
void DG_DrawFrame()
|
||||
{
|
||||
- auto& texture = s_window->texture();
|
||||
- for (size_t y = 0; y < DOOMGENERIC_RESY; y++)
|
||||
- for (size_t x = 0; x < DOOMGENERIC_RESX; x++)
|
||||
- texture.set_pixel(x, y, 0xFF000000 | DG_ScreenBuffer[y * DOOMGENERIC_RESX + x]);
|
||||
s_window->invalidate();
|
||||
s_window->poll_events();
|
||||
}
|
||||
--
|
||||
2.47.1
|
||||
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
NAME='quake2'
|
||||
VERSION='git'
|
||||
DOWNLOAD_URL="https://github.com/ozkl/quake2generic.git#a967e4f567a98941326fc7fe76eee5e52a04a633"
|
||||
DOWNLOAD_URL="https://github.com/ozkl/quake2generic.git#50190797664fd42fc1b0266150c54f76f92bfa15"
|
||||
DEPENDENCIES=('SDL2' 'SDL2_mixer')
|
||||
|
||||
configure() {
|
||||
:
|
||||
make clean
|
||||
}
|
||||
|
||||
build() {
|
||||
|
@ -24,11 +25,13 @@ build() {
|
|||
echo "File hash does not match" >&2
|
||||
exit 1
|
||||
fi
|
||||
make -j$(nproc) || exit 1
|
||||
|
||||
cflags='-Dstricmp=strcasecmp -Wno-incompatible-pointer-types'
|
||||
make CC="$CC" BASE_CFLAGS="$cflags" SDL_PATH="$BANAN_SYSROOT/usr/bin/" -j$(nproc) || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
cp build/quake2 "${BANAN_SYSROOT}/bin/" || exit 1
|
||||
cp -v build/quake2-soft "${BANAN_SYSROOT}/bin/quake2" || exit 1
|
||||
|
||||
baseq2_tar=$(realpath ../baseq2.tar.gz || exit 1)
|
||||
cd "$BANAN_SYSROOT/home/user/"
|
||||
|
|
|
@ -1,482 +0,0 @@
|
|||
From f900c2967edc684334b663e522aeec79e8fee10d Mon Sep 17 00:00:00 2001
|
||||
From: Bananymous <bananymousosq@gmail.com>
|
||||
Date: Thu, 14 Nov 2024 12:33:39 +0200
|
||||
Subject: [PATCH] Add support for banan-os
|
||||
|
||||
---
|
||||
Makefile | 106 +++-------------
|
||||
port_soft_banan_os.cpp | 277 +++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 295 insertions(+), 88 deletions(-)
|
||||
create mode 100644 port_soft_banan_os.cpp
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 46142df..4437418 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,7 +1,3 @@
|
||||
-
|
||||
-SDL_CFLAGS = `sdl2-config --cflags`
|
||||
-SDL_LIBS = `sdl2-config --cflags --libs` -lSDL2_mixer
|
||||
-
|
||||
MOUNT_DIR=.
|
||||
|
||||
BUILDDIR=build
|
||||
@@ -18,21 +14,19 @@ GAME_DIR=$(MOUNT_DIR)/game
|
||||
CTF_DIR=$(MOUNT_DIR)/ctf
|
||||
XATRIX_DIR=$(MOUNT_DIR)/xatrix
|
||||
|
||||
-CC=clang #emcc
|
||||
+CC=$(BANAN_ARCH)-banan_os-gcc
|
||||
BASE_CFLAGS=-Dstricmp=strcasecmp
|
||||
|
||||
+CXX=$(BANAN_ARCH)-banan_os-g++
|
||||
+CXXFLAGS=--std=c++20
|
||||
|
||||
RELEASE_CFLAGS=$(BASE_CFLAGS) -O6 -ffast-math -funroll-loops \
|
||||
-fomit-frame-pointer -fexpensive-optimizations -malign-loops=2 \
|
||||
-malign-jumps=2 -malign-functions=2
|
||||
|
||||
DEBUG_CFLAGS=$(BASE_CFLAGS) -g
|
||||
-LDFLAGS=-ldl -lm
|
||||
-XCFLAGS=-I/opt/X11/include
|
||||
-
|
||||
-GLLDFLAGS=-L/usr/X11/lib -L/usr/local/lib \
|
||||
- $(SDL_LIBS) -lGL
|
||||
-GLCFLAGS=$(SDL_CFLAGS)
|
||||
+LDFLAGS=-lgui -linput
|
||||
+XCFLAGS=
|
||||
|
||||
SHLIBEXT=so
|
||||
|
||||
@@ -43,6 +37,10 @@ DO_CC=$(CC) $(CFLAGS) -o $@ -c $<
|
||||
DO_SHLIB_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $<
|
||||
DO_GL_SHLIB_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) $(GLCFLAGS) $(XCFLAGS) -o $@ -c $<
|
||||
|
||||
+DO_CXX=$(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ -c $<
|
||||
+DO_SHLIB_CXX=$(CXX) $(CFLAGS) $(CXXFLAGS) $(SHLIBCFLAGS) -o $@ -c $<
|
||||
+DO_GL_SHLIB_CXX=$(CXX) $(CFLAGS) $(CXXFLAGS) $(SHLIBCFLAGS) $(GLCFLAGS) $(XCFLAGS) -o $@ -c $<
|
||||
+
|
||||
#############################################################################
|
||||
# SETUP AND BUILD
|
||||
#############################################################################
|
||||
@@ -61,14 +59,12 @@ createdirs:
|
||||
@-mkdir -p $(BUILDDIR) \
|
||||
$(BUILDDIR)/client \
|
||||
$(BUILDDIR)/ref_soft \
|
||||
- $(BUILDDIR)/ref_softsdl \
|
||||
- $(BUILDDIR)/ref_gl \
|
||||
$(BUILDDIR)/net \
|
||||
$(BUILDDIR)/sound \
|
||||
$(BUILDDIR)/game
|
||||
|
||||
|
||||
-TARGETS: $(BUILDDIR)/quake2-soft $(BUILDDIR)/quake2-gl
|
||||
+TARGETS: $(BUILDDIR)/quake2
|
||||
|
||||
#############################################################################
|
||||
# CLIENT/SERVER
|
||||
@@ -122,7 +118,7 @@ QUAKE2_OBJS = \
|
||||
\
|
||||
$(BUILDDIR)/client/pmove.o \
|
||||
\
|
||||
- $(BUILDDIR)/net/net_unix.o \
|
||||
+ $(BUILDDIR)/net/net_loopback.o \
|
||||
\
|
||||
$(BUILDDIR)/sound/snddma_null.o \
|
||||
\
|
||||
@@ -200,38 +196,11 @@ REF_SOFT_OBJS = \
|
||||
$(BUILDDIR)/ref_soft/r_rast.o \
|
||||
$(BUILDDIR)/ref_soft/r_scan.o \
|
||||
$(BUILDDIR)/ref_soft/r_sprite.o \
|
||||
- $(BUILDDIR)/ref_soft/r_surf.o
|
||||
-
|
||||
-
|
||||
-REF_SOFT_SDL_OBJS = \
|
||||
- $(BUILDDIR)/ref_soft/port_soft_sdl.o
|
||||
-
|
||||
-
|
||||
-#############################################################################
|
||||
-# REF_GL
|
||||
-#############################################################################
|
||||
-
|
||||
-REF_GL_OBJS = \
|
||||
- $(BUILDDIR)/ref_gl/gl_draw.o \
|
||||
- $(BUILDDIR)/ref_gl/gl_image.o \
|
||||
- $(BUILDDIR)/ref_gl/gl_light.o \
|
||||
- $(BUILDDIR)/ref_gl/gl_mesh.o \
|
||||
- $(BUILDDIR)/ref_gl/gl_model.o \
|
||||
- $(BUILDDIR)/ref_gl/gl_rmain.o \
|
||||
- $(BUILDDIR)/ref_gl/gl_rmisc.o \
|
||||
- $(BUILDDIR)/ref_gl/gl_rsurf.o \
|
||||
- $(BUILDDIR)/ref_gl/gl_warp.o \
|
||||
- \
|
||||
- $(BUILDDIR)/ref_gl/qgl_system.o \
|
||||
- $(BUILDDIR)/ref_gl/port_gl_sdl.o
|
||||
-
|
||||
-
|
||||
-$(BUILDDIR)/quake2-soft : $(QUAKE2_OBJS) $(GAME_OBJS) $(REF_SOFT_OBJS) $(REF_SOFT_SDL_OBJS)
|
||||
- $(CC) $(CFLAGS) -o $@ $(QUAKE2_OBJS) $(GAME_OBJS) $(REF_SOFT_OBJS) $(REF_SOFT_SDL_OBJS) $(LDFLAGS) $(GLLDFLAGS)
|
||||
-
|
||||
-$(BUILDDIR)/quake2-gl : $(QUAKE2_OBJS) $(GAME_OBJS) $(REF_GL_OBJS)
|
||||
- $(CC) $(CFLAGS) -o $@ $(QUAKE2_OBJS) $(GAME_OBJS) $(REF_GL_OBJS) $(LDFLAGS) $(GLLDFLAGS)
|
||||
+ $(BUILDDIR)/ref_soft/r_surf.o \
|
||||
+ $(BUILDDIR)/ref_soft/port_soft_banan_os.o
|
||||
|
||||
+$(BUILDDIR)/quake2 : $(QUAKE2_OBJS) $(GAME_OBJS) $(REF_SOFT_OBJS)
|
||||
+ $(CC) $(CFLAGS) -o $@ $(QUAKE2_OBJS) $(GAME_OBJS) $(REF_SOFT_OBJS) $(LDFLAGS)
|
||||
|
||||
$(BUILDDIR)/client/cl_cin.o : $(CLIENT_DIR)/cl_cin.c
|
||||
$(DO_CC)
|
||||
@@ -362,7 +331,7 @@ $(BUILDDIR)/client/q_system.o : $(OTHER_DIR)/q_system.c
|
||||
$(BUILDDIR)/client/glob.o : $(OTHER_DIR)/glob.c
|
||||
$(DO_CC)
|
||||
|
||||
-$(BUILDDIR)/net/net_unix.o : $(NET_DIR)/net_unix.c
|
||||
+$(BUILDDIR)/net/net_loopback.o : $(NET_DIR)/net_loopback.c
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/port_platform_unix.o : $(MOUNT_DIR)/port_platform_unix.c
|
||||
@@ -689,45 +658,8 @@ $(BUILDDIR)/ref_soft/r_sprite.o : $(REF_SOFT_DIR)/r_sprite.c
|
||||
$(BUILDDIR)/ref_soft/r_surf.o : $(REF_SOFT_DIR)/r_surf.c
|
||||
$(DO_GL_SHLIB_CC)
|
||||
|
||||
-$(BUILDDIR)/ref_soft/port_soft_sdl.o : $(MOUNT_DIR)/port_soft_sdl.c
|
||||
- $(DO_GL_SHLIB_CC)
|
||||
-
|
||||
-#############################################################################
|
||||
-# REF_GL
|
||||
-#############################################################################
|
||||
-
|
||||
-$(BUILDDIR)/ref_gl/gl_draw.o : $(REF_GL_DIR)/gl_draw.c
|
||||
- $(DO_GL_SHLIB_CC)
|
||||
-
|
||||
-$(BUILDDIR)/ref_gl/gl_image.o : $(REF_GL_DIR)/gl_image.c
|
||||
- $(DO_GL_SHLIB_CC)
|
||||
-
|
||||
-$(BUILDDIR)/ref_gl/gl_light.o : $(REF_GL_DIR)/gl_light.c
|
||||
- $(DO_GL_SHLIB_CC)
|
||||
-
|
||||
-$(BUILDDIR)/ref_gl/gl_mesh.o : $(REF_GL_DIR)/gl_mesh.c
|
||||
- $(DO_GL_SHLIB_CC)
|
||||
-
|
||||
-$(BUILDDIR)/ref_gl/gl_model.o : $(REF_GL_DIR)/gl_model.c
|
||||
- $(DO_GL_SHLIB_CC)
|
||||
-
|
||||
-$(BUILDDIR)/ref_gl/gl_rmain.o : $(REF_GL_DIR)/gl_rmain.c
|
||||
- $(DO_GL_SHLIB_CC)
|
||||
-
|
||||
-$(BUILDDIR)/ref_gl/gl_rmisc.o : $(REF_GL_DIR)/gl_rmisc.c
|
||||
- $(DO_GL_SHLIB_CC)
|
||||
-
|
||||
-$(BUILDDIR)/ref_gl/gl_rsurf.o : $(REF_GL_DIR)/gl_rsurf.c
|
||||
- $(DO_GL_SHLIB_CC)
|
||||
-
|
||||
-$(BUILDDIR)/ref_gl/gl_warp.o : $(REF_GL_DIR)/gl_warp.c
|
||||
- $(DO_GL_SHLIB_CC)
|
||||
-
|
||||
-$(BUILDDIR)/ref_gl/qgl_system.o : $(REF_GL_DIR)/qgl_system.c
|
||||
- $(DO_GL_SHLIB_CC)
|
||||
-
|
||||
-$(BUILDDIR)/ref_gl/port_gl_sdl.o : $(MOUNT_DIR)/port_gl_sdl.c
|
||||
- $(DO_GL_SHLIB_CC)
|
||||
+$(BUILDDIR)/ref_soft/port_soft_banan_os.o : $(MOUNT_DIR)/port_soft_banan_os.cpp
|
||||
+ $(DO_GL_SHLIB_CXX)
|
||||
|
||||
|
||||
#############################################################################
|
||||
@@ -738,8 +670,6 @@ clean:
|
||||
-rm -rf \
|
||||
$(BUILDDIR)/client \
|
||||
$(BUILDDIR)/ref_soft \
|
||||
- $(BUILDDIR)/ref_softsdl \
|
||||
- $(BUILDDIR)/ref_gl \
|
||||
$(BUILDDIR)/game \
|
||||
$(BUILDDIR)/net \
|
||||
$(BUILDDIR)/sound \
|
||||
diff --git a/port_soft_banan_os.cpp b/port_soft_banan_os.cpp
|
||||
new file mode 100644
|
||||
index 0000000..c7d7e16
|
||||
--- /dev/null
|
||||
+++ b/port_soft_banan_os.cpp
|
||||
@@ -0,0 +1,278 @@
|
||||
+#include <LibGUI/Window.h>
|
||||
+#include <LibInput/KeyEvent.h>
|
||||
+#include <LibInput/MouseEvent.h>
|
||||
+#include <LibImage/Image.h>
|
||||
+
|
||||
+#include <BAN/Debug.h>
|
||||
+
|
||||
+extern "C" {
|
||||
+
|
||||
+#include "ref_soft/r_local.h"
|
||||
+#include "client/keys.h"
|
||||
+
|
||||
+#include "quake2.h"
|
||||
+
|
||||
+static LibImage::Image::Color s_palette[256];
|
||||
+
|
||||
+static int s_mouse_dx { 0 };
|
||||
+static int s_mouse_dy { 0 };
|
||||
+static bool s_relative_mouse { false };
|
||||
+
|
||||
+static BAN::Vector<uint8_t> s_buffer;
|
||||
+static BAN::UniqPtr<LibGUI::Window> s_window;
|
||||
+static bool s_is_fullscreen { false };
|
||||
+
|
||||
+static int key_to_quake_key(LibInput::Key key)
|
||||
+{
|
||||
+ using namespace LibInput;
|
||||
+
|
||||
+ switch (key)
|
||||
+ {
|
||||
+ case Key::PageUp: return K_PGUP;
|
||||
+ case Key::PageDown: return K_PGDN;
|
||||
+ case Key::Home: return K_HOME;
|
||||
+ case Key::End: return K_END;
|
||||
+ case Key::ArrowLeft: return K_LEFTARROW;
|
||||
+ case Key::ArrowRight: return K_RIGHTARROW;
|
||||
+ case Key::ArrowDown: return K_DOWNARROW;
|
||||
+ case Key::ArrowUp: return K_UPARROW;
|
||||
+ case Key::Escape: return K_ESCAPE;
|
||||
+ case Key::Enter: return K_ENTER;
|
||||
+ case Key::Tab: return K_TAB;
|
||||
+ case Key::F1: return K_F1;
|
||||
+ case Key::F2: return K_F2;
|
||||
+ case Key::F3: return K_F3;
|
||||
+ case Key::F4: return K_F4;
|
||||
+ case Key::F5: return K_F5;
|
||||
+ case Key::F6: return K_F6;
|
||||
+ case Key::F7: return K_F7;
|
||||
+ case Key::F8: return K_F8;
|
||||
+ case Key::F9: return K_F9;
|
||||
+ case Key::F10: return K_F10;
|
||||
+ case Key::F11: return K_F11;
|
||||
+ case Key::F12: return K_F12;
|
||||
+ case Key::Backspace: return K_BACKSPACE;
|
||||
+ case Key::Delete: return K_DEL;
|
||||
+ case Key::LeftShift:
|
||||
+ case Key::RightShift: return K_SHIFT;
|
||||
+ case Key::LeftCtrl:
|
||||
+ case Key::RightCtrl: return K_CTRL;
|
||||
+ case Key::LeftAlt:
|
||||
+ case Key::RightAlt: return K_ALT;
|
||||
+ case Key::Insert: return K_INS;
|
||||
+ default:
|
||||
+ if (const char* ascii = key_to_utf8(key, 0); ascii && strlen(ascii) == 1)
|
||||
+ return *ascii;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int button_to_quake_button(LibInput::MouseButton button)
|
||||
+{
|
||||
+ using namespace LibInput;
|
||||
+
|
||||
+ switch (button)
|
||||
+ {
|
||||
+ case LibInput::MouseButton::Left: return K_MOUSE1;
|
||||
+ case LibInput::MouseButton::Right: return K_MOUSE2;
|
||||
+ case LibInput::MouseButton::Middle: return K_MOUSE3;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void create_window(uint32_t width, uint32_t height)
|
||||
+{
|
||||
+ ASSERT(!s_window);
|
||||
+ s_window = MUST(LibGUI::Window::create(width, height, "Quake2"_sv));
|
||||
+
|
||||
+ s_window->set_mouse_move_event_callback(
|
||||
+ [](auto event)
|
||||
+ {
|
||||
+ if (!s_relative_mouse)
|
||||
+ return;
|
||||
+ s_mouse_dx += event.x;
|
||||
+ s_mouse_dy += event.y;
|
||||
+ }
|
||||
+ );
|
||||
+
|
||||
+ s_window->set_mouse_button_event_callback(
|
||||
+ [](auto event)
|
||||
+ {
|
||||
+ if (int button = button_to_quake_button(event.button))
|
||||
+ Quake2_SendKey(button, event.pressed);
|
||||
+ }
|
||||
+ );
|
||||
+
|
||||
+ s_window->set_key_event_callback(
|
||||
+ [](auto event)
|
||||
+ {
|
||||
+ if (int key = key_to_quake_key(event.key))
|
||||
+ Quake2_SendKey(key, event.pressed());
|
||||
+ }
|
||||
+ );
|
||||
+
|
||||
+ s_window->set_close_window_event_callback(
|
||||
+ []()
|
||||
+ {
|
||||
+ char command[] = "quit";
|
||||
+ ri.Cmd_ExecuteText(EXEC_NOW, command);
|
||||
+ }
|
||||
+ );
|
||||
+}
|
||||
+
|
||||
+rserr_t SWimp_SetMode(int* pwidth, int* pheight, int mode, qboolean fullscreen)
|
||||
+{
|
||||
+ int width, height;
|
||||
+
|
||||
+ if (!ri.Vid_GetModeInfo(&width, &height, mode))
|
||||
+ return rserr_invalid_mode;
|
||||
+
|
||||
+ if (!s_window)
|
||||
+ create_window(width, height);
|
||||
+ else if (s_window->width() != width || s_window->height() != height)
|
||||
+ {
|
||||
+ s_window->request_resize(width, height);
|
||||
+
|
||||
+ bool resized { false };
|
||||
+ s_window->set_resize_window_event_callback([&]() { resized = true; });
|
||||
+ while (!resized)
|
||||
+ s_window->poll_events();
|
||||
+ s_window->set_resize_window_event_callback({});
|
||||
+
|
||||
+ ASSERT(s_window->width() == width && s_window->height() == height);
|
||||
+ }
|
||||
+
|
||||
+ if (s_is_fullscreen != fullscreen)
|
||||
+ {
|
||||
+ s_is_fullscreen = fullscreen;
|
||||
+ s_window->set_fullscreen(fullscreen);
|
||||
+ }
|
||||
+
|
||||
+ MUST(s_buffer.resize(s_window->width() * s_window->height()));
|
||||
+ vid.rowbytes = s_window->width();
|
||||
+ vid.buffer = s_buffer.data();
|
||||
+
|
||||
+ *pwidth = s_window->width();
|
||||
+ *pheight = s_window->height();
|
||||
+
|
||||
+ ri.Vid_NewWindow(s_window->width(), s_window->height());
|
||||
+
|
||||
+ return rserr_ok;
|
||||
+}
|
||||
+
|
||||
+void SWimp_Shutdown(void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+int SWimp_Init(void* hInstance, void* wndProc)
|
||||
+{
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static qboolean SWimp_InitGraphics(qboolean fullscreen)
|
||||
+{
|
||||
+ return rserr_ok;
|
||||
+}
|
||||
+
|
||||
+void SWimp_SetPalette(const unsigned char* palette)
|
||||
+{
|
||||
+ for (int i = 0; i < 256; i++)
|
||||
+ {
|
||||
+ s_palette[i].r = *palette++;
|
||||
+ s_palette[i].g = *palette++;
|
||||
+ s_palette[i].b = *palette++;
|
||||
+ s_palette[i].a = *palette++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void SWimp_BeginFrame(float camera_seperation)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+void SWimp_EndFrame(void)
|
||||
+{
|
||||
+ auto& texture = s_window->texture();
|
||||
+ const uint32_t width = s_window->width();
|
||||
+ const uint32_t height = s_window->height();
|
||||
+ for (int y = 0; y < height; y++)
|
||||
+ for (int x = 0; x < width; x++)
|
||||
+ texture.set_pixel(x, y, s_palette[s_buffer[y * width + x]].as_argb());
|
||||
+ s_window->invalidate();
|
||||
+}
|
||||
+
|
||||
+void SWimp_AppActivate(qboolean active)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+int QG_Milliseconds(void)
|
||||
+{
|
||||
+ struct timespec ts;
|
||||
+ clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
+ return (ts.tv_sec * 1'000) + (ts.tv_nsec / 1'000'000);
|
||||
+}
|
||||
+
|
||||
+void QG_GetMouseDiff(int* dx, int* dy)
|
||||
+{
|
||||
+ *dx = s_mouse_dx;
|
||||
+ s_mouse_dx = 0;
|
||||
+
|
||||
+ *dy = s_mouse_dy;
|
||||
+ s_mouse_dy = 0;
|
||||
+}
|
||||
+
|
||||
+void QG_CaptureMouse(void)
|
||||
+{
|
||||
+ s_relative_mouse = true;
|
||||
+ s_window->set_mouse_capture(true);
|
||||
+}
|
||||
+
|
||||
+void QG_ReleaseMouse(void)
|
||||
+{
|
||||
+ s_relative_mouse = false;
|
||||
+ s_window->set_mouse_capture(false);
|
||||
+}
|
||||
+
|
||||
+static uint64_t get_current_ns()
|
||||
+{
|
||||
+ timespec last_ts;
|
||||
+ clock_gettime(CLOCK_MONOTONIC, &last_ts);
|
||||
+ return (uint64_t)last_ts.tv_sec * 1'000'000'000 + last_ts.tv_nsec;
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char** argv)
|
||||
+{
|
||||
+ Quake2_Init(argc, argv);
|
||||
+
|
||||
+ uint64_t last_ns = get_current_ns();
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ s_window->poll_events();
|
||||
+
|
||||
+ const uint64_t current_ns = get_current_ns();
|
||||
+ uint64_t duration_ns = current_ns - last_ns;
|
||||
+
|
||||
+ if (duration_ns < 1'000'000)
|
||||
+ {
|
||||
+ timespec sleep_ts {
|
||||
+ .tv_sec = 0,
|
||||
+ .tv_nsec = (long)(1'000'000 - duration_ns)
|
||||
+ };
|
||||
+ while (nanosleep(&sleep_ts, &sleep_ts))
|
||||
+ continue;
|
||||
+ duration_ns = get_current_ns() - last_ns;
|
||||
+ }
|
||||
+
|
||||
+ Quake2_Frame(duration_ns / 1'000'000);
|
||||
+
|
||||
+ last_ns = current_ns;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+}
|
||||
--
|
||||
2.47.0
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
From fd08d90bb7ee8388a9e005bae23edcccbfc73dbb Mon Sep 17 00:00:00 2001
|
||||
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
|
||||
Date: Sun, 10 Aug 2025 19:52:20 +0300
|
||||
Subject: [PATCH] add support for custom SDL path and add sound support
|
||||
|
||||
---
|
||||
Makefile | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 8edbffa..de2f605 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
-SDL_CFLAGS = `sdl2-config --cflags`
|
||||
-SDL_LIBS = `sdl2-config --cflags --libs` -lSDL2_mixer
|
||||
+SDL_CFLAGS = `$(SDL_PATH)sdl2-config --cflags`
|
||||
+SDL_LIBS = `$(SDL_PATH)sdl2-config --cflags --libs` -lSDL2_mixer
|
||||
|
||||
MOUNT_DIR=.
|
||||
|
||||
@@ -124,7 +124,7 @@ QUAKE2_OBJS = \
|
||||
\
|
||||
$(BUILDDIR)/net/net_unix.o \
|
||||
\
|
||||
- $(BUILDDIR)/sound/snddma_null.o \
|
||||
+ $(BUILDDIR)/sound/snd_sdl.o \
|
||||
\
|
||||
$(BUILDDIR)/port_platform_unix.o
|
||||
|
||||
@@ -353,7 +353,7 @@ $(BUILDDIR)/client/vid_menu.o : $(OTHER_DIR)/vid_menu.c
|
||||
$(BUILDDIR)/client/vid_lib.o : $(OTHER_DIR)/vid_lib.c
|
||||
$(DO_CC)
|
||||
|
||||
-$(BUILDDIR)/client/snddma_null.o : $(NULL_DIR)/snddma_null.c
|
||||
+$(BUILDDIR)/client/snd_sdl.o : $(NULL_DIR)/snd_sdl.c
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/client/q_system.o : $(OTHER_DIR)/q_system.c
|
||||
@@ -368,7 +368,7 @@ $(BUILDDIR)/net/net_unix.o : $(NET_DIR)/net_unix.c
|
||||
$(BUILDDIR)/port_platform_unix.o : $(MOUNT_DIR)/port_platform_unix.c
|
||||
$(DO_CC)
|
||||
|
||||
-$(BUILDDIR)/sound/snddma_null.o : $(SOUND_DIR)/snddma_null.c
|
||||
+$(BUILDDIR)/sound/snd_sdl.o : $(SOUND_DIR)/snd_sdl.c
|
||||
$(DO_GL_SHLIB_CC)
|
||||
|
||||
|
||||
--
|
||||
2.50.1
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
From fbdf3e7c40c1de83a2361bb904d8dbd3464ccebd Mon Sep 17 00:00:00 2001
|
||||
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
|
||||
Date: Sun, 10 Aug 2025 19:54:38 +0300
|
||||
Subject: [PATCH 2/2] fix socket creation
|
||||
|
||||
---
|
||||
net/net_unix.c | 10 +---------
|
||||
1 file changed, 1 insertion(+), 9 deletions(-)
|
||||
|
||||
diff --git a/net/net_unix.c b/net/net_unix.c
|
||||
index a92e57c..f297dff 100644
|
||||
--- a/net/net_unix.c
|
||||
+++ b/net/net_unix.c
|
||||
@@ -451,24 +451,16 @@ int NET_Socket (char *net_interface, int port)
|
||||
qboolean _true = true;
|
||||
int i = 1;
|
||||
|
||||
- if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
|
||||
+ if ((newsocket = socket (PF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP)) == -1)
|
||||
{
|
||||
Com_Printf ("ERROR: UDP_OpenSocket: socket:", NET_ErrorString());
|
||||
return 0;
|
||||
}
|
||||
|
||||
- // make it non-blocking
|
||||
- if (ioctl (newsocket, FIONBIO, &_true) == -1)
|
||||
- {
|
||||
- Com_Printf ("ERROR: UDP_OpenSocket: ioctl FIONBIO:%s\n", NET_ErrorString());
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
// make it broadcast capable
|
||||
if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1)
|
||||
{
|
||||
Com_Printf ("ERROR: UDP_OpenSocket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString());
|
||||
- return 0;
|
||||
}
|
||||
|
||||
if (!net_interface || !net_interface[0] || !stricmp(net_interface, "localhost"))
|
||||
--
|
||||
2.50.1
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='timidity'
|
||||
VERSION='2.15.0'
|
||||
DOWNLOAD_URL="https://sourceforge.net/projects/timidity/files/TiMidity++/TiMidity++-$VERSION/TiMidity++-$VERSION.tar.gz#0b6109a3c64604c8851cd9bb4cbafc014a4e13b0025f597e586d9742388f6fb7"
|
||||
TAR_CONTENT="TiMidity++-$VERSION"
|
||||
CONFIG_SUB=('autoconf/config.sub')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'--without-x'
|
||||
'lib_cv_va_copy=y'
|
||||
'lib_cv___va_copy=n'
|
||||
'lib_cv_va_val_copy=n'
|
||||
'CFLAGS=-std=c11'
|
||||
)
|
||||
|
||||
pre_configure() {
|
||||
unset CC CXX LD
|
||||
}
|
||||
|
||||
post_install() {
|
||||
if [ ! -f ../eawpats.zip ]; then
|
||||
wget https://www.quaddicted.com/files/idgames/sounds/eawpats.zip -O ../eawpats.zip || exit 1
|
||||
fi
|
||||
|
||||
eawpats_dir="/usr/share/eawpats"
|
||||
mkdir -p "$BANAN_SYSROOT/$eawpats_dir"
|
||||
unzip -qod "$BANAN_SYSROOT/$eawpats_dir" ../eawpats.zip
|
||||
|
||||
cp "$BANAN_SYSROOT/$eawpats_dir/timidity.cfg" "$BANAN_SYSROOT/etc/"
|
||||
sed -i "s|^dir .*$|dir $eawpats_dir|g" "$BANAN_SYSROOT/etc/timidity.cfg"
|
||||
}
|
|
@ -3,13 +3,15 @@
|
|||
NAME='tinygb'
|
||||
VERSION='git'
|
||||
DOWNLOAD_URL="https://github.com/jewelcodes/tinygb.git#57fdaff675a6b5b963b2b6624868d9698eabe375"
|
||||
DEPENDENCIES=('SDL2')
|
||||
|
||||
configure() {
|
||||
make -f Makefile.banan_os clean
|
||||
sed -i "s|shell sdl2-config|shell $BANAN_SYSROOT/usr/bin/sdl2-config|g" Makefile
|
||||
make clean
|
||||
}
|
||||
|
||||
build() {
|
||||
make -f Makefile.banan_os -j$(nproc) || exit 1
|
||||
make CC="$CC" LD="$CC" || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
|
|
|
@ -1,420 +0,0 @@
|
|||
From 7f7c6402e384591bca63021aa97d60a8107de88d Mon Sep 17 00:00:00 2001
|
||||
From: Bananymous <bananymousosq@gmail.com>
|
||||
Date: Mon, 5 May 2025 00:59:03 +0300
|
||||
Subject: [PATCH] Add support for banan-os
|
||||
|
||||
---
|
||||
Makefile.banan_os | 28 +++
|
||||
src/platform/banan-os/main.cpp | 362 +++++++++++++++++++++++++++++++++
|
||||
2 files changed, 390 insertions(+)
|
||||
create mode 100644 Makefile.banan_os
|
||||
create mode 100644 src/platform/banan-os/main.cpp
|
||||
|
||||
diff --git a/Makefile.banan_os b/Makefile.banan_os
|
||||
new file mode 100644
|
||||
index 0000000..22e191e
|
||||
--- /dev/null
|
||||
+++ b/Makefile.banan_os
|
||||
@@ -0,0 +1,28 @@
|
||||
+CC = $(BANAN_ARCH)-banan_os-gcc
|
||||
+CXX = $(BANAN_ARCH)-banan_os-g++
|
||||
+LD = $(BANAN_ARCH)-banan_os-gcc
|
||||
+
|
||||
+CFLAGS = -c -O2 -Isrc/include -Wall
|
||||
+CXXFLAGS = --std=c++20
|
||||
+LDFLAGS = -O2 -lgui -linput
|
||||
+
|
||||
+SRC := $(shell find src -name "*.c" -not -path 'src/platform/*') $(shell find src/platform/banan-os -name "*.c" -or -name "*.cpp")
|
||||
+OBJ := $(addsuffix .o,$(SRC))
|
||||
+
|
||||
+all: tinygb
|
||||
+
|
||||
+clean:
|
||||
+ @rm -f $(OBJ)
|
||||
+ @rm -f tinygb
|
||||
+
|
||||
+%.c.o: %.c
|
||||
+ @echo -e "\x1B[0;1;35m [ CC ]\x1B[0m $@"
|
||||
+ $(CC) -o $@ $(CFLAGS) $<
|
||||
+
|
||||
+%.cpp.o: %.cpp
|
||||
+ @echo -e "\x1B[0;1;35m [ CC ]\x1B[0m $@"
|
||||
+ $(CXX) -o $@ $(CFLAGS) $(CXXFLAGS) $<
|
||||
+
|
||||
+tinygb: $(OBJ)
|
||||
+ @echo -e "\x1B[0;1;36m [ LD ]\x1B[0m tinygb"
|
||||
+ $(LD) $(OBJ) -o tinygb $(LDFLAGS)
|
||||
diff --git a/src/platform/banan-os/main.cpp b/src/platform/banan-os/main.cpp
|
||||
new file mode 100644
|
||||
index 0000000..94f249e
|
||||
--- /dev/null
|
||||
+++ b/src/platform/banan-os/main.cpp
|
||||
@@ -0,0 +1,364 @@
|
||||
+
|
||||
+/* tinygb - a tiny gameboy emulator
|
||||
+ (c) 2022 by jewel */
|
||||
+
|
||||
+extern "C" {
|
||||
+#include <tinygb.h>
|
||||
+}
|
||||
+
|
||||
+#include <LibGUI/Window.h>
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <time.h>
|
||||
+
|
||||
+long rom_size;
|
||||
+int scaling = 4;
|
||||
+int frameskip = 0; // no skip
|
||||
+
|
||||
+timing_t timing;
|
||||
+char *rom_filename;
|
||||
+
|
||||
+BAN::UniqPtr<LibGUI::Window> s_window;
|
||||
+
|
||||
+// Key Config
|
||||
+LibInput::Key key_a;
|
||||
+LibInput::Key key_b;
|
||||
+LibInput::Key key_start;
|
||||
+LibInput::Key key_select;
|
||||
+LibInput::Key key_up;
|
||||
+LibInput::Key key_down;
|
||||
+LibInput::Key key_left;
|
||||
+LibInput::Key key_right;
|
||||
+LibInput::Key key_throttle;
|
||||
+
|
||||
+LibInput::Key get_key(const char* keyname)
|
||||
+{
|
||||
+ if (keyname == nullptr);
|
||||
+ else if (!strcmp("a", keyname)) return LibInput::Key::A;
|
||||
+ else if (!strcmp("b", keyname)) return LibInput::Key::B;
|
||||
+ else if (!strcmp("c", keyname)) return LibInput::Key::C;
|
||||
+ else if (!strcmp("d", keyname)) return LibInput::Key::D;
|
||||
+ else if (!strcmp("e", keyname)) return LibInput::Key::E;
|
||||
+ else if (!strcmp("f", keyname)) return LibInput::Key::F;
|
||||
+ else if (!strcmp("g", keyname)) return LibInput::Key::G;
|
||||
+ else if (!strcmp("h", keyname)) return LibInput::Key::H;
|
||||
+ else if (!strcmp("i", keyname)) return LibInput::Key::I;
|
||||
+ else if (!strcmp("j", keyname)) return LibInput::Key::J;
|
||||
+ else if (!strcmp("k", keyname)) return LibInput::Key::K;
|
||||
+ else if (!strcmp("l", keyname)) return LibInput::Key::L;
|
||||
+ else if (!strcmp("m", keyname)) return LibInput::Key::M;
|
||||
+ else if (!strcmp("n", keyname)) return LibInput::Key::N;
|
||||
+ else if (!strcmp("o", keyname)) return LibInput::Key::O;
|
||||
+ else if (!strcmp("p", keyname)) return LibInput::Key::P;
|
||||
+ else if (!strcmp("q", keyname)) return LibInput::Key::Q;
|
||||
+ else if (!strcmp("r", keyname)) return LibInput::Key::R;
|
||||
+ else if (!strcmp("s", keyname)) return LibInput::Key::S;
|
||||
+ else if (!strcmp("t", keyname)) return LibInput::Key::T;
|
||||
+ else if (!strcmp("u", keyname)) return LibInput::Key::U;
|
||||
+ else if (!strcmp("v", keyname)) return LibInput::Key::V;
|
||||
+ else if (!strcmp("w", keyname)) return LibInput::Key::W;
|
||||
+ else if (!strcmp("x", keyname)) return LibInput::Key::X;
|
||||
+ else if (!strcmp("y", keyname)) return LibInput::Key::Y;
|
||||
+ else if (!strcmp("z", keyname)) return LibInput::Key::Z;
|
||||
+ else if (!strcmp("0", keyname)) return LibInput::Key::_0;
|
||||
+ else if (!strcmp("1", keyname)) return LibInput::Key::_1;
|
||||
+ else if (!strcmp("2", keyname)) return LibInput::Key::_2;
|
||||
+ else if (!strcmp("3", keyname)) return LibInput::Key::_3;
|
||||
+ else if (!strcmp("4", keyname)) return LibInput::Key::_4;
|
||||
+ else if (!strcmp("5", keyname)) return LibInput::Key::_5;
|
||||
+ else if (!strcmp("6", keyname)) return LibInput::Key::_6;
|
||||
+ else if (!strcmp("7", keyname)) return LibInput::Key::_7;
|
||||
+ else if (!strcmp("8", keyname)) return LibInput::Key::_8;
|
||||
+ else if (!strcmp("9", keyname)) return LibInput::Key::_9;
|
||||
+ else if (!strcmp("up", keyname)) return LibInput::Key::ArrowUp;
|
||||
+ else if (!strcmp("down", keyname)) return LibInput::Key::ArrowDown;
|
||||
+ else if (!strcmp("left", keyname)) return LibInput::Key::ArrowLeft;
|
||||
+ else if (!strcmp("right", keyname)) return LibInput::Key::ArrowRight;
|
||||
+ else if (!strcmp("space", keyname)) return LibInput::Key::Space;
|
||||
+ else if (!strcmp("rshift", keyname)) return LibInput::Key::RightShift;
|
||||
+ else if (!strcmp("lshift", keyname)) return LibInput::Key::LeftShift;
|
||||
+ else if (!strcmp("backspace", keyname)) return LibInput::Key::Backspace;
|
||||
+ else if (!strcmp("delete", keyname)) return LibInput::Key::Delete;
|
||||
+ else if (!strcmp("tab", keyname)) return LibInput::Key::Tab;
|
||||
+ else if (!strcmp("escape", keyname)) return LibInput::Key::Escape;
|
||||
+ else if (!strcmp("exclamation", keyname)) return LibInput::Key::ExclamationMark;
|
||||
+ else if (!strcmp("at", keyname)) return LibInput::Key::AtSign;
|
||||
+ else if (!strcmp("hash", keyname)) return LibInput::Key::Hashtag;
|
||||
+ else if (!strcmp("dollar", keyname)) return LibInput::Key::Dollar;
|
||||
+ else if (!strcmp("percent", keyname)) return LibInput::Key::Percent;
|
||||
+ else if (!strcmp("caret", keyname)) return LibInput::Key::Caret;
|
||||
+ else if (!strcmp("ampersand", keyname)) return LibInput::Key::Ampersand;
|
||||
+ else if (!strcmp("asterisk", keyname)) return LibInput::Key::Asterix;
|
||||
+ else if (!strcmp("leftparenthesis", keyname)) return LibInput::Key::OpenParenthesis;
|
||||
+ else if (!strcmp("rightparenthesis", keyname)) return LibInput::Key::CloseParenthesis;
|
||||
+
|
||||
+ return LibInput::Key::None;
|
||||
+}
|
||||
+
|
||||
+static void load_keys()
|
||||
+{
|
||||
+ key_a = get_key(config_file.a);
|
||||
+ if (key_a == LibInput::Key::None)
|
||||
+ key_a = LibInput::Key::Z;
|
||||
+
|
||||
+ key_b = get_key(config_file.b);
|
||||
+ if (key_b == LibInput::Key::None)
|
||||
+ key_b = LibInput::Key::X;
|
||||
+
|
||||
+ key_start = get_key(config_file.start);
|
||||
+ if (key_start == LibInput::Key::None)
|
||||
+ key_start = LibInput::Key::Enter;
|
||||
+
|
||||
+ key_select = get_key(config_file.select);
|
||||
+ if (key_select == LibInput::Key::None)
|
||||
+ key_select = LibInput::Key::RightShift;
|
||||
+
|
||||
+ key_up = get_key(config_file.up);
|
||||
+ if (key_up == LibInput::Key::None)
|
||||
+ key_up = LibInput::Key::ArrowUp;
|
||||
+
|
||||
+ key_down = get_key(config_file.down);
|
||||
+ if (key_down == LibInput::Key::None)
|
||||
+ key_down = LibInput::Key::ArrowDown;
|
||||
+
|
||||
+ key_left = get_key(config_file.left);
|
||||
+ if (key_left == LibInput::Key::None)
|
||||
+ key_left = LibInput::Key::ArrowLeft;
|
||||
+
|
||||
+ key_right = get_key(config_file.right);
|
||||
+ if (key_right == LibInput::Key::None)
|
||||
+ key_right = LibInput::Key::ArrowRight;
|
||||
+
|
||||
+ key_throttle = get_key(config_file.throttle);
|
||||
+ if (key_throttle == LibInput::Key::None)
|
||||
+ key_throttle = LibInput::Key::Space;
|
||||
+}
|
||||
+
|
||||
+void delay(int ms)
|
||||
+{
|
||||
+ const timespec ts {
|
||||
+ .tv_sec = static_cast<time_t>(ms / 1000),
|
||||
+ .tv_nsec = (ms % 1000) * 1000000
|
||||
+ };
|
||||
+ nanosleep(&ts, nullptr);
|
||||
+}
|
||||
+
|
||||
+void destroy_window()
|
||||
+{
|
||||
+ s_window.clear();
|
||||
+}
|
||||
+
|
||||
+void update_window(uint32_t *framebuffer)
|
||||
+{
|
||||
+ auto pixels = s_window->texture().pixels();
|
||||
+ for (int i = 0; i < scaled_h; i++)
|
||||
+ {
|
||||
+ uint32_t* src = &framebuffer[i * scaled_w];
|
||||
+ uint32_t* dst = using_sgb_border
|
||||
+ ? &pixels[(i + gb_y) * s_window->width() + gb_x]
|
||||
+ : &pixels[i * s_window->width()];
|
||||
+ memcpy(dst, src, scaled_w * 4);
|
||||
+ }
|
||||
+
|
||||
+ if (framecount > frameskip)
|
||||
+ {
|
||||
+ s_window->invalidate();
|
||||
+ framecount = 0;
|
||||
+ drawn_frames++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void update_border(uint32_t *framebuffer)
|
||||
+{
|
||||
+ auto pixels = s_window->texture().pixels();
|
||||
+ for (int i = 0; i < sgb_scaled_h; i++)
|
||||
+ {
|
||||
+ uint32_t* src = &framebuffer[i * sgb_scaled_w];
|
||||
+ uint32_t* dst = &pixels[i * s_window->width()];
|
||||
+ memcpy(dst, src, sgb_scaled_w*4);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void resize_sgb_window()
|
||||
+{
|
||||
+ s_window->request_resize(SGB_WIDTH * scaling, SGB_HEIGHT * scaling);
|
||||
+
|
||||
+ bool resized { false };
|
||||
+ s_window->set_resize_window_event_callback([&]() { resized = true; });
|
||||
+ while (!resized)
|
||||
+ s_window->poll_events();
|
||||
+ s_window->set_resize_window_event_callback({});
|
||||
+
|
||||
+ ASSERT(s_window->width() == static_cast<uint32_t>(SGB_WIDTH * scaling));
|
||||
+ ASSERT(s_window->height() == static_cast<uint32_t>(SGB_HEIGHT * scaling));
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char **argv) {
|
||||
+ if(argc != 2) {
|
||||
+ fprintf(stdout, "usage: %s rom_name\n", argv[0]);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ rom_filename = argv[1];
|
||||
+
|
||||
+ open_log();
|
||||
+ open_config();
|
||||
+ load_keys();
|
||||
+
|
||||
+ // open the rom
|
||||
+ FILE *rom_file = fopen(rom_filename, "r");
|
||||
+ if(!rom_file) {
|
||||
+ write_log("unable to open %s for reading: %s\n", rom_filename, strerror(errno));
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ fseek(rom_file, 0L, SEEK_END);
|
||||
+ rom_size = ftell(rom_file);
|
||||
+ fseek(rom_file, 0L, SEEK_SET);
|
||||
+
|
||||
+ write_log("loading rom from file %s, %d KiB\n", rom_filename, rom_size / 1024);
|
||||
+
|
||||
+ rom = malloc(rom_size);
|
||||
+ if(!rom) {
|
||||
+ write_log("unable to allocate memory\n");
|
||||
+ fclose(rom_file);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (fread(rom, 1, rom_size, rom_file) <= 0)
|
||||
+ {
|
||||
+ write_log("an error occured while reading from rom file: %s\n", strerror(errno));
|
||||
+ fclose(rom_file);
|
||||
+ free(rom);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ fclose(rom_file);
|
||||
+
|
||||
+ if (auto ret = LibGUI::Window::create(GB_WIDTH * scaling, GB_HEIGHT * scaling, "tinygb"_sv); !ret.is_error())
|
||||
+ s_window = ret.release_value();
|
||||
+ else
|
||||
+ {
|
||||
+ write_log("couldn't create SDL window: %s\n", ret.error().get_message());
|
||||
+ free(rom);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ s_window->set_key_event_callback([](LibGUI::EventPacket::KeyEvent::event_t event) {
|
||||
+ int key = 0;
|
||||
+ if (event.key == key_left)
|
||||
+ key = JOYPAD_LEFT;
|
||||
+ else if (event.key == key_right)
|
||||
+ key = JOYPAD_RIGHT;
|
||||
+ else if (event.key == key_up)
|
||||
+ key = JOYPAD_UP;
|
||||
+ else if (event.key == key_down)
|
||||
+ key = JOYPAD_DOWN;
|
||||
+ else if (event.key == key_a)
|
||||
+ key = JOYPAD_A;
|
||||
+ else if (event.key == key_b)
|
||||
+ key = JOYPAD_B;
|
||||
+ else if (event.key == key_start)
|
||||
+ key = JOYPAD_START;
|
||||
+ else if (event.key == key_select)
|
||||
+ key = JOYPAD_SELECT;
|
||||
+ else if (event.key == key_throttle)
|
||||
+ throttle_enabled = event.released();
|
||||
+ else if (event.pressed() && (event.key == LibInput::Key::Plus || event.key == LibInput::Key::Equals))
|
||||
+ next_palette();
|
||||
+ else if (event.pressed() && (event.key == LibInput::Key::Hyphen))
|
||||
+ prev_palette();
|
||||
+
|
||||
+ if (key)
|
||||
+ joypad_handle(event.pressed(), key);
|
||||
+ });
|
||||
+
|
||||
+ // start emulation
|
||||
+ memory_start();
|
||||
+ cpu_start();
|
||||
+ display_start();
|
||||
+ timer_start();
|
||||
+ sound_start();
|
||||
+
|
||||
+ time_t rawtime;
|
||||
+ struct tm *timeinfo;
|
||||
+ int sec = 500; // any invalid number
|
||||
+ char new_title[256];
|
||||
+ int percentage;
|
||||
+ int throttle_underflow = 0;
|
||||
+ int throttle_target = throttle_lo + SPEED_ALLOWANCE;
|
||||
+
|
||||
+ while(1) {
|
||||
+ s_window->poll_events();
|
||||
+
|
||||
+ for(timing.current_cycles = 0; timing.current_cycles < timing.main_cycles; ) {
|
||||
+ cpu_cycle();
|
||||
+ display_cycle();
|
||||
+ timer_cycle();
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ time(&rawtime);
|
||||
+ timeinfo = localtime(&rawtime);
|
||||
+
|
||||
+ if(sec != timeinfo->tm_sec) {
|
||||
+ sec = timeinfo->tm_sec;
|
||||
+ percentage = (drawn_frames * 1000) / 597;
|
||||
+ sprintf(new_title, "tinygb (%d fps - %d%%)", drawn_frames, percentage);
|
||||
+ s_window->set_title(new_title);
|
||||
+
|
||||
+ // adjust cpu throttle according to acceptable fps (98%-102%)
|
||||
+ if(throttle_enabled) {
|
||||
+ if(percentage < throttle_lo) {
|
||||
+ // emulation is too slow
|
||||
+ if(!throttle_time) {
|
||||
+ // throttle_time--;
|
||||
+
|
||||
+ if(!throttle_underflow) {
|
||||
+ throttle_underflow = 1;
|
||||
+ write_log("WARNING: CPU throttle interval has underflown, emulation may be too slow\n");
|
||||
+ }
|
||||
+ } else {
|
||||
+ //write_log("too slow; decreasing throttle time: %d\n", throttle_time);
|
||||
+
|
||||
+ // this will speed up the speed adjustments for a more natural feel
|
||||
+ if(percentage < (throttle_target/3)) throttle_time /= 3;
|
||||
+ else if(percentage < (throttle_target/2)) throttle_time /= 2;
|
||||
+ else throttle_time--;
|
||||
+ }
|
||||
+
|
||||
+ // prevent this from going too low
|
||||
+ if(throttle_time <= (THROTTLE_THRESHOLD/3)) {
|
||||
+ cycles_per_throttle += (cycles_per_throttle/5); // delay 20% less often
|
||||
+ throttle_time = (THROTTLE_THRESHOLD/3);
|
||||
+ }
|
||||
+ } else if(percentage > throttle_hi) {
|
||||
+ // emulation is too fast
|
||||
+ //write_log("too fast; increasing throttle time: %d\n", throttle_time);
|
||||
+
|
||||
+ if(throttle_time) {
|
||||
+ // to make sure we're not multiplying zero
|
||||
+ if(percentage > (throttle_target*3)) throttle_time *= 3;
|
||||
+ else if(percentage > (throttle_target*2)) throttle_time *= 2;
|
||||
+ else throttle_time++;
|
||||
+ }
|
||||
+ else {
|
||||
+ throttle_time++;
|
||||
+ }
|
||||
+
|
||||
+ // prevent unnecessary lag
|
||||
+ if(throttle_time > THROTTLE_THRESHOLD) {
|
||||
+ cycles_per_throttle -= (cycles_per_throttle/5); // delay 20% more often
|
||||
+ throttle_time = THROTTLE_THRESHOLD;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ drawn_frames = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ die(0, "");
|
||||
+ return 0;
|
||||
+}
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.49.0
|
||||
|
|
@ -113,6 +113,7 @@ __BEGIN_DECLS
|
|||
O(SYS_FUTEX, futex) \
|
||||
O(SYS_GETGROUPS, getgroups) \
|
||||
O(SYS_SETGROUPS, setgroups) \
|
||||
O(SYS_CHROOT, chroot) \
|
||||
|
||||
enum Syscall
|
||||
{
|
||||
|
|
|
@ -596,6 +596,7 @@ int unlinkat(int fd, const char* path, int flag);
|
|||
int usleep(useconds_t usec);
|
||||
ssize_t write(int fildes, const void* buf, size_t nbyte);
|
||||
|
||||
int chroot(const char* path);
|
||||
int getpagesize(void);
|
||||
char* getpass(const char* prompt);
|
||||
|
||||
|
|
|
@ -626,6 +626,11 @@ int getopt(int argc, char* const argv[], const char* optstring)
|
|||
return '?';
|
||||
}
|
||||
|
||||
int chroot(const char* path)
|
||||
{
|
||||
return syscall(SYS_CHROOT, path);
|
||||
}
|
||||
|
||||
int getpagesize(void)
|
||||
{
|
||||
return PAGE_SIZE;
|
||||
|
|
|
@ -31,7 +31,8 @@ namespace LibFont
|
|||
|
||||
#if __is_kernel
|
||||
{
|
||||
auto inode = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, path, O_RDONLY)).inode;
|
||||
// FIXME: This does not account for chroot
|
||||
auto inode = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path(Kernel::VirtualFileSystem::get().root_inode(), { 0, 0, 0, 0 }, path, O_RDONLY)).inode;
|
||||
TRY(file_data.resize(inode->size()));
|
||||
TRY(inode->read(0, BAN::ByteSpan(file_data.span())));
|
||||
}
|
||||
|
|
|
@ -128,7 +128,8 @@ namespace LibInput
|
|||
|
||||
#if __is_kernel
|
||||
{
|
||||
auto file = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, path, 0));
|
||||
// FIXME: This does not account for chroot
|
||||
auto file = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path(Kernel::VirtualFileSystem::get().root_inode(), { 0, 0, 0, 0 }, path, 0));
|
||||
TRY(file_data.resize(file.inode->size()));
|
||||
TRY(file.inode->read(0, BAN::ByteSpan { reinterpret_cast<uint8_t*>(file_data.data()), file_data.size() }));
|
||||
canonical_path = file.canonical_path;
|
||||
|
|
|
@ -42,6 +42,12 @@ int main(int argc, char** argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if (fork() == 0)
|
||||
{
|
||||
execl("/bin/AudioServer", "AudioServer", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bool first = true;
|
||||
|
||||
termios termios;
|
||||
|
|
Loading…
Reference in New Issue