Merge branch '86Box:master' into nec-v20
This commit is contained in:
26
.ci/Jenkinsfile
vendored
26
.ci/Jenkinsfile
vendored
@@ -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")
|
||||
}
|
||||
|
||||
|
||||
98
.ci/build.sh
98
.ci/build.sh
@@ -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
|
||||
|
||||
10
.ci/dependencies_macports.txt
Normal file
10
.ci/dependencies_macports.txt
Normal 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
|
||||
81
src/86box.c
81
src/86box.c
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
24
src/device.c
24
src/device.c
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
101
src/mem/rom.c
101
src/mem/rom.c
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ RendererStack::mouseMoveEvent(QMouseEvent *event)
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
#if defined __APPLE__ || defined _WIN32
|
||||
event->accept();
|
||||
return;
|
||||
#else
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user