Merge branch '86Box:master' into nec-v20

This commit is contained in:
Jasmine Iwanek
2022-04-12 16:57:52 -04:00
committed by GitHub
29 changed files with 477 additions and 152 deletions

26
.ci/Jenkinsfile vendored
View File

@@ -16,20 +16,22 @@
*/
/* ['main builds', 'branch builds'] */
def repository = ['https://github.com/86Box/86Box.git', 'https://github.com/richardg867/86Box.git']
def repository = ['https://github.com/86Box/86Box.git', scm.userRemoteConfigs[0].url]
def commitBrowser = ['https://github.com/86Box/86Box/commit/%s', null]
def branch = ['master', 'cleanup30']
def branch = ['master', scm.branches[0].name]
def buildType = ['beta', 'alpha']
def buildBranch = env.JOB_BASE_NAME.contains('-') ? 1 : 0
def osArchs = [
'Windows': ['32', '64'],
'Linux': ['x86', 'x86_64', 'arm32', 'arm64']
'Linux': ['x86', 'x86_64', 'arm32', 'arm64'],
'macOS': ['x86_64']
]
def osFlags = [
'Windows': '-D QT=ON',
'Linux': '-D QT=ON'
'Linux': '-D QT=ON',
'macOS': '-D QT=ON'
]
def archNames = [
@@ -41,6 +43,11 @@ def archNames = [
'arm64': 'ARM (64-bit)'
]
def archNamesMac = [
'x86_64': 'Intel',
'arm64': 'Apple Silicon'
]
def dynarecNames = [
'ODR': 'Old Recompiler (recommended)',
'NDR': 'New Recompiler (beta)',
@@ -53,9 +60,7 @@ def dynarecArchs = [
'64': ['ODR', 'NDR'],
'x86_64': ['ODR', 'NDR'],
'arm32': ['NDR'],
'ARM32': ['NDR'],
'arm64': ['NDR'],
'ARM64': ['NDR']
'arm64': ['NDR']
]
def dynarecFlags = [
@@ -238,7 +243,7 @@ pipeline {
osArchs.each { os, thisOsArchs ->
def combinations = [:]
thisOsArchs.each { arch ->
def thisArchDynarecs = dynarecArchs[arch]
def thisArchDynarecs = dynarecArchs[arch.toLowerCase()]
if (!thisArchDynarecs)
thisArchDynarecs = ['NoDR']
thisArchDynarecs.each { dynarec ->
@@ -257,7 +262,10 @@ pipeline {
/* Run build process. */
def packageName = "${env.JOB_BASE_NAME}${dynarecSlugs[dynarec]}${presetSlugs[preset]}-$os-$arch$buildSuffix"
def ret = -1
dir("${dynarecNames[dynarec]}/$os - ${archNames[arch]}") {
def archName = archNames[arch]
if (os == 'macOS')
archName = archNamesMac[arch]
dir("${dynarecNames[dynarec]}/$os - $archName") {
ret = runBuild("-b \"$packageName\" \"$arch\" ${presetFlags[preset]} ${dynarecFlags[dynarec]} ${osFlags[os]} $buildFlags")
}

View File

@@ -28,9 +28,17 @@
# - Packaging the Discord DLL requires wget (MSYS should come with it)
# - For Linux builds:
# - Only Debian and derivatives are supported
# - dpkg and apt-get are called through sudo to manage dependencies
# - dpkg and apt-get are called through sudo to manage dependencies; make sure those
# are configured as NOPASSWD in /etc/sudoers if you're doing unattended builds
# - For macOS builds:
# - TBD
# - A standard MacPorts installation is required, with the following macports.conf settings:
# buildfromsource always
# build_arch x86_64 (or arm64)
# universal_archs (blank)
# ui_interactive no
# macosx_deployment_target 10.13
# - port is called through sudo to manage dependencies; make sure it is configured
# as NOPASSWD in /etc/sudoers if you're doing unattended builds
#
# Define common functions.
@@ -178,13 +186,16 @@ fi
echo [-] Building [$package_name] for [$arch] with flags [$cmake_flags]
# Determine CMake toolchain file for this architecture.
toolchain_prefix=flags-gcc
is_mac && toolchain_prefix=llvm-macos
case $arch in
32 | x86) toolchain="flags-gcc-i686";;
64 | x86_64) toolchain="flags-gcc-x86_64";;
ARM32 | arm32) toolchain="flags-gcc-armv7";;
ARM64 | arm64) toolchain="flags-gcc-aarch64";;
*) toolchain="flags-gcc-$arch";;
32 | x86) toolchain="$toolchain_prefix-i686";;
64 | x86_64) toolchain="$toolchain_prefix-x86_64";;
ARM32 | arm32) toolchain="$toolchain_prefix-armv7";;
ARM64 | arm64) toolchain="$toolchain_prefix-aarch64";;
*) toolchain="$toolchain_prefix-$arch";;
esac
[ ! -e "cmake/$toolchain.cmake" ] && toolchain=flags-gcc
# Perform platform-specific setup.
strip_binary=strip
@@ -313,11 +324,27 @@ then
fi
# Point CMake to the toolchain file.
cmake_flags_extra="$cmake_flags_extra -D \"CMAKE_TOOLCHAIN_FILE=cmake/$toolchain.cmake\""
[ -e "cmake/$toolchain.cmake" ] && cmake_flags_extra="$cmake_flags_extra -D \"CMAKE_TOOLCHAIN_FILE=cmake/$toolchain.cmake\""
elif is_mac
then
# macOS lacks nproc, but sysctl can do the same job.
alias nproc='sysctl -n hw.logicalcpu'
# Locate the MacPorts prefix.
macports="/opt/local"
[ -e "/opt/$arch/bin/port" ] && macports="/opt/$arch"
[ "$arch" = "x86_64" -a -e "/opt/intel/bin/port" ] && macports="/opt/intel"
# Install dependencies.
echo [-] Installing dependencies through MacPorts
sudo $macports/bin/port selfupdate
sudo $macports/bin/port install $(cat .ci/dependencies_macports.txt)
# Point CMake to the toolchain file.
[ -e "cmake/$toolchain.cmake" ] && cmake_flags_extra="$cmake_flags_extra -D \"CMAKE_TOOLCHAIN_FILE=cmake/$toolchain.cmake\""
# Use OpenAL as MacPorts doesn't package FAudio.
cmake_flags_extra="$cmake_flags_extra -D OPENAL=ON"
else
# Determine Debian architecture.
case $arch in
@@ -350,18 +377,18 @@ else
[ $length -gt $longest_libpkg ] && longest_libpkg=$length
done
# Determine GNU toolchain architecture.
# Determine toolchain architecture triplet.
case $arch in
x86) arch_gnu="i686-linux-gnu";;
arm32) arch_gnu="arm-linux-gnueabihf";;
arm64) arch_gnu="aarch64-linux-gnu";;
*) arch_gnu="$arch-linux-gnu";;
x86) arch_triplet="i686-linux-gnu";;
arm32) arch_triplet="arm-linux-gnueabihf";;
arm64) arch_triplet="aarch64-linux-gnu";;
*) arch_triplet="$arch-linux-gnu";;
esac
# Determine library directory name for this architecture.
case $arch in
x86) libdir="i386-linux-gnu";;
*) libdir="$arch_gnu";;
*) libdir="$arch_triplet";;
esac
# Create CMake toolchain file.
@@ -369,15 +396,15 @@ else
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR $arch)
set(CMAKE_AR $arch_gnu-ar)
set(CMAKE_ASM_COMPILER $arch_gnu-gcc)
set(CMAKE_C_COMPILER $arch_gnu-gcc)
set(CMAKE_CXX_COMPILER $arch_gnu-g++)
set(CMAKE_LINKER $arch_gnu-ld)
set(CMAKE_OBJCOPY $arch_gnu-objcopy)
set(CMAKE_RANLIB $arch_gnu-ranlib)
set(CMAKE_SIZE $arch_gnu-size)
set(CMAKE_STRIP $arch_gnu-strip)
set(CMAKE_AR $arch_triplet-ar)
set(CMAKE_ASM_COMPILER $arch_triplet-gcc)
set(CMAKE_C_COMPILER $arch_triplet-gcc)
set(CMAKE_CXX_COMPILER $arch_triplet-g++)
set(CMAKE_LINKER $arch_triplet-ld)
set(CMAKE_OBJCOPY $arch_triplet-objcopy)
set(CMAKE_RANLIB $arch_triplet-ranlib)
set(CMAKE_SIZE $arch_triplet-size)
set(CMAKE_STRIP $arch_triplet-strip)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
@@ -389,7 +416,7 @@ set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/$libdir/pkgconfig:/usr/share/$libdir/pkgcon
include("$(pwd)/cmake/$toolchain.cmake")
EOF
cmake_flags_extra="$cmake_flags_extra -D CMAKE_TOOLCHAIN_FILE=toolchain.cmake"
strip_binary="$arch_gnu-strip"
strip_binary="$arch_triplet-strip"
# Install or update dependencies.
echo [-] Installing dependencies through apt
@@ -524,8 +551,21 @@ then
fi
elif is_mac
then
# TBD
:
# Archive app bundle with libraries.
cmake_flags_install=
[ $strip -ne 0 ] && cmake_flags_install="$cmake_flags_install --strip"
cmake --install build --prefix "$(pwd)/archive_tmp" $cmake_flags_install
status=$?
if [ $status -eq 0 ]
then
# Archive Discord Game SDK library.
unzip -j discord_game_sdk.zip "lib/$arch_discord/discord_game_sdk.dylib" -d "archive_tmp/"*".app/Contents/Frameworks"
[ ! -e "archive_tmp/"*".app/Contents/Frameworks/discord_game_sdk.dylib" ] && echo [!] No Discord Game SDK for architecture [$arch_discord]
# Sign app bundle.
codesign --force --deep -s - "archive_tmp/"*".app"
fi
else
cwd_root=$(pwd)
@@ -643,8 +683,10 @@ then
status=$?
elif is_mac
then
# TBD
:
# Create zip. (TODO: dmg)
cd archive_tmp
zip -r "$cwd/$package_name.zip" .
status=$?
else
# Determine AppImage runtime architecture.
case $arch in

