From f900c2967edc684334b663e522aeec79e8fee10d Mon Sep 17 00:00:00 2001 From: Bananymous 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 +#include +#include +#include + +#include + +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 s_buffer; +static BAN::UniqPtr 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