banan-os/ports/quake2/patches/0001-Add-support-for-banan-...

482 lines
12 KiB
Diff

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,277 @@
+#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)
+{
+ 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++)
+ s_window->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