diff --git a/CMakeLists.txt b/CMakeLists.txt index b7cfb056..d1988826 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,10 +36,14 @@ add_custom_target(headers ) add_custom_target(install-sysroot - COMMAND cd ${BANAN_SYSROOT} && tar cf ${BANAN_SYSROOT_TAR} * DEPENDS kernel-install DEPENDS ban-install DEPENDS libc-install DEPENDS userspace-install DEPENDS libelf-install ) + +add_custom_target(package-sysroot + COMMAND cd ${BANAN_SYSROOT} && tar cf ${BANAN_SYSROOT_TAR} * + DEPENDS install-sysroot +) diff --git a/ports/.gitignore b/ports/.gitignore new file mode 100644 index 00000000..f94d6edb --- /dev/null +++ b/ports/.gitignore @@ -0,0 +1 @@ +installed diff --git a/ports/README.md b/ports/README.md new file mode 100644 index 00000000..385edeb1 --- /dev/null +++ b/ports/README.md @@ -0,0 +1 @@ +Here are all of the ports for banan-os. To build a port and run it in banan-os; add a line containing directory name from here into a file called *installed*. When you create banan-os image, all directories listed in *installed* are built. diff --git a/ports/build.sh b/ports/build.sh new file mode 100755 index 00000000..25034474 --- /dev/null +++ b/ports/build.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +CURRENT_DIR=$(dirname $(realpath $0)) +pushd "$CURRENT_DIR" >/dev/null + +while read port; do + ${port}/build.sh +done < installed + +popd >/dev/null diff --git a/ports/doom/.gitignore b/ports/doom/.gitignore new file mode 100644 index 00000000..23126332 --- /dev/null +++ b/ports/doom/.gitignore @@ -0,0 +1 @@ +doomgeneric diff --git a/ports/doom/README.md b/ports/doom/README.md new file mode 100644 index 00000000..e026e733 --- /dev/null +++ b/ports/doom/README.md @@ -0,0 +1 @@ +This is a port of doomgeneric. You will need doom wad to play. Copy the wad file into sysroot and use the -iwad argument to specify wad location. diff --git a/ports/doom/build.sh b/ports/doom/build.sh new file mode 100755 index 00000000..9d589110 --- /dev/null +++ b/ports/doom/build.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +if [ -z $BANAN_ARCH ]; then + echo "You must set the BANAN_ARCH environment variable" >&2 + exit 1 +fi + +if [ -z $BANAN_SYSROOT ]; then + echo "You must set the BANAN_ARCH environment variable" >&2 + exit 1 +fi + +CURRENT_DIR=$(dirname $(realpath $0)) +pushd $CURRENT_DIR >/dev/null + +if [ ! -d "doomgeneric" ]; then + git clone https://github.com/ozkl/doomgeneric.git + cd doomgeneric + git checkout 613f870b6fa83ede448a247de5a2571092fa729d + for patch in ../patches/*; do + git am "$patch" + done + cd .. + + grep -qxF doom ../installed || echo doom >> ../installed +fi + +make --directory doomgeneric/doomgeneric --file Makefile.banan_os +cp "doomgeneric/doomgeneric/build-${BANAN_ARCH}/doomgeneric" "${BANAN_SYSROOT}/bin/doom" + +popd >/dev/null diff --git a/ports/doom/patches/0001-Add-support-for-banan-os.patch b/ports/doom/patches/0001-Add-support-for-banan-os.patch new file mode 100644 index 00000000..c9a3b4c1 --- /dev/null +++ b/ports/doom/patches/0001-Add-support-for-banan-os.patch @@ -0,0 +1,310 @@ +From 70cb1210ba2f6e1d922922f66f32efcf7bec51e1 Mon Sep 17 00:00:00 2001 +From: Bananymous +Date: Wed, 3 Apr 2024 17:57:11 +0300 +Subject: [PATCH] Add support for banan-os + +Add Makefile and implement required functions. +--- + doomgeneric/Makefile.banan_os | 58 +++++++ + doomgeneric/doomgeneric_banan_os.cpp | 224 +++++++++++++++++++++++++++ + 2 files changed, 282 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..453bed7 +--- /dev/null ++++ b/doomgeneric/Makefile.banan_os +@@ -0,0 +1,58 @@ ++################################################################ ++# ++# $Id:$ ++# ++# $Log:$ ++# ++ ++ifeq ($(V),1) ++ VB='' ++else ++ VB=@ ++endif ++ ++CC=$(BANAN_TOOLCHAIN_PREFIX)/bin/$(BANAN_ARCH)-banan_os-gcc ++CXX=$(BANAN_TOOLCHAIN_PREFIX)/bin/$(BANAN_ARCH)-banan_os-g++ ++CFLAGS+=-O2 -g ++CFLAGS+=-Wall -DNORMALUNIX -DLINUX -DSNDSERV -D_DEFAULT_SOURCE ++CXXFLAGS+=$(CFLAGS) --std=c++20 ++LDFLAGS+= ++LIBS+= ++ ++# subdirectory for objects ++OBJDIR=build-$(BANAN_ARCH) ++OUTPUT=$(OBJDIR)/doomgeneric ++ ++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) +diff --git a/doomgeneric/doomgeneric_banan_os.cpp b/doomgeneric/doomgeneric_banan_os.cpp +new file mode 100644 +index 0000000..e32c861 +--- /dev/null ++++ b/doomgeneric/doomgeneric_banan_os.cpp +@@ -0,0 +1,224 @@ ++extern "C" ++{ ++#include "doomgeneric.h" ++#include "doomkeys.h" ++} ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++extern "C" ++{ ++ ++static struct framebuffer_info_t s_fb_info; ++static uint32_t* s_framebuffer = NULL; ++ ++static int s_input_fd; ++ ++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; ++ ++void handle_key_input() ++{ ++ Kernel::Input::KeyEvent event; ++ if (read(s_input_fd, &event, sizeof(event)) <= 0) ++ return; ++ ++ unsigned short doom_key = 0; ++ ++ switch (event.keycode) ++ { ++ case 109: ++ doom_key = KEY_ENTER; ++ break; ++ case 0: ++ doom_key = KEY_ESCAPE; ++ break; ++ case 193: ++ doom_key = KEY_LEFTARROW; ++ break; ++ case 192: ++ doom_key = KEY_UPARROW; ++ break; ++ case 195: ++ doom_key = KEY_RIGHTARROW; ++ break; ++ case 194: ++ doom_key = KEY_DOWNARROW; ++ break; ++ case 160: ++ case 165: ++ doom_key = KEY_FIRE; ++ break; ++ case 163: ++ doom_key = KEY_USE; ++ break; ++ case 128: ++ case 140: ++ doom_key = KEY_RSHIFT; ++ break; ++ ++ case 65: doom_key = tolower('Q'); break; ++ case 66: doom_key = tolower('W'); break; ++ case 67: doom_key = tolower('E'); break; ++ case 68: doom_key = tolower('R'); break; ++ case 69: doom_key = tolower('T'); break; ++ case 70: doom_key = tolower('Y'); break; ++ case 71: doom_key = tolower('U'); break; ++ case 72: doom_key = tolower('I'); break; ++ case 73: doom_key = tolower('O'); break; ++ case 74: doom_key = tolower('P'); break; ++ ++ case 97: doom_key = tolower('A'); break; ++ case 98: doom_key = tolower('S'); break; ++ case 99: doom_key = tolower('D'); break; ++ case 100: doom_key = tolower('F'); break; ++ case 101: doom_key = tolower('G'); break; ++ case 102: doom_key = tolower('H'); break; ++ case 103: doom_key = tolower('J'); break; ++ case 104: doom_key = tolower('K'); break; ++ case 105: doom_key = tolower('L'); break; ++ ++ case 130: doom_key = tolower('Z'); break; ++ case 131: doom_key = tolower('X'); break; ++ case 132: doom_key = tolower('C'); break; ++ case 133: doom_key = tolower('V'); break; ++ case 134: doom_key = tolower('B'); break; ++ case 135: doom_key = tolower('N'); break; ++ case 136: doom_key = tolower('M'); break; ++ } ++ ++ doom_key |= (int)event.pressed() << 8; ++ ++ s_key_queue[s_key_write_index] = doom_key; ++ s_key_write_index = (s_key_write_index + 1) % s_key_queue_size; ++} ++ ++void DG_Init() ++{ ++ s_input_fd = open("/dev/input0", O_RDONLY | O_NONBLOCK); ++ if (s_input_fd == -1) ++ { ++ perror("open"); ++ exit(1); ++ } ++ ++ int fd = open("/dev/fb0", O_RDWR); ++ if (fd == -1) ++ { ++ perror("open"); ++ exit(1); ++ } ++ ++ if (pread(fd, &s_fb_info, sizeof(s_fb_info), -1) == -1) ++ { ++ perror("pread"); ++ exit(1); ++ } ++ ++ size_t bytes = s_fb_info.width * s_fb_info.height * (BANAN_FB_BPP / 8); ++ ++ s_framebuffer = (uint32_t*)mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); ++ if (s_framebuffer == NULL) ++ { ++ perror("mmap"); ++ exit(1); ++ } ++ ++ memset(s_framebuffer, 0, bytes); ++ msync(s_framebuffer, bytes, MS_SYNC); ++ ++ if (tty_ctrl(STDIN_FILENO, TTY_CMD_UNSET, TTY_FLAG_ENABLE_INPUT) == -1) ++ { ++ perror("tty_ctrl"); ++ exit(1); ++ } ++ ++ atexit([]() { tty_ctrl(STDIN_FILENO, TTY_CMD_SET, TTY_FLAG_ENABLE_INPUT); }); ++} ++ ++void DG_DrawFrame() ++{ ++ if (s_framebuffer == NULL) ++ return; ++ ++ assert(BANAN_FB_BPP == 32); ++ ++ for (size_t y = 0; y < BAN::Math::min(s_fb_info.height, DOOMGENERIC_RESY); y++) ++ { ++ memcpy( ++ s_framebuffer + y * s_fb_info.width, ++ DG_ScreenBuffer + y * DOOMGENERIC_RESX, ++ BAN::Math::min(s_fb_info.width, DOOMGENERIC_RESX) * sizeof(uint32_t) ++ ); ++ } ++ ++ int ret = msync(s_framebuffer, s_fb_info.width * s_fb_info.height * 4, MS_SYNC); ++ assert(ret != -1); ++ ++ handle_key_input(); ++} ++ ++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; ++} ++ ++int rename(const char* oldp, const char* newp) ++{ ++ fprintf(stderr, "rename(\"%s\", \"%s\")\n", oldp, newp); ++ exit(1); ++} ++ ++} +-- +2.44.0 + diff --git a/ports/doom/patches/0002-Call-exit-on-I_Error-and-I_Quit.patch b/ports/doom/patches/0002-Call-exit-on-I_Error-and-I_Quit.patch new file mode 100644 index 00000000..3288c510 --- /dev/null +++ b/ports/doom/patches/0002-Call-exit-on-I_Error-and-I_Quit.patch @@ -0,0 +1,34 @@ +From eafb5f1d01e3edd3035fc405de808b1a2e2151d2 Mon Sep 17 00:00:00 2001 +From: Bananymous +Date: Wed, 3 Apr 2024 19:08:08 +0300 +Subject: [PATCH] Call exit() on I_Error() and I_Quit() + +--- + doomgeneric/i_system.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/doomgeneric/i_system.c b/doomgeneric/i_system.c +index 5d00091..b71aa23 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(); + +@@ -454,6 +456,8 @@ void I_Error (char *error, ...) + } + #endif + ++ exit(1); ++ + // abort(); + #if ORIGCODE + SDL_Quit(); +-- +2.44.0 + diff --git a/script/build.sh b/script/build.sh index 2e2133d9..773b7eb5 100755 --- a/script/build.sh +++ b/script/build.sh @@ -49,6 +49,8 @@ build_toolchain () { create_image () { build_target bootloader build_target install-sysroot + $BANAN_ROOT_DIR/ports/build.sh + build_target package-sysroot $BANAN_SCRIPT_DIR/image.sh "$1" }