From acf64246dfbcb2cd9bd1e4c65fc11c409f892863 Mon Sep 17 00:00:00 2001 From: neonloop Date: Sat, 28 Jan 2023 17:36:08 +0000 Subject: Adds XRGB8888 core support Simple version, conversion can still be optimized --- Makefile | 5 +- core.c | 27 +++++++-- patches/dosbox-pure/1000-funkey-s-support.patch | 30 ++++++++++ video.c | 78 +++++++++++++++++++++++++ video.h | 11 ++++ 5 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 patches/dosbox-pure/1000-funkey-s-support.patch create mode 100644 video.c create mode 100644 video.h diff --git a/Makefile b/Makefile index bdb6e7e..452eeee 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ SYSROOT = $(shell $(CC) --print-sysroot) PROCS = -j4 -OBJS = libpicofe/input.o libpicofe/in_sdl.o libpicofe/linux/in_evdev.o libpicofe/linux/plat.o libpicofe/fonts.o libpicofe/readpng.o libpicofe/config_file.o cheat.o config.o content.o core.o menu.o main.o options.o overrides.o patch.o scale.o unzip.o util.o +OBJS = libpicofe/input.o libpicofe/in_sdl.o libpicofe/linux/in_evdev.o libpicofe/linux/plat.o libpicofe/fonts.o libpicofe/readpng.o libpicofe/config_file.o cheat.o config.o content.o core.o menu.o main.o options.o overrides.o patch.o scale.o unzip.o util.o video.o BIN = picoarch @@ -35,6 +35,9 @@ beetle-pce-fast_TYPES = pce,cue,ccd,chd,toc,m3u bluemsx_REPO = https://github.com/libretro/blueMSX-libretro bluemsx_TYPES = rom,ri,mx1,mx2,dsk,col,sg,sc,cas,m3u +dosbox-pure_REPO = https://github.com/schellingb/dosbox-pure +dosbox-pure_CORE = dosbox_pure_libretro.so + fake-08_REPO = https://github.com/jtothebell/fake-08 fake-08_BUILD_PATH = fake-08/platform/libretro fake-08_MAKEFILE = Makefile diff --git a/core.c b/core.c index 2f37a5a..b758e7c 100644 --- a/core.c +++ b/core.c @@ -15,6 +15,7 @@ #include "overrides.h" #include "plat.h" #include "util.h" +#include "video.h" struct core_cbs current_core; char core_path[MAX_PATH]; @@ -326,7 +327,7 @@ static void set_directories(const char *core_name) { snprintf(system_dir, MAX_PATH, "%s/system", cwd); mkdir(system_dir, 0755); } else { - PA_FATAL("Can't find system directory"); + PA_FATAL("Can't find system directory\n"); } #endif /* MINUI */ PA_INFO("Config dir: %s\n", config_dir); @@ -368,12 +369,15 @@ static bool pa_environment(unsigned cmd, void *data) { break; } case RETRO_ENVIRONMENT_SET_PIXEL_FORMAT: { /* 10 */ - const enum retro_pixel_format *format = (enum retro_pixel_format *)data; + const enum retro_pixel_format format = *(enum retro_pixel_format *)data; - if (*format != RETRO_PIXEL_FORMAT_RGB565) { - /* 565 is only supported format */ + if (format == RETRO_PIXEL_FORMAT_RGB565 || + format == RETRO_PIXEL_FORMAT_XRGB8888) { + video_set_pixel_format(format); + } else { return false; } + break; } case RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE: { /* 13 */ @@ -435,7 +439,7 @@ static bool pa_environment(unsigned cmd, void *data) { case RETRO_ENVIRONMENT_SET_CORE_OPTIONS: { /* 53 */ options_free(); if (data) { - options_init(*(const struct retro_core_option_definition **)data); + options_init((const struct retro_core_option_definition *)data); load_config(); } break; @@ -472,6 +476,14 @@ static bool pa_environment(unsigned cmd, void *data) { } break; } + case RETRO_ENVIRONMENT_SET_MESSAGE_EXT: { /* 6 */ + const struct retro_message_ext *message = (const struct retro_message_ext*)data; + if (message) { + pa_log(message->level, "%s\n", message->msg); + } + + break; + } case RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK: { /* 62 */ const struct retro_audio_buffer_status_callback *cb = (const struct retro_audio_buffer_status_callback *)data; @@ -504,7 +516,7 @@ static bool pa_environment(unsigned cmd, void *data) { static void pa_video_refresh(const void *data, unsigned width, unsigned height, size_t pitch) { if (data && !should_quit) { pa_track_render(); - plat_video_process(data, width, height, pitch); + video_process(data, width, height, pitch); } } @@ -675,6 +687,8 @@ int core_load_content(struct content *content) { sample_rate = av_info.timing.sample_rate; frame_rate = av_info.timing.fps; aspect_ratio = av_info.geometry.aspect_ratio; + + video_set_geometry(&av_info.geometry); plat_reinit(); #ifdef MMENU @@ -740,6 +754,7 @@ void core_close(void) { extensions = NULL; options_free(); + video_deinit(); if (current_core.handle) { dlclose(current_core.handle); diff --git a/patches/dosbox-pure/1000-funkey-s-support.patch b/patches/dosbox-pure/1000-funkey-s-support.patch new file mode 100644 index 0000000..27ef8f7 --- /dev/null +++ b/patches/dosbox-pure/1000-funkey-s-support.patch @@ -0,0 +1,30 @@ +diff --git a/Makefile b/Makefile +index f0acd51..8ad5a68 100644 +--- a/Makefile ++++ b/Makefile +@@ -104,6 +104,16 @@ else ifeq ($(platform),ctr) + COMMONFLAGS += -fomit-frame-pointer -fstrict-aliasing -ffast-math -fpermissive + COMMONFLAGS += -I$(DEVKITPRO)/libctru/include + STATIC_LINKING = 1 ++else ifeq ($(platform),classic_armv7_a7) ++ OUTNAME := dosbox_pure_libretro.so ++ CXX := $(CROSS_COMPILE)g++ ++ LDFLAGS := -Wl,--gc-sections -fno-ident ++ COMMONFLAGS += -pthread ++ CPUFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve ++ STRIPCMD := $(CROSS_COMPILE)strip --strip-all ++ ifeq ($(DEBUG), 1) ++ BUILD = DEBUG ++ endif + else ifeq ($(platform),ngc) + OUTNAME := dosbox_pure_libretro_ngc.a + CXX := $(DEVKITPPC)/bin/powerpc-eabi-g++ +@@ -200,6 +210,8 @@ else + BUILDDIR := release + ifeq ($(platform),vita) + CFLAGS := -DNDEBUG -O3 -fno-ident -fno-partial-inlining ++ else ifeq ($(platform),classic_armv7_a7) ++ CFLAGS := -DNDEBUG -Ofast -fno-ident + else + CFLAGS := -DNDEBUG -O2 -fno-ident + endif diff --git a/video.c b/video.c new file mode 100644 index 0000000..99ac2a6 --- /dev/null +++ b/video.c @@ -0,0 +1,78 @@ +#include "video.h" +#include "main.h" +#include "plat.h" + +static struct { + unsigned max_width; + unsigned max_height; + enum retro_pixel_format pixel_format; + uint16_t *buffer; +} screen_def; + +static void video_alloc_convert_buffer( + unsigned new_width, + unsigned new_height, + enum retro_pixel_format new_format +) { + if (new_width == screen_def.max_width && + new_height == screen_def.max_height && + new_format == screen_def.pixel_format) + return; + + if (screen_def.buffer) { + free(screen_def.buffer); + screen_def.buffer = NULL; + } + + if ((new_width > 0 || new_height > 0) && new_format == RETRO_PIXEL_FORMAT_XRGB8888) { + screen_def.buffer = malloc(new_width * new_height * sizeof(uint16_t)); + if (!screen_def.buffer) + PA_FATAL("Can't allocate buffer for color format conversion\n"); + } +} + +void video_set_geometry(struct retro_game_geometry *geometry) { + video_alloc_convert_buffer(geometry->max_width, + geometry->max_height, + screen_def.pixel_format); + + screen_def.max_width = geometry->max_width; + screen_def.max_height = geometry->max_height; +} + +void video_set_pixel_format(enum retro_pixel_format format) { + video_alloc_convert_buffer(screen_def.max_width, + screen_def.max_height, + format); + + screen_def.pixel_format = format; +} + +void video_process(const void *data, unsigned width, unsigned height, size_t pitch) { + const uint32_t *input = data; + uint16_t *output = screen_def.buffer; + size_t extra = pitch / sizeof(uint32_t) - width; + + if (screen_def.pixel_format != RETRO_PIXEL_FORMAT_XRGB8888) + return plat_video_process(data, width, height, pitch); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + *output = (*input & 0xF80000) >> 8; + *output |= (*input & 0xFC00) >> 5; + *output |= (*input & 0xF8) >> 3; + input++; + output++; + } + + input += extra; + } + + plat_video_process(screen_def.buffer, width, height, width * sizeof(uint16_t)); +} + +void video_deinit(void) { + free(screen_def.buffer); + screen_def.buffer = NULL; +} + diff --git a/video.h b/video.h new file mode 100644 index 0000000..15fa2ca --- /dev/null +++ b/video.h @@ -0,0 +1,11 @@ +#ifndef __VIDEO_H__ +#define __VIDEO_H__ + +#include "libretro.h" + +void video_set_pixel_format(enum retro_pixel_format format); +void video_set_geometry(struct retro_game_geometry *geometry); +void video_process(const void *data, unsigned width, unsigned height, size_t pitch); +void video_deinit(void); + +#endif -- cgit v1.2.3