From ce8f66bc071f153e2a55d696a0cafa6f2b5787f6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 17 Dec 2021 03:30:13 +0100 Subject: [PATCH 1/6] Reduced the texture size back 2048x2048. --- src/unix/unix_sdl.c | 6 +++--- src/video/video.c | 2 +- src/win/win_sdl.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index 4c309144f..356305d1c 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -134,9 +134,9 @@ sdl_blit_shim(int x, int y, int w, int h) params.w = w; params.h = h; if (!(!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL))) - video_copy(interpixels, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t)); + video_copy(interpixels, &(buffer32->line[y][x]), h * 2048 * sizeof(uint32_t)); if (screenshots) - video_screenshot(interpixels, 0, 0, (2048 + 64)); + video_screenshot(interpixels, 0, 0, 2048); blitreq = 1; video_blit_complete(); } @@ -198,7 +198,7 @@ sdl_blit(int x, int y, int w, int h) r_src.y = y; r_src.w = w; r_src.h = h; - SDL_UpdateTexture(sdl_tex, &r_src, interpixels, (2048 + 64) * 4); + SDL_UpdateTexture(sdl_tex, &r_src, interpixels, 2048 * 4); blitreq = 0; sdl_real_blit(&r_src); diff --git a/src/video/video.c b/src/video/video.c index 5118b886f..e3ff2200c 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -831,7 +831,7 @@ video_init(void) } /* Account for overscan. */ - buffer32 = create_bitmap(2048 + 64, 2048 + 64); + buffer32 = create_bitmap(2048, 2048); for (c = 0; c < 64; c++) { cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index af876540d..3a898f43c 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -244,10 +244,10 @@ sdl_blit(int x, int y, int w, int h) SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch); - video_copy(pixeldata, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t)); + video_copy(pixeldata, &(buffer32->line[y][x]), h * 2048 * sizeof(uint32_t)); if (screenshots) - video_screenshot((uint32_t *) pixeldata, 0, 0, (2048 + 64)); + video_screenshot((uint32_t *) pixeldata, 0, 0, 2048); SDL_UnlockTexture(sdl_tex); @@ -358,7 +358,7 @@ sdl_init_texture(void) sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, (2048 + 64), (2048 + 64)); + SDL_TEXTUREACCESS_STREAMING, 2048, 2048); } From 84ff7ab6ffb3b9473232312da9a68b3d95d42f9e Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 17 Dec 2021 03:44:22 +0100 Subject: [PATCH 2/6] Fixed OpenGL 3.0 core. --- src/win/win_opengl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c index 13b8c4fb7..bb9afd7be 100644 --- a/src/win/win_opengl.c +++ b/src/win/win_opengl.c @@ -62,10 +62,10 @@ typedef LONG atomic_flag; static const int INIT_WIDTH = 640; static const int INIT_HEIGHT = 400; -static const int BUFFERPIXELS = 4460544; /* Same size as render_buffer, pow(2048+64,2). */ -static const int BUFFERBYTES = 17842176; /* Pixel is 4 bytes. */ +static const int BUFFERPIXELS = 4194304; /* Same size as render_buffer, pow(2048+64,2). */ +static const int BUFFERBYTES = 16777216; /* Pixel is 4 bytes. */ static const int BUFFERCOUNT = 3; /* How many buffers to use for pixel transfer (2-3 is commonly recommended). */ -static const int ROW_LENGTH = 2112; /* Source buffer row lenght (including padding) */ +static const int ROW_LENGTH = 2048; /* Source buffer row lenght (including padding) */ /** * @brief A dedicated OpenGL thread. From 707acadd364eedaaba5bf28c597a0ef89cf1dd63 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 17 Dec 2021 03:49:54 +0100 Subject: [PATCH 3/6] Replaced the Win32 threads with the proven to be better performing C++11 threads. --- src/CMakeLists.txt | 2 +- src/cpp11_thread.cpp | 133 ++++++++++++++++++++++++++++++ src/win/CMakeLists.txt | 4 +- src/win/Makefile.mingw | 4 +- src/win/win_thread.c | 183 ----------------------------------------- 5 files changed, 138 insertions(+), 188 deletions(-) create mode 100644 src/cpp11_thread.cpp delete mode 100644 src/win/win_thread.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7e815c5e9..f2d638c2c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,7 +34,7 @@ endif() # WIN32 marks us as a GUI app on Windows # MACOSX_BUNDLE prepares a macOS application bundle including with the app icon -add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c +add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c cpp11_thread.cpp log.c random.c timer.c io.c acpi.c apm.c dma.c ddma.c nmi.c pic.c pit.c port_6x.c port_92.c ppi.c pci.c mca.c usb.c device.c nvr.c nvr_at.c nvr_ps2.c rtmidi_midi.cpp ${APP_ICON_MACOSX}) diff --git a/src/cpp11_thread.cpp b/src/cpp11_thread.cpp new file mode 100644 index 000000000..96eb4a2e1 --- /dev/null +++ b/src/cpp11_thread.cpp @@ -0,0 +1,133 @@ +#include +#include +#include + +#include <86box/plat.h> + +struct event_cpp11_t +{ + std::condition_variable cond; + std::mutex mutex; + bool state = false; +}; + +extern "C" { + +thread_t * +thread_create(void (*thread_rout)(void *param), void *param) +{ + auto thread = new std::thread([thread_rout, param] { + thread_rout(param); + }); + return thread; +} + +mutex_t * +thread_create_mutex_with_spin_count(unsigned int spin_count) +{ + /* Setting spin count of a mutex is not possible with pthreads. */ + return thread_create_mutex(); +} + +int +thread_wait(thread_t *arg, int timeout) +{ + (void) timeout; + auto thread = reinterpret_cast(arg); + thread->join(); + return 0; +} + +mutex_t * +thread_create_mutex(void) +{ + auto mutex = new std::mutex; + return mutex; +} + +int +thread_wait_mutex(mutex_t *_mutex) +{ + if (_mutex == nullptr) + return(0); + auto mutex = reinterpret_cast(_mutex); + mutex->lock(); + return 1; +} + + +int +thread_release_mutex(mutex_t *_mutex) +{ + if (_mutex == nullptr) + return(0); + auto mutex = reinterpret_cast(_mutex); + mutex->unlock(); + return 1; +} + + +void +thread_close_mutex(mutex_t *_mutex) +{ + auto mutex = reinterpret_cast(_mutex); + delete mutex; +} + +event_t * +thread_create_event() +{ + auto ev = new event_cpp11_t; + return ev; +} + +int +thread_wait_event(event_t *handle, int timeout) +{ + auto event = reinterpret_cast(handle); + auto lock = std::unique_lock(event->mutex); + + if (timeout < 0) { + event->cond.wait(lock, [event] { return event->state; }); + } else { + auto to = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout); + std::cv_status status; + + do { + status = event->cond.wait_until(lock, to); + } while ((status != std::cv_status::timeout) && !event->state); + + if (status == std::cv_status::timeout) { + return 1; + } + } + return 0; +} + +void +thread_set_event(event_t *handle) +{ + auto event = reinterpret_cast(handle); + { + auto lock = std::unique_lock(event->mutex); + event->state = true; + } + event->cond.notify_all(); +} + +void +thread_reset_event(event_t *handle) +{ + auto event = reinterpret_cast(handle); + auto lock = std::unique_lock(event->mutex); + event->state = false; +} + +void +thread_destroy_event(event_t *handle) +{ + auto event = reinterpret_cast(handle); + delete event; +} + +} diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index 301544798..304ff8d68 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -15,8 +15,8 @@ enable_language(RC) -add_library(plat OBJECT win.c win_dynld.c win_cdrom.c win_thread.c - win_keyboard.c win_crashdump.c win_mouse.c) +add_library(plat OBJECT win.c win_dynld.c win_cdrom.c win_keyboard.c + win_crashdump.c win_mouse.c) add_library(ui OBJECT win_ui.c win_icon.c win_stbar.c win_sdl.c win_dialog.c win_about.c win_settings.c win_devconf.c win_snd_gain.c win_specify_dim.c win_new_floppy.c diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index e3199b319..4ef41f2e6 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -464,7 +464,7 @@ CXXFLAGS := $(CFLAGS) ######################################################################### # Create the (final) list of objects to build. # ######################################################################### -MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ +MAINOBJ := 86box.o config.o cpp11_thread.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ nmi.o pic.o pit.o port_6x.o port_92.o ppi.o pci.o mca.o \ usb.o device.o nvr.o nvr_at.o nvr_ps2.o rtmidi_midi.o \ $(VNCOBJ) @@ -672,7 +672,7 @@ VOODOOOBJ := vid_voodoo.o vid_voodoo_banshee.o \ vid_voodoo_texture.o PLATOBJ := win.o \ - win_dynld.o win_thread.o \ + win_dynld.o \ win_cdrom.o win_keyboard.o \ win_crashdump.o \ win_mouse.o diff --git a/src/win/win_thread.c b/src/win/win_thread.c deleted file mode 100644 index f8d81fa86..000000000 --- a/src/win/win_thread.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implement threads and mutexes for the Win32 platform. - * - * - * - * Authors: Sarah Walker, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/plat.h> - - -typedef struct { - HANDLE handle; -} win_event_t; - - -thread_t * -thread_create(void (*func)(void *param), void *param) -{ - uintptr_t bt = _beginthread(func, 0, param); - return((thread_t *)bt); -} - - -int -thread_wait(thread_t *arg, int timeout) -{ - if (arg == NULL) return(0); - - if (timeout == -1) - timeout = INFINITE; - - if (WaitForSingleObject(arg, timeout)) return(1); - - return(0); -} - - -event_t * -thread_create_event(void) -{ - win_event_t *ev = malloc(sizeof(win_event_t)); - - ev->handle = CreateEvent(NULL, FALSE, FALSE, NULL); - - return((event_t *)ev); -} - - -void -thread_set_event(event_t *arg) -{ - win_event_t *ev = (win_event_t *)arg; - - if (arg == NULL) return; - - SetEvent(ev->handle); -} - - -void -thread_reset_event(event_t *arg) -{ - win_event_t *ev = (win_event_t *)arg; - - if (arg == NULL) return; - - ResetEvent(ev->handle); -} - - -int -thread_wait_event(event_t *arg, int timeout) -{ - win_event_t *ev = (win_event_t *)arg; - - if (arg == NULL) return(0); - - if (ev->handle == NULL) return(0); - - if (timeout == -1) - timeout = INFINITE; - - if (WaitForSingleObject(ev->handle, timeout)) return(1); - - return(0); -} - - -void -thread_destroy_event(event_t *arg) -{ - win_event_t *ev = (win_event_t *)arg; - - if (arg == NULL) return; - - CloseHandle(ev->handle); - - free(ev); -} - - -mutex_t * -thread_create_mutex(void) -{ - mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION)); - - InitializeCriticalSection(mutex); - - return mutex; -} - - -mutex_t * -thread_create_mutex_with_spin_count(unsigned int spin_count) -{ - mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION)); - - InitializeCriticalSectionAndSpinCount(mutex, spin_count); - - return mutex; -} - - -int -thread_wait_mutex(mutex_t *mutex) -{ - if (mutex == NULL) return(0); - - LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex; - - EnterCriticalSection(critsec); - - return 1; -} - - -int -thread_release_mutex(mutex_t *mutex) -{ - if (mutex == NULL) return(0); - - LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex; - - LeaveCriticalSection(critsec); - - return 1; -} - - -void -thread_close_mutex(mutex_t *mutex) -{ - if (mutex == NULL) return; - - LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex; - - DeleteCriticalSection(critsec); - - free(critsec); -} From 7df9e2a45437e1383fc03241ebbc5ad269a19bc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Fri, 17 Dec 2021 06:59:53 +0100 Subject: [PATCH 4/6] Add a compile option to choose between thread implementations --- CMakeLists.txt | 1 + src/CMakeLists.txt | 6 +- src/unix/CMakeLists.txt | 12 ++- src/win/CMakeLists.txt | 4 + src/win/Makefile.mingw | 13 ++- src/win/win_thread.c | 183 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 212 insertions(+), 7 deletions(-) create mode 100644 src/win/win_thread.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 5299448f3..5db0f0108 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ option(MUNT "MUNT" ON) option(VRAMDUMP "Video RAM dumping" OFF) option(DINPUT "DirectInput" OFF) option(DISCORD "Discord integration" ON) +option(CPPTHRAD "C++11 threads" ON) option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f2d638c2c..142fdfabd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,10 +34,14 @@ endif() # WIN32 marks us as a GUI app on Windows # MACOSX_BUNDLE prepares a macOS application bundle including with the app icon -add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c cpp11_thread.cpp log.c random.c timer.c io.c acpi.c apm.c +add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c dma.c ddma.c nmi.c pic.c pit.c port_6x.c port_92.c ppi.c pci.c mca.c usb.c device.c nvr.c nvr_at.c nvr_ps2.c rtmidi_midi.cpp ${APP_ICON_MACOSX}) +if(CPPTHREADS) + target_sources(plat PRIVATE cpp11_thread.cpp) +endif() + if(APPLE) target_link_libraries(86Box "-framework AppKit") endif() diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index e21265370..7cd52879b 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -8,7 +8,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") else() set(PLAT_SOURCES unix_midi.c) endif() -add_library(plat STATIC ${PLAT_SOURCES} unix_thread.c) +add_library(plat STATIC ${PLAT_SOURCES}) add_library(ui STATIC unix.c unix_sdl.c unix_cdrom.c) target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64) target_link_libraries(ui dl) @@ -28,6 +28,10 @@ if (ALSA_FOUND) target_link_libraries(plat ALSA::ALSA) endif() -set(THREADS_PREFER_PTHREAD_FLAG TRUE) -find_package(Threads REQUIRED) -target_link_libraries(86Box Threads::Threads) +if (NOT CPPTHREADS) + target_sources(plat PRIVATE unix_thread.c) + + set(THREADS_PREFER_PTHREAD_FLAG TRUE) + find_package(Threads REQUIRED) + target_link_libraries(86Box Threads::Threads) +endif() diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index 304ff8d68..9b0016e6f 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -23,6 +23,10 @@ add_library(ui OBJECT win_ui.c win_icon.c win_stbar.c win_sdl.c win_dialog.c win win_jsconf.c win_media_menu.c win_preferences.c win_discord.c glad.c win_opengl.c win_opengl_glslp.c 86Box.rc) +if(NOT CPPTHREADS) + target_sources(plat PRIVATE win_thread.c) +endif() + if(MSVC) # MSVC complains when we include the manifest from 86Box.rc... # On the bright side, CMake supports passing the manifest as a source diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 4ef41f2e6..d7bf837da 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -163,6 +163,9 @@ endif ifndef DYNAREC DYNAREC := y endif +ifndef CPPTHREADS + CPPTHREADS := cpp11 +endif ifeq ($(DYNAREC), y) ifeq ($(ARM), y) ifeq ($(NEW_DYNAREC), n) @@ -370,6 +373,12 @@ MUNTOBJ := midi_mt32.o \ Synth.o Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o endif +ifeq ($(CPPTHREADS), y) +THREADOBJ := cpp11_thread.o +else +THREADOBJ := win_thread.o +endif + ifeq ($(VNC), y) OPTS += -DUSE_VNC RFLAGS += -DUSE_VNC @@ -464,7 +473,7 @@ CXXFLAGS := $(CFLAGS) ######################################################################### # Create the (final) list of objects to build. # ######################################################################### -MAINOBJ := 86box.o config.o cpp11_thread.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ +MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ nmi.o pic.o pit.o port_6x.o port_92.o ppi.o pci.o mca.o \ usb.o device.o nvr.o nvr_at.o nvr_ps2.o rtmidi_midi.o \ $(VNCOBJ) @@ -693,7 +702,7 @@ endif OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \ $(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) $(MINIVHDOBJ) \ $(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) $(VOODOOOBJ) \ - $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ) + $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ) $(THREADOBJ) ifdef EXOBJ OBJ += $(EXOBJ) endif diff --git a/src/win/win_thread.c b/src/win/win_thread.c new file mode 100644 index 000000000..f8d81fa86 --- /dev/null +++ b/src/win/win_thread.c @@ -0,0 +1,183 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implement threads and mutexes for the Win32 platform. + * + * + * + * Authors: Sarah Walker, + * Fred N. van Kempen, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2017,2018 Fred N. van Kempen. + */ +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#include +#undef BITMAP +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/plat.h> + + +typedef struct { + HANDLE handle; +} win_event_t; + + +thread_t * +thread_create(void (*func)(void *param), void *param) +{ + uintptr_t bt = _beginthread(func, 0, param); + return((thread_t *)bt); +} + + +int +thread_wait(thread_t *arg, int timeout) +{ + if (arg == NULL) return(0); + + if (timeout == -1) + timeout = INFINITE; + + if (WaitForSingleObject(arg, timeout)) return(1); + + return(0); +} + + +event_t * +thread_create_event(void) +{ + win_event_t *ev = malloc(sizeof(win_event_t)); + + ev->handle = CreateEvent(NULL, FALSE, FALSE, NULL); + + return((event_t *)ev); +} + + +void +thread_set_event(event_t *arg) +{ + win_event_t *ev = (win_event_t *)arg; + + if (arg == NULL) return; + + SetEvent(ev->handle); +} + + +void +thread_reset_event(event_t *arg) +{ + win_event_t *ev = (win_event_t *)arg; + + if (arg == NULL) return; + + ResetEvent(ev->handle); +} + + +int +thread_wait_event(event_t *arg, int timeout) +{ + win_event_t *ev = (win_event_t *)arg; + + if (arg == NULL) return(0); + + if (ev->handle == NULL) return(0); + + if (timeout == -1) + timeout = INFINITE; + + if (WaitForSingleObject(ev->handle, timeout)) return(1); + + return(0); +} + + +void +thread_destroy_event(event_t *arg) +{ + win_event_t *ev = (win_event_t *)arg; + + if (arg == NULL) return; + + CloseHandle(ev->handle); + + free(ev); +} + + +mutex_t * +thread_create_mutex(void) +{ + mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION)); + + InitializeCriticalSection(mutex); + + return mutex; +} + + +mutex_t * +thread_create_mutex_with_spin_count(unsigned int spin_count) +{ + mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION)); + + InitializeCriticalSectionAndSpinCount(mutex, spin_count); + + return mutex; +} + + +int +thread_wait_mutex(mutex_t *mutex) +{ + if (mutex == NULL) return(0); + + LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex; + + EnterCriticalSection(critsec); + + return 1; +} + + +int +thread_release_mutex(mutex_t *mutex) +{ + if (mutex == NULL) return(0); + + LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex; + + LeaveCriticalSection(critsec); + + return 1; +} + + +void +thread_close_mutex(mutex_t *mutex) +{ + if (mutex == NULL) return; + + LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex; + + DeleteCriticalSection(critsec); + + free(critsec); +} From 275919859ace287af2189da319bfe95cbb2fd9e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Fri, 17 Dec 2021 07:41:07 +0100 Subject: [PATCH 5/6] Fix typos --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 +- src/unix/CMakeLists.txt | 8 ++++---- src/win/Makefile.mingw | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5db0f0108..2070e3a50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,7 +64,7 @@ option(MUNT "MUNT" ON) option(VRAMDUMP "Video RAM dumping" OFF) option(DINPUT "DirectInput" OFF) option(DISCORD "Discord integration" ON) -option(CPPTHRAD "C++11 threads" ON) +option(CPPTHREADS "C++11 threads" ON) option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 142fdfabd..742e8a1af 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,7 +39,7 @@ add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c log.c random.c timer.c device.c nvr.c nvr_at.c nvr_ps2.c rtmidi_midi.cpp ${APP_ICON_MACOSX}) if(CPPTHREADS) - target_sources(plat PRIVATE cpp11_thread.cpp) + target_sources(86Box PRIVATE cpp11_thread.cpp) endif() if(APPLE) diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index 7cd52879b..22a424a3a 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -30,8 +30,8 @@ endif() if (NOT CPPTHREADS) target_sources(plat PRIVATE unix_thread.c) - - set(THREADS_PREFER_PTHREAD_FLAG TRUE) - find_package(Threads REQUIRED) - target_link_libraries(86Box Threads::Threads) endif() + +set(THREADS_PREFER_PTHREAD_FLAG TRUE) +find_package(Threads REQUIRED) +target_link_libraries(86Box Threads::Threads) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index d7bf837da..d7a676713 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -164,7 +164,7 @@ ifndef DYNAREC DYNAREC := y endif ifndef CPPTHREADS - CPPTHREADS := cpp11 + CPPTHREADS := y endif ifeq ($(DYNAREC), y) ifeq ($(ARM), y) From e0a73a99ec29faafdd5149839093f5a27265fc64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Fri, 17 Dec 2021 08:57:00 +0100 Subject: [PATCH 6/6] Turn the RtMidi module into a full standalone MIDI module Removes the now-redundant platform MIDI infrastructure --- src/86box.c | 1 - src/CMakeLists.txt | 2 +- src/config.c | 1 - src/include/86box/midi.h | 3 +- src/include/86box/midi_input.h | 1 - src/include/86box/midi_rtmidi.h | 13 + src/include/86box/midi_system.h | 1 - src/include/86box/plat_midi.h | 15 - src/sound/CMakeLists.txt | 2 +- src/sound/midi.c | 6 +- .../midi_rtmidi.cpp} | 152 ++++++-- src/sound/midi_system.c | 139 -------- src/unix/CMakeLists.txt | 34 +- src/unix/linux_midi_alsa.c | 326 ------------------ src/unix/unix_midi.c | 57 --- src/win/Makefile.mingw | 4 +- src/win/win.c | 1 - src/win/win_devconf.c | 10 +- src/win/win_settings.c | 1 - src/win/win_ui.c | 1 - 20 files changed, 148 insertions(+), 622 deletions(-) delete mode 100644 src/include/86box/midi_input.h create mode 100644 src/include/86box/midi_rtmidi.h delete mode 100644 src/include/86box/midi_system.h delete mode 100644 src/include/86box/plat_midi.h rename src/{rtmidi_midi.cpp => sound/midi_rtmidi.cpp} (59%) delete mode 100644 src/sound/midi_system.c delete mode 100644 src/unix/linux_midi_alsa.c delete mode 100644 src/unix/unix_midi.c diff --git a/src/86box.c b/src/86box.c index 045b3bd0a..132551e79 100644 --- a/src/86box.c +++ b/src/86box.c @@ -90,7 +90,6 @@ #include <86box/video.h> #include <86box/ui.h> #include <86box/plat.h> -#include <86box/plat_midi.h> #include <86box/version.h> diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 742e8a1af..1d508b248 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,7 +36,7 @@ endif() # MACOSX_BUNDLE prepares a macOS application bundle including with the app icon add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c dma.c ddma.c nmi.c pic.c pit.c port_6x.c port_92.c ppi.c pci.c mca.c usb.c - device.c nvr.c nvr_at.c nvr_ps2.c rtmidi_midi.cpp ${APP_ICON_MACOSX}) + device.c nvr.c nvr_at.c nvr_ps2.c ${APP_ICON_MACOSX}) if(CPPTHREADS) target_sources(86Box PRIVATE cpp11_thread.cpp) diff --git a/src/config.c b/src/config.c index d41da7a4e..06eda4ff3 100644 --- a/src/config.c +++ b/src/config.c @@ -64,7 +64,6 @@ #include <86box/snd_mpu401.h> #include <86box/video.h> #include <86box/plat.h> -#include <86box/plat_midi.h> #include <86box/plat_dir.h> #include <86box/ui.h> diff --git a/src/include/86box/midi.h b/src/include/86box/midi.h index 5ff8b505e..e80fe79d6 100644 --- a/src/include/86box/midi.h +++ b/src/include/86box/midi.h @@ -95,7 +95,8 @@ extern void midi_in_sysex(uint8_t *buffer, uint32_t len); #define MIDI_INPUT_INTERNAL_NAME "midi_in" #ifdef EMU_DEVICE_H -extern const device_t system_midi_device; +extern const device_t rtmidi_device; +extern const device_t rtmidi_input_device; #ifdef USE_FLUIDSYNTH extern const device_t fluidsynth_device; #endif diff --git a/src/include/86box/midi_input.h b/src/include/86box/midi_input.h deleted file mode 100644 index 163d6fa91..000000000 --- a/src/include/86box/midi_input.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t midi_input_device; diff --git a/src/include/86box/midi_rtmidi.h b/src/include/86box/midi_rtmidi.h new file mode 100644 index 000000000..beaccdf54 --- /dev/null +++ b/src/include/86box/midi_rtmidi.h @@ -0,0 +1,13 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +extern int rtmidi_get_num_devs(void); +extern void rtmidi_get_dev_name(int num, char *s); +extern int rtmidi_in_get_num_devs(void); +extern void rtmidi_in_get_dev_name(int num, char *s); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/include/86box/midi_system.h b/src/include/86box/midi_system.h deleted file mode 100644 index b79bbf96f..000000000 --- a/src/include/86box/midi_system.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t system_midi_device; diff --git a/src/include/86box/plat_midi.h b/src/include/86box/plat_midi.h deleted file mode 100644 index 933e49ee6..000000000 --- a/src/include/86box/plat_midi.h +++ /dev/null @@ -1,15 +0,0 @@ -extern void plat_midi_init(void); -extern void plat_midi_close(void); - -extern void plat_midi_play_msg(uint8_t *msg); -extern void plat_midi_play_sysex(uint8_t *sysex, unsigned int len); -extern int plat_midi_write(uint8_t val); - -extern int plat_midi_get_num_devs(void); -extern void plat_midi_get_dev_name(int num, char *s); - -extern void plat_midi_input_init(void); -extern void plat_midi_input_close(void); - -extern int plat_midi_in_get_num_devs(void); -extern void plat_midi_in_get_dev_name(int num, char *s); diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index f5a6435c4..553f3d4f2 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -14,7 +14,7 @@ # add_library(snd OBJECT sound.c openal.c snd_opl.c snd_opl_nuked.c snd_resid.cc - midi.c midi_system.c snd_speaker.c snd_pssj.c snd_lpt_dac.c snd_ac97_codec.c snd_ac97_via.c + midi.c midi_rtmidi.cpp snd_speaker.c snd_pssj.c snd_lpt_dac.c snd_ac97_codec.c snd_ac97_via.c snd_lpt_dss.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c) diff --git a/src/sound/midi.c b/src/sound/midi.c index e985f277f..8a195e2f9 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -28,9 +28,7 @@ #include <86box/86box.h> #include <86box/device.h> #include <86box/plat.h> -#include <86box/plat_midi.h> #include <86box/midi.h> -#include <86box/midi_input.h> int midi_device_current = 0; @@ -84,14 +82,14 @@ static const MIDI_DEVICE devices[] = { "mt32", &mt32_device }, { "cm32l", &cm32l_device }, #endif - { SYSTEM_MIDI_INTERNAL_NAME, &system_midi_device }, + { SYSTEM_MIDI_INTERNAL_NAME, &rtmidi_device }, { "", NULL } }; static const MIDI_IN_DEVICE midi_in_devices[] = { { "none", NULL }, - { MIDI_INPUT_INTERNAL_NAME, &midi_input_device }, + { MIDI_INPUT_INTERNAL_NAME, &rtmidi_input_device }, { "", NULL } }; diff --git a/src/rtmidi_midi.cpp b/src/sound/midi_rtmidi.cpp similarity index 59% rename from src/rtmidi_midi.cpp rename to src/sound/midi_rtmidi.cpp index 45e34197a..e150159e4 100644 --- a/src/rtmidi_midi.cpp +++ b/src/sound/midi_rtmidi.cpp @@ -30,8 +30,9 @@ extern "C" { #include <86box/86box.h> +#include <86box/device.h> #include <86box/midi.h> -#include <86box/plat_midi.h> +#include <86box/midi_rtmidi.h> #include <86box/config.h> @@ -42,19 +43,43 @@ static const int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; int -plat_midi_write(uint8_t val) +rtmidi_write(uint8_t val) { return 0; } -void plat_midi_init(void) +void +rtmidi_play_msg(uint8_t *msg) { + if (midiout) + midiout->sendMessage(msg, midi_lengths[(msg[0] >> 4) & 7]); +} + + +void +rtmidi_play_sysex(uint8_t *sysex, unsigned int len) +{ + if (midiout) + midiout->sendMessage(sysex, len); +} + + +void* +rtmidi_init(const device_t *info) +{ + midi_device_t* dev = (midi_device_t*)malloc(sizeof(midi_device_t)); + memset(dev, 0, sizeof(midi_device_t)); + + dev->play_msg = rtmidi_play_msg; + dev->play_sysex = rtmidi_play_sysex; + dev->write = rtmidi_write; + try { if (!midiout) midiout = new RtMidiOut; } catch (RtMidiError& error) { - pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); - return; + pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); + return nullptr; } midi_out_id = config_get_int((char*)SYSTEM_MIDI_NAME, (char*)"midi", 0); @@ -70,14 +95,18 @@ void plat_midi_init(void) pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); delete midiout; midiout = nullptr; - return; + return nullptr; } } + + midi_init(dev); + + return dev; } void -plat_midi_close(void) +rtmidi_close(void *p) { if (!midiout) return; @@ -86,11 +115,13 @@ plat_midi_close(void) delete midiout; midiout = nullptr; + + midi_close(); } int -plat_midi_get_num_devs(void) +rtmidi_get_num_devs(void) { if (!midiout) { try { @@ -105,30 +136,14 @@ plat_midi_get_num_devs(void) void -plat_midi_play_msg(uint8_t *msg) -{ - if (midiout) - midiout->sendMessage(msg, midi_lengths[(msg[0] >> 4) & 7]); -} - - -void -plat_midi_get_dev_name(int num, char *s) +rtmidi_get_dev_name(int num, char *s) { strcpy(s, midiout->getPortName(num).c_str()); } void -plat_midi_play_sysex(uint8_t *sysex, unsigned int len) -{ - if (midiout) - midiout->sendMessage(sysex, len); -} - - -static void -plat_midi_callback(double timeStamp, std::vector *message, void *userData) +rtmidi_input_callback(double timeStamp, std::vector *message, void *userData) { if (message->size() <= 3) midi_in_msg(message->data()); @@ -137,15 +152,18 @@ plat_midi_callback(double timeStamp, std::vector *message, void * } -void -plat_midi_input_init(void) +void* +rtmidi_input_init(const device_t *info) { + midi_device_t* dev = (midi_device_t*)malloc(sizeof(midi_device_t)); + memset(dev, 0, sizeof(midi_device_t)); + try { if (!midiin) midiin = new RtMidiIn; } catch (RtMidiError& error) { pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); - return; + return nullptr; } midi_in_id = config_get_int((char*)SYSTEM_MIDI_NAME, (char*)"midi_input", 0); @@ -161,16 +179,24 @@ plat_midi_input_init(void) pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); delete midiin; midiin = nullptr; - return; + return nullptr; } } - midiin->setCallback(plat_midi_callback); + midiin->setCallback(rtmidi_input_callback); + + midi_in_init(dev, &midi_in); + + midi_in->midi_realtime = device_get_config_int("realtime"); + midi_in->thruchan = device_get_config_int("thruchan"); + midi_in->midi_clockout = device_get_config_int("clockout"); + + return dev; } void -plat_midi_input_close(void) +rtmidi_input_close(void* p) { midiin->cancelCallback(); midiin->closePort(); @@ -178,12 +204,12 @@ plat_midi_input_close(void) delete midiin; midiin = nullptr; - return; + midi_close(); } int -plat_midi_in_get_num_devs(void) +rtmidi_in_get_num_devs(void) { if (!midiin) { try { @@ -198,9 +224,65 @@ plat_midi_in_get_num_devs(void) void -plat_midi_in_get_dev_name(int num, char *s) +rtmidi_in_get_dev_name(int num, char *s) { strcpy(s, midiin->getPortName(num).c_str()); } +static const device_config_t system_midi_config[] = +{ + { + "midi", "MIDI out device", CONFIG_MIDI, "", 0 + }, + { + "", "", -1 + } +}; + +static const device_config_t midi_input_config[] = +{ + { + "midi_input", "MIDI in device", CONFIG_MIDI_IN, "", 0 + }, + { + "realtime", "MIDI Real time", CONFIG_BINARY, "", 0 + }, + { + "thruchan", "MIDI Thru", CONFIG_BINARY, "", 1 + }, + { + "clockout", "MIDI Clockout", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 + } +}; + +const device_t rtmidi_device = +{ + SYSTEM_MIDI_NAME, + 0, 0, + rtmidi_init, + rtmidi_close, + NULL, + { rtmidi_get_num_devs }, + NULL, + NULL, + system_midi_config +}; + + +const device_t rtmidi_input_device = +{ + MIDI_INPUT_NAME, + 0, 0, + rtmidi_input_init, + rtmidi_input_close, + NULL, + { rtmidi_in_get_num_devs }, + NULL, + NULL, + midi_input_config +}; + } diff --git a/src/sound/midi_system.c b/src/sound/midi_system.c deleted file mode 100644 index 1a577d932..000000000 --- a/src/sound/midi_system.c +++ /dev/null @@ -1,139 +0,0 @@ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/plat_midi.h> -#include <86box/midi.h> -#include <86box/midi_input.h> - - -void* system_midi_init(const device_t *info) -{ - midi_device_t* dev = malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); - - dev->play_msg = plat_midi_play_msg; - dev->play_sysex = plat_midi_play_sysex; - dev->write = plat_midi_write; - - plat_midi_init(); - - midi_init(dev); - - return dev; -} - -void* midi_input_init(const device_t *info) -{ - midi_device_t* dev = malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); - - plat_midi_input_init(); - - midi_in_init(dev, &midi_in); - - midi_in->midi_realtime = device_get_config_int("realtime"); - midi_in->thruchan = device_get_config_int("thruchan"); - midi_in->midi_clockout = device_get_config_int("clockout"); - - return dev; -} - -void system_midi_close(void* p) -{ - plat_midi_close(); - - midi_close(); -} - -void midi_input_close(void* p) -{ - plat_midi_input_close(); - - midi_close(); -} - -int system_midi_available(void) -{ - return plat_midi_get_num_devs(); -} - -int midi_input_available(void) -{ - return plat_midi_in_get_num_devs(); -} - -static const device_config_t system_midi_config[] = -{ - { - .name = "midi", - .description = "MIDI out device", - .type = CONFIG_MIDI, - .default_int = 0 - }, - { - .type = -1 - } -}; - -static const device_config_t midi_input_config[] = -{ - { - .name = "midi_input", - .description = "MIDI in device", - .type = CONFIG_MIDI_IN, - .default_int = 0 - }, - { - .name = "realtime", - .description = "MIDI Real time", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "thruchan", - .description = "MIDI Thru", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "clockout", - .description = "MIDI Clockout", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .type = -1 - } -}; - -const device_t system_midi_device = -{ - SYSTEM_MIDI_NAME, - 0, 0, - system_midi_init, - system_midi_close, - NULL, - { system_midi_available }, - NULL, - NULL, - system_midi_config -}; - - -const device_t midi_input_device = -{ - MIDI_INPUT_NAME, - 0, 0, - midi_input_init, - midi_input_close, - NULL, - { midi_input_available }, - NULL, - NULL, - midi_input_config -}; \ No newline at end of file diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index 22a424a3a..85961f920 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -1,32 +1,4 @@ -if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - find_package(ALSA) - if (ALSA_FOUND) - set(PLAT_SOURCES linux_midi_alsa.c) - else() - set(PLAT_SOURCES unix_midi.c) - endif() -else() - set(PLAT_SOURCES unix_midi.c) -endif() -add_library(plat STATIC ${PLAT_SOURCES}) -add_library(ui STATIC unix.c unix_sdl.c unix_cdrom.c) -target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64) -target_link_libraries(ui dl) - -find_package(SDL2 REQUIRED) -include_directories(${SDL2_INCLUDE_DIRS}) -if(MINGW) - target_link_libraries(ui SDL2::SDL2-static) -else() - if (TARGET SDL2::SDL2) - target_link_libraries(ui SDL2::SDL2) - else() - target_link_libraries(ui ${SDL2_LIBRARIES}) - endif() -endif() -if (ALSA_FOUND) - target_link_libraries(plat ALSA::ALSA) -endif() +add_library(plat OBJECT unix.c) if (NOT CPPTHREADS) target_sources(plat PRIVATE unix_thread.c) @@ -35,3 +7,7 @@ endif() set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) target_link_libraries(86Box Threads::Threads) + +add_library(ui OBJECT unix_sdl.c unix_cdrom.c) +target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64) +target_link_libraries(ui dl) diff --git a/src/unix/linux_midi_alsa.c b/src/unix/linux_midi_alsa.c deleted file mode 100644 index e3b009d6d..000000000 --- a/src/unix/linux_midi_alsa.c +++ /dev/null @@ -1,326 +0,0 @@ -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/midi.h> -#include <86box/plat.h> -#include <86box/plat_midi.h> - -#define MAX_MIDI_DEVICES 128 - -static struct -{ - int card; - int device; - int sub; - char name[50]; -} midi_devices[MAX_MIDI_DEVICES], midi_in_devices[MAX_MIDI_DEVICES]; - -static int midi_device_count = 0, midi_in_device_count = 0; - -static int midi_queried = 0, midi_in_queried = 0; - -static snd_rawmidi_t *midiout = NULL, *midiin = NULL; - -static void plat_midi_query() -{ - int status; - int card = -1; - - midi_queried = 1; - - if ((status = snd_card_next(&card)) < 0) - return; - - if (card < 0) - return; /*No cards*/ - - while (card >= 0) - { - char *shortname; - - if ((status = snd_card_get_name(card, &shortname)) >= 0) - { - snd_ctl_t *ctl; - char name[32]; - - sprintf(name, "hw:%i", card); - - if ((status = snd_ctl_open(&ctl, name, 0)) >= 0) - { - int device = -1; - - do - { - status = snd_ctl_rawmidi_next_device(ctl, &device); - if (status >= 0 && device != -1) - { - snd_rawmidi_info_t *info; - int sub_nr, sub; - - snd_rawmidi_info_alloca(&info); - snd_rawmidi_info_set_device(info, device); - snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); - snd_ctl_rawmidi_info(ctl, info); - sub_nr = snd_rawmidi_info_get_subdevices_count(info); - //pclog("sub_nr=%i\n",sub_nr); - - for (sub = 0; sub < sub_nr; sub++) - { - snd_rawmidi_info_set_subdevice(info, sub); - - if (snd_ctl_rawmidi_info(ctl, info) == 0) - { - //pclog("%s: MIDI device=%i:%i:%i\n", shortname, card, device,sub); - - midi_devices[midi_device_count].card = card; - midi_devices[midi_device_count].device = device; - midi_devices[midi_device_count].sub = sub; - snprintf(midi_devices[midi_device_count].name, 50, "%s (%i:%i:%i)", shortname, card, device, sub); - midi_device_count++; - if (midi_device_count >= MAX_MIDI_DEVICES) - return; - } - } - } - } while (device >= 0); - } - } - - if (snd_card_next(&card) < 0) - break; - } -} - -void plat_midi_init() -{ - char portname[32]; - int midi_id; - - if (!midi_queried) - plat_midi_query(); - - midi_id = config_get_int(SYSTEM_MIDI_NAME, "midi", 0); - - sprintf(portname, "hw:%i,%i,%i", midi_devices[midi_id].card, - midi_devices[midi_id].device, - midi_devices[midi_id].sub); - //pclog("Opening MIDI port %s\n", portname); - - if (snd_rawmidi_open(NULL, &midiout, portname, SND_RAWMIDI_SYNC) < 0) - { - //pclog("Failed to open MIDI\n"); - return; - } -} - -void plat_midi_close() -{ - if (midiout != NULL) - { - snd_rawmidi_close(midiout); - midiout = NULL; - } -} - -static int midi_pos, midi_len; -static uint8_t midi_command[4]; -static int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; -static int midi_insysex; -static uint8_t midi_sysex_data[65536]; - -int plat_midi_write(uint8_t val) -{ - return 0; -} - -void plat_midi_play_sysex(uint8_t *sysex, unsigned int len) -{ - if (midiout) - { - snd_rawmidi_write(midiout, (const void*)sysex, (size_t)len); - } -} - -void plat_midi_play_msg(uint8_t *msg) -{ - plat_midi_play_sysex(msg, midi_lengths[(msg[0] >> 4) & 7]); -} - -int plat_midi_get_num_devs() -{ - if (!midi_queried) - plat_midi_query(); - - return midi_device_count; -} - -void plat_midi_get_dev_name(int num, char *s) -{ - strcpy(s, midi_devices[num].name); -} - -static void plat_midi_query_in() -{ - int status; - int card = -1; - - midi_in_queried = 1; - - if ((status = snd_card_next(&card)) < 0) - return; - - if (card < 0) - return; /*No cards*/ - - while (card >= 0) - { - char *shortname; - - if ((status = snd_card_get_name(card, &shortname)) >= 0) - { - snd_ctl_t *ctl; - char name[32]; - - sprintf(name, "hw:%i", card); - - if ((status = snd_ctl_open(&ctl, name, 0)) >= 0) - { - int device = -1; - - do - { - status = snd_ctl_rawmidi_next_device(ctl, &device); - if (status >= 0 && device != -1) - { - snd_rawmidi_info_t *info; - int sub_nr, sub; - - snd_rawmidi_info_alloca(&info); - snd_rawmidi_info_set_device(info, device); - snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); - snd_ctl_rawmidi_info(ctl, info); - sub_nr = snd_rawmidi_info_get_subdevices_count(info); - //pclog("sub_nr=%i\n",sub_nr); - - for (sub = 0; sub < sub_nr; sub++) - { - snd_rawmidi_info_set_subdevice(info, sub); - - if (snd_ctl_rawmidi_info(ctl, info) == 0) - { - //pclog("%s: MIDI device=%i:%i:%i\n", shortname, card, device,sub); - - midi_in_devices[midi_device_count].card = card; - midi_in_devices[midi_device_count].device = device; - midi_in_devices[midi_device_count].sub = sub; - snprintf(midi_in_devices[midi_device_count].name, 50, "%s (%i:%i:%i)", shortname, card, device, sub); - midi_in_device_count++; - if (midi_in_device_count >= MAX_MIDI_DEVICES) - return; - } - } - } - } while (device >= 0); - } - } - - if (snd_card_next(&card) < 0) - break; - } -} -mutex_t* midiinmtx = NULL; - -static void plat_midi_in_thread(void* param) -{ - int sysexpos = 0; - uint8_t midimsg[3]; - while(1) - { - thread_wait_mutex(midiinmtx); - if (midiin == NULL) - { - thread_release_mutex(midiinmtx); - break; - } - if (snd_rawmidi_read(midiin, midimsg, 1) > 0) - { - if (midimsg[0] == 0xF0) - { - MIDI_InSysexBuf[sysexpos++] = 0xF0; - while(1) - { - snd_rawmidi_read(midiin, &MIDI_InSysexBuf[sysexpos++], 1); - if (MIDI_InSysexBuf[sysexpos - 1] == 0xF7) - { - midi_in_sysex(MIDI_InSysexBuf, sysexpos); - } - } - } - else if (midimsg[0] & 0x80) - { - int lengthofmsg = midi_lengths[(midimsg[0] >> 4) & 7] - 1; - snd_rawmidi_read(midiin, midimsg + 1, lengthofmsg); - midi_in_msg(midimsg); - } - } - thread_release_mutex(midiinmtx); - } -} - -void plat_midi_input_init(void) -{ - char portname[32]; - int midi_id; - snd_rawmidi_params_t* params; - int err; - - snd_rawmidi_params_malloc(¶ms); - if (!params) return; - if (!midi_in_queried) - plat_midi_query_in(); - - - midi_id = config_get_int(MIDI_INPUT_NAME, "midi_input", 0); - - sprintf(portname, "hw:%i,%i,%i", midi_in_devices[midi_id].card, - midi_in_devices[midi_id].device, - midi_in_devices[midi_id].sub); - //pclog("Opening MIDI port %s\n", portname); - - if (snd_rawmidi_open(NULL, &midiin, portname, SND_RAWMIDI_NONBLOCK) < 0) - { - //pclog("Failed to open MIDI\n"); - return; - } - midiin = thread_create_mutex(); - thread_create(plat_midi_in_thread, NULL); -} - -void plat_midi_input_close(void) -{ - if (midiinmtx) thread_wait_mutex(midiinmtx); - if (midiin != NULL) - { - snd_rawmidi_close(midiin); - midiin = NULL; - } - if (midiinmtx) - { - thread_release_mutex(midiinmtx); - thread_close_mutex(midiinmtx); - } - midiinmtx = NULL; -} - -int plat_midi_in_get_num_devs(void) -{ - if (!midi_queried) - plat_midi_query_in(); - - return midi_in_device_count; -} - -void plat_midi_in_get_dev_name(int num, char *s) -{ - strcpy(s, midi_in_devices[num].name); -} diff --git a/src/unix/unix_midi.c b/src/unix/unix_midi.c deleted file mode 100644 index c92820bef..000000000 --- a/src/unix/unix_midi.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -void plat_midi_init(void) -{ - -} - -void plat_midi_close(void) -{ - -} - -void plat_midi_play_msg(uint8_t *msg) -{ - -} - -void plat_midi_play_sysex(uint8_t *sysex, unsigned int len) -{ - -} - -int plat_midi_write(uint8_t val) -{ - return 0; -} - -int plat_midi_get_num_devs(void) -{ - return 0; -} - -void plat_midi_get_dev_name(int num, char *s) -{ - s[0] = ' '; - s[1] = 0; -} - -void plat_midi_input_init(void) -{ - -} - -void plat_midi_input_close(void) -{ - -} - -int plat_midi_in_get_num_devs(void) -{ - return 0; -} - -void plat_midi_in_get_dev_name(int num, char *s) -{ - s[0] = ' '; - s[1] = 0; -} \ No newline at end of file diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index d7a676713..6a596beae 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -475,7 +475,7 @@ CXXFLAGS := $(CFLAGS) ######################################################################### MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ nmi.o pic.o pit.o port_6x.o port_92.o ppi.o pci.o mca.o \ - usb.o device.o nvr.o nvr_at.o nvr_ps2.o rtmidi_midi.o \ + usb.o device.o nvr.o nvr_at.o nvr_ps2.o \ $(VNCOBJ) MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o smram.o spd.o sst_flash.o @@ -617,7 +617,7 @@ SNDOBJ := sound.o \ wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ wave8580_PST.o wave.o \ - midi.o midi_system.o \ + midi.o midi_rtmidi.o \ snd_speaker.o \ snd_pssj.o \ snd_lpt_dac.o snd_lpt_dss.o \ diff --git a/src/win/win.c b/src/win/win.c index 650e43ba8..9298aa7fd 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -46,7 +46,6 @@ #include <86box/video.h> #define GLOBAL #include <86box/plat.h> -#include <86box/plat_midi.h> #include <86box/ui.h> #ifdef USE_VNC # include <86box/vnc.h> diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index 0ca76c8d8..4f4ddc639 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -25,7 +25,7 @@ #include <86box/config.h> #include <86box/device.h> #include <86box/plat.h> -#include <86box/plat_midi.h> +#include <86box/midi_rtmidi.h> #include <86box/ui.h> #include <86box/win.h> #include @@ -97,9 +97,9 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) val_int = config_get_int((char *) config_device.name, (char *) config->name, config->default_int); - num = plat_midi_get_num_devs(); + num = rtmidi_get_num_devs(); for (c = 0; c < num; c++) { - plat_midi_get_dev_name(c, s); + rtmidi_get_dev_name(c, s); mbstowcs(lptsTemp, s, strlen(s) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); if (val_int == c) @@ -112,9 +112,9 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) val_int = config_get_int((char *) config_device.name, (char *) config->name, config->default_int); - num = plat_midi_in_get_num_devs(); + num = rtmidi_in_get_num_devs(); for (c = 0; c < num; c++) { - plat_midi_in_get_dev_name(c, s); + rtmidi_in_get_dev_name(c, s); mbstowcs(lptsTemp, s, strlen(s) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); if (val_int == c) diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 5d977ba1d..da91c271d 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -64,7 +64,6 @@ #include <86box/snd_mpu401.h> #include <86box/video.h> #include <86box/plat.h> -#include <86box/plat_midi.h> #include <86box/ui.h> #include <86box/win.h> #include "../disk/minivhd/minivhd.h" diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 703e3e414..5b1e8b809 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -39,7 +39,6 @@ #include <86box/nvr.h> #include <86box/video.h> #include <86box/vid_ega.h> // for update_overscan -#include <86box/plat_midi.h> #include <86box/plat_dynld.h> #include <86box/ui.h> #include <86box/win.h>