View File

@@ -0,0 +1,10 @@
cmake@3.22.3_0
pkgconfig@0.29.2_0
ninja@1.10.2_4
freetype@2.11.1_0
libsdl2@2.0.20_0
libpng@1.6.37_0
openal-soft@1.21.1_0
rtmidi@5.0.0_0
qt5@5.15.3_0
wget

View File

@@ -32,11 +32,11 @@
#ifndef _WIN32
#include <pwd.h>
#include <unistd.h>
#endif
#ifdef __APPLE__
#include <string.h>
#include <dispatch/dispatch.h>
#include "mac/macOSXGlue.h"
#ifdef __aarch64__
#include <pthread.h>
#endif
@@ -125,6 +125,7 @@ uint64_t unique_id = 0;
uint64_t source_hwnd = 0;
#endif
char rom_path[1024] = { '\0'}; /* (O) full path to ROMs */
rom_path_t rom_paths = { "", NULL }; /* (O) full paths to ROMs */
char log_path[1024] = { '\0'}; /* (O) full path of logfile */
char vm_name[1024] = { '\0'}; /* (O) display name of the VM */
@@ -394,12 +395,12 @@ pc_log(const char *fmt, ...)
int
pc_init(int argc, char *argv[])
{
char path[2048], path2[2048];
char *ppath = NULL, *rpath = NULL;
char *cfg = NULL, *p;
#if !defined(__APPLE__) && !defined(_WIN32)
char *appimage;
#endif
char temp[128];
char temp[2048];
struct tm *info;
time_t now;
int c, vmrp = 0;
@@ -412,6 +413,14 @@ pc_init(int argc, char *argv[])
p = plat_get_filename(exe_path);
*p = '\0';
#if !defined(_WIN32) && !defined(__APPLE__)
/* Grab the actual path if we are an AppImage. */
appimage = getenv("APPIMAGE");
if (appimage && (appimage[0] != '\0')) {
plat_get_dirname(exe_path, appimage);
}
#endif
/*
* Get the current working directory.
*
@@ -423,9 +432,6 @@ pc_init(int argc, char *argv[])
plat_getcwd(usr_path, sizeof(usr_path) - 1);
plat_getcwd(rom_path, sizeof(rom_path) - 1);
memset(path, 0x00, sizeof(path));
memset(path2, 0x00, sizeof(path));
for (c=1; c<argc; c++) {
if (argv[c][0] != '-') break;
@@ -448,7 +454,6 @@ usage:
printf("-H or --hwnd id,hwnd - sends back the main dialog's hwnd\n");
#endif
printf("-L or --logfile path - set 'path' to be the logfile\n");
printf("-M or --vmrompath - ROM path is roms subdirectory inside the userfiles path\n");
printf("-N or --noconfirm - do not ask for confirmation on quit\n");
printf("-O or --dumpcfg - dump config file after loading\n");
printf("-P or --vmpath path - set 'path' to be root for vm\n");
@@ -490,12 +495,13 @@ usage:
!strcasecmp(argv[c], "-P")) {
if ((c+1) == argc) goto usage;
strcpy(path, argv[++c]);
ppath = argv[++c];
} else if (!strcasecmp(argv[c], "--rompath") ||
!strcasecmp(argv[c], "-R")) {
if ((c+1) == argc) goto usage;
strcpy(path2, argv[++c]);
rpath = argv[++c];
rom_add_path(rpath);
} else if (!strcasecmp(argv[c], "--config") ||
!strcasecmp(argv[c], "-C")) {
if ((c+1) == argc) goto usage;
@@ -552,7 +558,7 @@ usage:
/* One argument (config file) allowed. */
if (c < argc) {
if (lvmp)
strcpy(path, argv[c++]);
ppath = argv[c++];
else
cfg = argv[c++];
}
@@ -568,21 +574,21 @@ usage:
* make sure that if that was a relative path, we
* make it absolute.
*/
if (path[0] != '\0') {
if (! plat_path_abs(path)) {
if (ppath != NULL) {
if (! plat_path_abs(ppath)) {
/*
* This looks like a relative path.
*
* Add it to the current working directory
* to convert it (back) to an absolute path.
*/
strcat(usr_path, path);
strcat(usr_path, ppath);
} else {
/*
* The user-provided path seems like an
* absolute path, so just use that.
*/
strcpy(usr_path, path);
strcpy(usr_path, ppath);
}
/* If the specified path does not yet exist,
@@ -591,26 +597,15 @@ usage:
plat_dir_create(usr_path);
}
if (path2[0] == '\0') {
#if defined(__APPLE__)
getDefaultROMPath(path2);
#elif !defined(_WIN32)
appimage = getenv("APPIMAGE");
if (appimage && (appimage[0] != '\0')) {
plat_get_dirname(path2, appimage);
plat_path_slash(path2);
strcat(path2, "roms");
plat_path_slash(path2);
}
#endif
}
// Add the VM-local ROM path.
plat_append_filename(temp, usr_path, "roms");
rom_add_path(temp);
if (vmrp && (path2[0] == '\0')) {
strcpy(path2, usr_path);
plat_path_slash(path2);
strcat(path2, "roms");
plat_path_slash(path2);
}
// Add the standard ROM path in the same directory as the executable.
plat_append_filename(temp, exe_path, "roms");
rom_add_path(temp);
plat_init_rom_paths();
/*
* If the user provided a path for ROMs, use that
@@ -618,21 +613,21 @@ usage:
* make sure that if that was a relative path, we
* make it absolute.
*/
if (path2[0] != '\0') {
if (! plat_path_abs(path2)) {
if (rpath != NULL) {
if (! plat_path_abs(rpath)) {
/*
* This looks like a relative path.
*
* Add it to the current working directory
* to convert it (back) to an absolute path.
*/
strcat(rom_path, path2);
strcat(rom_path, rpath);
} else {
/*
* The user-provided path seems like an
* absolute path, so just use that.
*/
strcpy(rom_path, path2);
strcpy(rom_path, rpath);
}
/* If the specified path does not yet exist,
@@ -708,14 +703,10 @@ usage:
pclog("# VM: %s\n#\n", vm_name);
pclog("# Emulator path: %s\n", exe_path);
pclog("# Userfiles path: %s\n", usr_path);
if (rom_path[0] != '\0')
pclog("# ROM path: %s\n", rom_path);
else
#ifndef _WIN32
pclog("# ROM path: %sroms/\n", exe_path);
#else
pclog("# ROM path: %sroms\\\n", exe_path);
#endif
for(rom_path_t *rom_path = &rom_paths; rom_path != NULL; rom_path = rom_path->next) {
pclog("# ROM path: %s\n", rom_path->path);
}
pclog("# Configuration file: %s\n#\n\n", cfg_path);
/*
* We are about to read the configuration file, which MAY

View File

@@ -19,6 +19,10 @@ add_executable(86Box 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c
dma.c ddma.c discord.c nmi.c pic.c pit.c port_6x.c port_92.c ppi.c pci.c
mca.c usb.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c)
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1)
endif()
if(CPPTHREADS)
target_sources(86Box PRIVATE thread.cpp)
endif()

View File

@@ -339,6 +339,30 @@ device_available(const device_t *d)
}
int
device_has_config(const device_t *d)
{
int c = 0;
device_config_t *config;
if (d == NULL)
return 0;
if (d->config == NULL)
return 0;
config = (device_config_t *) d->config;
while (config->type != -1) {
if (config->type != CONFIG_MAC)
c++;
config++;
}
return (c > 0) ? 1 : 0;
}
int
device_poll(const device_t *d, int x, int y, int z, int b)
{

View File

@@ -202,7 +202,7 @@ hdc_has_config(int hdc)
if (dev == NULL) return(0);
if (dev->config == NULL) return(0);
if (!device_has_config(dev)) return(0);
return(1);
}

View File

@@ -154,7 +154,7 @@ fdc_card_has_config(int card)
{
if (! fdc_cards[card].device) return(0);
return(fdc_cards[card].device->config ? 1 : 0);
return(device_has_config(fdc_cards[card].device) ? 1 : 0);
}

View File

@@ -147,6 +147,7 @@ extern void device_register_pci_slot(const device_t *d, int device, int type, i
extern void device_speed_changed(void);
extern void device_force_redraw(void);
extern void device_get_name(const device_t *d, int bus, char *name);
extern int device_has_config(const device_t *d);
extern int device_is_valid(const device_t *, int m);

View File

@@ -104,6 +104,7 @@ extern int plat_getcwd(char *bufp, int max);
extern int plat_chdir(char *path);
extern void plat_tempfile(char *bufp, char *prefix, char *suffix);
extern void plat_get_exe_name(char *s, int size);
extern void plat_init_rom_paths();
extern char *plat_get_basename(const char *path);
extern void plat_get_dirname(char *dest, const char *path);
extern char *plat_get_filename(char *s);

View File

@@ -41,6 +41,15 @@ typedef struct {
} rom_t;
typedef struct rom_path_t {
char path[1024];
struct rom_path_t* next;
} rom_path_t;
extern rom_path_t rom_paths;
extern void rom_add_path(const char* path);
extern uint8_t rom_read(uint32_t addr, void *p);
extern uint16_t rom_readw(uint32_t addr, void *p);
extern uint32_t rom_readl(uint32_t addr, void *p);

View File

@@ -29,7 +29,7 @@ else()
endif()
target_link_libraries(86Box "-framework AppKit")
target_sources(86Box PRIVATE macOSXGlue.m ${APP_ICON_MACOSX})
target_sources(86Box PRIVATE ${APP_ICON_MACOSX})
# Make sure the icon is copied to the bundle
set_source_files_properties(${APP_ICON_MACOSX}
@@ -48,7 +48,6 @@ configure_file(Info.plist.in Info.plist @ONLY)
set_target_properties(86Box
PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "-o linker-signed")
set(XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "YES")
set(XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-")
#set(XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${CMAKE_CURRENT_SOURCE_DIR}/mac/codesign/dev/app.entitlements)
#set(XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "YES")
#set(XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-")
#set(XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${CMAKE_CURRENT_SOURCE_DIR}/mac/codesign/dev/app.entitlements)

View File

@@ -57,39 +57,59 @@ rom_log(const char *fmt, ...)
#define rom_log(fmt, ...)
#endif
void
rom_add_path(const char* path)
{
char cwd[1024] = { 0 };
rom_path_t* rom_path = &rom_paths;
if (rom_paths.path[0] != '\0')
{
// Iterate to the end of the list.
while (rom_path->next != NULL) {
rom_path = rom_path->next;
}
// Allocate the new entry.
rom_path = rom_path->next = calloc(1, sizeof(rom_path_t));
}
// Save the path, turning it into absolute if needed.
if (!plat_path_abs((char*) path)) {
plat_getcwd(cwd, sizeof(cwd));
plat_path_slash(cwd);
snprintf(rom_path->path, sizeof(rom_path->path), "%s%s", cwd, path);
} else {
snprintf(rom_path->path, sizeof(rom_path->path), "%s", path);
}
// Ensure the path ends with a separator.
plat_path_slash(rom_path->path);
}
FILE *
rom_fopen(char *fn, char *mode)
{
char temp[1024];
char *fn2;
rom_path_t *rom_path = &rom_paths;
FILE *fp;
if ((strstr(fn, "roms/") == fn) || (strstr(fn, "roms\\") == fn)) {
/* Relative path */
fn2 = (char *) malloc(strlen(fn) + 1);
memcpy(fn2, fn, strlen(fn) + 1);
if (strstr(fn, "roms/") == fn) {
/* Relative path */
for(rom_path_t *rom_path = &rom_paths; rom_path != NULL; rom_path = rom_path->next) {
plat_append_filename(temp, rom_path->path, fn + 5);
if (rom_path[0] != '\0') {
memset(fn2, 0x00, strlen(fn) + 1);
memcpy(fn2, &(fn[5]), strlen(fn) - 4);
if ((fp = plat_fopen(temp, mode)) != NULL) {
return fp;
}
}
plat_append_filename(temp, rom_path, fn2);
} else {
/* Make sure to make it a backslash, just in case there's malformed
code calling us that assumes Windows. */
if (fn2[4] == '\\')
fn2[4] = '/';
plat_append_filename(temp, exe_path, fn2);
}
free(fn2);
fn2 = NULL;
return(plat_fopen(temp, mode));
return fp;
} else {
/* Absolute path */
return(plat_fopen(fn, mode));
/* Absolute path */
return plat_fopen(fn, mode);
}
}
@@ -97,17 +117,30 @@ rom_fopen(char *fn, char *mode)
int
rom_getfile(char *fn, char *s, int size)
{
FILE *f;
char temp[1024];
rom_path_t *rom_path = &rom_paths;
plat_append_filename(s, exe_path, fn);
if (strstr(fn, "roms/") == fn) {
/* Relative path */
for(rom_path_t *rom_path = &rom_paths; rom_path != NULL; rom_path = rom_path->next) {
plat_append_filename(temp, rom_path->path, fn + 5);
f = plat_fopen(s, "rb");
if (f != NULL) {
(void)fclose(f);
return(1);
if (rom_present(temp)) {
strncpy(s, temp, size);
return 1;
}
}
return 0;
} else {
/* Absolute path */
if (rom_present(fn)) {
strncpy(s, fn, size);
return 1;
}
return 0;
}
return(0);
}
@@ -118,8 +151,8 @@ rom_present(char *fn)
f = rom_fopen(fn, "rb");
if (f != NULL) {
(void)fclose(f);
return(1);
(void)fclose(f);
return(1);
}
return(0);

View File

@@ -630,7 +630,7 @@ network_card_has_config(int card)
{
if (! net_cards[card].device) return(0);
return(net_cards[card].device->config ? 1 : 0);
return(device_has_config(net_cards[card].device) ? 1 : 0);
}

View File

@@ -22,6 +22,14 @@ endif()
find_package(Threads REQUIRED)
find_package(Qt${QT_MAJOR} COMPONENTS Core Widgets Network OpenGL REQUIRED)
find_package(Qt${QT_MAJOR}LinguistTools REQUIRED)
# TODO: Is this the correct way to do this, and is it required on any
# other platforms or with Qt 5?
if(APPLE AND USE_QT6)
find_package(Qt6Gui/Qt6QCocoaIntegrationPlugin REQUIRED)
find_package(Qt6Widgets/Qt6QMacStylePlugin REQUIRED)
find_package(Qt6Gui/Qt6QICOPlugin REQUIRED)
find_package(Qt6Gui/Qt6QICNSPlugin REQUIRED)
endif()
add_library(plat STATIC
qt.c
@@ -232,17 +240,13 @@ if (APPLE AND CMAKE_MACOSX_BUNDLE)
set(INSTALL_CMAKE_DIR "${prefix}/Resources")
# using the install_qt5_plugin to add Qt plugins into the macOS app bundle
if (USE_QT6)
install_qt5_plugin("Qt6::QCocoaIntegrationPlugin" QT_PLUGINS ${prefix})
else()
install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS ${prefix})
install_qt5_plugin("Qt5::QMacStylePlugin" QT_PLUGINS ${prefix})
install_qt5_plugin("Qt5::QICOPlugin" QT_PLUGINS ${prefix})
install_qt5_plugin("Qt5::QICNSPlugin" QT_PLUGINS ${prefix})
endif()
install_qt5_plugin("Qt${QT_MAJOR}::QCocoaIntegrationPlugin" QT_PLUGINS ${prefix})
install_qt5_plugin("Qt${QT_MAJOR}::QMacStylePlugin" QT_PLUGINS ${prefix})
install_qt5_plugin("Qt${QT_MAJOR}::QICOPlugin" QT_PLUGINS ${prefix})
install_qt5_plugin("Qt${QT_MAJOR}::QICNSPlugin" QT_PLUGINS ${prefix})
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
"[Paths]\nPlugins = ${_qt_plugin_dir}\n")
"[Paths]\nPlugins = PlugIns\n")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
DESTINATION "${INSTALL_CMAKE_DIR}")
@@ -253,8 +257,8 @@ if (APPLE AND CMAKE_MACOSX_BUNDLE)
endforeach()
endif()
# Append Qt's lib folder which is two levels above Qt5Widgets_DIR
list(APPEND DIRS "${Qt5Widgets_DIR}/../..")
# Append Qt's lib folder which is two levels above Qt*Widgets_DIR
list(APPEND DIRS "${Qt${QT_MAJOR}Widgets_DIR}/../..")
include(InstallRequiredSystemLibraries)

View File

@@ -614,7 +614,7 @@ msgid "ZIP images"
msgstr "Imagens ZIP"
msgid "86Box could not find any usable ROM images.\n\nPlease <a href=\"https://github.com/86Box/roms/releases/latest\">download</a> a ROM set and extract it into the \"roms\" directory."
msgstr "O 86Box não conseguiu encontrar nenhuma imagem ROM utilizável.\n\nPor favor, vá a href=\"https://github.com/86Box/roms/releases/latest\">descarregue</a> um pacote ROM e instale-o na pasta \"roms\"."
msgstr "O 86Box não conseguiu encontrar nenhuma imagem ROM utilizável.\n\nPor favor, vá <a href=\"https://github.com/86Box/roms/releases/latest\">descarregue</a> um pacote ROM e instale-o na pasta \"roms\"."
msgid "(empty)"
msgstr "(empty)"

View File

@@ -82,6 +82,14 @@ extern "C" {
#undef KeyRelease
#endif
#ifdef Q_OS_MACOS
// The namespace is required to avoid clashing typedefs; we only use this
// header for its #defines anyway.
namespace IOKit {
#include <IOKit/hidsystem/IOLLEvent.h>
}
#endif
#ifdef __HAIKU__
#include <os/AppKit.h>
#include <os/InterfaceKit.h>
@@ -1215,7 +1223,7 @@ uint16_t x11_keycode_to_keysym(uint32_t keycode)
uint16_t finalkeycode = 0;
#if defined(Q_OS_WINDOWS)
finalkeycode = (keycode & 0xFFFF);
#elif defined(__APPLE__)
#elif defined(Q_OS_MACOS)
finalkeycode = darwin_to_xt[keycode];
#elif defined(__HAIKU__)
finalkeycode = be_to_xt[keycode];
@@ -1252,6 +1260,68 @@ uint16_t x11_keycode_to_keysym(uint32_t keycode)
return finalkeycode;
}
#ifdef Q_OS_MACOS
// These modifiers are listed as "device-dependent" in IOLLEvent.h, but
// that's followed up with "(really?)". It's the only way to distinguish
// left and right modifiers with Qt 6 on macOS, so let's just roll with it.
static std::unordered_map<uint32_t, uint16_t> mac_modifiers_to_xt = {
{NX_DEVICELCTLKEYMASK, 0x1D},
{NX_DEVICELSHIFTKEYMASK, 0x2A},
{NX_DEVICERSHIFTKEYMASK, 0x36},
{NX_DEVICELCMDKEYMASK, 0x15B},
{NX_DEVICERCMDKEYMASK, 0x15C},
{NX_DEVICELALTKEYMASK, 0x38},
{NX_DEVICERALTKEYMASK, 0x138},
{NX_DEVICE_ALPHASHIFT_STATELESS_MASK, 0x3A},
{NX_DEVICERCTLKEYMASK, 0x11D},
};
void MainWindow::processMacKeyboardInput(bool down, const QKeyEvent* event) {
// Per QTBUG-69608 (https://bugreports.qt.io/browse/QTBUG-69608),
// QKeyEvents QKeyEvents for presses/releases of modifiers on macOS give
// nativeVirtualKey() == 0 (at least in Qt 6). Handle this by manually
// processing the nativeModifiers(). We need to check whether the key() is
// a known modifier because because kVK_ANSI_A is also 0, so the
// nativeVirtualKey() == 0 condition is ambiguous...
if (event->nativeVirtualKey() == 0
&& (event->key() == Qt::Key_Shift
|| event->key() == Qt::Key_Control
|| event->key() == Qt::Key_Meta
|| event->key() == Qt::Key_Alt
|| event->key() == Qt::Key_AltGr
|| event->key() == Qt::Key_CapsLock)) {
// We only process one modifier at a time since events from Qt seem to
// always be non-coalesced (NX_NONCOALESCEDMASK is always set).
uint32_t changed_modifiers = last_modifiers ^ event->nativeModifiers();
for (auto const& pair : mac_modifiers_to_xt) {
if (changed_modifiers & pair.first) {
last_modifiers ^= pair.first;
keyboard_input(down, pair.second);
return;
}
}
// Caps Lock seems to be delivered as a single key press event when
// enabled and a single key release event when disabled, so we can't
// detect Caps Lock being held down; just send an infinitesimally-long
// press and release as a compromise.
//
// The event also doesn't get delivered if you turn Caps Lock off after
// turning it on when the window isn't focused. Doing better than this
// probably requires bypassing Qt input processing.
//
// It's possible that other lock keys get delivered in this way, but
// standard Apple keyboards don't have them, so this is untested.
if (event->key() == Qt::Key_CapsLock) {
keyboard_input(1, 0x3A);
keyboard_input(0, 0x3A);
}
} else {
keyboard_input(down, x11_keycode_to_keysym(event->nativeVirtualKey()));
}
}
#endif
void MainWindow::on_actionFullscreen_triggered() {
if (video_fullscreen > 0) {
showNormal();
@@ -1370,8 +1440,8 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
{
if (send_keyboard_input && !(kbd_req_capture && !mouse_capture && !video_fullscreen))
{
#ifdef __APPLE__
keyboard_input(1, x11_keycode_to_keysym(event->nativeVirtualKey()));
#ifdef Q_OS_MACOS
processMacKeyboardInput(true, event);
#else
keyboard_input(1, x11_keycode_to_keysym(event->nativeScanCode()));
#endif
@@ -1397,8 +1467,8 @@ void MainWindow::keyReleaseEvent(QKeyEvent* event)
if (!send_keyboard_input)
return;
#ifdef __APPLE__
keyboard_input(0, x11_keycode_to_keysym(event->nativeVirtualKey()));
#ifdef Q_OS_MACOS
processMacKeyboardInput(false, event);
#else
keyboard_input(0, x11_keycode_to_keysym(event->nativeScanCode()));
#endif

View File

@@ -118,6 +118,11 @@ private:
std::unique_ptr<MachineStatus> status;
std::shared_ptr<MediaMenu> mm;
#ifdef Q_OS_MACOS
uint32_t last_modifiers = 0;
void processMacKeyboardInput(bool down, const QKeyEvent* event);
#endif
/* If main window should send keyboard input */
bool send_keyboard_input = true;
bool shownonce = false;

View File

@@ -338,6 +338,9 @@ void MediaMenu::floppyExportTo86f(int i) {
void MediaMenu::floppyUpdateMenu(int i) {
QString name = floppyfns[i];
if (!floppyMenus.contains(i))
return;
auto* menu = floppyMenus[i];
auto childs = menu->children();
@@ -412,6 +415,8 @@ void MediaMenu::cdromReload(int i) {
void MediaMenu::cdromUpdateMenu(int i) {
QString name = cdrom[i].image_path;
if (!cdromMenus.contains(i))
return;
auto* menu = cdromMenus[i];
auto childs = menu->children();
@@ -515,6 +520,8 @@ void MediaMenu::zipReload(int i) {
void MediaMenu::zipUpdateMenu(int i) {
QString name = zip_drives[i].image_path;
QString prev_name = zip_drives[i].prev_image_path;
if (!zipMenus.contains(i))
return;
auto* menu = zipMenus[i];
auto childs = menu->children();
@@ -612,6 +619,8 @@ void MediaMenu::moReload(int i) {
void MediaMenu::moUpdateMenu(int i) {
QString name = mo_drives[i].image_path;
QString prev_name = mo_drives[i].prev_image_path;
if (!moMenus.contains(i))
return;
auto* menu = moMenus[i];
auto childs = menu->children();

View File

@@ -30,6 +30,7 @@
#include <QDir>
#include <QFileInfo>
#include <QTemporaryFile>
#include <QStandardPaths>
#include <QCoreApplication>
#include <QDateTime>
#include <QLocalSocket>
@@ -88,6 +89,8 @@ extern "C" {
#include <86box/timer.h>
#include <86box/nvr.h>
#include <86box/plat_dynld.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/config.h>
#include <86box/ui.h>
#include <86box/discord.h>
@@ -375,7 +378,7 @@ extern "C++"
{
{0x0405, {"cs-CZ", "Czech (Czech Republic)"} },
{0x0407, {"de-DE", "German (Germany)"} },
{0x0408, {"en-US", "English (United States)"} },
{0x0409, {"en-US", "English (United States)"} },
{0x0809, {"en-GB", "English (United Kingdom)"} },
{0x0C0A, {"es-ES", "Spanish (Spain)"} },
{0x040B, {"fi-FI", "Finnish (Finland)"} },
@@ -517,11 +520,6 @@ size_t c16stombs(char dst[], const uint16_t src[], int len)
#define LIB_NAME_FREETYPE "libfreetype"
#define MOUSE_CAPTURE_KEYSEQ "CTRL-END"
#endif
#ifdef Q_OS_MACOS
#define ROMDIR "~/Library/Application Support/net.86box.86box/roms"
#else
#define ROMDIR "roms"
#endif
QMap<int, std::wstring> ProgSettings::translatedstrings;
@@ -547,7 +545,7 @@ void ProgSettings::reloadStrings()
translatedstrings[IDS_2128] = QCoreApplication::translate("", "Hardware not available").toStdWString();
translatedstrings[IDS_2142] = QCoreApplication::translate("", "Monitor in sleep mode").toStdWString();
translatedstrings[IDS_2120] = QCoreApplication::translate("", "No ROMs found").toStdWString();
translatedstrings[IDS_2056] = QCoreApplication::translate("", "86Box could not find any usable ROM images.\n\nPlease <a href=\"https://github.com/86Box/roms/releases/latest\">download</a> a ROM set and extract it into the \"roms\" directory.").replace("roms", ROMDIR).toStdWString();
translatedstrings[IDS_2056] = QCoreApplication::translate("", "86Box could not find any usable ROM images.\n\nPlease <a href=\"https://github.com/86Box/roms/releases/latest\">download</a> a ROM set and extract it into the \"roms\" directory.").toStdWString();
auto flsynthstr = QCoreApplication::translate("", " is required for FluidSynth MIDI output.");
if (flsynthstr.contains("libfluidsynth"))
@@ -583,3 +581,26 @@ plat_chdir(char *path)
{
return QDir::setCurrent(QString(path)) ? 0 : -1;
}
void
plat_init_rom_paths()
{
auto paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
#ifdef _WIN32
// HACK: The standard locations returned for GenericDataLocation include
// the EXE path and a `data` directory within it as the last two entries.
// Remove the entries as we don't need them.
paths.removeLast();
paths.removeLast();
#endif
for (auto& path : paths) {
#ifdef __APPLE__
rom_add_path(QDir(path).filePath("net.86Box.86Box/roms").toUtf8().constData());
#else
rom_add_path(QDir(path).filePath("86Box/roms").toUtf8().constData());
#endif
}
}

View File

@@ -174,7 +174,7 @@ RendererStack::mouseMoveEvent(QMouseEvent *event)
event->ignore();
return;
}
#ifdef __APPLE__
#if defined __APPLE__ || defined _WIN32
event->accept();
return;
#else

View File

@@ -153,7 +153,7 @@ scsi_card_has_config(int card)
{
if (! scsi_cards[card].device) return(0);
return(scsi_cards[card].device->config ? 1 : 0);
return(device_has_config(scsi_cards[card].device) ? 1 : 0);
}

View File

@@ -186,7 +186,7 @@ sound_card_has_config(int card)
{
if (!sound_cards[card].device)
return 0;
return sound_cards[card].device->config ? 1 : 0;
return device_has_config(sound_cards[card].device) ? 1 : 0;
}
char *

View File

@@ -28,3 +28,7 @@ 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 ${CMAKE_DL_LIBS})
if(APPLE)
target_sources(plat PRIVATE macOSXGlue.m)
endif()

View File

@@ -18,9 +18,12 @@
#include <inttypes.h>
#include <dlfcn.h>
#include <wchar.h>
#include <pwd.h>
#include <stdatomic.h>
#include <86box/86box.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/keyboard.h>
#include <86box/mouse.h>
#include <86box/config.h>
@@ -34,6 +37,10 @@
#include <86box/ui.h>
#include <86box/gdbstub.h>
#ifdef __APPLE__
#include "macOSXGlue.h"
#endif
static int first_use = 1;
static uint64_t StartingTime;
static uint64_t Frequency;
@@ -744,6 +751,63 @@ plat_pause(int p)
}
}
void
plat_init_rom_paths()
{
#ifndef __APPLE__
if (getenv("XDG_DATA_HOME")) {
char xdg_rom_path[1024] = { 0 };
strncpy(xdg_rom_path, getenv("XDG_DATA_HOME"), 1024);
plat_path_slash(xdg_rom_path);
strncat(xdg_rom_path, "86Box/", 1024);
if (!plat_dir_check(xdg_rom_path))
plat_dir_create(xdg_rom_path);
strcat(xdg_rom_path, "roms/");
if (!plat_dir_check(xdg_rom_path))
plat_dir_create(xdg_rom_path);
rom_add_path(xdg_rom_path);
} else {
char home_rom_path[1024] = { 0 };
snprintf(home_rom_path, 1024, "%s/.local/share/86Box/", getenv("HOME") ? getenv("HOME") : getpwuid(getuid())->pw_dir);
if (!plat_dir_check(home_rom_path))
plat_dir_create(home_rom_path);
strcat(home_rom_path, "roms/");
if (!plat_dir_check(home_rom_path))
plat_dir_create(home_rom_path);
rom_add_path(home_rom_path);
}
if (getenv("XDG_DATA_DIRS")) {
char* xdg_rom_paths = strdup(getenv("XDG_DATA_DIRS"));
char* xdg_rom_paths_orig = xdg_rom_paths;
char* cur_xdg_rom_path = NULL;
if (xdg_rom_paths) {
while (xdg_rom_paths[strlen(xdg_rom_paths) - 1] == ':') {
xdg_rom_paths[strlen(xdg_rom_paths) - 1] = '\0';
}
while ((cur_xdg_rom_path = local_strsep(&xdg_rom_paths, ";")) != NULL) {
char real_xdg_rom_path[1024] = { '\0' };
strcat(real_xdg_rom_path, cur_xdg_rom_path);
plat_path_slash(real_xdg_rom_path);
strcat(real_xdg_rom_path, "86Box/roms/");
rom_add_path(real_xdg_rom_path);
}
}
free(xdg_rom_paths_orig);
} else {
rom_add_path("/usr/local/share/86Box/roms/");
rom_add_path("/usr/share/86Box/roms/");
}
#else
char default_rom_path[1024] = { '\0 '};
getDefaultROMPath(default_rom_path);
rom_path_add(default_rom_path);
#endif
}
bool process_media_commands_3(uint8_t* id, char* fn, uint8_t* wp, int cmdargc)
{
bool err = false;

View File

@@ -364,7 +364,7 @@ video_card_has_config(int card)
{
if (video_cards[card].device == NULL) return(0);
return(video_cards[card].device->config ? 1 : 0);
return(device_has_config(video_cards[card].device) ? 1 : 0);
}

View File

@@ -45,6 +45,8 @@
#include <86box/timer.h>
#include <86box/nvr.h>
#include <86box/video.h>
#include <86box/mem.h>
#include <86box/rom.h>
#define GLOBAL
#include <86box/plat.h>
#include <86box/ui.h>
@@ -910,6 +912,30 @@ plat_mmap(size_t size, uint8_t executable)
}
void
plat_init_rom_paths()
{
wchar_t appdata_dir[1024] = { L'\0' };
if (_wgetenv("LOCALAPPDATA") && _wgetenv("LOCALAPPDATA")[0] != L'\0') {
char appdata_dir_a[1024] = { '\0' };
size_t len = 0;
wcsncpy(appdata_dir, _wgetenv("LOCALAPPDATA"), 1024);
len = wcslen(appdata_dir);
if (appdata_dir[len - 1] != L'\\') {
appdata_dir[len] = L'\\';
appdata_dir[len + 1] = L'\0';
}
wcscat(appdata_dir, L"86box");
CreateDirectoryW(appdata_dir, NULL);
wcscat(appdata_dir, L"\\roms");
CreateDirectoryW(appdata_dir, NULL);
wcscat(appdata_dir, L"\\");
c16stombs(appdata_dir_a, appdata_dir, 1024);
rom_add_path(appdata_dir_a);
}
}
void
plat_munmap(void *ptr, size_t size)
{