diff --git a/ports/tinygb/build.sh b/ports/tinygb/build.sh index 9b3cfac7..401434dd 100755 --- a/ports/tinygb/build.sh +++ b/ports/tinygb/build.sh @@ -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() { diff --git a/ports/tinygb/patches/0001-Add-support-for-banan-os.patch b/ports/tinygb/patches/0001-Add-support-for-banan-os.patch deleted file mode 100644 index 2cffdd04..00000000 --- a/ports/tinygb/patches/0001-Add-support-for-banan-os.patch +++ /dev/null @@ -1,420 +0,0 @@ -From 7f7c6402e384591bca63021aa97d60a8107de88d Mon Sep 17 00:00:00 2001 -From: Bananymous -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 -+} -+ -+#include -+ -+#include -+#include -+#include -+ -+long rom_size; -+int scaling = 4; -+int frameskip = 0; // no skip -+ -+timing_t timing; -+char *rom_filename; -+ -+BAN::UniqPtr 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(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(SGB_WIDTH * scaling)); -+ ASSERT(s_window->height() == static_cast(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 -