diff --git a/.gitignore b/.gitignore index fe3a35b37..79cfbb168 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ Makefile /.vs /.vscode src/win/RCa04980 + +# Qt Creator +CMakeLists.txt.user diff --git a/CMakeLists.txt b/CMakeLists.txt index 941506bed..b8635cdc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,11 +13,15 @@ # Copyright 2020,2021 David Hrdlička. # -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.16) cmake_policy(SET CMP0091 NEW) cmake_policy(SET CMP0079 NEW) +if (QT) + list(APPEND VCPKG_MANIFEST_FEATURES "qt-ui") +endif() + project(86Box VERSION 3.2 DESCRIPTION "Emulator of x86-based systems" @@ -110,6 +114,7 @@ option(CPPTHREADS "C++11 threads" option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF) option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF) option(DEV_BRANCH "Development branch" OFF) +option(QT "QT GUI" OFF) # Development branch features # @@ -132,6 +137,11 @@ cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) +# Ditto but for Qt +if (QT) + option(USE_QT6 "Use Qt6 instead of Qt5" OFF) +endif() + # Determine the build type set(RELEASE_BUILD OFF) set(BETA_BUILD OFF) diff --git a/cmake/llvm-macos-aarch64.cmake b/cmake/llvm-macos-aarch64.cmake new file mode 100644 index 000000000..da9ccb449 --- /dev/null +++ b/cmake/llvm-macos-aarch64.cmake @@ -0,0 +1,22 @@ +# +# 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. +# +# CMake toolchain file defining Clang compiler flags +# for AArch64 (ARM64)-based Apple Silicon targets. +# +# Authors: David Hrdlička, +# dob205 +# +# Copyright 2021 David Hrdlička. +# Copyright 2022 dob205. +# + +string(APPEND CMAKE_C_FLAGS_INIT " -march=armv8.5-a+simd") +string(APPEND CMAKE_CXX_FLAGS_INIT " -march=armv8.5-a+simd") + +include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc.cmake) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8bb53a5d2..a502b602f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,7 +17,7 @@ # WIN32 marks us as a GUI app on Windows 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 fifo8.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(CPPTHREADS) @@ -75,8 +75,31 @@ if(APPLE) # Force using the newest library if it's installed by homebrew set(CMAKE_FIND_FRAMEWORK LAST) - # setting our compilation target to macOS 10.13 High Sierra - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13") + # setting our compilation target to macOS 10.15 Catalina if targetting Qt6, macOS 10.13 High Sierra otherwise + if (USE_QT6) + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15") + else() + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13") + endif() +endif() + +if(QT) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) + if (USE_QT6) + set(QT_MAJOR 6) + else() + set(QT_MAJOR 5) + endif() + + # if we want to use qt5-static to eliminate need for bundling qt dlls (windows) + #set(QT_STATIC ON) + # needed to build with qt5-static if both qt5 and qt5-static are installed + #set(CMAKE_PREFIX_PATH "path/to/qt5-static") + + find_package(Qt${QT_MAJOR} COMPONENTS Core Widgets OpenGL REQUIRED) + find_package(Qt${QT_MAJOR}LinguistTools REQUIRED) endif() find_package(Freetype REQUIRED) @@ -155,15 +178,85 @@ else() install(TARGETS 86Box) endif() +# prepare everything for Qt5 bundle creation +if (APPLE AND QT) + set(prefix "86Box.app/Contents") + set(INSTALL_RUNTIME_DIR "${prefix}/MacOS") + set(INSTALL_CMAKE_DIR "${prefix}/Resources") +endif() + +# loads a macro to install Qt5 plugins on macOS +# based on https://stackoverflow.com/questions/35612687/cmake-macos-x-bundle-with-bundleutiliies-for-qt-application +macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var _prefix) + get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION) + if(EXISTS "${_qt_plugin_path}") + get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME) + get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH) + get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME) + set(_qt_plugin_dest "${_prefix}/PlugIns/${_qt_plugin_type}") + install(FILES "${_qt_plugin_path}" + DESTINATION "${_qt_plugin_dest}") + set(${_qt_plugins_var} + "${${_qt_plugins_var}};\$ENV{DEST_DIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}") + else() + message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found") + endif() +endmacro() + # Install our dependencies to the macOS bundle if(APPLE) - install(CODE " - include(BundleUtilities) - get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \${CMAKE_INSTALL_PREFIX} ABSOLUTE) - fixup_bundle(\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/86Box.app\" \"\" \"\")" - COMPONENT Runtime) + if (NOT QT) + install(CODE " + include(BundleUtilities) + get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \${CMAKE_INSTALL_PREFIX} ABSOLUTE) + fixup_bundle(\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/86Box.app\" \"\" \"\")" + COMPONENT Runtime) + endif() + + if(QT) + # 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() + + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" + "[Paths]\nPlugins = ${_qt_plugin_dir}\n") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" + DESTINATION "${INSTALL_CMAKE_DIR}") + + # Note Mac specific extension .app + set(APPS "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/86Box.app") + + # Directories to look for dependencies + set(DIRS "${CMAKE_BINARY_DIR}") + + # Path used for searching by FIND_XXX(), with appropriate suffixes added + if(CMAKE_PREFIX_PATH) + foreach(dir ${CMAKE_PREFIX_PATH}) + list(APPEND DIRS "${dir}/bin" "${dir}/lib") + endforeach() + endif() + + # Append Qt's lib folder which is two levels above Qt5Widgets_DIR + list(APPEND DIRS "${Qt5Widgets_DIR}/../..") + + include(InstallRequiredSystemLibraries) + + message(STATUS "APPS: ${APPS}") + message(STATUS "QT_PLUGINS: ${QT_PLUGINS}") + message(STATUS "DIRS: ${DIRS}") + + install(CODE "include(BundleUtilities) + fixup_bundle(\"${APPS}\" \"${QT_PLUGINS}\" \"${DIRS}\")") + endif() endif() + # Install our dependencies if using vcpkg if(VCPKG_TOOLCHAIN) x_vcpkg_install_local_dependencies(TARGETS 86Box DESTINATION ".") @@ -198,9 +291,12 @@ add_subdirectory(sio) add_subdirectory(scsi) add_subdirectory(sound) add_subdirectory(video) -if(APPLE) - add_subdirectory(mac) - add_subdirectory(unix) +if (APPLE) + add_subdirectory(mac) +endif() + +if (QT) + add_subdirectory(qt) elseif(WIN32) add_subdirectory(win) else() diff --git a/src/win/win_discord.c b/src/discord.c similarity index 85% rename from src/win/win_discord.c rename to src/discord.c index 487157af5..7a9dc1fec 100644 --- a/src/win/win_discord.c +++ b/src/discord.c @@ -19,18 +19,23 @@ #include #include #include -#include #include #define HAVE_STDARG_H #include <86box/86box.h> -#include "cpu.h" +#include "cpu/cpu.h" #include <86box/machine.h> #include <86box/plat.h> #include <86box/plat_dynld.h> -#include <86box/win_discord.h> +#include <86box/discord.h> #include +#ifdef _WIN32 #define PATH_DISCORD_DLL "discord_game_sdk.dll" +#elif defined __APPLE__ +#define PATH_DISCORD_DLL "discord_game_sdk.dylib" +#else +#define PATH_DISCORD_DLL "discord_game_sdk.so" +#endif int discord_loaded = 0; @@ -74,7 +79,7 @@ discord_update_activity(int paused) if(discord_activities == NULL) return; - discord_log("win_discord: discord_update_activity(paused=%d)\n", paused); + discord_log("discord: discord_update_activity(paused=%d)\n", paused); memset(&activity, 0x00, sizeof(activity)); @@ -85,13 +90,13 @@ discord_update_activity(int paused) if (strlen(vm_name) < 100) { - sprintf_s(activity.details, sizeof(activity.details), "Running \"%s\"", vm_name); - sprintf_s(activity.state, sizeof(activity.state), "%s (%s/%s)", strchr(machine_getname(), ']') + 2, cpufamily, cpu_s->name); + snprintf(activity.details, sizeof(activity.details), "Running \"%s\"", vm_name); + snprintf(activity.state, sizeof(activity.state), "%s (%s/%s)", strchr(machine_getname(), ']') + 2, cpufamily, cpu_s->name); } else { strncpy(activity.details, strchr(machine_getname(), ']') + 2, sizeof(activity.details) - 1); - sprintf_s(activity.state, sizeof(activity.state), "%s/%s", cpufamily, cpu_s->name); + snprintf(activity.state, sizeof(activity.state), "%s/%s", cpufamily, cpu_s->name); } activity.timestamps.start = time(NULL); @@ -139,7 +144,7 @@ discord_load() if (discord_handle == NULL) { - discord_log("win_discord: couldn't load " PATH_DISCORD_DLL "\n"); + discord_log("discord: couldn't load " PATH_DISCORD_DLL "\n"); discord_close(); return(0); @@ -165,7 +170,7 @@ discord_init() result = discord_create(DISCORD_VERSION, ¶ms, &discord_core); if (result != DiscordResult_Ok) { - discord_log("win_discord: DiscordCreate returned %d\n", result); + discord_log("discord: DiscordCreate returned %d\n", result); discord_close(); return; } diff --git a/src/include/86box/win_discord.h b/src/include/86box/discord.h similarity index 90% rename from src/include/86box/win_discord.h rename to src/include/86box/discord.h index 9e56b9a32..90621e16d 100644 --- a/src/include/86box/win_discord.h +++ b/src/include/86box/discord.h @@ -17,6 +17,11 @@ #ifndef WIN_DISCORD_H # define WIN_DISCORD_H +#ifdef __cplusplus +extern "C" +{ +#endif + extern int discord_loaded; extern int discord_load(); @@ -25,4 +30,8 @@ extern void discord_close(); extern void discord_update_activity(int paused); extern void discord_run_callbacks(); -#endif \ No newline at end of file +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index ff8b31b02..c60e6d922 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -20,6 +20,8 @@ #ifndef EMU_PLAT_H # define EMU_PLAT_H +#include "86box/device.h" +#include "86box/machine.h" #ifndef GLOBAL # define GLOBAL extern #endif @@ -164,6 +166,25 @@ extern int ioctl_open(uint8_t id, char d); extern void ioctl_reset(uint8_t id); extern void ioctl_close(uint8_t id); +#ifdef __APPLE__ +#define thread_t plat_thread_t +#define event_t plat_event_t +#define mutex_t plat_mutex_t + +#define thread_create plat_thread_create +#define thread_wait plat_thread_wait +#define thread_create_event plat_thread_create_event +#define thread_set_event plat_thread_set_event +#define thread_reset_event plat_thread_reset_event +#define thread_wait_event plat_thread_wait_event +#define thread_destroy_event plat_thread_destroy_event + +#define thread_create_mutex plat_thread_create_mutex +#define thread_create_mutex_with_spin_count plat_thread_create_mutex_with_spin_count +#define thread_close_mutex plat_thread_close_mutex +#define thread_wait_mutex plat_thread_wait_mutex +#define thread_release_mutex plat_thread_release_mutex +#endif /* Thread support. */ typedef void thread_t; diff --git a/src/mac/CMakeLists.txt b/src/mac/CMakeLists.txt index 91759690f..6682d5bcd 100644 --- a/src/mac/CMakeLists.txt +++ b/src/mac/CMakeLists.txt @@ -48,6 +48,7 @@ configure_file(Info.plist.in Info.plist @ONLY) set_target_properties(86Box PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) -#set(XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "YES") -#set(XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-") +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) \ No newline at end of file diff --git a/src/minitrace/minitrace.c b/src/minitrace/minitrace.c index 11cae6b9a..32d2ebcae 100644 --- a/src/minitrace/minitrace.c +++ b/src/minitrace/minitrace.c @@ -30,6 +30,7 @@ #include #include #include +#include #endif #include @@ -66,8 +67,8 @@ typedef struct raw_event { static raw_event_t *event_buffer; static raw_event_t *flush_buffer; static volatile int event_count; -static __attribute__ ((aligned (32))) volatile long is_tracing = FALSE; -static __attribute__ ((aligned (32))) volatile long stop_flushing_requested = FALSE; +static __attribute__ ((aligned (32))) atomic_long is_tracing = FALSE; +static __attribute__ ((aligned (32))) atomic_long stop_flushing_requested = FALSE; static int is_flushing = FALSE; static int events_in_progress = 0; static int64_t time_offset; @@ -93,8 +94,6 @@ void mtr_flush_with_state(int); // mtr_time_s() // pthread basics #ifdef _WIN32 -#define atomic_load(a) InterlockedOr((a), 0) -#define atomic_store(a, b) InterlockedExchange((a), b) static int get_cur_thread_id() { return (int)GetCurrentThreadId(); @@ -162,6 +161,31 @@ static inline int get_cur_process_id() { return (int)getpid(); } +static pthread_t thread_handle = 0; +static void* thread_flush_proc(void* param) { + while(1) { + mtr_flush_with_state(0); + if(atomic_load(&stop_flushing_requested)) { + break; + } + } + return 0; +} +static void init_flushing_thread(void) { + pthread_mutex_lock(&mutex); + is_flushing = FALSE; + pthread_mutex_unlock(&mutex); + if (pthread_create(&thread_handle, NULL, thread_flush_proc, NULL) != 0) + { + thread_handle = 0; + } +} + +static void join_flushing_thread(void) { + if (thread_handle) pthread_join(thread_handle, NULL); + thread_handle = 0; +} + #if defined(BLACKBERRY) double mtr_time_s() { struct timespec time; @@ -269,9 +293,9 @@ void mtr_start() { #ifndef MTR_ENABLED return; #endif - pthread_cond_init(&buffer_not_full_cond); - pthread_cond_init(&buffer_full_cond); - atomic_store(&is_tracing, TRUE); + pthread_cond_init(&buffer_not_full_cond, NULL); + pthread_cond_init(&buffer_full_cond, NULL); + atomic_store(&is_tracing, TRUE); init_flushing_thread(); } diff --git a/src/network/slirp/CMakeLists.txt b/src/network/slirp/CMakeLists.txt index b7f995947..1f0458bdb 100644 --- a/src/network/slirp/CMakeLists.txt +++ b/src/network/slirp/CMakeLists.txt @@ -13,12 +13,27 @@ # Copyright 2020,2021 David Hrdlička. # -add_library(slirp STATIC tinyglib.c arp_table.c bootp.c cksum.c dnssearch.c if.c ip_icmp.c +add_library(slirp STATIC arp_table.c bootp.c cksum.c dnssearch.c if.c ip_icmp.c ip_input.c ip_output.c mbuf.c misc.c sbuf.c slirp.c socket.c tcp_input.c tcp_output.c tcp_subr.c tcp_timer.c udp.c util.c version.c) -#target_link_libraries(slirp wsock32 iphlpapi) -#target_link_libraries(slirp) if (CMAKE_SYSTEM_NAME MATCHES "Windows") -target_link_libraries(slirp wsock32 iphlpapi) + target_link_libraries(slirp wsock32 iphlpapi) +endif() + +if(QT) + if(UNIX AND NOT APPLE) + find_package(PkgConfig REQUIRED) + pkg_check_modules(GLIB_PKG IMPORTED_TARGET glib-2.0) + if (GLIB_PKG_FOUND) + target_compile_definitions(slirp PRIVATE TINYGLIB_USE_GLIB) + target_link_libraries(slirp PkgConfig::GLIB_PKG) + else() + message(ERROR "GLib development headers are required when compiling with Qt on Unix") + endif() + else() + target_sources(slirp PRIVATE tinyglib.c) + endif() +else() + target_sources(slirp PRIVATE tinyglib.c) endif() diff --git a/src/network/slirp/misc.c b/src/network/slirp/misc.c index 4b520fc43..3bea32ac1 100644 --- a/src/network/slirp/misc.c +++ b/src/network/slirp/misc.c @@ -11,7 +11,7 @@ #ifdef BSD #define g_strlcpy strlcpy #else -extern int g_strlcpy(gchar* dest, const gchar* src, gsize dest_size); +extern gsize g_strlcpy(gchar* dest, const gchar* src, gsize dest_size); #endif #endif diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt new file mode 100644 index 000000000..020a60cbe --- /dev/null +++ b/src/qt/CMakeLists.txt @@ -0,0 +1,220 @@ +# Find includes in corresponding build directories +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) + +find_package(Threads REQUIRED) + +add_library(plat STATIC + qt.c + qt_main.cpp + qt_platform.cpp +) + +add_library(ui STATIC + qt_ui.cpp + qt_cdrom.c + + qt_mainwindow.cpp + qt_mainwindow.hpp + qt_mainwindow.ui + qt_machinestatus.cpp + qt_machinestatus.hpp + qt_mediamenu.cpp + qt_mediamenu.hpp + qt_rendererstack.cpp + qt_rendererstack.hpp + qt_rendererstack.ui + qt_renderercommon.cpp + qt_renderercommon.hpp + qt_softwarerenderer.cpp + qt_softwarerenderer.hpp + qt_hardwarerenderer.cpp + qt_hardwarerenderer.hpp + + qt_settings.cpp + qt_settings.hpp + qt_settings.ui + + qt_settingsmachine.cpp + qt_settingsmachine.hpp + qt_settingsmachine.ui + qt_settingsdisplay.cpp + qt_settingsdisplay.hpp + qt_settingsdisplay.ui + qt_settingsinput.cpp + qt_settingsinput.hpp + qt_settingsinput.ui + qt_settingssound.cpp + qt_settingssound.hpp + qt_settingssound.ui + qt_settingsnetwork.cpp + qt_settingsnetwork.hpp + qt_settingsnetwork.ui + qt_settingsports.cpp + qt_settingsports.hpp + qt_settingsports.ui + qt_settingsstoragecontrollers.cpp + qt_settingsstoragecontrollers.hpp + qt_settingsstoragecontrollers.ui + qt_settingsharddisks.cpp + qt_settingsharddisks.hpp + qt_settingsharddisks.ui + qt_settingsfloppycdrom.cpp + qt_settingsfloppycdrom.hpp + qt_settingsfloppycdrom.ui + qt_settingsotherremovable.cpp + qt_settingsotherremovable.hpp + qt_settingsotherremovable.ui + qt_settingsotherperipherals.cpp + qt_settingsotherperipherals.hpp + qt_settingsotherperipherals.ui + qt_settings_bus_tracking.cpp + qt_settings_bus_tracking.hpp + + qt_deviceconfig.cpp + qt_deviceconfig.hpp + qt_deviceconfig.ui + qt_joystickconfiguration.cpp + qt_joystickconfiguration.hpp + qt_joystickconfiguration.ui + + qt_filefield.cpp + qt_filefield.hpp + qt_filefield.ui + qt_newfloppydialog.cpp + qt_newfloppydialog.hpp + qt_newfloppydialog.ui + qt_harddiskdialog.cpp + qt_harddiskdialog.hpp + qt_harddiskdialog.ui + + qt_harddrive_common.cpp + qt_harddrive_common.hpp + qt_models_common.cpp + qt_models_common.hpp + + qt_specifydimensions.h + qt_specifydimensions.cpp + qt_specifydimensions.ui + qt_soundgain.hpp + qt_soundgain.cpp + qt_soundgain.ui + + qt_styleoverride.cpp + qt_styleoverride.hpp + qt_progsettings.hpp + qt_progsettings.cpp + qt_progsettings.ui + qt_util.hpp + qt_util.cpp + + ../qt_resources.qrc +) + + +if(WIN32) + enable_language(RC) + target_sources(86Box PUBLIC ../win/86Box-qt.rc) + target_sources(plat PRIVATE win_joystick_rawinput.c) + target_link_libraries(86Box hid) + + # CMake 3.22 messed this up for clang/clang++ + # See https://gitlab.kitware.com/cmake/cmake/-/issues/22611 + if(MSVC OR (NOT MINGW AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)) + # MSVC linker adds its own manifest to the executable, which fails if + # we include ours in 86Box.rc. We therefore need to pass the manifest + # directly as as a source file, so the linker can use that instead. + set_property(SOURCE ../win/86Box-qt.rc PROPERTY COMPILE_DEFINITIONS NO_INCLUDE_MANIFEST) + target_sources(86Box PRIVATE ../win/86Box.manifest) + endif() +else() + target_sources(plat PRIVATE sdl_joystick.cpp) +endif() + +if(WIN32 AND NOT MINGW) + target_sources(plat PRIVATE ../win/win_opendir.c) +endif() + +if (APPLE) + target_sources(ui PRIVATE macos_event_filter.mm) +endif() + +if (WIN32) + target_sources(ui PRIVATE + qt_winrawinputfilter.hpp + qt_winrawinputfilter.cpp + qt_winmanagerfilter.hpp + qt_winmanagerfilter.cpp + ) +endif() + +target_link_libraries( + plat + PRIVATE + Qt${QT_MAJOR}::Widgets + Qt${QT_MAJOR}::Gui + Threads::Threads +) + +target_link_libraries( + ui + PRIVATE + Qt${QT_MAJOR}::Widgets + Qt${QT_MAJOR}::Gui + Qt${QT_MAJOR}::OpenGL + Threads::Threads +) + +# needed for static builds +if (WIN32) + qt_import_plugins(plat INCLUDE Qt${QT_MAJOR}::QWindowsIntegrationPlugin Qt${QT_MAJOR}::QICOPlugin QWindowsVistaStylePlugin) +endif() + +if (UNIX AND NOT APPLE) + find_package(X11 REQUIRED) + target_link_libraries(ui PRIVATE X11::X11) + find_package(PkgConfig REQUIRED) + pkg_check_modules(LIBEVDEV IMPORTED_TARGET libevdev) + if (LIBEVDEV_FOUND) + target_compile_definitions(ui PRIVATE EVDEV_INPUT) + target_link_libraries(ui PUBLIC PkgConfig::LIBEVDEV) + target_sources(ui PRIVATE evdev_mouse.cpp) + endif() + + find_package(ECM NO_MODULE) + if (ECM_FOUND) + list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) + find_package(Wayland COMPONENTS Client) + if (Wayland_FOUND) + target_link_libraries(ui PRIVATE Wayland::Client) + find_package(WaylandScanner REQUIRED) + if (WaylandScanner_FOUND) + set(WL_SOURCE_VAR) + ecm_add_wayland_client_protocol(WL_SOURCE_VAR PROTOCOL ${CMAKE_SOURCE_DIR}/wl_protocols/relative-pointer-unstable-v1.xml BASENAME relative-pointer-unstable-v1) + ecm_add_wayland_client_protocol(WL_SOURCE_VAR PROTOCOL ${CMAKE_SOURCE_DIR}/wl_protocols/pointer-constraints-unstable-v1.xml BASENAME pointer-constraints-unstable-v1) + target_include_directories(ui PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${Qt${QT_MAJOR}Gui_PRIVATE_INCLUDE_DIRS}) + target_sources(ui PRIVATE ${WL_SOURCE_VAR} wl_mouse.cpp) + target_compile_definitions(ui PRIVATE WAYLAND) + endif() + endif() + endif() +endif() +set(QM_FILES) +file(GLOB po_files "${CMAKE_CURRENT_SOURCE_DIR}/languages/*.po") +foreach(po_file ${po_files}) + get_target_property(LCONVERT_EXECUTABLE Qt${QT_MAJOR}::lconvert IMPORTED_LOCATION) + get_filename_component(_lconvert_bin_dir "${LCONVERT_EXECUTABLE}" DIRECTORY) + find_program(LCONVERT_EXECUTABLE lconvert HINTS "${_lconvert_bin_dir}") + + get_filename_component(PO_FILE_NAME ${po_file} NAME_WE) + add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/86box_${PO_FILE_NAME}.qm" + COMMAND ${LCONVERT_EXECUTABLE} -i ${po_file} -o ${CMAKE_CURRENT_BINARY_DIR}/86box_${PO_FILE_NAME}.qm + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + DEPENDS "${po_file}") + list(APPEND QM_FILES "${CMAKE_CURRENT_BINARY_DIR}/86box_${PO_FILE_NAME}.qm") + list(APPEND QM_FILES "${po_file}") +endforeach() +configure_file(qt_translations.qrc ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) +target_sources(ui PRIVATE ${QM_FILES} ${CMAKE_CURRENT_BINARY_DIR}/qt_translations.qrc) diff --git a/src/qt/TODO b/src/qt/TODO new file mode 100644 index 000000000..a8b0b4970 --- /dev/null +++ b/src/qt/TODO @@ -0,0 +1 @@ +* Joystick support diff --git a/src/qt/cocoa_mouse.hpp b/src/qt/cocoa_mouse.hpp new file mode 100644 index 000000000..8db79d9e8 --- /dev/null +++ b/src/qt/cocoa_mouse.hpp @@ -0,0 +1,16 @@ +#include +#include + +#if QT_VERSION_MAJOR >= 6 +#define result_t qintptr +#else +#define result_t long +#endif + +class CocoaEventFilter : public QAbstractNativeEventFilter +{ +public: + CocoaEventFilter() {}; + ~CocoaEventFilter(); + virtual bool nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) override; +}; diff --git a/src/qt/evdev_mouse.cpp b/src/qt/evdev_mouse.cpp new file mode 100644 index 000000000..cb4cd4ffe --- /dev/null +++ b/src/qt/evdev_mouse.cpp @@ -0,0 +1,102 @@ +#include "evdev_mouse.hpp" +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern "C" +{ +#include <86box/86box.h> +#include <86box/plat.h> +#include <86box/mouse.h> +} + +static std::vector> evdev_mice; +static std::atomic stopped = false; +static QThread* evdev_thread; + +static std::atomic evdev_mouse_rel_x = 0, evdev_mouse_rel_y = 0; + +void evdev_mouse_poll() +{ + if (!evdev_mice.size() || !mouse_capture) + { + evdev_mouse_rel_x = 0; + evdev_mouse_rel_y = 0; + return; + } + mouse_x = evdev_mouse_rel_x; + mouse_y = evdev_mouse_rel_y; + evdev_mouse_rel_x = evdev_mouse_rel_y = 0; +} + +void evdev_thread_func() +{ + while (!stopped) + { + for (int i = 0; i < evdev_mice.size(); i++) + { + struct input_event ev; + int rc = libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev); + if (rc == 0 && ev.type == EV_REL && mouse_capture) + { + if (ev.code == REL_X) evdev_mouse_rel_x += ev.value; + if (ev.code == REL_Y) evdev_mouse_rel_y += ev.value; + } + } + } + for (int i = 0; i < evdev_mice.size(); i++) + { + libevdev_free(evdev_mice[i].second); + close(evdev_mice[i].first); + } + evdev_mice.clear(); +} + +void evdev_stop() +{ + stopped = true; + evdev_thread->wait(); +} + +void evdev_init() +{ + for (int i = 0; i < 256; i++) + { + std::string evdev_device_path = "/dev/input/event" + std::to_string(i); + int fd = open(evdev_device_path.c_str(), O_NONBLOCK | O_RDONLY); + if (fd != -1) + { + libevdev* input_struct = nullptr; + int rc = libevdev_new_from_fd(fd, &input_struct); + if (rc <= -1) + { + close(fd); + continue; + } + else + { + if (!libevdev_has_event_type(input_struct, EV_REL) || !libevdev_has_event_code(input_struct, EV_KEY, BTN_LEFT)) + { + libevdev_free(input_struct); + close(fd); + continue; + } + evdev_mice.push_back(std::make_pair(fd, input_struct)); + } + } + else if (errno == ENOENT) break; + } + if (evdev_mice.size() != 0) + { + evdev_thread = QThread::create(evdev_thread_func); + evdev_thread->start(); + atexit(evdev_stop); + } +} diff --git a/src/qt/evdev_mouse.hpp b/src/qt/evdev_mouse.hpp new file mode 100644 index 000000000..7681771c6 --- /dev/null +++ b/src/qt/evdev_mouse.hpp @@ -0,0 +1,4 @@ +#ifdef EVDEV_INPUT +void evdev_init(); +void evdev_mouse_poll(); +#endif diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po new file mode 100644 index 000000000..4e2135271 --- /dev/null +++ b/src/qt/languages/cs-CZ.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Akce" + +msgid "&Keyboard requires capture" +msgstr "&Klávesnice vyžaduje záběr" + +msgid "&Right CTRL is left ALT" +msgstr "&Pravý Ctrl je levý Alt" + +msgid "&Hard Reset..." +msgstr "&Resetovat" + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "P&ozastavit" + +msgid "E&xit..." +msgstr "&Ukončit" + +msgid "&View" +msgstr "&Zobrazení" + +msgid "&Hide status bar" +msgstr "&Schovat stavový řádek" + +msgid "Hide &toolbar" +msgstr "Schovat panel &nástrojů" + +msgid "&Resizeable window" +msgstr "&Měnitelná velikost okna" + +msgid "R&emember size && position" +msgstr "&Pamatovat velikost a pozici" + +msgid "Re&nderer" +msgstr "&Renderer" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "&Zadat velikost..." + +msgid "F&orce 4:3 display ratio" +msgstr "&Dodržovat poměr stran 4:3" + +msgid "&Window scale factor" +msgstr "&Násobek zvětšení okna" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Metoda &filtrování" + +msgid "&Nearest" +msgstr "&Nejbližší" + +msgid "&Linear" +msgstr "&Lineární" + +msgid "Hi&DPI scaling" +msgstr "Š&kálování HiDPI" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Celá obrazovka\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "Režím roztá&hnutí při celé obrazovce" + +msgid "&Full screen stretch" +msgstr "&Roztáhnout" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Zachovat poměr stran" + +msgid "&Integer scale" +msgstr "&Celočíselné škálování" + +msgid "E&GA/(S)VGA settings" +msgstr "Nastavení pro E&GA a (S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "&Převrátit barvy" + +msgid "VGA screen &type" +msgstr "&Typ VGA monitoru" + +msgid "RGB &Color" +msgstr "RGB &barevný" + +msgid "&RGB Grayscale" +msgstr "&Odstíny šedi" + +msgid "&Amber monitor" +msgstr "&Jantarová obrazovka" + +msgid "&Green monitor" +msgstr "&Zelená obrazovka" + +msgid "&White monitor" +msgstr "&Bílá obrazovka" + +msgid "Grayscale &conversion type" +msgstr "Převod na &odstíny šedi" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Průměr" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "Přesah obrazu CGA/PCjr/Tandy/E&GA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "&Upravit kontrast černobílé obrazovky" + +msgid "&Media" +msgstr "&Média" + +msgid "&Tools" +msgstr "&Nástroje" + +msgid "&Settings..." +msgstr "&Nastavení..." + +msgid "&Update status bar icons" +msgstr "&Aktualizovat ikony stavového řádku" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Pořídit &screenshot\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Předvolby..." + +msgid "Enable &Discord integration" +msgstr "Povolit integraci s &Discordem" + +msgid "Sound &gain..." +msgstr "&Zesílení zvuku" + +msgid "Begin trace\tCtrl+T" +msgstr "Začít trace\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Zastavit trace\tCtrl+T" + +msgid "&Logging" +msgstr "&Záznamy" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Povolit záznamy BusLogic\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Povolit záznamy CD-ROM\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Povolit záznamy diskety (86F)\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Povolit záznamy disketového řadiče\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Povolit záznamy IDE\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Povolit záznamy sériového portu\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Povolit záznamy sítě\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "Zaznamenat do &logu zarážku\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "Zaznamenat obsah &video RAM\tCtrl+F1" + +msgid "&Help" +msgstr "Ná&pověda" + +msgid "&Documentation..." +msgstr "&Dokumentace" + +msgid "&About 86Box..." +msgstr "&O programu 86Box" + +msgid "&New image..." +msgstr "&Nový obraz..." + +msgid "&Existing image..." +msgstr "&Existující obraz..." + +msgid "Existing image (&Write-protected)..." +msgstr "Existující obraz (&ochrana proti zápisu)..." + +msgid "&Record" +msgstr "&Nahrávat" + +msgid "&Play" +msgstr "&Přehrát" + +msgid "&Rewind to the beginning" +msgstr "Přetočit na &začátek" + +msgid "&Fast forward to the end" +msgstr "Přetočit na &konec" + +msgid "E&ject" +msgstr "&Vyjmout" + +msgid "&Image..." +msgstr "&Obraz..." + +msgid "E&xport to 86F..." +msgstr "E&xportovat do 86F..." + +msgid "&Mute" +msgstr "&Ztišit" + +msgid "E&mpty" +msgstr "&Vyjmout" + +msgid "&Reload previous image" +msgstr "&Načíst znova předchozí obraz" + +msgid "&Image" +msgstr "&Obraz..." + +msgid "Target &framerate" +msgstr "&Cílová snímková frekvence" + +msgid "&Sync with video" +msgstr "&Synchronizovat s obrazem" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Zvolit shader..." + +msgid "&Remove shader" +msgstr "&Odebrat shader" + +msgid "Preferences" +msgstr "Předvolby" + +msgid "Sound Gain" +msgstr "Zesílení zvuku" + +msgid "New Image" +msgstr "Nový obraz" + +msgid "Settings" +msgstr "Nastavení" + +msgid "Specify Main Window Dimensions" +msgstr "Zadat rozměry hlavního okna" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Storno" + +msgid "Save these settings as &global defaults" +msgstr "Uložit toto nastavení jako &globální výchozí stav" + +msgid "&Default" +msgstr "&Výchozí" + +msgid "Language:" +msgstr "Jazyk:" + +msgid "Icon set:" +msgstr "Sada ikon:" + +msgid "Gain" +msgstr "Zesílení" + +msgid "File name:" +msgstr "Název souboru:" + +msgid "Disk size:" +msgstr "Velikost disku:" + +msgid "RPM mode:" +msgstr "Režím ot./m:" + +msgid "Progress:" +msgstr "Průběh:" + +msgid "Width:" +msgstr "Šířka:" + +msgid "Height:" +msgstr "Výška:" + +msgid "Lock to this size" +msgstr "Uzamknout na tyto rozměry" + +msgid "Machine type:" +msgstr "Typ počítače:" + +msgid "Machine:" +msgstr "Počítač:" + +msgid "Configure" +msgstr "Nastavit" + +msgid "CPU type:" +msgstr "Procesor:" + +msgid "Speed:" +msgstr "Rychlost:" + +msgid "FPU:" +msgstr "Koprocesor:" + +msgid "Wait states:" +msgstr "Čekací stavy:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Pamět:" + +msgid "Time synchronization" +msgstr "Synchronizace času" + +msgid "Disabled" +msgstr "Vypnuta" + +msgid "Enabled (local time)" +msgstr "Zapnuta (místní čas)" + +msgid "Enabled (UTC)" +msgstr "Zapnuta (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dynamický překladač" + +msgid "Video:" +msgstr "Grafika:" + +msgid "Voodoo Graphics" +msgstr "Použít grafický akcelerátor Voodoo" + +msgid "Mouse:" +msgstr "Myš:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card:" +msgstr "Zvuková karta:" + +msgid "MIDI Out Device:" +msgstr "MIDI výstup:" + +msgid "MIDI In Device:" +msgstr "MIDI vstup:" + +msgid "Standalone MPU-401" +msgstr "Samostatný MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "Použít zvuk FLOAT32" + +msgid "Network type:" +msgstr "Druh sítě:" + +msgid "PCap device:" +msgstr "PCap zařízení:" + +msgid "Network adapter:" +msgstr "Síťový adaptér:" + +msgid "COM1 Device:" +msgstr "Zařízení na COM1:" + +msgid "COM2 Device:" +msgstr "Zařízení na COM2:" + +msgid "COM3 Device:" +msgstr "Zařízení na COM3:" + +msgid "COM4 Device:" +msgstr "Zařízení na COM4:" + +msgid "LPT1 Device:" +msgstr "Zařízení na LPT1:" + +msgid "LPT2 Device:" +msgstr "Zařízení na LPT2:" + +msgid "LPT3 Device:" +msgstr "Zařízení na LPT3:" + +msgid "LPT4 Device:" +msgstr "Zařízení na LPT4:" + +msgid "Serial port 1" +msgstr "Povolit port COM1" + +msgid "Serial port 2" +msgstr "Povolit port COM2" + +msgid "Serial port 3" +msgstr "Povolit port COM3" + +msgid "Serial port 4" +msgstr "Povolit port COM4" + +msgid "Parallel port 1" +msgstr "Povolit port LPT1" + +msgid "Parallel port 2" +msgstr "Povolit port LPT2" + +msgid "Parallel port 3" +msgstr "Povolit port LPT3" + +msgid "Parallel port 4" +msgstr "Povolit port LPT4" + +msgid "HD Controller:" +msgstr "Řadič disku:" + +msgid "FD Controller:" +msgstr "Disketový řadič:" + +msgid "Tertiary IDE Controller" +msgstr "Třetí řadič IDE" + +msgid "Quaternary IDE Controller" +msgstr "Čtvrtý řadič IDE" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Řadič 1:" + +msgid "Controller 2:" +msgstr "Řadič 2:" + +msgid "Controller 3:" +msgstr "Řadič 3:" + +msgid "Controller 4:" +msgstr "Řadič 4:" + +msgid "Cassette" +msgstr "Kazeta" + +msgid "Hard disks:" +msgstr "Pevné disky:" + +msgid "&New..." +msgstr "&Nový..." + +msgid "&Existing..." +msgstr "&Existující..." + +msgid "&Remove" +msgstr "&Odebrat" + +msgid "Bus:" +msgstr "Sběrnice:" + +msgid "Channel:" +msgstr "Kanál:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Zadat..." + +msgid "Sectors:" +msgstr "Sektory:" + +msgid "Heads:" +msgstr "Hlavy:" + +msgid "Cylinders:" +msgstr "Cylindry:" + +msgid "Size (MB):" +msgstr "Velikost (MB):" + +msgid "Type:" +msgstr "Typ:" + +msgid "Image Format:" +msgstr "Formát obrazu:" + +msgid "Block Size:" +msgstr "Velikost bloků:" + +msgid "Floppy drives:" +msgstr "Disketové mechaniky:" + +msgid "Turbo timings" +msgstr "Turbo časování" + +msgid "Check BPB" +msgstr "Kontrola BPB" + +msgid "CD-ROM drives:" +msgstr "Mechaniky CD-ROM:" + +msgid "MO drives:" +msgstr "Magnetooptické mechaniky:" + +msgid "ZIP drives:" +msgstr "Mechaniky ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA hodiny:" + +msgid "ISA Memory Expansion" +msgstr "ISA rozšíření paměti" + +msgid "Card 1:" +msgstr "Karta 1:" + +msgid "Card 2:" +msgstr "Karta 2:" + +msgid "Card 3:" +msgstr "Karta 3:" + +msgid "Card 4:" +msgstr "Karta 4:" + +msgid "ISABugger device" +msgstr "Zařízení ISABugger" + +msgid "POST card" +msgstr "Karta pro kódy POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Chyba" + +msgid "Fatal error" +msgstr "Kritická chyba" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Stiskněte Ctrl+Alt+Page Down pro návrat z režimu celé obrazovky." + +msgid "Speed" +msgstr "Rychlost" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Obrazy ZIP disků" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box nenalezl žádné použitelné image pamětí ROM.\n\nStáhněte sadu obrazů ROM a extrahujte ji do složky \"roms\"." + +msgid "(empty)" +msgstr "(prázdné)" + +msgid "All files" +msgstr "All files" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Zap." + +msgid "Off" +msgstr "Vyp." + +msgid "All images" +msgstr "Všechny obrazy disků" + +msgid "Basic sector images" +msgstr "Základní sektorové obrazy" + +msgid "Surface images" +msgstr "Obrazy povrchu" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Počítač \"%hs\" není dostupný, jelikož chybí obraz jeho paměti ROM ve složce \"roms/machines\". Konfigurace se přepne na jiný dostupný počítač." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Video adaptér \"%hs\" není dostupný, jelikož chybí obraz jeho paměti ROM ve složce \"roms/video\". Konfigurace se přepne na jiný dostupný adaptér." + +msgid "Machine" +msgstr "Počítač" + +msgid "Display" +msgstr "Obraz" + +msgid "Input devices" +msgstr "Vstupní zařízení" + +msgid "Sound" +msgstr "Zvuk" + +msgid "Network" +msgstr "Síť" + +msgid "Ports (COM & LPT)" +msgstr "COM a LPT porty" + +msgid "Storage controllers" +msgstr "Řadiče úložiště" + +msgid "Hard disks" +msgstr "Pevné disky" + +msgid "Floppy & CD-ROM drives" +msgstr "Disketové a CD-ROM mechaniky" + +msgid "Other removable devices" +msgstr "Další vyměnitelná zařízení" + +msgid "Other peripherals" +msgstr "Jiné příslušenství" + +msgid "Click to capture mouse" +msgstr "Klikněte pro zabraní myši" + +msgid "Press F8+F12 to release mouse" +msgstr "Stiskněte F8+F12 pro uvolnění myši" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Stiskněte F8+F12 nebo prostřední tlačítko pro uvolnění myši" + +msgid "Unable to initialize FluidSynth" +msgstr "Nastala chyba při inicializaci knihovny FluidSynth." + +msgid "Bus" +msgstr "Sběrnice" + +msgid "File" +msgstr "Soubor" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Nastala chyba při inicializaci video rendereru." + +msgid "Default" +msgstr "Výchozí" + +msgid "%i Wait state(s)" +msgstr "%i čekací stav(y)" + +msgid "Type" +msgstr "Typ" + +msgid "Failed to set up PCap" +msgstr "Nastala chyba při inicializaci knihovny PCap" + +msgid "No PCap devices found" +msgstr "Nebyla nalezena žádná PCap zařízení" + +msgid "Invalid PCap device" +msgstr "Neplatné PCap zařízení" + +msgid "Standard 2-button joystick(s)" +msgstr "Standardní 2tlačítkový joystick" + +msgid "Standard 4-button joystick" +msgstr "Standardní 4tlačítkový joystick" + +msgid "Standard 6-button joystick" +msgstr "Standardní 6tlačítkový joystick" + +msgid "Standard 8-button joystick" +msgstr "Standardní 8tlačítkový joystick" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Žadné" + +msgid "Unable to load keyboard accelerators." +msgstr "Nebylo možné nahrát klávesnicové zkratky." + +msgid "Unable to register raw input." +msgstr "Nebylo možné zaregistrovat raw input." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Disketová mechanika %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Rozšířené sektorové obrazy" + +msgid "Flux images" +msgstr "Obrazy magnetického toku" + +msgid "Unable to initialize FreeType" +msgstr "Nastala chyba při inicializaci knihovny FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Nastala chyba při inicializaci knihovny SDL, je potřeba SDL2.dll" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Opravdu chcete resetovat emulovaný počítač?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Opravdu chcete ukončit 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Nastala chyba při inicializaci knihovny Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Obrazy MO" + +msgid "Welcome to 86Box!" +msgstr "Vítejte v programu 86Box!" + +msgid "Internal controller" +msgstr "Vestavěný řadič" + +msgid "Exit" +msgstr "Ukončit" + +msgid "No ROMs found" +msgstr "Nebyly nalezeny žádné obrazy ROM" + +msgid "Do you want to save the settings?" +msgstr "Chcete uložit nastavení?" + +msgid "This will hard reset the emulated machine." +msgstr "Pokračováním se resetuje emulovaný počítač." + +msgid "Save" +msgstr "Uložit" + +msgid "About 86Box" +msgstr "O programu 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Emulátor starých počítačů\n\nAutoři: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nZveřejněno pod licencí GNU General Public License verze 2 nebo novější. Viz soubor LICENSE pro více informací." + +msgid "Hardware not available" +msgstr "Hardware není dostupný" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Ujistěte se, že je nainstalován libpcap a používáte síťové připojení s ním kompatibilní." + +msgid "Invalid configuration" +msgstr "Neplatná konfigurace" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " je potřeba pro emulaci ESC/P tiskáren." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " je potřeba pro automatický převod PostScript dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PostScriptovou tiskárnu budou uloženy jako PostScript (.ps) soubory." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " je potřeba pro MIDI výstup přes knihovnu FluidSynth." + +msgid "Entering fullscreen mode" +msgstr "Vstup do režimu celé obrazovky" + +msgid "Don't show this message again" +msgstr "Nezobrazovat dále tuto zprávu" + +msgid "Don't exit" +msgstr "Neukončovat" + +msgid "Reset" +msgstr "Resetovat" + +msgid "Don't reset" +msgstr "Neresetovat" + +msgid "CD-ROM images" +msgstr "Obraz CD-ROM disku" + +msgid "%hs Device Configuration" +msgstr "Konfigurace zařízení %hs" + +msgid "Monitor in sleep mode" +msgstr "Monitor je v režimu spánku" + +msgid "OpenGL Shaders" +msgstr "Shadery OpenGL" + +msgid "OpenGL options" +msgstr "Možnosti OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Pokoušíte se spustit nepodporovanou konfiguraci" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Pro tuto konfiguraci bylo vypnuto filtrování procesorů podle zvoleného počítače.\n\nToto umožňuje zvolit procesor, který by jinak se zvoleným počítačem nebyl kompatibilní. Můžou však nastat potíže s BIOSem nebo jiným softwarem.\n\nPovolení tohoto nastavení není oficiálně podporováno a jakákoliv hlášení o chybách mohou být uzavřeny jako neplatné." + +msgid "Continue" +msgstr "Pokračovat" + +msgid "Cassette: %s" +msgstr "Kazeta: %s" + +msgid "Cassette images" +msgstr "Kazetové nahrávky" + +msgid "Cartridge %i: %ls" +msgstr "Cartridge %i: %ls" + +msgid "Cartridge images" +msgstr "Obrazy cartridge" + +msgid "Error initializing renderer" +msgstr "Error initializing renderer" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + +msgid "Resume execution" +msgstr "Obnovit" + +msgid "Pause execution" +msgstr "Pozastavit" + +msgid "Press Ctrl+Alt+Del" +msgstr "Stisknout Ctrl+Alt+Delete" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Stisknout Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Resetovat" + +msgid "ACPI shutdown" +msgstr "Vypnout skrze rozhraní ACPI" + +msgid "Hard disk (%s)" +msgstr "Pevný disk (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "CD-ROM mechaniky pro rozhraní MFM/RLL nebo ESDI nikdy neexistovaly" + +msgid "Custom..." +msgstr "Vlastní..." + +msgid "Custom (large)..." +msgstr "Vlastní (velký)..." + +msgid "Add New Hard Disk" +msgstr "Přidat nový pevný disk" + +msgid "Add Existing Hard Disk" +msgstr "Přidat existující pevný disk" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Obraz disku formátu HDI nemůžou být větší než 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Obraz disku nemůžou být větší než 127 GB." + +msgid "Hard disk images" +msgstr "Obrazy pevného disku" + +msgid "Unable to read file" +msgstr "Nebylo možné přečíst soubor" + +msgid "Unable to write file" +msgstr "Nebylo možné zapisovat do souboru" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Obraz disku ve formátu HDI nebo HDX s velikostí sektoru jinou než 512 bajtů nejsou podporovány." + +msgid "USB is not yet supported" +msgstr "USB zatím není podporováno." + +msgid "Disk image file already exists" +msgstr "Soubor obrazu disku již existuje" + +msgid "Please specify a valid file name." +msgstr "Zadejte platný název souboru." + +msgid "Disk image created" +msgstr "Obraz disku byl vytvořen" + +msgid "Make sure the file exists and is readable." +msgstr "Ujistěte se, že soubor existuje a lze jej přečíst." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Ujistěte se, že se do složky, kde se má soubor uložit, dá zapisovat." + +msgid "Disk image too large" +msgstr "Obraz disku je příliš velký" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Nezapomeňte nově vytvořený disk rozdělit a naformátovat." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Zvolený soubor bude přepsán. Opravdu jej chcete použít?" + +msgid "Unsupported disk image" +msgstr "Nepodporovaný obraz disku" + +msgid "Overwrite" +msgstr "Přepsat" + +msgid "Don't overwrite" +msgstr "Nepřepisovat" + +msgid "Raw image (.img)" +msgstr "Surový obraz (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI obraz (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX obraz (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD s pevnou velikostí (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD s dynamickou velikostí (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Rozdílový VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Velké bloky (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Malé bloky (512 KB)" + +msgid "VHD files" +msgstr "Soubory VHD" + +msgid "Select the parent VHD" +msgstr "Vyberte nadřazený virtuální disk" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "To může znamenat, že se obsahy nadřazeného disku změnily po vytvoření rozdílového disku.\n\nTato chyba také může nastat, pokud byl obraz disku kopírován nebo přesunut, nebo kvůli chybě v programu, který jej vytvořil.\n\nChcete časová razítka opravit?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Časová razítka nadřazeného a podřazeného disku nesouhlasí" + +msgid "Could not fix VHD timestamp." +msgstr "Nebylo možné opravit časové razítko VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "Dokonalé otáčky za minutu" + +msgid "1%% below perfect RPM" +msgstr "1%% pod dokonalými ot./m" + +msgid "1.5%% below perfect RPM" +msgstr "1.5%% pod dokonalými ot./m" + +msgid "2%% below perfect RPM" +msgstr "2%% pod dokonalými ot./m" + +msgid "(System Default)" +msgstr "(Výchozí nastavení systému)" + diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po new file mode 100644 index 000000000..3f2133deb --- /dev/null +++ b/src/qt/languages/de-DE.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Aktionen" + +msgid "&Keyboard requires capture" +msgstr "&Tastatur benötigt das Einfangen des Mauszeigers" + +msgid "&Right CTRL is left ALT" +msgstr "&Die rechte Strg-Taste ist die Linke Alt-Taste" + +msgid "&Hard Reset..." +msgstr "&Hard-Reset..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Strg+Alt+Entf\tStrg+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Strg+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pause" + +msgid "E&xit..." +msgstr "Be&enden..." + +msgid "&View" +msgstr "&Ansicht" + +msgid "&Hide status bar" +msgstr "&Statusleiste ausblenden" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "&Größenverstellbares Fenster" + +msgid "R&emember size && position" +msgstr "&Größe && Position merken" + +msgid "Re&nderer" +msgstr "Re&nderer" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0-Kern)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Fenstergröße einstellen..." + +msgid "F&orce 4:3 display ratio" +msgstr "&4:3-Seitenverhältnis erzwingen" + +msgid "&Window scale factor" +msgstr "&Fensterskalierungsfaktor" + +msgid "&0.5x" +msgstr "&0,5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1,&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Filteringmethode" + +msgid "&Nearest" +msgstr "&Nearest" + +msgid "&Linear" +msgstr "&Linear" + +msgid "Hi&DPI scaling" +msgstr "Hi&DPI-Skalierung" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Vollbild\tStrg+Alt+BildAuf" + +msgid "Fullscreen &stretch mode" +msgstr "&Stretching-Modus im Vollbildmodus" + +msgid "&Full screen stretch" +msgstr "&Vollbild-Stretching" + +msgid "&4:3" +msgstr "&4:3-Seitenverhältnis erzwingen" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Quadratische Pixel (Seitenverhältnis beibehalten)" + +msgid "&Integer scale" +msgstr "&Integer-Skalierung" + +msgid "E&GA/(S)VGA settings" +msgstr "E&GA/(S)VGA-Einstellungen" + +msgid "&Inverted VGA monitor" +msgstr "&Invertierte VGA-Anzeige" + +msgid "VGA screen &type" +msgstr "&VGA-Bildschirmtyp" + +msgid "RGB &Color" +msgstr "&RGB-Farbe" + +msgid "&RGB Grayscale" +msgstr "&RGB-Graustufen" + +msgid "&Amber monitor" +msgstr "&Bernstein-Monitor" + +msgid "&Green monitor" +msgstr "&Grüner Monitor" + +msgid "&White monitor" +msgstr "&Weißer Monitor" + +msgid "Grayscale &conversion type" +msgstr "Methode zur &Graustufenkonversion" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Durchschnittsmethode" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "Overscan für CGA/PCjr/Tandy/E&GA/(S)VGA-Displays" + +msgid "Change contrast for &monochrome display" +msgstr "Kontrast für &monochrome Displays ändern" + +msgid "&Media" +msgstr "&Medien" + +msgid "&Tools" +msgstr "&Werkzeuge" + +msgid "&Settings..." +msgstr "&Optionen..." + +msgid "&Update status bar icons" +msgstr "&Statusleistenicons aktualisieren" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "S&creenshot aufnehmen\tStrg+F11" + +msgid "&Preferences..." +msgstr "&Einstellungen..." + +msgid "Enable &Discord integration" +msgstr "&Discord-Integration aktivieren" + +msgid "Sound &gain..." +msgstr "&Klangverstärkung..." + +msgid "Begin trace\tCtrl+T" +msgstr "Tracing starten\tStrg+T" + +msgid "End trace\tCtrl+T" +msgstr "Tracing beenden\tStrg+T" + +msgid "&Logging" +msgstr "&Logging" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "BusLogic-Logs aktivieren\tStrg+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "CD-ROM-Logs aktivieren\tStrg+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Disketten (86F)-Logs aktivieren\tStrg+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Diskettencontroller-Logs aktivieren\tStrg+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "IDE-Logs aktivieren\tStrg+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Seriell-Port-Logs aktivieren\tStrg+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Netzwerk-Logs aktivieren\tStrg+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Breakpoint für die Log-Datei\tStrg+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "&Video-RAM dumpen\tStrg+F1" + +msgid "&Help" +msgstr "&Hilfe" + +msgid "&Documentation..." +msgstr "&Dokumentation..." + +msgid "&About 86Box..." +msgstr "&Über 86Box..." + +msgid "&New image..." +msgstr "&Neues Image..." + +msgid "&Existing image..." +msgstr "&Bestehendes Image..." + +msgid "Existing image (&Write-protected)..." +msgstr "Bestehendes Image (&schreibgeschützt)..." + +msgid "&Record" +msgstr "&Aufnehmen" + +msgid "&Play" +msgstr "&Abspielen" + +msgid "&Rewind to the beginning" +msgstr "&An den Anfang zurückspulen" + +msgid "&Fast forward to the end" +msgstr "&An das Ende vorspulen" + +msgid "E&ject" +msgstr "A&uswerfen" + +msgid "&Image..." +msgstr "&Cartridgeimage..." + +msgid "E&xport to 86F..." +msgstr "&In das 86F-Format e&xportieren..." + +msgid "&Mute" +msgstr "&Stummschalten" + +msgid "E&mpty" +msgstr "L&eer" + +msgid "&Reload previous image" +msgstr "&Voriges Image neu laden" + +msgid "&Image" +msgstr "&Image" + +msgid "Target &framerate" +msgstr "Ziel&framerate" + +msgid "&Sync with video" +msgstr "&Mit Videoausgabe synchronisieren" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Shader auswählen..." + +msgid "&Remove shader" +msgstr "&Shader entfernen" + +msgid "Preferences" +msgstr "Einstellungen" + +msgid "Sound Gain" +msgstr "Klangverstärkung" + +msgid "New Image" +msgstr "Neues Image" + +msgid "Settings" +msgstr "Optionen" + +msgid "Specify Main Window Dimensions" +msgstr "Fenstergröße einstellen" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Abbrechen" + +msgid "Save these settings as &global defaults" +msgstr "Einstellungen als &globalen Standard speichern" + +msgid "&Default" +msgstr "&Standard" + +msgid "Language:" +msgstr "Sprache:" + +msgid "Icon set:" +msgstr "Icon-Satz:" + +msgid "Gain" +msgstr "Verstärkung" + +msgid "File name:" +msgstr "Dateiname:" + +msgid "Disk size:" +msgstr "Plattengröße:" + +msgid "RPM mode:" +msgstr "Drehzahlmodus:" + +msgid "Progress:" +msgstr "Fortschritt:" + +msgid "Width:" +msgstr "Breite:" + +msgid "Height:" +msgstr "Höhe:" + +msgid "Lock to this size" +msgstr "Feste Größe" + +msgid "Machine type:" +msgstr "Systemtyp:" + +msgid "Machine:" +msgstr "Maschine:" + +msgid "Configure" +msgstr "Einstellen" + +msgid "CPU type:" +msgstr "CPU-Typ:" + +msgid "Speed:" +msgstr "Geschwindigkeit:" + +msgid "FPU:" +msgstr "FPU-Einheit:" + +msgid "Wait states:" +msgstr "Wartezustände:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Hauptspeicher:" + +msgid "Time synchronization" +msgstr "Zeitsynchronisierung" + +msgid "Disabled" +msgstr "Deaktiviert" + +msgid "Enabled (local time)" +msgstr "Aktiviert (Lokale Uhrzeit)" + +msgid "Enabled (UTC)" +msgstr "Aktiviert (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dynamischer Recompiler" + +msgid "Video:" +msgstr "Videokarte:" + +msgid "Voodoo Graphics" +msgstr "Voodoo-Grafik" + +msgid "Mouse:" +msgstr "Maus:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card:" +msgstr "Soundkarte:" + +msgid "MIDI Out Device:" +msgstr "MIDI Out-Gerät:" + +msgid "MIDI In Device:" +msgstr "MIDI In-Gerät:" + +msgid "Standalone MPU-401" +msgstr "Standalone-MPU-401-Gerät" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "FLOAT32-Wiedergabe benutzen" + +msgid "Network type:" +msgstr "Netzwerktyp:" + +msgid "PCap device:" +msgstr "PCap-Gerät:" + +msgid "Network adapter:" +msgstr "Netzwerkadapter:" + +msgid "COM1 Device:" +msgstr "COM1-Gerät:" + +msgid "COM2 Device:" +msgstr "COM2-Gerät:" + +msgid "COM3 Device:" +msgstr "COM3-Gerät:" + +msgid "COM4 Device:" +msgstr "COM4-Gerät:" + +msgid "LPT1 Device:" +msgstr "LPT1-Gerät:" + +msgid "LPT2 Device:" +msgstr "LPT2-Gerät:" + +msgid "LPT3 Device:" +msgstr "LPT3-Gerät:" + +msgid "LPT4 Device:" +msgstr "LPT4-Gerät:" + +msgid "Serial port 1" +msgstr "Serielle Schnittstelle 1" + +msgid "Serial port 2" +msgstr "Serielle Schnittstelle 2" + +msgid "Serial port 3" +msgstr "Serielle Schnittstelle 3" + +msgid "Serial port 4" +msgstr "Serielle Schnittstelle 4" + +msgid "Parallel port 1" +msgstr "Parallelport 1" + +msgid "Parallel port 2" +msgstr "Parallelport 2" + +msgid "Parallel port 3" +msgstr "Parallelport 3" + +msgid "Parallel port 4" +msgstr "Parallelport 4" + +msgid "HD Controller:" +msgstr "HDD-Controller:" + +msgid "FD Controller:" +msgstr "FD-Controller:" + +msgid "Tertiary IDE Controller" +msgstr "Tertiärer IDE-Controller" + +msgid "Quaternary IDE Controller" +msgstr "Quartärer IDE-Controller" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Controller 1:" + +msgid "Controller 2:" +msgstr "Controller 2:" + +msgid "Controller 3:" +msgstr "Controller 3:" + +msgid "Controller 4:" +msgstr "Controller 4:" + +msgid "Cassette" +msgstr "Kassette" + +msgid "Hard disks:" +msgstr "Festplatten:" + +msgid "&New..." +msgstr "&Neu..." + +msgid "&Existing..." +msgstr "&Vorhanden..." + +msgid "&Remove" +msgstr "&Entfernen" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Kanal:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Festlegen..." + +msgid "Sectors:" +msgstr "Sektoren:" + +msgid "Heads:" +msgstr "Köpfe:" + +msgid "Cylinders:" +msgstr "Zylinder:" + +msgid "Size (MB):" +msgstr "Größe (MB):" + +msgid "Type:" +msgstr "Typ:" + +msgid "Image Format:" +msgstr "Imageformat:" + +msgid "Block Size:" +msgstr "Blockgröße:" + +msgid "Floppy drives:" +msgstr "Diskettenlaufwerke:" + +msgid "Turbo timings" +msgstr "Turbo-Timings" + +msgid "Check BPB" +msgstr "BPB überprüfen" + +msgid "CD-ROM drives:" +msgstr "CD-ROM-Laufwerke:" + +msgid "MO drives:" +msgstr "MO-Laufwerke:" + +msgid "ZIP drives:" +msgstr "ZIP-Laufwerke:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA-Echtzeituhr:" + +msgid "ISA Memory Expansion" +msgstr "ISA-Speichererweiterung:" + +msgid "Card 1:" +msgstr "Steckkarte 1:" + +msgid "Card 2:" +msgstr "Steckkarte 2:" + +msgid "Card 3:" +msgstr "Steckkarte 3:" + +msgid "Card 4:" +msgstr "Steckkarte 4:" + +msgid "ISABugger device" +msgstr "ISABugger-Gerät" + +msgid "POST card" +msgstr "POST-Code-Karte" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Fehler" + +msgid "Fatal error" +msgstr "Fataler Fehler" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Bitte Strg+Alt+Bild ab zur Rückkehr in den Fenstermodus drücken." + +msgid "Speed" +msgstr "Geschwindigkeit" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIP-Images" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box konnte keine nutzbaren ROM-Dateien finden.\n\nBitte besuchen Sie download, laden ein ROM-Set herunter und extrahieren dies in das \"roms\"-Verzeichnis." + +msgid "(empty)" +msgstr "(leer)" + +msgid "All files" +msgstr "Alle Dateien" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "An" + +msgid "Off" +msgstr "Aus" + +msgid "All images" +msgstr "Alle Images" + +msgid "Basic sector images" +msgstr "Basissektorimages" + +msgid "Surface images" +msgstr "Oberflächenimages" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Das System \"%hs\" ist aufgrund von fehlenden ROMs im Verzeichnis roms/machines nicht verfügbar. Es wird auf ein verfügbares System gewechselt." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Die Videokarte \"%hs\" ist aufgrund von fehlenden ROMs im Verzeichnis roms/video nicht verfügbar. Es wird auf eine verfügbare Videokarte gewechselt." + +msgid "Machine" +msgstr "System" + +msgid "Display" +msgstr "Anzeige" + +msgid "Input devices" +msgstr "Eingabegeräte" + +msgid "Sound" +msgstr "Multimedia" + +msgid "Network" +msgstr "Netzwerk" + +msgid "Ports (COM & LPT)" +msgstr "Anschlüsse (COM & LPT)" + +msgid "Storage controllers" +msgstr "Speichercontroller" + +msgid "Hard disks" +msgstr "Festplatten" + +msgid "Floppy & CD-ROM drives" +msgstr "Disketten- & CD-ROM-Laufwerke" + +msgid "Other removable devices" +msgstr "Andere Wechsellaufwerke" + +msgid "Other peripherals" +msgstr "Andere Peripheriegeräte" + +msgid "Click to capture mouse" +msgstr "Zum Einfangen des Mauszeigers bitte klicken" + +msgid "Press F8+F12 to release mouse" +msgstr "Bitte F8+F12 zur Mausfreigabe drücken" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Bitte F8+F12 oder die mittlere Maustaste zur Mausfreigabe drücken" + +msgid "Unable to initialize FluidSynth" +msgstr "FluidSynth konnte nicht initialisiert werden" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "Datei" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Der Videorenderer konnte nicht initialisiert werden." + +msgid "Default" +msgstr "Standard" + +msgid "%i Wait state(s)" +msgstr "%i Wartezustände" + +msgid "Type" +msgstr "Typ" + +msgid "Failed to set up PCap" +msgstr "PCap konnte nicht eingerichtet werden" + +msgid "No PCap devices found" +msgstr "Keine PCap-Geräte gefunden" + +msgid "Invalid PCap device" +msgstr "Ungültiges PCap-Gerät" + +msgid "Standard 2-button joystick(s)" +msgstr "Standard 2-Tasten-Joystick(s)" + +msgid "Standard 4-button joystick" +msgstr "Standard 4-Tasten-Joystick" + +msgid "Standard 6-button joystick" +msgstr "Standard 6-Tasten-Joystick" + +msgid "Standard 8-button joystick" +msgstr "Standard 8-Tasten-Joystick" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Ohne" + +msgid "Unable to load keyboard accelerators." +msgstr "Tastaturbeschleuniger konnten nicht geladen werden." + +msgid "Unable to register raw input." +msgstr "Roheingaben konnten nicht registriert werden." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Diskette %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Fortgeschrittene Sektorimages" + +msgid "Flux images" +msgstr "Fluximages" + +msgid "Unable to initialize FreeType" +msgstr "FreeType konnte nicht initialisiert werden" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "SDL konnte nicht initialisiert werden, die Datei SDL2.dll wird benötigt" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Sind Sie sich sicher, dass Sie einen Hard-Reset für das emulierte System durchführen wollen?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Sind Sie sich sicher, dass Sie 86Box beenden wollen?" + +msgid "Unable to initialize Ghostscript" +msgstr "Ghostscript konnte nicht initialisiert werden" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "MO-Images" + +msgid "Welcome to 86Box!" +msgstr "Willkommen bei 86Box!" + +msgid "Internal controller" +msgstr "Interner Controller" + +msgid "Exit" +msgstr "Beenden" + +msgid "No ROMs found" +msgstr "Keine ROMs gefunden" + +msgid "Do you want to save the settings?" +msgstr "Möchten Sie die Einstellungen speichern?" + +msgid "This will hard reset the emulated machine." +msgstr "Dies wird zu einem Hard-Reset der emulierten Maschine führen." + +msgid "Save" +msgstr "Speichern" + +msgid "About 86Box" +msgstr "Über 86Box" + +msgid "86Box v" +msgstr "86Box Version " + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Ein Emulator für alte Computer\n\nAutoren: Sarah Walker, Miran Grča, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho sowie andere.\n\nÜbersetzt von: dob205\n\nVeröffentlicht unter der GNU General Public License in der Version 2 oder neuer. Siehe LICENSE für mehr Informationen." + +msgid "Hardware not available" +msgstr "Hardware nicht verfügbar" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Bitte stellen Sie sicher, dass libpcap installiert ist und sie eine libpcap-kompatible Netzwerkverbindung nutzen." + +msgid "Invalid configuration" +msgstr "Ungültige Konfiguration" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " wird für die ESC/P-Druckeremulation benötigt." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " wird zur automatischen Konversion von PostScript-Dateien in das PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (.ps)-Dateien gesichert." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " wird für die FluidSynth-MIDI-Ausgabe benötigt." + +msgid "Entering fullscreen mode" +msgstr "Vollbildmodus wird aktiviert" + +msgid "Don't show this message again" +msgstr "Diese Nachricht nicht mehr anzeigen" + +msgid "Don't exit" +msgstr "Nicht beenden" + +msgid "Reset" +msgstr "Zurücksetzen" + +msgid "Don't reset" +msgstr "Nicht zurücksetzen" + +msgid "CD-ROM images" +msgstr "CD-ROM-Images" + +msgid "%hs Device Configuration" +msgstr "%hs-Gerätekonfiguration" + +msgid "Monitor in sleep mode" +msgstr "Monitor im Standbymodus" + +msgid "OpenGL Shaders" +msgstr "OpenGL-Shader" + +msgid "OpenGL options" +msgstr "OpenGL-Optionen" + +msgid "You are loading an unsupported configuration" +msgstr "Sie laden gerade eine nicht unterstützte Konfiguration" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Das Filtern der CPU-Typen basierend auf dem ausgewählten System ist für dieses System deaktiviert.\n\nDies ermöglicht es, dass man eine sonst nicht mit dem ausgewählten System inkompatible CPU auswählen kann. Allerdings kann dies zu Inkompatiblilitäten mit dem BIOS des Systems oder anderen Programmen kommen.\n\nDas Aktivieren dieser Einstellung wird nicht unterstützt und sämtliche Bugreports können als \"invalid\" geschlossen werden." + +msgid "Continue" +msgstr "Fortfahren" + +msgid "Cassette: %s" +msgstr "Kassette: %s" + +msgid "Cassette images" +msgstr "Kassettenimages" + +msgid "Cartridge %i: %ls" +msgstr "Cartridge %i: %ls" + +msgid "Cartridge images" +msgstr "Cartridgeimages" + +msgid "Error initializing renderer" +msgstr "Fehler bei der Rendererinitialisierung" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Der OpenGL (3.0-Kern)-Renderer konnte nicht initialisiert werden. Bitte benutzen Sie einen anderen Renderer." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "Festplatte (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLL- oder ESDI CD-ROM-Laufwerke hat es niemals gegeben" + +msgid "Custom..." +msgstr "Angepasst..." + +msgid "Custom (large)..." +msgstr "Angepasst (Groß)..." + +msgid "Add New Hard Disk" +msgstr "Neue Festplatte hinzufügen" + +msgid "Add Existing Hard Disk" +msgstr "Bestehende Festplatte hinzufügen" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "HDI-Diskimages können nicht größer als 4 GB groß sein." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Festplattenimages können nicht größer als 127 GB groß sein." + +msgid "Hard disk images" +msgstr "Festplattenimages" + +msgid "Unable to read file" +msgstr "Die Datei konnte nicht gelesen werden" + +msgid "Unable to write file" +msgstr "Die Datei konnte nicht beschrieben werden" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "HDI- oder HDX-Images mit einer Sektorgröße größer als 512 kB werden nicht unterstützt." + +msgid "USB is not yet supported" +msgstr "USB wird noch nicht unterstützt" + +msgid "Disk image file already exists" +msgstr "Die Festplattenimagedatei existiert bereits" + +msgid "Please specify a valid file name." +msgstr "Bitte geben Sie einen gültigen Dateinamen ein." + +msgid "Disk image created" +msgstr "Disk-Image wurde erstellt" + +msgid "Make sure the file exists and is readable." +msgstr "Bitte stellen Sie sicher, dass die Datei existiert und lesbar ist." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Bitte stellen Sie sicher, dass die Datei in ein Verzeichnis mit Schreibberechtigungen gespeichert wird." + +msgid "Disk image too large" +msgstr "Festplattenimage ist zu groß" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Bitte denken Sie an das Partitionieren und Formatieren des neu erstellten Laufwerks." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Die ausgewählte Datei wird überschrieben. Möchten Sie diese Datei nutzen?" + +msgid "Unsupported disk image" +msgstr "Nicht unterstütztes Festplattenimage" + +msgid "Overwrite" +msgstr "Überschreiben" + +msgid "Don't overwrite" +msgstr "Nicht überschreiben" + +msgid "Raw image (.img)" +msgstr "Rohdatenimages (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI-Images (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX-Images (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD mit fester Größe (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD mit dynamischer Größe (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Differenzierende VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Große Blöcke (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Kleine Blöcke (512 KB)" + +msgid "VHD files" +msgstr "VHD-Dateien" + +msgid "Select the parent VHD" +msgstr "Eltern-VHD-Datei bitte auswählen" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Dies bedeutet, dass das Elternimage nach der Erstellung des differenzierenden Images erzeugt wurde.\n\nDies kann auch passieren, falls die Image-Dateien verschoben oder kopiert wurden. Ebenso kann auch dies durch einen Bug im Programm, welches das Image erstellt hat, passieren.\n\nMöchten Sie die Zeitstempel korrigieren?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Die Zeitstempel der Eltern- und der Kindesplatte stimmen nicht überein" + +msgid "Could not fix VHD timestamp." +msgstr "Der Zeitstempel der VHD konnte nicht korrigiert werden." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1,2 MB" + +msgid "1.25 MB" +msgstr "1,25 MB" + +msgid "1.44 MB" +msgstr "1,44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (1024 Cluster)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (2048 Cluster)" + +msgid "2.88 MB" +msgstr "2,88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3,5-Zoll 128 MB M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3,5-Zoll 230 MB M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3,5-Zoll 540 MB M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3,5-Zoll 640 MB M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3,5-Zoll 1,3 GB M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3,5-Zoll 2,3 GB M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5,25-Zoll 600 MB M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5,25-Zoll 650 MB M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5,25-Zoll 1 GB M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5,25-Zoll 1,3 GB M.O." + +msgid "Perfect RPM" +msgstr "Perfekte Drehzahl" + +msgid "1%% below perfect RPM" +msgstr "1%% unterhalb der perfekten Drehzahl" + +msgid "1.5%% below perfect RPM" +msgstr "1,5%% unterhalb der perfekten Drehzahl" + +msgid "2%% below perfect RPM" +msgstr "2%% unterhalb der perfekten Drehzahl" + +msgid "(System Default)" +msgstr "(Systemstandard)" + diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po new file mode 100644 index 000000000..d20e08705 --- /dev/null +++ b/src/qt/languages/en-GB.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Action" + +msgid "&Keyboard requires capture" +msgstr "&Keyboard requires capture" + +msgid "&Right CTRL is left ALT" +msgstr "&Right CTRL is left ALT" + +msgid "&Hard Reset..." +msgstr "&Hard Reset..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pause" + +msgid "E&xit..." +msgstr "E&xit..." + +msgid "&View" +msgstr "&View" + +msgid "&Hide status bar" +msgstr "&Hide status bar" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "&Resizeable window" + +msgid "R&emember size && position" +msgstr "R&emember size && position" + +msgid "Re&nderer" +msgstr "Re&nderer" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Specify dimensions..." + +msgid "F&orce 4:3 display ratio" +msgstr "F&orce 4:3 display ratio" + +msgid "&Window scale factor" +msgstr "&Window scale factor" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Filter method" + +msgid "&Nearest" +msgstr "&Nearest" + +msgid "&Linear" +msgstr "&Linear" + +msgid "Hi&DPI scaling" +msgstr "Hi&DPI scaling" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Fullscreen\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "Fullscreen &stretch mode" + +msgid "&Full screen stretch" +msgstr "&Full screen stretch" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Square pixels (Keep ratio)" + +msgid "&Integer scale" +msgstr "&Integer scale" + +msgid "E&GA/(S)VGA settings" +msgstr "E&GA/(S)VGA settings" + +msgid "&Inverted VGA monitor" +msgstr "&Inverted VGA monitor" + +msgid "VGA screen &type" +msgstr "VGA screen &type" + +msgid "RGB &Color" +msgstr "RGB &Colour" + +msgid "&RGB Grayscale" +msgstr "&RGB Greyscale" + +msgid "&Amber monitor" +msgstr "&Amber monitor" + +msgid "&Green monitor" +msgstr "&Green monitor" + +msgid "&White monitor" +msgstr "&White monitor" + +msgid "Grayscale &conversion type" +msgstr "Grayscale &conversion type" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Average" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" + +msgid "Change contrast for &monochrome display" +msgstr "Change contrast for &monochrome display" + +msgid "&Media" +msgstr "&Media" + +msgid "&Tools" +msgstr "&Tools" + +msgid "&Settings..." +msgstr "&Settings..." + +msgid "&Update status bar icons" +msgstr "&Update status bar icons" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Take s&creenshot\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Preferences..." + +msgid "Enable &Discord integration" +msgstr "Enable &Discord integration" + +msgid "Sound &gain..." +msgstr "Sound &gain..." + +msgid "Begin trace\tCtrl+T" +msgstr "Begin trace\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "End trace\tCtrl+T" + +msgid "&Logging" +msgstr "&Logging" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Enable BusLogic logs\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Enable CD-ROM logs\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Enable floppy (86F) logs\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Enable floppy controller logs\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Enable IDE logs\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Enable Serial Port logs\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Enable Network logs\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Log breakpoint\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "Dump &video RAM\tCtrl+F1" + +msgid "&Help" +msgstr "&Help" + +msgid "&Documentation..." +msgstr "&Documentation..." + +msgid "&About 86Box..." +msgstr "&About 86Box..." + +msgid "&New image..." +msgstr "&New image..." + +msgid "&Existing image..." +msgstr "&Existing image..." + +msgid "Existing image (&Write-protected)..." +msgstr "Existing image (&Write-protected)..." + +msgid "&Record" +msgstr "&Record" + +msgid "&Play" +msgstr "&Play" + +msgid "&Rewind to the beginning" +msgstr "&Rewind to the beginning" + +msgid "&Fast forward to the end" +msgstr "&Fast forward to the end" + +msgid "E&ject" +msgstr "E&ject" + +msgid "&Image..." +msgstr "&Image..." + +msgid "E&xport to 86F..." +msgstr "E&xport to 86F..." + +msgid "&Mute" +msgstr "&Mute" + +msgid "E&mpty" +msgstr "E&mpty" + +msgid "&Reload previous image" +msgstr "&Reload previous image" + +msgid "&Image" +msgstr "&Image" + +msgid "Target &framerate" +msgstr "Target &framerate" + +msgid "&Sync with video" +msgstr "&Sync with video" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Select shader..." + +msgid "&Remove shader" +msgstr "&Remove shader" + +msgid "Preferences" +msgstr "Preferences" + +msgid "Sound Gain" +msgstr "Sound Gain" + +msgid "New Image" +msgstr "New Image" + +msgid "Settings" +msgstr "Settings" + +msgid "Specify Main Window Dimensions" +msgstr "Specify Main Window Dimensions" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Cancel" + +msgid "Save these settings as &global defaults" +msgstr "Save these settings as &global defaults" + +msgid "&Default" +msgstr "&Default" + +msgid "Language:" +msgstr "Language:" + +msgid "Icon set:" +msgstr "Icon set:" + +msgid "Gain" +msgstr "Gain" + +msgid "File name:" +msgstr "File name:" + +msgid "Disk size:" +msgstr "Disk size:" + +msgid "RPM mode:" +msgstr "RPM mode:" + +msgid "Progress:" +msgstr "Progress:" + +msgid "Width:" +msgstr "Width:" + +msgid "Height:" +msgstr "Height:" + +msgid "Lock to this size" +msgstr "Lock to this size" + +msgid "Machine type:" +msgstr "Machine type:" + +msgid "Machine:" +msgstr "Machine:" + +msgid "Configure" +msgstr "Configure" + +msgid "CPU type:" +msgstr "CPU type:" + +msgid "Speed:" +msgstr "Speed:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Wait states:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Memory:" + +msgid "Time synchronization" +msgstr "Time synchronization" + +msgid "Disabled" +msgstr "Disabled" + +msgid "Enabled (local time)" +msgstr "Enabled (local time)" + +msgid "Enabled (UTC)" +msgstr "Enabled (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dynamic Recompiler" + +msgid "Video:" +msgstr "Video:" + +msgid "Voodoo Graphics" +msgstr "Voodoo Graphics" + +msgid "Mouse:" +msgstr "Mouse:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card:" +msgstr "Sound card:" + +msgid "MIDI Out Device:" +msgstr "MIDI Out Device:" + +msgid "MIDI In Device:" +msgstr "MIDI In Device:" + +msgid "Standalone MPU-401" +msgstr "Standalone MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "Use FLOAT32 sound" + +msgid "Network type:" +msgstr "Network type:" + +msgid "PCap device:" +msgstr "PCap device:" + +msgid "Network adapter:" +msgstr "Network adapter:" + +msgid "COM1 Device:" +msgstr "COM1 Device:" + +msgid "COM2 Device:" +msgstr "COM2 Device:" + +msgid "COM3 Device:" +msgstr "COM3 Device:" + +msgid "COM4 Device:" +msgstr "COM4 Device:" + +msgid "LPT1 Device:" +msgstr "LPT1 Device:" + +msgid "LPT2 Device:" +msgstr "LPT2 Device:" + +msgid "LPT3 Device:" +msgstr "LPT3 Device:" + +msgid "LPT4 Device:" +msgstr "LPT4 Device:" + +msgid "Serial port 1" +msgstr "Serial port 1" + +msgid "Serial port 2" +msgstr "Serial port 2" + +msgid "Serial port 3" +msgstr "Serial port 3" + +msgid "Serial port 4" +msgstr "Serial port 4" + +msgid "Parallel port 1" +msgstr "Parallel port 1" + +msgid "Parallel port 2" +msgstr "Parallel port 2" + +msgid "Parallel port 3" +msgstr "Parallel port 3" + +msgid "Parallel port 4" +msgstr "Parallel port 4" + +msgid "HD Controller:" +msgstr "HD Controller:" + +msgid "FD Controller:" +msgstr "FD Controller:" + +msgid "Tertiary IDE Controller" +msgstr "Tertiary IDE Controller" + +msgid "Quaternary IDE Controller" +msgstr "Quaternary IDE Controller" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Controller 1:" + +msgid "Controller 2:" +msgstr "Controller 2:" + +msgid "Controller 3:" +msgstr "Controller 3:" + +msgid "Controller 4:" +msgstr "Controller 4:" + +msgid "Cassette" +msgstr "Cassette" + +msgid "Hard disks:" +msgstr "Hard disks:" + +msgid "&New..." +msgstr "&New..." + +msgid "&Existing..." +msgstr "&Existing..." + +msgid "&Remove" +msgstr "&Remove" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Channel:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Specify..." + +msgid "Sectors:" +msgstr "Sectors:" + +msgid "Heads:" +msgstr "Heads:" + +msgid "Cylinders:" +msgstr "Cylinders:" + +msgid "Size (MB):" +msgstr "Size (MB):" + +msgid "Type:" +msgstr "Type:" + +msgid "Image Format:" +msgstr "Image Format:" + +msgid "Block Size:" +msgstr "Block Size:" + +msgid "Floppy drives:" +msgstr "Floppy drives:" + +msgid "Turbo timings" +msgstr "Turbo timings" + +msgid "Check BPB" +msgstr "Check BPB" + +msgid "CD-ROM drives:" +msgstr "CD-ROM drives:" + +msgid "MO drives:" +msgstr "MO drives:" + +msgid "ZIP drives:" +msgstr "ZIP drives:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "ISA Memory Expansion" + +msgid "Card 1:" +msgstr "Card 1:" + +msgid "Card 2:" +msgstr "Card 2:" + +msgid "Card 3:" +msgstr "Card 3:" + +msgid "Card 4:" +msgstr "Card 4:" + +msgid "ISABugger device" +msgstr "ISABugger device" + +msgid "POST card" +msgstr "POST card" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Error" + +msgid "Fatal error" +msgstr "Fatal error" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Press CTRL+ALT+PAGE DOWN to return to windowed mode." + +msgid "Speed" +msgstr "Speed" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIP images" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." + +msgid "(empty)" +msgstr "(empty)" + +msgid "All files" +msgstr "All files" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "On" + +msgid "Off" +msgstr "Off" + +msgid "All images" +msgstr "All images" + +msgid "Basic sector images" +msgstr "Basic sector images" + +msgid "Surface images" +msgstr "Surface images" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." + +msgid "Machine" +msgstr "Machine" + +msgid "Display" +msgstr "Display" + +msgid "Input devices" +msgstr "Input devices" + +msgid "Sound" +msgstr "Sound" + +msgid "Network" +msgstr "Network" + +msgid "Ports (COM & LPT)" +msgstr "Ports (COM & LPT)" + +msgid "Storage controllers" +msgstr "Storage controllers" + +msgid "Hard disks" +msgstr "Hard disks" + +msgid "Floppy & CD-ROM drives" +msgstr "Floppy & CD-ROM drives" + +msgid "Other removable devices" +msgstr "Other removable devices" + +msgid "Other peripherals" +msgstr "Other peripherals" + +msgid "Click to capture mouse" +msgstr "Click to capture mouse" + +msgid "Press F8+F12 to release mouse" +msgstr "Press F8+F12 to release mouse" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Press F8+F12 or middle button to release mouse" + +msgid "Unable to initialize FluidSynth" +msgstr "Unable to initialize FluidSynth" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "File" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Could not initialize the video renderer." + +msgid "Default" +msgstr "Default" + +msgid "%i Wait state(s)" +msgstr "%i Wait state(s)" + +msgid "Type" +msgstr "Type" + +msgid "Failed to set up PCap" +msgstr "Failed to set up PCap" + +msgid "No PCap devices found" +msgstr "No PCap devices found" + +msgid "Invalid PCap device" +msgstr "Invalid PCap device" + +msgid "Standard 2-button joystick(s)" +msgstr "Standard 2-button joystick(s)" + +msgid "Standard 4-button joystick" +msgstr "Standard 4-button joystick" + +msgid "Standard 6-button joystick" +msgstr "Standard 6-button joystick" + +msgid "Standard 8-button joystick" +msgstr "Standard 8-button joystick" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "None" + +msgid "Unable to load keyboard accelerators." +msgstr "Unable to load keyboard accelerators." + +msgid "Unable to register raw input." +msgstr "Unable to register raw input." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Floppy %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Advanced sector images" + +msgid "Flux images" +msgstr "Flux images" + +msgid "Unable to initialize FreeType" +msgstr "Unable to initialize FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Unable to initialize SDL, SDL2.dll is required" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Are you sure you want to hard reset the emulated machine?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Are you sure you want to exit 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Unable to initialize Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "MO images" + +msgid "Welcome to 86Box!" +msgstr "Welcome to 86Box!" + +msgid "Internal controller" +msgstr "Internal controller" + +msgid "Exit" +msgstr "Exit" + +msgid "No ROMs found" +msgstr "No ROMs found" + +msgid "Do you want to save the settings?" +msgstr "Do you want to save the settings?" + +msgid "This will hard reset the emulated machine." +msgstr "This will hard reset the emulated machine." + +msgid "Save" +msgstr "Save" + +msgid "About 86Box" +msgstr "About 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." + +msgid "Hardware not available" +msgstr "Hardware not available" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." + +msgid "Invalid configuration" +msgstr "Invalid configuration" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " is required for ESC/P printer emulation." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " is required for FluidSynth MIDI output." + +msgid "Entering fullscreen mode" +msgstr "Entering fullscreen mode" + +msgid "Don't show this message again" +msgstr "Don't show this message again" + +msgid "Don't exit" +msgstr "Don't exit" + +msgid "Reset" +msgstr "Reset" + +msgid "Don't reset" +msgstr "Don't reset" + +msgid "CD-ROM images" +msgstr "CD-ROM images" + +msgid "%hs Device Configuration" +msgstr "%hs Device Configuration" + +msgid "Monitor in sleep mode" +msgstr "Monitor in sleep mode" + +msgid "OpenGL Shaders" +msgstr "OpenGL Shaders" + +msgid "OpenGL options" +msgstr "OpenGL options" + +msgid "You are loading an unsupported configuration" +msgstr "You are loading an unsupported configuration" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." + +msgid "Continue" +msgstr "Continue" + +msgid "Cassette: %s" +msgstr "Cassette: %s" + +msgid "Cassette images" +msgstr "Cassette images" + +msgid "Cartridge %i: %ls" +msgstr "Cartridge %i: %ls" + +msgid "Cartridge images" +msgstr "Cartridge images" + +msgid "Error initializing renderer" +msgstr "Error initializing renderer" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "Hard disk (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLL or ESDI CD-ROM drives never existed" + +msgid "Custom..." +msgstr "Custom..." + +msgid "Custom (large)..." +msgstr "Custom (large)..." + +msgid "Add New Hard Disk" +msgstr "Add New Hard Disk" + +msgid "Add Existing Hard Disk" +msgstr "Add Existing Hard Disk" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "HDI disk images cannot be larger than 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Disk images cannot be larger than 127 GB." + +msgid "Hard disk images" +msgstr "Hard disk images" + +msgid "Unable to read file" +msgstr "Unable to read file" + +msgid "Unable to write file" +msgstr "Unable to write file" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "HDI or HDX images with a sector size other than 512 are not supported." + +msgid "USB is not yet supported" +msgstr "USB is not yet supported" + +msgid "Disk image file already exists" +msgstr "Disk image file already exists" + +msgid "Please specify a valid file name." +msgstr "Please specify a valid file name." + +msgid "Disk image created" +msgstr "Disk image created" + +msgid "Make sure the file exists and is readable." +msgstr "Make sure the file exists and is readable." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Make sure the file is being saved to a writable directory." + +msgid "Disk image too large" +msgstr "Disk image too large" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Remember to partition and format the newly-created drive." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "The selected file will be overwritten. Are you sure you want to use it?" + +msgid "Unsupported disk image" +msgstr "Unsupported disk image" + +msgid "Overwrite" +msgstr "Overwrite" + +msgid "Don't overwrite" +msgstr "Don't overwrite" + +msgid "Raw image (.img)" +msgstr "Raw image (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI image (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX image (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "Fixed-size VHD (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "Dynamic-size VHD (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Differencing VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Large blocks (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Small blocks (512 KB)" + +msgid "VHD files" +msgstr "VHD files" + +msgid "Select the parent VHD" +msgstr "Select the parent VHD" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Parent and child disk timestamps do not match" + +msgid "Could not fix VHD timestamp." +msgstr "Could not fix VHD timestamp." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "Perfect RPM" + +msgid "1%% below perfect RPM" +msgstr "1%% below perfect RPM" + +msgid "1.5%% below perfect RPM" +msgstr "1.5%% below perfect RPM" + +msgid "2%% below perfect RPM" +msgstr "2%% below perfect RPM" + +msgid "(System Default)" +msgstr "(System Default)" + diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po new file mode 100644 index 000000000..973ba63e9 --- /dev/null +++ b/src/qt/languages/en-US.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Action" + +msgid "&Keyboard requires capture" +msgstr "&Keyboard requires capture" + +msgid "&Right CTRL is left ALT" +msgstr "&Right CTRL is left ALT" + +msgid "&Hard Reset..." +msgstr "&Hard Reset..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pause" + +msgid "E&xit..." +msgstr "E&xit..." + +msgid "&View" +msgstr "&View" + +msgid "&Hide status bar" +msgstr "&Hide status bar" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "&Resizeable window" + +msgid "R&emember size && position" +msgstr "R&emember size && position" + +msgid "Re&nderer" +msgstr "Re&nderer" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Specify dimensions..." + +msgid "F&orce 4:3 display ratio" +msgstr "F&orce 4:3 display ratio" + +msgid "&Window scale factor" +msgstr "&Window scale factor" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Filter method" + +msgid "&Nearest" +msgstr "&Nearest" + +msgid "&Linear" +msgstr "&Linear" + +msgid "Hi&DPI scaling" +msgstr "Hi&DPI scaling" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Fullscreen\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "Fullscreen &stretch mode" + +msgid "&Full screen stretch" +msgstr "&Full screen stretch" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Square pixels (Keep ratio)" + +msgid "&Integer scale" +msgstr "&Integer scale" + +msgid "E&GA/(S)VGA settings" +msgstr "E&GA/(S)VGA settings" + +msgid "&Inverted VGA monitor" +msgstr "&Inverted VGA monitor" + +msgid "VGA screen &type" +msgstr "VGA screen &type" + +msgid "RGB &Color" +msgstr "RGB &Color" + +msgid "&RGB Grayscale" +msgstr "&RGB Grayscale" + +msgid "&Amber monitor" +msgstr "&Amber monitor" + +msgid "&Green monitor" +msgstr "&Green monitor" + +msgid "&White monitor" +msgstr "&White monitor" + +msgid "Grayscale &conversion type" +msgstr "Grayscale &conversion type" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Average" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" + +msgid "Change contrast for &monochrome display" +msgstr "Change contrast for &monochrome display" + +msgid "&Media" +msgstr "&Media" + +msgid "&Tools" +msgstr "&Tools" + +msgid "&Settings..." +msgstr "&Settings..." + +msgid "&Update status bar icons" +msgstr "&Update status bar icons" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Take s&creenshot\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Preferences..." + +msgid "Enable &Discord integration" +msgstr "Enable &Discord integration" + +msgid "Sound &gain..." +msgstr "Sound &gain..." + +msgid "Begin trace\tCtrl+T" +msgstr "Begin trace\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "End trace\tCtrl+T" + +msgid "&Logging" +msgstr "&Logging" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Enable BusLogic logs\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Enable CD-ROM logs\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Enable floppy (86F) logs\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Enable floppy controller logs\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Enable IDE logs\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Enable Serial Port logs\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Enable Network logs\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Log breakpoint\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "Dump &video RAM\tCtrl+F1" + +msgid "&Help" +msgstr "&Help" + +msgid "&Documentation..." +msgstr "&Documentation..." + +msgid "&About 86Box..." +msgstr "&About 86Box..." + +msgid "&New image..." +msgstr "&New image..." + +msgid "&Existing image..." +msgstr "&Existing image..." + +msgid "Existing image (&Write-protected)..." +msgstr "Existing image (&Write-protected)..." + +msgid "&Record" +msgstr "&Record" + +msgid "&Play" +msgstr "&Play" + +msgid "&Rewind to the beginning" +msgstr "&Rewind to the beginning" + +msgid "&Fast forward to the end" +msgstr "&Fast forward to the end" + +msgid "E&ject" +msgstr "E&ject" + +msgid "&Image..." +msgstr "&Image..." + +msgid "E&xport to 86F..." +msgstr "E&xport to 86F..." + +msgid "&Mute" +msgstr "&Mute" + +msgid "E&mpty" +msgstr "E&mpty" + +msgid "&Reload previous image" +msgstr "&Reload previous image" + +msgid "&Image" +msgstr "&Image" + +msgid "Target &framerate" +msgstr "Target &framerate" + +msgid "&Sync with video" +msgstr "&Sync with video" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Select shader..." + +msgid "&Remove shader" +msgstr "&Remove shader" + +msgid "Preferences" +msgstr "Preferences" + +msgid "Sound Gain" +msgstr "Sound Gain" + +msgid "New Image" +msgstr "New Image" + +msgid "Settings" +msgstr "Settings" + +msgid "Specify Main Window Dimensions" +msgstr "Specify Main Window Dimensions" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Cancel" + +msgid "Save these settings as &global defaults" +msgstr "Save these settings as &global defaults" + +msgid "&Default" +msgstr "&Default" + +msgid "Language:" +msgstr "Language:" + +msgid "Icon set:" +msgstr "Icon set:" + +msgid "Gain" +msgstr "Gain" + +msgid "File name:" +msgstr "File name:" + +msgid "Disk size:" +msgstr "Disk size:" + +msgid "RPM mode:" +msgstr "RPM mode:" + +msgid "Progress:" +msgstr "Progress:" + +msgid "Width:" +msgstr "Width:" + +msgid "Height:" +msgstr "Height:" + +msgid "Lock to this size" +msgstr "Lock to this size" + +msgid "Machine type:" +msgstr "Machine type:" + +msgid "Machine:" +msgstr "Machine:" + +msgid "Configure" +msgstr "Configure" + +msgid "CPU type:" +msgstr "CPU type:" + +msgid "Speed:" +msgstr "Speed:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Wait states:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Memory:" + +msgid "Time synchronization" +msgstr "Time synchronization" + +msgid "Disabled" +msgstr "Disabled" + +msgid "Enabled (local time)" +msgstr "Enabled (local time)" + +msgid "Enabled (UTC)" +msgstr "Enabled (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dynamic Recompiler" + +msgid "Video:" +msgstr "Video:" + +msgid "Voodoo Graphics" +msgstr "Voodoo Graphics" + +msgid "Mouse:" +msgstr "Mouse:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card:" +msgstr "Sound card:" + +msgid "MIDI Out Device:" +msgstr "MIDI Out Device:" + +msgid "MIDI In Device:" +msgstr "MIDI In Device:" + +msgid "Standalone MPU-401" +msgstr "Standalone MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "Use FLOAT32 sound" + +msgid "Network type:" +msgstr "Network type:" + +msgid "PCap device:" +msgstr "PCap device:" + +msgid "Network adapter:" +msgstr "Network adapter:" + +msgid "COM1 Device:" +msgstr "COM1 Device:" + +msgid "COM2 Device:" +msgstr "COM2 Device:" + +msgid "COM3 Device:" +msgstr "COM3 Device:" + +msgid "COM4 Device:" +msgstr "COM4 Device:" + +msgid "LPT1 Device:" +msgstr "LPT1 Device:" + +msgid "LPT2 Device:" +msgstr "LPT2 Device:" + +msgid "LPT3 Device:" +msgstr "LPT3 Device:" + +msgid "LPT4 Device:" +msgstr "LPT4 Device:" + +msgid "Serial port 1" +msgstr "Serial port 1" + +msgid "Serial port 2" +msgstr "Serial port 2" + +msgid "Serial port 3" +msgstr "Serial port 3" + +msgid "Serial port 4" +msgstr "Serial port 4" + +msgid "Parallel port 1" +msgstr "Parallel port 1" + +msgid "Parallel port 2" +msgstr "Parallel port 2" + +msgid "Parallel port 3" +msgstr "Parallel port 3" + +msgid "Parallel port 4" +msgstr "Parallel port 4" + +msgid "HD Controller:" +msgstr "HD Controller:" + +msgid "FD Controller:" +msgstr "FD Controller:" + +msgid "Tertiary IDE Controller" +msgstr "Tertiary IDE Controller" + +msgid "Quaternary IDE Controller" +msgstr "Quaternary IDE Controller" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Controller 1:" + +msgid "Controller 2:" +msgstr "Controller 2:" + +msgid "Controller 3:" +msgstr "Controller 3:" + +msgid "Controller 4:" +msgstr "Controller 4:" + +msgid "Cassette" +msgstr "Cassette" + +msgid "Hard disks:" +msgstr "Hard disks:" + +msgid "&New..." +msgstr "&New..." + +msgid "&Existing..." +msgstr "&Existing..." + +msgid "&Remove" +msgstr "&Remove" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Channel:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Specify..." + +msgid "Sectors:" +msgstr "Sectors:" + +msgid "Heads:" +msgstr "Heads:" + +msgid "Cylinders:" +msgstr "Cylinders:" + +msgid "Size (MB):" +msgstr "Size (MB):" + +msgid "Type:" +msgstr "Type:" + +msgid "Image Format:" +msgstr "Image Format:" + +msgid "Block Size:" +msgstr "Block Size:" + +msgid "Floppy drives:" +msgstr "Floppy drives:" + +msgid "Turbo timings" +msgstr "Turbo timings" + +msgid "Check BPB" +msgstr "Check BPB" + +msgid "CD-ROM drives:" +msgstr "CD-ROM drives:" + +msgid "MO drives:" +msgstr "MO drives:" + +msgid "ZIP drives:" +msgstr "ZIP drives:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "ISA Memory Expansion" + +msgid "Card 1:" +msgstr "Card 1:" + +msgid "Card 2:" +msgstr "Card 2:" + +msgid "Card 3:" +msgstr "Card 3:" + +msgid "Card 4:" +msgstr "Card 4:" + +msgid "ISABugger device" +msgstr "ISABugger device" + +msgid "POST card" +msgstr "POST card" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Error" + +msgid "Fatal error" +msgstr "Fatal error" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Press CTRL+ALT+PAGE DOWN to return to windowed mode." + +msgid "Speed" +msgstr "Speed" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIP images" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." + +msgid "(empty)" +msgstr "(empty)" + +msgid "All files" +msgstr "All files" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "On" + +msgid "Off" +msgstr "Off" + +msgid "All images" +msgstr "All images" + +msgid "Basic sector images" +msgstr "Basic sector images" + +msgid "Surface images" +msgstr "Surface images" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." + +msgid "Machine" +msgstr "Machine" + +msgid "Display" +msgstr "Display" + +msgid "Input devices" +msgstr "Input devices" + +msgid "Sound" +msgstr "Sound" + +msgid "Network" +msgstr "Network" + +msgid "Ports (COM & LPT)" +msgstr "Ports (COM & LPT)" + +msgid "Storage controllers" +msgstr "Storage controllers" + +msgid "Hard disks" +msgstr "Hard disks" + +msgid "Floppy & CD-ROM drives" +msgstr "Floppy & CD-ROM drives" + +msgid "Other removable devices" +msgstr "Other removable devices" + +msgid "Other peripherals" +msgstr "Other peripherals" + +msgid "Click to capture mouse" +msgstr "Click to capture mouse" + +msgid "Press F8+F12 to release mouse" +msgstr "Press F8+F12 to release mouse" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Press F8+F12 or middle button to release mouse" + +msgid "Unable to initialize FluidSynth" +msgstr "Unable to initialize FluidSynth" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "File" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Could not initialize the video renderer." + +msgid "Default" +msgstr "Default" + +msgid "%i Wait state(s)" +msgstr "%i Wait state(s)" + +msgid "Type" +msgstr "Type" + +msgid "Failed to set up PCap" +msgstr "Failed to set up PCap" + +msgid "No PCap devices found" +msgstr "No PCap devices found" + +msgid "Invalid PCap device" +msgstr "Invalid PCap device" + +msgid "Standard 2-button joystick(s)" +msgstr "Standard 2-button joystick(s)" + +msgid "Standard 4-button joystick" +msgstr "Standard 4-button joystick" + +msgid "Standard 6-button joystick" +msgstr "Standard 6-button joystick" + +msgid "Standard 8-button joystick" +msgstr "Standard 8-button joystick" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "None" + +msgid "Unable to load keyboard accelerators." +msgstr "Unable to load keyboard accelerators." + +msgid "Unable to register raw input." +msgstr "Unable to register raw input." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Floppy %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Advanced sector images" + +msgid "Flux images" +msgstr "Flux images" + +msgid "Unable to initialize FreeType" +msgstr "Unable to initialize FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Unable to initialize SDL, SDL2.dll is required" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Are you sure you want to hard reset the emulated machine?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Are you sure you want to exit 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Unable to initialize Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "MO images" + +msgid "Welcome to 86Box!" +msgstr "Welcome to 86Box!" + +msgid "Internal controller" +msgstr "Internal controller" + +msgid "Exit" +msgstr "Exit" + +msgid "No ROMs found" +msgstr "No ROMs found" + +msgid "Do you want to save the settings?" +msgstr "Do you want to save the settings?" + +msgid "This will hard reset the emulated machine." +msgstr "This will hard reset the emulated machine." + +msgid "Save" +msgstr "Save" + +msgid "About 86Box" +msgstr "About 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." + +msgid "Hardware not available" +msgstr "Hardware not available" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." + +msgid "Invalid configuration" +msgstr "Invalid configuration" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " is required for ESC/P printer emulation." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " is required for FluidSynth MIDI output." + +msgid "Entering fullscreen mode" +msgstr "Entering fullscreen mode" + +msgid "Don't show this message again" +msgstr "Don't show this message again" + +msgid "Don't exit" +msgstr "Don't exit" + +msgid "Reset" +msgstr "Reset" + +msgid "Don't reset" +msgstr "Don't reset" + +msgid "CD-ROM images" +msgstr "CD-ROM images" + +msgid "%hs Device Configuration" +msgstr "%hs Device Configuration" + +msgid "Monitor in sleep mode" +msgstr "Monitor in sleep mode" + +msgid "OpenGL Shaders" +msgstr "OpenGL Shaders" + +msgid "OpenGL options" +msgstr "OpenGL options" + +msgid "You are loading an unsupported configuration" +msgstr "You are loading an unsupported configuration" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." + +msgid "Continue" +msgstr "Continue" + +msgid "Cassette: %s" +msgstr "Cassette: %s" + +msgid "Cassette images" +msgstr "Cassette images" + +msgid "Cartridge %i: %ls" +msgstr "Cartridge %i: %ls" + +msgid "Cartridge images" +msgstr "Cartridge images" + +msgid "Error initializing renderer" +msgstr "Error initializing renderer" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "Hard disk (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLL or ESDI CD-ROM drives never existed" + +msgid "Custom..." +msgstr "Custom..." + +msgid "Custom (large)..." +msgstr "Custom (large)..." + +msgid "Add New Hard Disk" +msgstr "Add New Hard Disk" + +msgid "Add Existing Hard Disk" +msgstr "Add Existing Hard Disk" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "HDI disk images cannot be larger than 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Disk images cannot be larger than 127 GB." + +msgid "Hard disk images" +msgstr "Hard disk images" + +msgid "Unable to read file" +msgstr "Unable to read file" + +msgid "Unable to write file" +msgstr "Unable to write file" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "HDI or HDX images with a sector size other than 512 are not supported." + +msgid "USB is not yet supported" +msgstr "USB is not yet supported" + +msgid "Disk image file already exists" +msgstr "Disk image file already exists" + +msgid "Please specify a valid file name." +msgstr "Please specify a valid file name." + +msgid "Disk image created" +msgstr "Disk image created" + +msgid "Make sure the file exists and is readable." +msgstr "Make sure the file exists and is readable." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Make sure the file is being saved to a writable directory." + +msgid "Disk image too large" +msgstr "Disk image too large" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Remember to partition and format the newly-created drive." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "The selected file will be overwritten. Are you sure you want to use it?" + +msgid "Unsupported disk image" +msgstr "Unsupported disk image" + +msgid "Overwrite" +msgstr "Overwrite" + +msgid "Don't overwrite" +msgstr "Don't overwrite" + +msgid "Raw image (.img)" +msgstr "Raw image (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI image (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX image (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "Fixed-size VHD (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "Dynamic-size VHD (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Differencing VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Large blocks (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Small blocks (512 KB)" + +msgid "VHD files" +msgstr "VHD files" + +msgid "Select the parent VHD" +msgstr "Select the parent VHD" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Parent and child disk timestamps do not match" + +msgid "Could not fix VHD timestamp." +msgstr "Could not fix VHD timestamp." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "Perfect RPM" + +msgid "1%% below perfect RPM" +msgstr "1%% below perfect RPM" + +msgid "1.5%% below perfect RPM" +msgstr "1.5%% below perfect RPM" + +msgid "2%% below perfect RPM" +msgstr "2%% below perfect RPM" + +msgid "(System Default)" +msgstr "(System Default)" + diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po new file mode 100644 index 000000000..a0c0b9d2d --- /dev/null +++ b/src/qt/languages/es-ES.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Acción" + +msgid "&Keyboard requires capture" +msgstr "&Teclado requiere captura" + +msgid "&Right CTRL is left ALT" +msgstr "CTRL &derecho es ALT izquierdo" + +msgid "&Hard Reset..." +msgstr "&Hard Reset..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pausa" + +msgid "E&xit..." +msgstr "&Salir..." + +msgid "&View" +msgstr "&Vista" + +msgid "&Hide status bar" +msgstr "&Ocultar barra de estado" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "&Ventana redimensionable" + +msgid "R&emember size && position" +msgstr "&Recordar tamaño y posición" + +msgid "Re&nderer" +msgstr "Re&nderizador" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "E&specificar dimensiones..." + +msgid "F&orce 4:3 display ratio" +msgstr "F&orzar ratio 4:3" + +msgid "&Window scale factor" +msgstr "&Factor de escalado de ventana" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "&Método de filtrado" + +msgid "&Nearest" +msgstr "&Más cercano" + +msgid "&Linear" +msgstr "&Lineal" + +msgid "Hi&DPI scaling" +msgstr "&Escalado alta densidad" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Pantalla completa\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "Escalado pantalla completa" + +msgid "&Full screen stretch" +msgstr "&Estirar" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Píxeles cuadrados (Mant. aspecto)" + +msgid "&Integer scale" +msgstr "&Escalado valor entero" + +msgid "E&GA/(S)VGA settings" +msgstr "&Ajustes EGA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "&Monitor VGA invertido" + +msgid "VGA screen &type" +msgstr "&Tipo de pantalla VGA" + +msgid "RGB &Color" +msgstr "RGB &Color" + +msgid "&RGB Grayscale" +msgstr "RGB &Grises" + +msgid "&Amber monitor" +msgstr "Monitor &Ámbar" + +msgid "&Green monitor" +msgstr "Monitor &Verde" + +msgid "&White monitor" +msgstr "Monitor &Blanco" + +msgid "Grayscale &conversion type" +msgstr "&Conversión a grises" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Media" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Cambiar contraste para pantalla &monocroma" + +msgid "&Media" +msgstr "&Medios" + +msgid "&Tools" +msgstr "&Herramientas" + +msgid "&Settings..." +msgstr "&Ajustes..." + +msgid "&Update status bar icons" +msgstr "&Actualizar iconos en barra de estado" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Tomar c&aptura\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Preferencias..." + +msgid "Enable &Discord integration" +msgstr "Habilitar integración con &Discord" + +msgid "Sound &gain..." +msgstr "&Ganancia de sonido..." + +msgid "Begin trace\tCtrl+T" +msgstr "Comenzar traza\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Terminar traza\tCtrl+T" + +msgid "&Logging" +msgstr "&Trazas" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Habilitar trazas de BusLogic\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Habilitar trazas de CD-ROM\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Habilitar trazas de disquete (86F)\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Habilitar trazas de controladora de disquete\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Habilitar trazas de IDE\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Habilitar trazas de Puerto Serie\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Habilitar trazas de Red\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Punto de ruptura de traza\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "Volcar RAM de &video\tCtrl+F1" + +msgid "&Help" +msgstr "&Ayuda" + +msgid "&Documentation..." +msgstr "&Documentación..." + +msgid "&About 86Box..." +msgstr "&Acerca de 86Box..." + +msgid "&New image..." +msgstr "&Nueva imagen..." + +msgid "&Existing image..." +msgstr "Imagen &Existente..." + +msgid "Existing image (&Write-protected)..." +msgstr "Imagen Existente (&Sólo-lectura)..." + +msgid "&Record" +msgstr "&Grabar" + +msgid "&Play" +msgstr "&Reproducir" + +msgid "&Rewind to the beginning" +msgstr "&Rebobinar al inicio" + +msgid "&Fast forward to the end" +msgstr "&Avance rápido al final" + +msgid "E&ject" +msgstr "E&xtraer" + +msgid "&Image..." +msgstr "&Imagen..." + +msgid "E&xport to 86F..." +msgstr "E&xportar a 86F..." + +msgid "&Mute" +msgstr "&Silenciar" + +msgid "E&mpty" +msgstr "E&xtraer disco" + +msgid "&Reload previous image" +msgstr "&Recargar imagen previa" + +msgid "&Image" +msgstr "&Imagen..." + +msgid "Target &framerate" +msgstr "&Tasa de refresco objetivo" + +msgid "&Sync with video" +msgstr "&Sincronizar con vídeo" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Seleccionar shader..." + +msgid "&Remove shader" +msgstr "&Eliminar shader" + +msgid "Preferences" +msgstr "Preferencias" + +msgid "Sound Gain" +msgstr "Ganancia de Sonido" + +msgid "New Image" +msgstr "Nueva Imagen" + +msgid "Settings" +msgstr "Ajustes" + +msgid "Specify Main Window Dimensions" +msgstr "Especificar Dimensiones de la Ventana Principal" + +msgid "OK" +msgstr "Aceptar" + +msgid "Cancel" +msgstr "Cancelar" + +msgid "Save these settings as &global defaults" +msgstr "Salvar estos ajustes como por &defecto globalmente" + +msgid "&Default" +msgstr "&Por defecto" + +msgid "Language:" +msgstr "Idioma:" + +msgid "Icon set:" +msgstr "Juego de iconos:" + +msgid "Gain" +msgstr "Ganancia" + +msgid "File name:" +msgstr "Nombre de archivo:" + +msgid "Disk size:" +msgstr "Tamaño de disco:" + +msgid "RPM mode:" +msgstr "Modo RPM:" + +msgid "Progress:" +msgstr "Progreso:" + +msgid "Width:" +msgstr "Ancho:" + +msgid "Height:" +msgstr "Alto:" + +msgid "Lock to this size" +msgstr "Bloquear a este tamaño" + +msgid "Machine type:" +msgstr "Tipo de máquina:" + +msgid "Machine:" +msgstr "Máquina:" + +msgid "Configure" +msgstr "Configurar" + +msgid "CPU type:" +msgstr "Tipo de CPU:" + +msgid "Speed:" +msgstr "Velocidad:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Estados en espera:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Memoria:" + +msgid "Time synchronization" +msgstr "Sincronización horaria" + +msgid "Disabled" +msgstr "Deshabilitado" + +msgid "Enabled (local time)" +msgstr "Habilitado (hora local)" + +msgid "Enabled (UTC)" +msgstr "Habilitado (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Recompilador Dinámico" + +msgid "Video:" +msgstr "Vídeo:" + +msgid "Voodoo Graphics" +msgstr "Voodoo Graphics" + +msgid "Mouse:" +msgstr "Ratón:" + +msgid "Joystick:" +msgstr "Mando:" + +msgid "Joystick 1..." +msgstr "Mando 1..." + +msgid "Joystick 2..." +msgstr "Mando 2..." + +msgid "Joystick 3..." +msgstr "Mando 3..." + +msgid "Joystick 4..." +msgstr "Mando 4..." + +msgid "Sound card:" +msgstr "Tarjeta de sonido:" + +msgid "MIDI Out Device:" +msgstr "Dispositivo MIDI de salida:" + +msgid "MIDI In Device:" +msgstr "Dispositivo MIDI de entrada:" + +msgid "Standalone MPU-401" +msgstr "MPU-401 independiente" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "Usar sonido FLOAT32" + +msgid "Network type:" +msgstr "Tipo de red:" + +msgid "PCap device:" +msgstr "Dispositivo PCap:" + +msgid "Network adapter:" +msgstr "Adaptador de red:" + +msgid "COM1 Device:" +msgstr "Dispositivo COM1:" + +msgid "COM2 Device:" +msgstr "Dispositivo COM2:" + +msgid "COM3 Device:" +msgstr "Dispositivo COM3:" + +msgid "COM4 Device:" +msgstr "Dispositivo COM4:" + +msgid "LPT1 Device:" +msgstr "Dispositivo LPT1:" + +msgid "LPT2 Device:" +msgstr "Dispositivo LPT2:" + +msgid "LPT3 Device:" +msgstr "Dispositivo LPT3:" + +msgid "LPT4 Device:" +msgstr "Dispositivo LPT4:" + +msgid "Serial port 1" +msgstr "Puerto serie 1" + +msgid "Serial port 2" +msgstr "Puerto serie 2" + +msgid "Serial port 3" +msgstr "Puerto serie 3" + +msgid "Serial port 4" +msgstr "Puerto serie 4" + +msgid "Parallel port 1" +msgstr "Puerto paralelo 1" + +msgid "Parallel port 2" +msgstr "Puerto paralelo 2" + +msgid "Parallel port 3" +msgstr "Puerto paralelo 3" + +msgid "Parallel port 4" +msgstr "Puerto paralelo 4" + +msgid "HD Controller:" +msgstr "Controladora HD:" + +msgid "FD Controller:" +msgstr "Controladora FD:" + +msgid "Tertiary IDE Controller" +msgstr "Tercera controladora IDE" + +msgid "Quaternary IDE Controller" +msgstr "Cuarta controladora IDE" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Controladora 1:" + +msgid "Controller 2:" +msgstr "Controladora 2:" + +msgid "Controller 3:" +msgstr "Controladora 3:" + +msgid "Controller 4:" +msgstr "Controladora 4:" + +msgid "Cassette" +msgstr "Cassette" + +msgid "Hard disks:" +msgstr "Discos duros:" + +msgid "&New..." +msgstr "&Nuevo..." + +msgid "&Existing..." +msgstr "&Existente..." + +msgid "&Remove" +msgstr "E&liminar" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Canal:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "E&specificar..." + +msgid "Sectors:" +msgstr "Sectores:" + +msgid "Heads:" +msgstr "Cabezas:" + +msgid "Cylinders:" +msgstr "Cilindros:" + +msgid "Size (MB):" +msgstr "Tamaño (MB):" + +msgid "Type:" +msgstr "Tipo:" + +msgid "Image Format:" +msgstr "Formato de imagen:" + +msgid "Block Size:" +msgstr "Tamaño de bloque:" + +msgid "Floppy drives:" +msgstr "Unidades de disquete:" + +msgid "Turbo timings" +msgstr "Temporizaciones Turbo" + +msgid "Check BPB" +msgstr "Chequear BPB" + +msgid "CD-ROM drives:" +msgstr "Unidades de CD-ROM:" + +msgid "MO drives:" +msgstr "Unidades MO:" + +msgid "ZIP drives:" +msgstr "Unidades ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "Expansión de Memoria ISA" + +msgid "Card 1:" +msgstr "Tarjeta 1:" + +msgid "Card 2:" +msgstr "Tarjeta 2:" + +msgid "Card 3:" +msgstr "Tarjeta 3:" + +msgid "Card 4:" +msgstr "Tarjeta 4:" + +msgid "ISABugger device" +msgstr "Dispositivo ISABugger" + +msgid "POST card" +msgstr "Tarjeta POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Error" + +msgid "Fatal error" +msgstr "Error fatal" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Pulsa CTRL+ALT+AVPÁG para volver a modo ventana." + +msgid "Speed" +msgstr "Velocidad" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Imagenes ZIP" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box no pudo encontrar ninguna imagen ROM usable.\n\nPor favor descarga un grupo de imágenes y extráelas en el directorio \"roms\"." + +msgid "(empty)" +msgstr "(vacío)" + +msgid "All files" +msgstr "All files" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "On" + +msgid "Off" +msgstr "Off" + +msgid "All images" +msgstr "Todas las imagenes" + +msgid "Basic sector images" +msgstr "Basic sector images" + +msgid "Surface images" +msgstr "Surface images" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "La máquina \"%hs\" no está disponible debido a ROMs faltantes en el directorio roms/machines. Cambiando a una máquina disponible." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "La tarjeta de vídeo \"%hs\" no está disponible debido a ROMs faltantes en el directorio roms/machines. Cambiando a una tarjeta de vídeo disponible." + +msgid "Machine" +msgstr "Máquina" + +msgid "Display" +msgstr "Vídeo" + +msgid "Input devices" +msgstr "Dispositivos de Entrada" + +msgid "Sound" +msgstr "Sonido" + +msgid "Network" +msgstr "Red" + +msgid "Ports (COM & LPT)" +msgstr "Puertos (COM y LPT)" + +msgid "Storage controllers" +msgstr "Controladoras de Almacenamiento" + +msgid "Hard disks" +msgstr "Discos Duros" + +msgid "Floppy & CD-ROM drives" +msgstr "Disquetes y unidades de CD-ROM" + +msgid "Other removable devices" +msgstr "Otros dispositivos extraíbles" + +msgid "Other peripherals" +msgstr "Otros periféricos" + +msgid "Click to capture mouse" +msgstr "Haz click para capturar el ratón" + +msgid "Press F8+F12 to release mouse" +msgstr "Pulsa F8+F12 para liberar el ratón" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Pulsa F8+F12 o el botón central para liberar el ratón" + +msgid "Unable to initialize FluidSynth" +msgstr "Incapaz de inicializar FluidSynth" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "Archivo" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Incapaz de inicializar el renderizador de vídeo." + +msgid "Default" +msgstr "Por defecto" + +msgid "%i Wait state(s)" +msgstr "%i estado(s) de Espera" + +msgid "Type" +msgstr "Tipo" + +msgid "Failed to set up PCap" +msgstr "Incapaz de configurar PCap" + +msgid "No PCap devices found" +msgstr "No se encontraron dispositivos PCap" + +msgid "Invalid PCap device" +msgstr "Dispositivo PCap inválido" + +msgid "Standard 2-button joystick(s)" +msgstr "Mando(s) de 2 botones estándar" + +msgid "Standard 4-button joystick" +msgstr "Mando de 4 botones estándar" + +msgid "Standard 6-button joystick" +msgstr "Mando de 6 botones estándar" + +msgid "Standard 8-button joystick" +msgstr "Mando de 8 botones estándar" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Ninguno" + +msgid "Unable to load keyboard accelerators." +msgstr "Incapaz de cargar aceleradores de teclado." + +msgid "Unable to register raw input." +msgstr "Incapaz de registrar entrada directa." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Disquete %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Advanced sector images" + +msgid "Flux images" +msgstr "Flux images" + +msgid "Unable to initialize FreeType" +msgstr "Incapaz de inicializar FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Incapaz de inicializar SDL, se requiere SDL2.dll" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "¿Seguro que quieres resetear la máquina emulada?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "¿Seguro que quieres cerrar 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Incapaz de inicializar Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Imágenes de MO" + +msgid "Welcome to 86Box!" +msgstr "¡Bienvenido a 86Box!" + +msgid "Internal controller" +msgstr "Controladora interna" + +msgid "Exit" +msgstr "Salir" + +msgid "No ROMs found" +msgstr "No se encontraron ROMs" + +msgid "Do you want to save the settings?" +msgstr "¿Quieres guardar los ajustes?" + +msgid "This will hard reset the emulated machine." +msgstr "Se hará hard reset de la máquina emulada." + +msgid "Save" +msgstr "Guardar" + +msgid "About 86Box" +msgstr "Acerca de 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Un emulador de ordenadores antigüos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, y otros.\n\nLiberado bajo la GNU General Public License versión 2 o posterior. Ver LICENSE para más información." + +msgid "Hardware not available" +msgstr "Hardware no disponible" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Asegúrate de que libpcap está instalado y de que estás en una conexión de red compatible con libpcap." + +msgid "Invalid configuration" +msgstr "Configuración inválida" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " es necesaria para emulación de impresión ESC/P." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " es necesaria para la conversión automática de archivos PostScript a PDF.\n\nCualquier documento enviado a la impresora genérica postScript se guardará como archivo PostScript (.ps)." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " es necesario para salida MIDI FluidSynth." + +msgid "Entering fullscreen mode" +msgstr "Entrando en modo pantalla completa" + +msgid "Don't show this message again" +msgstr "No mostrar más este mensaje" + +msgid "Don't exit" +msgstr "No salir" + +msgid "Reset" +msgstr "Resetear" + +msgid "Don't reset" +msgstr "No resetear" + +msgid "CD-ROM images" +msgstr "Imágenes de CD-ROM" + +msgid "%hs Device Configuration" +msgstr "%hs Configuración de Dispositivo" + +msgid "Monitor in sleep mode" +msgstr "Monitor en modo ahorro" + +msgid "OpenGL Shaders" +msgstr "Shaders OpenGL" + +msgid "OpenGL options" +msgstr "Opciones OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Estás cargando una configuración no soportada" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "El Filtrado de tipo de CPU basado en máquina seleccionada está deshabilitado para la esta máquina.\n\nEsto hace posible seleccionar una CPU que sea incompatible con esta máquina. Por ello, pueden aparecer incompatibilidader con la BIOS de la máquina u otro software.\n\nActivar este ajuste no está oficialmente soportado y cualquier reporte de fallo puede ser cerrado como inválido." + +msgid "Continue" +msgstr "Continuar" + +msgid "Cassette: %s" +msgstr "Cassette: %s" + +msgid "Cassette images" +msgstr "Imágenes de Cassette" + +msgid "Cartridge %i: %ls" +msgstr "Cartucho %i: %ls" + +msgid "Cartridge images" +msgstr "Imágenes de Cartucho" + +msgid "Error initializing renderer" +msgstr "Error initializing renderer" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "Disco duro (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "Nunca hubo unidades de CD-ROM MFM/RLL o ESDI" + +msgid "Custom..." +msgstr "A medida..." + +msgid "Custom (large)..." +msgstr "A medida (grande)..." + +msgid "Add New Hard Disk" +msgstr "Añadir Nuevo Disco Duro" + +msgid "Add Existing Hard Disk" +msgstr "Añadir Disco Duro Existente" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Las imágenes de disco HDI no pueden superar los 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Las imágenes de disco no pueden superar los 127 GB." + +msgid "Hard disk images" +msgstr "Imágenes de Disco Duro" + +msgid "Unable to read file" +msgstr "No se pudo leer el archivo" + +msgid "Unable to write file" +msgstr "No se pudo escribir el archivo" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "No se soportan las imágenes HDI o HDX con un tamaño de sector diferente a 512." + +msgid "USB is not yet supported" +msgstr "No se soporta aún el USB" + +msgid "Disk image file already exists" +msgstr "La imagen de disco ya existe" + +msgid "Please specify a valid file name." +msgstr "Por favor especifique un nombre de archivo válido." + +msgid "Disk image created" +msgstr "Imagen de disco creada" + +msgid "Make sure the file exists and is readable." +msgstr "Asegúrese de que el archivo existe y es leíble." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Asegúrese de que el archivo en un directorio con permiso de escritura." + +msgid "Disk image too large" +msgstr "Imagen de disco demasiado grande" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Recuerde particionar y formatear la nueva unidad." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "El archivo selecionado será sobreescrito. ¿Está seguro de querer usarlo?" + +msgid "Unsupported disk image" +msgstr "Imagen de disco no soportada" + +msgid "Overwrite" +msgstr "Sobreescribir" + +msgid "Don't overwrite" +msgstr "No sobreescribir" + +msgid "Raw image (.img)" +msgstr "Imagen plana (.img)" + +msgid "HDI image (.hdi)" +msgstr "Imagen HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Imagen HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD de tamaño fijo (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD de tamaño dinámico (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "VHD diferencial (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Bloques grandes (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Bloques pequeños (512 KB)" + +msgid "VHD files" +msgstr "Archivos VHD" + +msgid "Select the parent VHD" +msgstr "Seleccione el VHD padre" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Esto puede deberse a que la imagen padre se modificó después de que la imagen diferencial se crease.\n\nTambién puede ocurrir si las imágenes fueron movidas o copiadas, o por un fallo en el programa que creó este disco.\n\n¿Quiere corregir los registros de tiempo?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Las marcas de tiempo del padre e hijo no coinciden" + +msgid "Could not fix VHD timestamp." +msgstr "No se pudo corregir la marca de tiempo del VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "RPM perfectas" + +msgid "1%% below perfect RPM" +msgstr "1%% por debajo de RPM perfectas" + +msgid "1.5%% below perfect RPM" +msgstr "1.5%% por debajo de RPM perfectas" + +msgid "2%% below perfect RPM" +msgstr "2%% por debajo de RPM perfectas" + +msgid "(System Default)" +msgstr "(Por defecto del sistema)" + diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po new file mode 100644 index 000000000..3812b49db --- /dev/null +++ b/src/qt/languages/fi-FI.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Toiminto" + +msgid "&Keyboard requires capture" +msgstr "&Vaadi näppäimistön kaappaus" + +msgid "&Right CTRL is left ALT" +msgstr "&Oikea CTRL on vasen ALT" + +msgid "&Hard Reset..." +msgstr "&Uudelleenkäynnistys (kylmä)..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Tauko" + +msgid "E&xit..." +msgstr "&Poistu..." + +msgid "&View" +msgstr "&Näytä" + +msgid "&Hide status bar" +msgstr "&Piilota tilapalkki" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "&Salli koon muuttaminen" + +msgid "R&emember size && position" +msgstr "&Muista koko ja sijainti" + +msgid "Re&nderer" +msgstr "&Renderöijä" + +msgid "&SDL (Software)" +msgstr "&SDL (ohjelmistopohjainen)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&laitteistokiihdytetty)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "&Määritä koko..." + +msgid "F&orce 4:3 display ratio" +msgstr "Pakota 4:3 näyttösuhde" + +msgid "&Window scale factor" +msgstr "&Ikkunan kokokerroin" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "&Suodatusmetodi" + +msgid "&Nearest" +msgstr "&Lähin naapuri" + +msgid "&Linear" +msgstr "Li&neaarinen interpolaatio" + +msgid "Hi&DPI scaling" +msgstr "&Suuri DPI-skaalaus" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Koko näytön tila\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "Koko näytön &skaalaustila" + +msgid "&Full screen stretch" +msgstr "&Venytä koko näyttöön" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Tasasivuiset kuvapisteet (säilytä kuvasuhde)" + +msgid "&Integer scale" +msgstr "&Kokonaislukuskaalaus" + +msgid "E&GA/(S)VGA settings" +msgstr "&EGA/(S)VGA asetukset" + +msgid "&Inverted VGA monitor" +msgstr "&VGA näyttö käänteisillä väreillä" + +msgid "VGA screen &type" +msgstr "VGA näytön &tyyppi" + +msgid "RGB &Color" +msgstr "RGB &värit" + +msgid "&RGB Grayscale" +msgstr "&RGB harmaasävyinen" + +msgid "&Amber monitor" +msgstr "&Meripihkanvärinen" + +msgid "&Green monitor" +msgstr "V&ihreä" + +msgid "&White monitor" +msgstr "V&alkoinen" + +msgid "Grayscale &conversion type" +msgstr "&Harmaasävymuunnoksen tyyppi" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Keskiarvo" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA &yliskannaus" + +msgid "Change contrast for &monochrome display" +msgstr "&Muuta harmaavärinäytön kontrastia" + +msgid "&Media" +msgstr "&Media" + +msgid "&Tools" +msgstr "&Työkalut" + +msgid "&Settings..." +msgstr "&Kokoonpano..." + +msgid "&Update status bar icons" +msgstr "&Päivitä tilapalkin kuvakkeita" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Ota &kuvakaappaus\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Sovellusasetukset..." + +msgid "Enable &Discord integration" +msgstr "Käytä &Discord integraatiota" + +msgid "Sound &gain..." +msgstr "&Äänen tulotaso..." + +msgid "Begin trace\tCtrl+T" +msgstr "Aloita jäljitys\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Lopeta jäljitys\tCtrl+T" + +msgid "&Logging" +msgstr "&Lokitus" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "BusLogic-lokitus päällä\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "CD-ROM-lokitus päällä\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Levykelokitus (86F) päällä\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Levykekontrollerin lokitus päällä\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "IDE-lokitus päällä\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Sarjaporttilokitus päällä\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Verkkolokitus päällä\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Kirjaa keskeytyskohdat\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "Tallenna &videomuistin vedos\tCtrl+F1" + +msgid "&Help" +msgstr "&Ohje" + +msgid "&Documentation..." +msgstr "&Dokumentaatio..." + +msgid "&About 86Box..." +msgstr "&Tietoja 86Box:sta..." + +msgid "&New image..." +msgstr "&Uusi kasettikuva..." + +msgid "&Existing image..." +msgstr "&Olemassaoleva kasettikuva..." + +msgid "Existing image (&Write-protected)..." +msgstr "Olemassaoleva kasettikuva (&kirjoitussuojattu)..." + +msgid "&Record" +msgstr "&Nauhoita" + +msgid "&Play" +msgstr "&Toista" + +msgid "&Rewind to the beginning" +msgstr "Kelaa &alkuun" + +msgid "&Fast forward to the end" +msgstr "Kelaa &loppuun" + +msgid "E&ject" +msgstr "&Poista kasettipesästä" + +msgid "&Image..." +msgstr "&ROM-moduulikuva..." + +msgid "E&xport to 86F..." +msgstr "&Vie 86F-tiedostoon..." + +msgid "&Mute" +msgstr "&Mykistä" + +msgid "E&mpty" +msgstr "&Tyhjä" + +msgid "&Reload previous image" +msgstr "&Lataa edellinen levykuva uudelleen" + +msgid "&Image" +msgstr "L&evykuva" + +msgid "Target &framerate" +msgstr "&Kuvataajuustavoite" + +msgid "&Sync with video" +msgstr "&Synkronisoi videoon" + +msgid "&25 fps" +msgstr "&25 ruutua/s" + +msgid "&30 fps" +msgstr "&30 ruutua/s" + +msgid "&50 fps" +msgstr "&50 ruutua/s" + +msgid "&60 fps" +msgstr "&60 ruutua/s" + +msgid "&75 fps" +msgstr "&75 ruutua/s" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "Valitse varjostin&ohjelma..." + +msgid "&Remove shader" +msgstr "&Poista varjostinohjelma" + +msgid "Preferences" +msgstr "Sovellusasetukset" + +msgid "Sound Gain" +msgstr "Äänen tulotaso" + +msgid "New Image" +msgstr "Uusi levykuva" + +msgid "Settings" +msgstr "Kokoonpano" + +msgid "Specify Main Window Dimensions" +msgstr "Määritä pääikkunan koko" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Peruuta" + +msgid "Save these settings as &global defaults" +msgstr "Tallenna nämä asetukset &globaaleiksi oletuksiksi" + +msgid "&Default" +msgstr "&Oletus" + +msgid "Language:" +msgstr "Kieli:" + +msgid "Icon set:" +msgstr "Kuvakkeet:" + +msgid "Gain" +msgstr "Taso" + +msgid "File name:" +msgstr "Tiedostonimi:" + +msgid "Disk size:" +msgstr "Levyn koko:" + +msgid "RPM mode:" +msgstr "RPM tila:" + +msgid "Progress:" +msgstr "Edistyminen:" + +msgid "Width:" +msgstr "Leveys:" + +msgid "Height:" +msgstr "Korkeus:" + +msgid "Lock to this size" +msgstr "Lukitse tähän kokoon" + +msgid "Machine type:" +msgstr "Tietokoneen tyyppi:" + +msgid "Machine:" +msgstr "Tietokone:" + +msgid "Configure" +msgstr "Määritys" + +msgid "CPU type:" +msgstr "Suorittimen tyyppi:" + +msgid "Speed:" +msgstr "Nopeus:" + +msgid "FPU:" +msgstr "Apusuoritin:" + +msgid "Wait states:" +msgstr "Odotustilat:" + +msgid "MB" +msgstr "Mt" + +msgid "Memory:" +msgstr "Muisti:" + +msgid "Time synchronization" +msgstr "Kellon synkronointi" + +msgid "Disabled" +msgstr "Ei käytössä" + +msgid "Enabled (local time)" +msgstr "Käytössä (paikallinen)" + +msgid "Enabled (UTC)" +msgstr "Käytössä (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dynaaminen uudelleenkääntäjä" + +msgid "Video:" +msgstr "Näytönohjain:" + +msgid "Voodoo Graphics" +msgstr "Voodoo-grafiikkasuoritin" + +msgid "Mouse:" +msgstr "Hiiri:" + +msgid "Joystick:" +msgstr "Peliohjain:" + +msgid "Joystick 1..." +msgstr "Peliohjain 1..." + +msgid "Joystick 2..." +msgstr "Peliohjain 2..." + +msgid "Joystick 3..." +msgstr "Peliohjain 3..." + +msgid "Joystick 4..." +msgstr "Peliohjain 4..." + +msgid "Sound card:" +msgstr "Äänikortti:" + +msgid "MIDI Out Device:" +msgstr "MIDI-ulostulo:" + +msgid "MIDI In Device:" +msgstr "MIDI-sisääntulo:" + +msgid "Standalone MPU-401" +msgstr "Erillinen MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "Käytä FLOAT32-ääntä" + +msgid "Network type:" +msgstr "Verkon tyyppi:" + +msgid "PCap device:" +msgstr "PCap-laite:" + +msgid "Network adapter:" +msgstr "Verkkokortti:" + +msgid "COM1 Device:" +msgstr "COM1-laite:" + +msgid "COM2 Device:" +msgstr "COM2-laite:" + +msgid "COM3 Device:" +msgstr "COM3-laite:" + +msgid "COM4 Device:" +msgstr "COM4-laite:" + +msgid "LPT1 Device:" +msgstr "LPT1-laite:" + +msgid "LPT2 Device:" +msgstr "LPT2-laite:" + +msgid "LPT3 Device:" +msgstr "LPT3-laite:" + +msgid "LPT4 Device:" +msgstr "LPT4-laite:" + +msgid "Serial port 1" +msgstr "Sarjaportti 1" + +msgid "Serial port 2" +msgstr "Sarjaportti 2" + +msgid "Serial port 3" +msgstr "Sarjaportti 3" + +msgid "Serial port 4" +msgstr "Sarjaportti 4" + +msgid "Parallel port 1" +msgstr "Rinnakkaisportti 1" + +msgid "Parallel port 2" +msgstr "Rinnakkaisportti 2" + +msgid "Parallel port 3" +msgstr "Rinnakkaisportti 3" + +msgid "Parallel port 4" +msgstr "Rinnakkaisportti 4" + +msgid "HD Controller:" +msgstr "Kiintolevyohjain:" + +msgid "FD Controller:" +msgstr "Levykeohjain:" + +msgid "Tertiary IDE Controller" +msgstr "Tertinäärinen IDE-ohjain" + +msgid "Quaternary IDE Controller" +msgstr "Kvaternaarinen IDE-ohjain" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Ohjain 1:" + +msgid "Controller 2:" +msgstr "Ohjain 2:" + +msgid "Controller 3:" +msgstr "Ohjain 3:" + +msgid "Controller 4:" +msgstr "Ohjain 4:" + +msgid "Cassette" +msgstr "Kasettiasema" + +msgid "Hard disks:" +msgstr "Kiintolevyt:" + +msgid "&New..." +msgstr "&Uusi..." + +msgid "&Existing..." +msgstr "&Olemassaoleva..." + +msgid "&Remove" +msgstr "&Poista" + +msgid "Bus:" +msgstr "Väylä:" + +msgid "Channel:" +msgstr "Kanava:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Määritä..." + +msgid "Sectors:" +msgstr "Sektorit:" + +msgid "Heads:" +msgstr "Päät:" + +msgid "Cylinders:" +msgstr "Sylinterit:" + +msgid "Size (MB):" +msgstr "Koko (Mt):" + +msgid "Type:" +msgstr "Tyyppi:" + +msgid "Image Format:" +msgstr "Tiedostomuoto:" + +msgid "Block Size:" +msgstr "Lohkon koko:" + +msgid "Floppy drives:" +msgstr "Levykeasemat:" + +msgid "Turbo timings" +msgstr "Turbo-ajoitukset" + +msgid "Check BPB" +msgstr "Tarkista BPB" + +msgid "CD-ROM drives:" +msgstr "CD-ROM-asemat:" + +msgid "MO drives:" +msgstr "Magneettisoptiset asemat (MO):" + +msgid "ZIP drives:" +msgstr "ZIP-asemat:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA-RTC (kello):" + +msgid "ISA Memory Expansion" +msgstr "ISA-muistilaajennus" + +msgid "Card 1:" +msgstr "Kortti 1:" + +msgid "Card 2:" +msgstr "Kortti 2:" + +msgid "Card 3:" +msgstr "Kortti 3:" + +msgid "Card 4:" +msgstr "Kortti 4:" + +msgid "ISABugger device" +msgstr "ISABugger-laite" + +msgid "POST card" +msgstr "POST-kortti" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Virhe" + +msgid "Fatal error" +msgstr "Vakava virhe" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Paina CTRL+ALT+PAGE DOWN palataksesi ikkunoituun tilaan." + +msgid "Speed" +msgstr "Nopeus" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIP-levykuvat" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box ei löytänyt käyttökelpoisia ROM-tiedostoja.\n\nVoit ladata ROM-paketin ja purkaa sen \"roms\" hakemistoon." + +msgid "(empty)" +msgstr "(tyhjä)" + +msgid "All files" +msgstr "Kaikki tiedostot" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Päällä" + +msgid "Off" +msgstr "Pois" + +msgid "All images" +msgstr "Kaikki levykuvat" + +msgid "Basic sector images" +msgstr "Perussektorilevykuvat" + +msgid "Surface images" +msgstr "Pintalevykuvat" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Konetta \"%hs\" ei voi käyttää puuttuvien ROM-tiedostojen vuoksi. Vaihdetaan käyttökelpoiseen koneeseen." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Näytönohjainta \"%hs\" ei voi käyttää puuttuvien ROM-tiedostojen vuoksi. Vaihdetaan käyttökelpoiseen näytönohjaimeen." + +msgid "Machine" +msgstr "Tietokone" + +msgid "Display" +msgstr "Näyttö" + +msgid "Input devices" +msgstr "Syöttölaitteet" + +msgid "Sound" +msgstr "Ääni" + +msgid "Network" +msgstr "Verkko" + +msgid "Ports (COM & LPT)" +msgstr "Portit (COM & LPT)" + +msgid "Storage controllers" +msgstr "Tallennusohjaimet" + +msgid "Hard disks" +msgstr "Kiintolevyt" + +msgid "Floppy & CD-ROM drives" +msgstr "Levyke ja CD-ROM" + +msgid "Other removable devices" +msgstr "Muut tallennuslaitteet" + +msgid "Other peripherals" +msgstr "Muut oheislaitteet" + +msgid "Click to capture mouse" +msgstr "Kaappaa hiiri klikkaamalla" + +msgid "Press F8+F12 to release mouse" +msgstr "Paina F8+F12 vapauttaaksesi hiiren" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Paina F8+F12 tai keskipainiketta vapauttaaksesi hiiren" + +msgid "Unable to initialize FluidSynth" +msgstr "FluidSynth:in alustus epäonnistui" + +msgid "Bus" +msgstr "Väylä" + +msgid "File" +msgstr "Tiedosto" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "kt" + +msgid "Could not initialize the video renderer." +msgstr "Video-renderöijän alustus epäonnistui" + +msgid "Default" +msgstr "Oletus" + +msgid "%i Wait state(s)" +msgstr "%i odotustilaa" + +msgid "Type" +msgstr "Tyyppi" + +msgid "Failed to set up PCap" +msgstr "PCap-asennus epäonnistui" + +msgid "No PCap devices found" +msgstr "PCap-laitteita ei löytynyt" + +msgid "Invalid PCap device" +msgstr "Virheellinen PCap-laite" + +msgid "Standard 2-button joystick(s)" +msgstr "Standardi 2-painikkeinen peliohjain/-ohjaimet" + +msgid "Standard 4-button joystick" +msgstr "Standardi 4-painikkeinen peliohjain" + +msgid "Standard 6-button joystick" +msgstr "Standardi 6-painikkeinen peliohjain" + +msgid "Standard 8-button joystick" +msgstr "Standardi 8-painikkeinen peliohjain" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Ei mikään" + +msgid "Unable to load keyboard accelerators." +msgstr "Näppäinkiihdyttimien lataus epäonnistui" + +msgid "Unable to register raw input." +msgstr "Raakasyötteen rekisteröinti epäonnistui" + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u Mt (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Levyke %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Kehittyneet sektorilevykuvat" + +msgid "Flux images" +msgstr "Flux-levykuvat" + +msgid "Unable to initialize FreeType" +msgstr "FreeType:n alustus epäonnistui" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "SDL:n alustus epäonnistui. Tarvitaan SDL2.dll" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Oletko varma, että haluat käynnistää emuloidun tietokoneen uudelleen?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Haluatko varmasti sulkea 86Box:in?" + +msgid "Unable to initialize Ghostscript" +msgstr "Ghostscript:in alustus epäonnistui" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "MO-levykuvat" + +msgid "Welcome to 86Box!" +msgstr "Tervetuloa 86Box:iin!" + +msgid "Internal controller" +msgstr "Sisäinen ohjain" + +msgid "Exit" +msgstr "Poistu" + +msgid "No ROMs found" +msgstr "ROM-tiedostoja ei löytynyt" + +msgid "Do you want to save the settings?" +msgstr "Tallennetaanko asetukset?" + +msgid "This will hard reset the emulated machine." +msgstr "Tämä käynnistää emuloidun tietokoneen uudelleen." + +msgid "Save" +msgstr "Tallenna" + +msgid "About 86Box" +msgstr "Tietoja 86Box:sta" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Vanhojen tietokoneiden emulaattori\n\nTekijät: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho ja muut.\n\nJulkaistu GNU General Public License 2. version tai myöhemmän alaisena. Tarkempia tietoja LICENSE-tiedostossa." + +msgid "Hardware not available" +msgstr "Laitteisto ei ole saatavilla" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Varmista, että libpcap on asennettu ja että verkkoyhteytesi on libpcap-yhteensopiva." + +msgid "Invalid configuration" +msgstr "Virheelliset määritykset" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " vaaditaan ESC/P-tulostimen emuloimiseksi." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PostScript-tulostimelle lähetetyt asiakirjat tallennetaan PostScript (.ps) -tiedostoina." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " vaaditaan FluidSynth MIDI-ulostuloa varten." + +msgid "Entering fullscreen mode" +msgstr "Siirrytään koko näytön tilaan" + +msgid "Don't show this message again" +msgstr "Älä näytä tätä viestiä uudelleen" + +msgid "Don't exit" +msgstr "Älä poistu" + +msgid "Reset" +msgstr "Käynnistä uudelleen" + +msgid "Don't reset" +msgstr "Älä käynnistä uudelleen" + +msgid "CD-ROM images" +msgstr "CD-ROM-levykuvat" + +msgid "%hs Device Configuration" +msgstr "%hs - Laitteen määritykset" + +msgid "Monitor in sleep mode" +msgstr "Näyttö lepotilassa" + +msgid "OpenGL Shaders" +msgstr "OpenGL-varjostinohjelmat" + +msgid "OpenGL options" +msgstr "OpenGL-asetukset" + +msgid "You are loading an unsupported configuration" +msgstr "Olet lataamassa ei-tuettuja määrittelyjä" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Valittuun tietokoneeseen perustuva suoritintyypin suodatus ei ole käytössä tällä emuloidulla koneella.\n\nTämä mahdollistaa muutoin yhteensopimattoman suorittimen valinnan kyseisen tietokoneen kanssa. Voit kuitenkin kohdata ongelmia tietokoneen BIOS:in tai muun ohjelmiston kanssa.\n\nTämän asetuksen käyttö ei ole virallisesti tuettua ja kaikki tehdyt virheraportit voidaan sulkea epäpätevinä." + +msgid "Continue" +msgstr "Jatka" + +msgid "Cassette: %s" +msgstr "Kasetti: %s" + +msgid "Cassette images" +msgstr "Kasetti-tiedostot" + +msgid "Cartridge %i: %ls" +msgstr "ROM-moduuli %i: %ls" + +msgid "Cartridge images" +msgstr "ROM-moduulikuvat" + +msgid "Error initializing renderer" +msgstr "Virhe renderöijän alustuksessa" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) renderöijän alustus epäonnistui. Käytä toista renderöijää." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "Kiintolevy (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLL tai ESDI CD-ROM asemia ei ole koskaan ollut olemassa" + +msgid "Custom..." +msgstr "Mukautettu..." + +msgid "Custom (large)..." +msgstr "Mukautettu (suuri)..." + +msgid "Add New Hard Disk" +msgstr "Lisää uusi kiintolevy" + +msgid "Add Existing Hard Disk" +msgstr "Lisää olemassaoleva kiintolevy" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "HDI levykuvan suurin mahdollinen koko on 4 Gt." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Levykuvien suurin mahdollinen koko on 127 Gt." + +msgid "Hard disk images" +msgstr "Kiintolevykuvat" + +msgid "Unable to read file" +msgstr "Tiedostoa ei voi lukea" + +msgid "Unable to write file" +msgstr "Tiedostoon ei voi kirjoittaa" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "HDI- ja HDX-levykuvien ainoa tuettu sektorikoko on 512" + +msgid "USB is not yet supported" +msgstr "USB-tukea ei vielä ole" + +msgid "Disk image file already exists" +msgstr "Levykuva on jo olemassa" + +msgid "Please specify a valid file name." +msgstr "Anna kelvollinen tiedostonimi." + +msgid "Disk image created" +msgstr "Levykuva luotu" + +msgid "Make sure the file exists and is readable." +msgstr "Varmista, että tiedosto on olemassa ja lukukelpoinen" + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Varmista, että tiedoston tallennuskansioon on kirjoitusoikeus" + +msgid "Disk image too large" +msgstr "Liian suuri levykuva" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Muista osioida ja alustaa juuri luomasi asema." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Valittu tiedosto ylikirjoitetaan. Oletko varma, että haluat käyttää sitä?" + +msgid "Unsupported disk image" +msgstr "Levynkuvaa ei tueta" + +msgid "Overwrite" +msgstr "Ylikirjoita" + +msgid "Don't overwrite" +msgstr "Älä ylikirjoita" + +msgid "Raw image (.img)" +msgstr "Raaka levykuva (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI-levykuva (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX-levykuva (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "Kiinteä VHD (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "Dynaaminen VHD (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Differentiaalinen VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Suuret lohkot (2 Mt)" + +msgid "Small blocks (512 KB)" +msgstr "Pienet lohkot (512 kt)" + +msgid "VHD files" +msgstr "VHD-tiedostot" + +msgid "Select the parent VHD" +msgstr "Valitse ylätason VHD" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Tämä saattaa tarkoittaa, että ylätason levykuvaa on muokattu differentiaalisen levykuvan luonnin jälkeen.\n\nNäin voi käydä myös, jos levykuvatiedostoja on siirretty tai kopioitu. Lisäksi syynä voi olla levyn luoneessa sovelluksessa oleva ohjelmistovirhe.\n\nKorjataanko aikaleimat?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Ylä- ja alatason levyjen aikaleimat eivät täsmää" + +msgid "Could not fix VHD timestamp." +msgstr "VHD aikaleimaa ei pystytty korjaamaan." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kt" + +msgid "180 kB" +msgstr "180 kt" + +msgid "320 kB" +msgstr "320 kt" + +msgid "360 kB" +msgstr "360 kt" + +msgid "640 kB" +msgstr "640 kt" + +msgid "720 kB" +msgstr "720 kt" + +msgid "1.2 MB" +msgstr "1.2 Mt" + +msgid "1.25 MB" +msgstr "1.25 Mt" + +msgid "1.44 MB" +msgstr "1.44 Mt" + +msgid "DMF (cluster 1024)" +msgstr "DMF (lohko 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (lohko 2048)" + +msgid "2.88 MB" +msgstr "2.88 Mt" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mt M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mt M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mt M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mt M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gt M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gt M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mt M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mt M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gt M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gt M.O." + +msgid "Perfect RPM" +msgstr "Täydellinen RPM" + +msgid "1%% below perfect RPM" +msgstr "1%% alle täydellisen RPM:n" + +msgid "1.5%% below perfect RPM" +msgstr "1.5%% alle täydellisen RPM:n" + +msgid "2%% below perfect RPM" +msgstr "2%% alle täydellisen RPM:n" + +msgid "(System Default)" +msgstr "(Järjestelmän oletus)" + diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po new file mode 100644 index 000000000..d13c00585 --- /dev/null +++ b/src/qt/languages/fr-FR.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Action" + +msgid "&Keyboard requires capture" +msgstr "&Capturer le clavier" + +msgid "&Right CTRL is left ALT" +msgstr "CTRL &Droite devient ALT Gauche" + +msgid "&Hard Reset..." +msgstr "&Hard Reset..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pause" + +msgid "E&xit..." +msgstr "&Quitter..." + +msgid "&View" +msgstr "&Vue" + +msgid "&Hide status bar" +msgstr "&Masquer la barre de status" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "Fenètre &Retaillable" + +msgid "R&emember size && position" +msgstr "S&auvegarder taille && position" + +msgid "Re&nderer" +msgstr "Moteur de &rendu vidéo" + +msgid "&SDL (Software)" +msgstr "&SDL (Logiciel)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Materiel)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Specifier dimensions..." + +msgid "F&orce 4:3 display ratio" +msgstr "F&orcer 4:3" + +msgid "&Window scale factor" +msgstr "&Echelle facteur" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Methode Filtre" + +msgid "&Nearest" +msgstr "&Plus proche" + +msgid "&Linear" +msgstr "&Lineaire" + +msgid "Hi&DPI scaling" +msgstr "Mise à l'échelle Hi&DPI" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Plein Ecran\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "Mode &Elargi plein écran" + +msgid "&Full screen stretch" +msgstr "&Plein écran étiré" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "pixels &Carrés(Keep ratio)" + +msgid "&Integer scale" +msgstr "Echelle &Entière" + +msgid "E&GA/(S)VGA settings" +msgstr "Réglages E&GA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "Moniteur VGA &Inversé" + +msgid "VGA screen &type" +msgstr "&Type Ecran VGA" + +msgid "RGB &Color" +msgstr "RGB &Couleur" + +msgid "&RGB Grayscale" +msgstr "&RGB Ton de Gris" + +msgid "&Amber monitor" +msgstr "Moniteur &Ambre" + +msgid "&Green monitor" +msgstr "Moniteur &Vert" + +msgid "&White monitor" +msgstr "Moniteur &Blanc" + +msgid "Grayscale &conversion type" +msgstr "Grayscale &conversion type" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Moyenne" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" + +msgid "Change contrast for &monochrome display" +msgstr "Modifier contraste affichage &monochrome" + +msgid "&Media" +msgstr "&Media" + +msgid "&Tools" +msgstr "Ou&tils" + +msgid "&Settings..." +msgstr "&Réglages..." + +msgid "&Update status bar icons" +msgstr "Mettre à jour la barre de stat&us" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Copie &Ecran\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Préférences..." + +msgid "Enable &Discord integration" +msgstr "Activer intégration &Discord" + +msgid "Sound &gain..." +msgstr "&Gain Son..." + +msgid "Begin trace\tCtrl+T" +msgstr "Démarrer traces\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Finir traces\tCtrl+T" + +msgid "&Logging" +msgstr "&Journalisation" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Activer journaux de BusLogic\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Activer journaux du CD-ROM\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Activer journaux des disquettes (86F)s\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Activer journaux du contrôleur de disquettes\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Activer journaux de IDE\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Activer journaux de port série\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Activer journaux du réseau\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Point d'arrêt du journal\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "Vidage de la mémoire &vidéo\tCtrl+F1" + +msgid "&Help" +msgstr "&Aide" + +msgid "&Documentation..." +msgstr "&Documentation..." + +msgid "&About 86Box..." +msgstr "&A Propos de 86Box..." + +msgid "&New image..." +msgstr "&Nouvelle image..." + +msgid "&Existing image..." +msgstr "Image &Existante..." + +msgid "Existing image (&Write-protected)..." +msgstr "Image Existante(&Lecture seule)..." + +msgid "&Record" +msgstr "En®istrer" + +msgid "&Play" +msgstr "&Jouer" + +msgid "&Rewind to the beginning" +msgstr "&Revenir au debut" + +msgid "&Fast forward to the end" +msgstr "Aller à la &Fin" + +msgid "E&ject" +msgstr "E&jecter" + +msgid "&Image..." +msgstr "&Image..." + +msgid "E&xport to 86F..." +msgstr "E&xport vers 86F..." + +msgid "&Mute" +msgstr "&Couper" + +msgid "E&mpty" +msgstr "E&jecter" + +msgid "&Reload previous image" +msgstr "&Recharger image précedente" + +msgid "&Image" +msgstr "&Image" + +msgid "Target &framerate" +msgstr "&Taux de rafraîchissement cible" + +msgid "&Sync with video" +msgstr "&Synchronisation avec la vidéo" + +msgid "&25 fps" +msgstr "&25 images par seconde" + +msgid "&30 fps" +msgstr "&30 images par seconde" + +msgid "&50 fps" +msgstr "&50 images par seconde" + +msgid "&60 fps" +msgstr "&60 images par seconde" + +msgid "&75 fps" +msgstr "&75 images par seconde" + +msgid "&VSync" +msgstr "Synchronisation &verticale" + +msgid "&Select shader..." +msgstr "Sé&lectionnez le shader..." + +msgid "&Remove shader" +msgstr "S&upprimer le shader" + +msgid "Preferences" +msgstr "Préférences" + +msgid "Sound Gain" +msgstr "Gain son" + +msgid "New Image" +msgstr "Nouvelle image" + +msgid "Settings" +msgstr "Réglages" + +msgid "Specify Main Window Dimensions" +msgstr "Spécifier le détournement de la fenêtre principale" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Annuler" + +msgid "Save these settings as &global defaults" +msgstr "Sauvegarder ces paramètres comme valeurs par défaut &globales" + +msgid "&Default" +msgstr "&Défaut" + +msgid "Language:" +msgstr "Langue:" + +msgid "Icon set:" +msgstr "Ensemble d'icônes:" + +msgid "Gain" +msgstr "Gain" + +msgid "File name:" +msgstr "Nom fichier:" + +msgid "Disk size:" +msgstr "Taille disque:" + +msgid "RPM mode:" +msgstr "Mode RPM:" + +msgid "Progress:" +msgstr "Progrès:" + +msgid "Width:" +msgstr "Largeur:" + +msgid "Height:" +msgstr "Hauteur:" + +msgid "Lock to this size" +msgstr "Verrouiller à cette taille" + +msgid "Machine type:" +msgstr "Type de machine:" + +msgid "Machine:" +msgstr "Machine:" + +msgid "Configure" +msgstr "Configurer" + +msgid "CPU type:" +msgstr "Type du processeur:" + +msgid "Speed:" +msgstr "Vitesse:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "États d'attente:" + +msgid "MB" +msgstr "Mo" + +msgid "Memory:" +msgstr "Mémoire:" + +msgid "Time synchronization" +msgstr "Synchronisation du temps" + +msgid "Disabled" +msgstr "Désactivé" + +msgid "Enabled (local time)" +msgstr "Activé (heure locale)" + +msgid "Enabled (UTC)" +msgstr "Activé (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Recompilateur dynamique" + +msgid "Video:" +msgstr "Vidéo:" + +msgid "Voodoo Graphics" +msgstr "Graphique Voodoo" + +msgid "Mouse:" +msgstr "Souris:" + +msgid "Joystick:" +msgstr "Manette de commande:" + +msgid "Joystick 1..." +msgstr "Manette 1..." + +msgid "Joystick 2..." +msgstr "Manette 2..." + +msgid "Joystick 3..." +msgstr "Manette 3..." + +msgid "Joystick 4..." +msgstr "Manette 4..." + +msgid "Sound card:" +msgstr "Carte son:" + +msgid "MIDI Out Device:" +msgstr "Sortie MIDI:" + +msgid "MIDI In Device:" +msgstr "Entrée MIDI:" + +msgid "Standalone MPU-401" +msgstr "MPU-401 autonome" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "Utiliser le son FLOAT32" + +msgid "Network type:" +msgstr "Type de réseau:" + +msgid "PCap device:" +msgstr "Dispositif PCap:" + +msgid "Network adapter:" +msgstr "Adaptateur de réseau:" + +msgid "COM1 Device:" +msgstr "Dispositif COM1:" + +msgid "COM2 Device:" +msgstr "Dispositif COM2:" + +msgid "COM3 Device:" +msgstr "Dispositif COM3:" + +msgid "COM4 Device:" +msgstr "Dispositif COM4:" + +msgid "LPT1 Device:" +msgstr "Dispositif LPT1:" + +msgid "LPT2 Device:" +msgstr "Dispositif LPT2:" + +msgid "LPT3 Device:" +msgstr "Dispositif LPT3:" + +msgid "LPT4 Device:" +msgstr "Dispositif LPT4:" + +msgid "Serial port 1" +msgstr "Port série 1" + +msgid "Serial port 2" +msgstr "Port série 2" + +msgid "Serial port 3" +msgstr "Port série 3" + +msgid "Serial port 4" +msgstr "Port série 4" + +msgid "Parallel port 1" +msgstr "Port parallèle 1" + +msgid "Parallel port 2" +msgstr "Port parallèle 2" + +msgid "Parallel port 3" +msgstr "Port parallèle 3" + +msgid "Parallel port 4" +msgstr "Port parallèle 4" + +msgid "HD Controller:" +msgstr "Contrôleur HD:" + +msgid "FD Controller:" +msgstr "Contrôleur FD:" + +msgid "Tertiary IDE Controller" +msgstr "Contrôleur IDE tertiaire" + +msgid "Quaternary IDE Controller" +msgstr "Contrôleur IDE quaternair" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Contrôleur 1:" + +msgid "Controller 2:" +msgstr "Contrôleur 2:" + +msgid "Controller 3:" +msgstr "Contrôleur 3:" + +msgid "Controller 4:" +msgstr "Contrôleur 4:" + +msgid "Cassette" +msgstr "Cassette" + +msgid "Hard disks:" +msgstr "Disques durs:" + +msgid "&New..." +msgstr "&Nouveau..." + +msgid "&Existing..." +msgstr "&Existant..." + +msgid "&Remove" +msgstr "&Supprimer" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Canal:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Spécifier..." + +msgid "Sectors:" +msgstr "Secteurs:" + +msgid "Heads:" +msgstr "Têtes:" + +msgid "Cylinders:" +msgstr "Cylindres:" + +msgid "Size (MB):" +msgstr "Taille (Mo):" + +msgid "Type:" +msgstr "Type:" + +msgid "Image Format:" +msgstr "Format Image:" + +msgid "Block Size:" +msgstr "Taille du bloc:" + +msgid "Floppy drives:" +msgstr "Lecteurs de disquettes:" + +msgid "Turbo timings" +msgstr "Turbo" + +msgid "Check BPB" +msgstr "Vérifier BPB" + +msgid "CD-ROM drives:" +msgstr "Lecterus CD-ROM:" + +msgid "MO drives:" +msgstr "Lecteurs magnéto-optiques:" + +msgid "ZIP drives:" +msgstr "Lecteurs ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "Horloge temps réel ISA:" + +msgid "ISA Memory Expansion" +msgstr "Expansion de la mémoire ISA" + +msgid "Card 1:" +msgstr "Carte 1:" + +msgid "Card 2:" +msgstr "Carte 2:" + +msgid "Card 3:" +msgstr "Carte 3:" + +msgid "Card 4:" +msgstr "Carte 4:" + +msgid "ISABugger device" +msgstr "Dispositif ISABugger" + +msgid "POST card" +msgstr "Carte POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Erreur" + +msgid "Fatal error" +msgstr "Erreur fatale" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Appuyez sur CTRL+ALT+PAGE ↓ pour revenir au mode fenêtré." + +msgid "Speed" +msgstr "Vitesse" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Images ZIP" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box n'a pas pu trouver d'images ROM utilisables.\n\nS'il vous plait, téléchargez un ensemble ROM et extrayez-le dans le répertoire \"roms\"." + +msgid "(empty)" +msgstr "(vide)" + +msgid "All files" +msgstr "Tous les fichiers" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Activé" + +msgid "Off" +msgstr "Désactivé" + +msgid "All images" +msgstr "Tous les images" + +msgid "Basic sector images" +msgstr "Images basiques du secteur" + +msgid "Surface images" +msgstr "Images de la surface" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "La machine \"%hs\" n'est pas disponible en raison de l'absence de ROMs dans le répertoire roms/machines. Basculer vers une machine disponible." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "La carte vidéo \"%hs\" n'est pas disponible en raison de l'absence de ROMs dans le répertoire roms/video. Basculer vers une carte vidéo disponible." + +msgid "Machine" +msgstr "Machine" + +msgid "Display" +msgstr "Affichage" + +msgid "Input devices" +msgstr "Dispositifs d'entrée" + +msgid "Sound" +msgstr "Son" + +msgid "Network" +msgstr "Réseau" + +msgid "Ports (COM & LPT)" +msgstr "Ports (COM et LPT)" + +msgid "Storage controllers" +msgstr "Contrôleurs de stockage" + +msgid "Hard disks" +msgstr "Disques durs" + +msgid "Floppy & CD-ROM drives" +msgstr "Lecteurs de disquette et CD-ROM" + +msgid "Other removable devices" +msgstr "Autres dispositifs amovibles" + +msgid "Other peripherals" +msgstr "Autres périfériques" + +msgid "Click to capture mouse" +msgstr "Cliquer pour capturer la souris" + +msgid "Press F8+F12 to release mouse" +msgstr "Appuyer sur F8+F12 pour libérer la souris" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Appuyer sur F8+F12 ou le bouton central pour libérer la souris" + +msgid "Unable to initialize FluidSynth" +msgstr "Impossible d'initialiser FluidSynth" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "File" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "T" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "Ko" + +msgid "Could not initialize the video renderer." +msgstr "Impossible d'initialiser le moteur de rendu vidéo." + +msgid "Default" +msgstr "Défaut" + +msgid "%i Wait state(s)" +msgstr "%i état(s) d'attente" + +msgid "Type" +msgstr "Type" + +msgid "Failed to set up PCap" +msgstr "Impossible d'initialiser PCap" + +msgid "No PCap devices found" +msgstr "Aucun dispositif PCap trouvé" + +msgid "Invalid PCap device" +msgstr "Dispositif PCap non valide" + +msgid "Standard 2-button joystick(s)" +msgstr "Manette(s) standard avec 2 boutons" + +msgid "Standard 4-button joystick" +msgstr "Manette standard avec 4 boutons" + +msgid "Standard 6-button joystick" +msgstr "Manette standard avec 6 boutons" + +msgid "Standard 8-button joystick" +msgstr "Manette standard avec 6 boutons" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Système de contrôle de vol Thrustmaster" + +msgid "None" +msgstr "Aucun" + +msgid "Unable to load keyboard accelerators." +msgstr "Impossible de charger les accélérateurs de clavier." + +msgid "Unable to register raw input." +msgstr "Impossible de charger l'entrée raw." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u Mo (CTS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Disquette %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Images du secteur avancés" + +msgid "Flux images" +msgstr "Images du flux" + +msgid "Unable to initialize FreeType" +msgstr "Impossible d'initialiser FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Impossible d'initialiser SDL, SDL2.dll est nécessaire" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Etes-vous sûr de vouloir quitter 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Impossible d'initialiser Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "Magnéto-optique %i (%ls): %ls" + +msgid "MO images" +msgstr "Images magnéto-optiques" + +msgid "Welcome to 86Box!" +msgstr "Bienvenue dans 86Box !" + +msgid "Internal controller" +msgstr "Côntrolleur interne" + +msgid "Exit" +msgstr "Sortir" + +msgid "No ROMs found" +msgstr "Pas de ROMs trouvées" + +msgid "Do you want to save the settings?" +msgstr "Voulez-vous sauvegarder les paramètres ?" + +msgid "This will hard reset the emulated machine." +msgstr "Cela entraînera la réinitialisation complète de la machine émulée." + +msgid "Save" +msgstr "Sauvegarder" + +msgid "About 86Box" +msgstr "À propos de 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Un émulateur de vieux ordinateurs\n\nAuteurs: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nLibéré sous la licence GNU General Public License version 2 ou ultérieure. Pour plus d'informations, voir le fichier LICENSE." + +msgid "Hardware not available" +msgstr "Matériel non disponible" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Assurez-vous que libpcap est installé et que vou utilisez une connexion réseau compatible avec libpcap." + +msgid "Invalid configuration" +msgstr "Configuration non valide" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " est nécessaire pour l'émulation de l'imprimante ESC/P." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " est nécessair pour la conversion automatique des fichiers PostScript dans PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés comme des fichiers PostScript (.ps)." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " est nécessaire pour la sortie MIDI FluidSynth." + +msgid "Entering fullscreen mode" +msgstr "Entrer en mode plein écran" + +msgid "Don't show this message again" +msgstr "Ne pas montrer ce message à nouveau" + +msgid "Don't exit" +msgstr "Ne pas sortir" + +msgid "Reset" +msgstr "Réinitialiser" + +msgid "Don't reset" +msgstr "Ne pas réinitialiser" + +msgid "CD-ROM images" +msgstr "Images CD-ROM" + +msgid "%hs Device Configuration" +msgstr "Configuration du dispositif %hs" + +msgid "Monitor in sleep mode" +msgstr "Moniteur en mode veille" + +msgid "OpenGL Shaders" +msgstr "Shaders OpenGL" + +msgid "OpenGL options" +msgstr "Options OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Vous chargez une configuration non prise en charge" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "La filtrage du type du processeur sur la base de la machine sélectionné est désactivé pur cette machine émulée.\n\nCela permet de sélectionner une processeur que est sinon incompatible avec la machine sélectionné. Cependant, il pourrait y avoir des incompatibilités avec le BIOS de la machine ou autres logiciels.\n\nL'activatione de cette configuration non est officiellement prise en charge et tout rapport de bogue peut être fermé comme étant invalide." + +msgid "Continue" +msgstr "Continuer" + +msgid "Cassette: %s" +msgstr "Cassette: %s" + +msgid "Cassette images" +msgstr "Images cassette" + +msgid "Cartridge %i: %ls" +msgstr "Cartouche %i: %ls" + +msgid "Cartridge images" +msgstr "Images cartouche" + +msgid "Error initializing renderer" +msgstr "Error initializing renderer" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "Disque dur (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "Les lecteurs de CD-ROM MFM/RLL ou ESDI n'ont jamais existé" + +msgid "Custom..." +msgstr "Personnalisé..." + +msgid "Custom (large)..." +msgstr "Personnalisé (grand)..." + +msgid "Add New Hard Disk" +msgstr "Ajouter un nouveau disque dur" + +msgid "Add Existing Hard Disk" +msgstr "Ajouter un disque dur existant" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Les images de disque HDI ne peuvent pas avoir une taille supériure à Go." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Les images de disque ne peuvent pas avoir un taille supérieure à 127 Go." + +msgid "Hard disk images" +msgstr "Images de dique dur" + +msgid "Unable to read file" +msgstr "Impossible de lire le fichier" + +msgid "Unable to write file" +msgstr "Impossible d'écrire le fichier" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Les images HDI ou HDX avec une taille de secteur différente de 512 non sont pas prises en charge." + +msgid "USB is not yet supported" +msgstr "USB n'est pas encore pris en charge." + +msgid "Disk image file already exists" +msgstr "Le fichier de l'image disque existe déjà." + +msgid "Please specify a valid file name." +msgstr "Veuillez spécifier un nom de fichier valide." + +msgid "Disk image created" +msgstr "Image de disque créée" + +msgid "Make sure the file exists and is readable." +msgstr "Assurez-vous que le fichier existe et est lisible." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Assurez-vous que le fichier en cours d'enregistrement se trouve dans un répertoire accessible en écriture." + +msgid "Disk image too large" +msgstr "Image disque trop grande" + +msgid "Remember to partition and format the newly-created drive." +msgstr "N'oubliez pas de partitionner et de formater le nouveau disque créé." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Le fichier sélectionné sera écrasé. Etes-vous sûr de vouloir l'utiliser?" + +msgid "Unsupported disk image" +msgstr "Image disque non prise en charge" + +msgid "Overwrite" +msgstr "Écraser" + +msgid "Don't overwrite" +msgstr "Ne pas écraser" + +msgid "Raw image (.img)" +msgstr "Image brute (.img)" + +msgid "HDI image (.hdi)" +msgstr "Image HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Image HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD à taille fixe (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD à taille dynamique (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "VHD à différenciation (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Blocs grands (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Blocs petits (512 KB)" + +msgid "VHD files" +msgstr "Fichiers VHD" + +msgid "Select the parent VHD" +msgstr "Sélectionnez le VHD parent" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Il est possible que l'image parente a été modifié après la création de l'image à différenciation.\n\nIl est même possible que les fichiers de l'mage ont été déplacés ou copiés ou il existe un bogue dans le programme que a créé ce disque.\n\nVoulez-vous réparer l'horodatage?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Les horodatages des disques parent et enfant ne correspondent pas" + +msgid "Could not fix VHD timestamp." +msgstr "Impossible de réparer l'horodatage du VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "RPM précis" + +msgid "1%% below perfect RPM" +msgstr "Précision RPM de moins 1%" + +msgid "1.5%% below perfect RPM" +msgstr "Précision RPM de moins 1.5%" + +msgid "2%% below perfect RPM" +msgstr "Précision RPM de moins 2%" + +msgid "(System Default)" +msgstr "(Défaut du système)" + diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po new file mode 100644 index 000000000..e6dd3d190 --- /dev/null +++ b/src/qt/languages/hr-HR.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Radnje" + +msgid "&Keyboard requires capture" +msgstr "&Tipkovnica zahtijeva hvatanje miša" + +msgid "&Right CTRL is left ALT" +msgstr "&Desni CTRL je lijevi ALT" + +msgid "&Hard Reset..." +msgstr "&Ponovno pokretanje..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pauza" + +msgid "E&xit..." +msgstr "Iz&laz..." + +msgid "&View" +msgstr "&Pogled" + +msgid "&Hide status bar" +msgstr "&Sakrij statusni redak" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "&Prozor s promjenjivim veličinama" + +msgid "R&emember size && position" +msgstr "&Zapamtite veličinu i položaj" + +msgid "Re&nderer" +msgstr "&Renderer" + +msgid "&SDL (Software)" +msgstr "&SDL (Softver)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardver)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 jezgra)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Odrediti veličinu..." + +msgid "F&orce 4:3 display ratio" +msgstr "&4:3 omjer prikaza" + +msgid "&Window scale factor" +msgstr "&Faktor skaliranja prozora" + +msgid "&0.5x" +msgstr "&0,5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1,&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Metoda filtriranja" + +msgid "&Nearest" +msgstr "&Najbliža" + +msgid "&Linear" +msgstr "&Linearna" + +msgid "Hi&DPI scaling" +msgstr "&HiDPI skaliranje" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Cijelozaslonski način\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "&Način cijelozaslonskog rastezanja" + +msgid "&Full screen stretch" +msgstr "&Razvuci na cijeli zaslona" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Kvadratni pikseli (zadrži omjer)" + +msgid "&Integer scale" +msgstr "&Cijelobrojno skaliranje" + +msgid "E&GA/(S)VGA settings" +msgstr "E&GA/(S)VGA postavke" + +msgid "&Inverted VGA monitor" +msgstr "&Obrni boje zaslona VGA" + +msgid "VGA screen &type" +msgstr "&Tip zaslona VGA" + +msgid "RGB &Color" +msgstr "RGB u &boji" + +msgid "&RGB Grayscale" +msgstr "&RGB u nijansama sive boje" + +msgid "&Amber monitor" +msgstr "&Jantarni zaslon" + +msgid "&Green monitor" +msgstr "&Zeleni zaslon" + +msgid "&White monitor" +msgstr "&Bijeli zaslon" + +msgid "Grayscale &conversion type" +msgstr "&Vrsta konverzije nijansa sive boje" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Prosjek" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "&Višak slike CGA/PCjr/Tandy/EGA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "&Promjeni kontrast za crno-bijeli zaslon" + +msgid "&Media" +msgstr "&Mediji" + +msgid "&Tools" +msgstr "&Alati" + +msgid "&Settings..." +msgstr "&Opcije..." + +msgid "&Update status bar icons" +msgstr "&Ažuriraj ikone statusnog redka" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Napravi &snimku zaslona\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Postavke..." + +msgid "Enable &Discord integration" +msgstr "Omogući integraciju sa programom &Discord" + +msgid "Sound &gain..." +msgstr "&Pojačanje zvuka..." + +msgid "Begin trace\tCtrl+T" +msgstr "Z&apočni praćenje\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "&Svrši praćenje\tCtrl+T" + +msgid "&Logging" +msgstr "&Logging" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Omogući bilježenje za BusLogic\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Omogući bilježenje za CD-ROM\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Omogući bilježenje za diskete (86F)\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Omogući bilježenje za disketni krmilnik\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Omogući bilježenje za IDE\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Omogući bilježenje za serijska vrata\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Omogući bilježenje za omrežje\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Zabilježi prekidnu točku\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "&Ispiši memoriju zaslona\tCtrl+F1" + +msgid "&Help" +msgstr "&Pomoć" + +msgid "&Documentation..." +msgstr "&Dokumentacija..." + +msgid "&About 86Box..." +msgstr "&O programu 86Box..." + +msgid "&New image..." +msgstr "&Nova slika..." + +msgid "&Existing image..." +msgstr "&Postojeća slika..." + +msgid "Existing image (&Write-protected)..." +msgstr "Postojeća slika (&zaštićena od pisanja)..." + +msgid "&Record" +msgstr "&Snimi" + +msgid "&Play" +msgstr "&Pokreni" + +msgid "&Rewind to the beginning" +msgstr "P&remotaj na početak" + +msgid "&Fast forward to the end" +msgstr "&Preskoči do kraja" + +msgid "E&ject" +msgstr "&Izbaci" + +msgid "&Image..." +msgstr "&Slika..." + +msgid "E&xport to 86F..." +msgstr "&Izvozi u 86F..." + +msgid "&Mute" +msgstr "&Isključi zvuk" + +msgid "E&mpty" +msgstr "&Prazno" + +msgid "&Reload previous image" +msgstr "&Ponovo učitaj prethodnu sliku" + +msgid "&Image" +msgstr "&Slika" + +msgid "Target &framerate" +msgstr "&Ciljni broj okvira u sekundi" + +msgid "&Sync with video" +msgstr "&Sinkroniziraj s videom" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Odaberi shader..." + +msgid "&Remove shader" +msgstr "&Ukloni shader" + +msgid "Preferences" +msgstr "Postavke" + +msgid "Sound Gain" +msgstr "Pojačavanje zvuka" + +msgid "New Image" +msgstr "Nova slika" + +msgid "Settings" +msgstr "Opcije" + +msgid "Specify Main Window Dimensions" +msgstr "Odredite glavne dimenzije prozora" + +msgid "OK" +msgstr "U redu" + +msgid "Cancel" +msgstr "Otkaži" + +msgid "Save these settings as &global defaults" +msgstr "Spremite ove postavke kao &globalne zadane postavke" + +msgid "&Default" +msgstr "Zadano" + +msgid "Language:" +msgstr "Jezik:" + +msgid "Icon set:" +msgstr "Paket ikona:" + +msgid "Gain" +msgstr "Pojačavanje" + +msgid "File name:" +msgstr "Ime datoteke:" + +msgid "Disk size:" +msgstr "Veličina diska:" + +msgid "RPM mode:" +msgstr "Način broja okretaja:" + +msgid "Progress:" +msgstr "Napredak:" + +msgid "Width:" +msgstr "Širina:" + +msgid "Height:" +msgstr "Visina:" + +msgid "Lock to this size" +msgstr "Zaključajte na ovu veličinu" + +msgid "Machine type:" +msgstr "Tip sistema:" + +msgid "Machine:" +msgstr "Sistem:" + +msgid "Configure" +msgstr "Namjesti" + +msgid "CPU type:" +msgstr "Tip procesora:" + +msgid "Speed:" +msgstr "Brzina:" + +msgid "FPU:" +msgstr "FPU uređaj:" + +msgid "Wait states:" +msgstr "Stanja čekanja:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Memorija:" + +msgid "Time synchronization" +msgstr "Sinkronizacija vremena" + +msgid "Disabled" +msgstr "Isključeno" + +msgid "Enabled (local time)" +msgstr "Uključeno (lokalno vrijeme)" + +msgid "Enabled (UTC)" +msgstr "Uključeno (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dinamički rekompilator" + +msgid "Video:" +msgstr "Video:" + +msgid "Voodoo Graphics" +msgstr "Voodoo grafika" + +msgid "Mouse:" +msgstr "Miš:" + +msgid "Joystick:" +msgstr "Palica za igru:" + +msgid "Joystick 1..." +msgstr "Palica za igru 1..." + +msgid "Joystick 2..." +msgstr "Palica za igru 2..." + +msgid "Joystick 3..." +msgstr "Palica za igru 3..." + +msgid "Joystick 4..." +msgstr "Palica za igru 4..." + +msgid "Sound card:" +msgstr "Zvučna kartica:" + +msgid "MIDI Out Device:" +msgstr "Izlazni uređaj MIDI:" + +msgid "MIDI In Device:" +msgstr "Ulazni uređaj MIDI:" + +msgid "Standalone MPU-401" +msgstr "Samostalni MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "Koristi FLOAT32 za zvuk" + +msgid "Network type:" +msgstr "Tip mreže:" + +msgid "PCap device:" +msgstr "Uređaj PCap:" + +msgid "Network adapter:" +msgstr "Mrežna kartica:" + +msgid "COM1 Device:" +msgstr "Uređaj COM1:" + +msgid "COM2 Device:" +msgstr "Uređaj COM2:" + +msgid "COM3 Device:" +msgstr "Uređaj COM3:" + +msgid "COM4 Device:" +msgstr "Uređaj COM4:" + +msgid "LPT1 Device:" +msgstr "Uređaj LPT1:" + +msgid "LPT2 Device:" +msgstr "Uređaj LPT2:" + +msgid "LPT3 Device:" +msgstr "Uređaj LPT3:" + +msgid "LPT4 Device:" +msgstr "Uređaj LPT4:" + +msgid "Serial port 1" +msgstr "Serijska vrata 1" + +msgid "Serial port 2" +msgstr "Serijska vrata 2" + +msgid "Serial port 3" +msgstr "Serijska vrata 3" + +msgid "Serial port 4" +msgstr "Serijska vrata 4" + +msgid "Parallel port 1" +msgstr "Paralelna vrata 1" + +msgid "Parallel port 2" +msgstr "Paralelna vrata 2" + +msgid "Parallel port 3" +msgstr "Paralelna vrata 3" + +msgid "Parallel port 4" +msgstr "Paralelna vrata 4" + +msgid "HD Controller:" +msgstr "Kontroler tvrdog diska:" + +msgid "FD Controller:" +msgstr "Kontroler diskete:" + +msgid "Tertiary IDE Controller" +msgstr "Tercijarni IDE kontroler" + +msgid "Quaternary IDE Controller" +msgstr "Kvaternarni IDE kontroler" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Kontroler 1:" + +msgid "Controller 2:" +msgstr "Kontroler 2:" + +msgid "Controller 3:" +msgstr "Kontroler 3:" + +msgid "Controller 4:" +msgstr "Kontroler 4:" + +msgid "Cassette" +msgstr "Audio kaseta" + +msgid "Hard disks:" +msgstr "Tvrdi diskovi:" + +msgid "&New..." +msgstr "&Novi..." + +msgid "&Existing..." +msgstr "&Postojeći..." + +msgid "&Remove" +msgstr "&Ukloni" + +msgid "Bus:" +msgstr "Sabirnica:" + +msgid "Channel:" +msgstr "Kanal:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Odredi..." + +msgid "Sectors:" +msgstr "Sektori:" + +msgid "Heads:" +msgstr "Glave:" + +msgid "Cylinders:" +msgstr "Cilindri:" + +msgid "Size (MB):" +msgstr "Veličina (MB):" + +msgid "Type:" +msgstr "Tip:" + +msgid "Image Format:" +msgstr "Format slike:" + +msgid "Block Size:" +msgstr "Veličina slike:" + +msgid "Floppy drives:" +msgstr "Disketni pogoni:" + +msgid "Turbo timings" +msgstr "Turbo vrijemena" + +msgid "Check BPB" +msgstr "Provjeraj BPB" + +msgid "CD-ROM drives:" +msgstr "CD-ROM pogoni:" + +msgid "MO drives:" +msgstr "MO pogoni:" + +msgid "ZIP drives:" +msgstr "ZIP pogoni:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "Sat stvarnog vremena (RTC):" + +msgid "ISA Memory Expansion" +msgstr "Proširenje memorije ISA" + +msgid "Card 1:" +msgstr "Kartica 1:" + +msgid "Card 2:" +msgstr "Kartica 2:" + +msgid "Card 3:" +msgstr "Kartica 3:" + +msgid "Card 4:" +msgstr "Kartica 4:" + +msgid "ISABugger device" +msgstr "Uređaj ISABugger" + +msgid "POST card" +msgstr "Kartica POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Greška" + +msgid "Fatal error" +msgstr "Fatalna greška" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Pritisnite CTRL+ALT+PAGE DOWN za povratak u prozorski način rada." + +msgid "Speed" +msgstr "Brzina" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIP slike" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box nije mogao pronaći upotrebljive ROM datoteke.\n\nMolimte posjetite sknite paket s ROM datotekama i ekstrahirajte paket u \"roms\" mapu." + +msgid "(empty)" +msgstr "(prazno)" + +msgid "All files" +msgstr "Sve datoteke" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Uključeno" + +msgid "Off" +msgstr "Isključeno" + +msgid "All images" +msgstr "Sve slike" + +msgid "Basic sector images" +msgstr "BOsnovne sektorske slike" + +msgid "Surface images" +msgstr "Površinske slike" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Sistem \"%hs\" nije dostupan jer ne postoje potrebni ROM-ovi u mapu roms/machines. Prebacivanje na dostupno računalo." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Video kartica \"%hs\" nije dostupna jer ne postoje potrebni ROM-ovi u mapu roms/video. Prebacivanje na dostupnu video karticu." + +msgid "Machine" +msgstr "Sistem" + +msgid "Display" +msgstr "Video" + +msgid "Input devices" +msgstr "Ulazni uređaji" + +msgid "Sound" +msgstr "Zvuk" + +msgid "Network" +msgstr "Mreža" + +msgid "Ports (COM & LPT)" +msgstr "Vrata (COM & LPT)" + +msgid "Storage controllers" +msgstr "Kontroleri za diskove" + +msgid "Hard disks" +msgstr "Tvrdi diskovi" + +msgid "Floppy & CD-ROM drives" +msgstr "Floppy & CD-ROM pogoni" + +msgid "Other removable devices" +msgstr "Ostali uklonjivi uređaji" + +msgid "Other peripherals" +msgstr "Ostali periferni uređaji" + +msgid "Click to capture mouse" +msgstr "Kliknite da uhvatite miš" + +msgid "Press F8+F12 to release mouse" +msgstr "Pritisnite F8+F12 za otpustanje miša" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Pritisnite F8+F12 ili srednji gumb miša za otpuštanje miša" + +msgid "Unable to initialize FluidSynth" +msgstr "Nije moguće inicijalizirati FluidSynth" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "Datoteka" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Nije moguće inicijalizirati renderer." + +msgid "Default" +msgstr "Standard" + +msgid "%i Wait state(s)" +msgstr "%i stanje čekanja" + +msgid "Type" +msgstr "Tip" + +msgid "Failed to set up PCap" +msgstr "Postavljanje PCap-a nije uspjelo" + +msgid "No PCap devices found" +msgstr "Nema PCap uređaja" + +msgid "Invalid PCap device" +msgstr "Nevažeći PCap uređaj" + +msgid "Standard 2-button joystick(s)" +msgstr "Standardna palica za igru s 2 tipke" + +msgid "Standard 4-button joystick" +msgstr "Standardna palica za igru s 4 tipke" + +msgid "Standard 6-button joystick" +msgstr "Standardna palica za igru s 6 tipke" + +msgid "Standard 8-button joystick" +msgstr "Standardna palica za igru s 8 tipke" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Bez" + +msgid "Unable to load keyboard accelerators." +msgstr "Nije moguće učitati ubrzivače tipkovnice." + +msgid "Unable to register raw input." +msgstr "Nije moguće registrirati neobrađeni unos." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Disketa %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Napredne sektorske slike" + +msgid "Flux images" +msgstr "Flux slike" + +msgid "Unable to initialize FreeType" +msgstr "Nije moguće inicijalizirati FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Nije moguće inicijalizirati SDL, SDL2.dll je potrebno" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Jeste li sigurni da želite hard resetirati emulirani sistem?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Jeste li sigurni da želite zatvoriti 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Nije moguće inicijalizirati GhostScript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "MO slike" + +msgid "Welcome to 86Box!" +msgstr "Dobrodošli u 86Box!" + +msgid "Internal controller" +msgstr "Uunutarnji kontroler" + +msgid "Exit" +msgstr "Izlazi" + +msgid "No ROMs found" +msgstr "Nisu pronađene ROM datoteke" + +msgid "Do you want to save the settings?" +msgstr "Želite li spremiti postavke?" + +msgid "This will hard reset the emulated machine." +msgstr "Ovo će napraviti hard resetiranje emuliranog sistema." + +msgid "Save" +msgstr "Spremaj" + +msgid "About 86Box" +msgstr "O programu 86Box" + +msgid "86Box v" +msgstr "86Box verzija " + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Emulator starih računala\n\nAutori: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, i drugi.\n\nPreveo: dob205\n\nObjavljeno pod licencom GNU General Public License, verzija 2 ili novije. Za više informacija pogledajte datoteku LICENCE." + +msgid "Hardware not available" +msgstr "Hardver nije dostupan" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Provjerite je li libpcap instaliran i jeste li na mreži, kompadibilnoj s libpcap." + +msgid "Invalid configuration" +msgstr "Nevažeća konfiguracija" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " je potrebno za emuliranje ESC/P pisača." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " je potrebno za automatsku konverziju PostScript datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PostScript pisač bit će spremljeni kao PostScript (.ps) datoteke." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " je potrebno za FluidSynth MIDI izlaz." + +msgid "Entering fullscreen mode" +msgstr "Ulazim u cijelozaslonski način" + +msgid "Don't show this message again" +msgstr "Ne pokazi više ovu poruku" + +msgid "Don't exit" +msgstr "Ne izlazi" + +msgid "Reset" +msgstr "Resetiraj" + +msgid "Don't reset" +msgstr "Ne resetiraj" + +msgid "CD-ROM images" +msgstr "CD-ROM slike" + +msgid "%hs Device Configuration" +msgstr "Konfiguracija uređaja %hs " + +msgid "Monitor in sleep mode" +msgstr "Ekran u stanju mirovanja" + +msgid "OpenGL Shaders" +msgstr "OpenGL shaderi" + +msgid "OpenGL options" +msgstr "OpenGL opcije" + +msgid "You are loading an unsupported configuration" +msgstr "Učitavate nepodržanu konfiguraciju" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Filtriranje tipa CPU-a na temelju odabranog sistema onemogućeno je za ovaj emulirani sistem.\n\nOvo omogućuje odabir procesora koji inače nisu kompatibilne s odabranog sistem. Međutim, možete naići na na nekompatibilnosti s BIOS-om sustava ili drugim softverom.\n\nOmogućavanje ove postavke nije službeno podržano i sva prijava o greškama mogu biti zatvorena kao \"invalid\"." + +msgid "Continue" +msgstr "Nastavi" + +msgid "Cassette: %s" +msgstr "Audio kaseta: %s" + +msgid "Cassette images" +msgstr "Slike audio kasete" + +msgid "Cartridge %i: %ls" +msgstr "Kaseta %i: %ls" + +msgid "Cartridge images" +msgstr "Slike kasete" + +msgid "Error initializing renderer" +msgstr "Nije moguće inicijalizirati renderer" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Nije moguće inicijalizirati OpenGL (3.0 jezgra) renderer. Molimte koristite drugi renderer." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "Tvrdi disk (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLL ili ESDI CD-ROM pogoni nisu nikada postojali" + +msgid "Custom..." +msgstr "Prilagođeno..." + +msgid "Custom (large)..." +msgstr "Prilagođeno (veliko)..." + +msgid "Add New Hard Disk" +msgstr "Dodajte novi tvrdi disk" + +msgid "Add Existing Hard Disk" +msgstr "Dodajte postojeći tvrdi disk" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "HDI disk image datoteke ne mogu biti veće od 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Slike tvrdog diska ne mogu biti veće od 127 GB." + +msgid "Hard disk images" +msgstr "Slike za tvrde diskove" + +msgid "Unable to read file" +msgstr "Nije moguće pročitati datoteku" + +msgid "Unable to write file" +msgstr "Nije moguće napisati datoteku" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "HDI ili HDX slike s veličinom sektora koja nije 512 kB nisu podržane." + +msgid "USB is not yet supported" +msgstr "USB nije još podržano" + +msgid "Disk image file already exists" +msgstr "Slika diska već postoji" + +msgid "Please specify a valid file name." +msgstr "Molimte unesite važeći naziv datoteke." + +msgid "Disk image created" +msgstr "Slika je stvorena" + +msgid "Make sure the file exists and is readable." +msgstr "Provjerite je li postoji datoteka i je li čitljiva." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Provjerite je li se datoteka sprema u mapu s dopuštenjima za pisanje." + +msgid "Disk image too large" +msgstr "Slika diska je prevelika" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Ne zaboravite stvoriti particije i formatirati ih na novom disku." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Odabrana datoteka bit će prebrisana. Jeste li sigurni da želite koristiti ovu daoteku?" + +msgid "Unsupported disk image" +msgstr "Nepodržana slika diska" + +msgid "Overwrite" +msgstr "Prepiši" + +msgid "Don't overwrite" +msgstr "Ne prepiši" + +msgid "Raw image (.img)" +msgstr "Slika neobrađenih podataka (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI slika (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX slika (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD fiksne veličine (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD dinamičke veličine (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Različiti VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Veliki blokovi (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Mali blokovi (512 KB)" + +msgid "VHD files" +msgstr "VHD slike" + +msgid "Select the parent VHD" +msgstr "Izaberi matičnu sliku VHD" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "To bi moglo značiti da je matična slika promijenjena nakon što je stvorena različita slika.\n\nTo se također može dogoditi ako su slike premještene ili kopirane, ili greška u programu koji je stvorio ovaj disk.\n\nŽelite li popraviti vremenske oznake?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Vremenske ozanke matične i poređenog diska ne odgovaraju." + +msgid "Could not fix VHD timestamp." +msgstr "Ne mogu popraviti vremensku oznaku slike VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1,2 MB" + +msgid "1.25 MB" +msgstr "1,25 MB" + +msgid "1.44 MB" +msgstr "1,44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (1024 clusteri)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (2048 clusteri)" + +msgid "2.88 MB" +msgstr "2,88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3,5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3,5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3,5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3,5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3,5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3,5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5,25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5,25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5,25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5,25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "Savršeni broj okretaja u minuti" + +msgid "1%% below perfect RPM" +msgstr "1%% ispod savršenog broja okretaja" + +msgid "1.5%% below perfect RPM" +msgstr "1,5%% ispod savršenog broja okretaja" + +msgid "2%% below perfect RPM" +msgstr "2%% ispod savršenog broja okretaja" + +msgid "(System Default)" +msgstr "(Zadana postavka operativnog sustava)" + diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po new file mode 100644 index 000000000..d6426a9a3 --- /dev/null +++ b/src/qt/languages/hu-HU.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Művelet" + +msgid "&Keyboard requires capture" +msgstr "A &billentyűzet elfogást igényel" + +msgid "&Right CTRL is left ALT" +msgstr "A &jobb oldali CTRL a bal ALT" + +msgid "&Hard Reset..." +msgstr "Hardveres &újraindítás..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Szüneteltetés" + +msgid "E&xit..." +msgstr "&Kilépés..." + +msgid "&View" +msgstr "&Nézet" + +msgid "&Hide status bar" +msgstr "Állapotsor &elrejtése" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "&Átméretezhető ablak" + +msgid "R&emember size && position" +msgstr "Méret és pozíció &megjegyzése" + +msgid "Re&nderer" +msgstr "&Megjelenítő" + +msgid "&SDL (Software)" +msgstr "&SDL (Szoftveres)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardveres)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Méretek kézi megadása..." + +msgid "F&orce 4:3 display ratio" +msgstr "&Rögzített 4:3 képarány" + +msgid "&Window scale factor" +msgstr "&Ablak méretezési tényező" + +msgid "&0.5x" +msgstr "&0,5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1,&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Szűrési mód" + +msgid "&Nearest" +msgstr "&Szomszédos" + +msgid "&Linear" +msgstr "&Lineáris" + +msgid "Hi&DPI scaling" +msgstr "Hi&DPI méretezés" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Teljes képernyő\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "Teljes képernyős &méretezés" + +msgid "&Full screen stretch" +msgstr "&Nyújtás a teljes képernyőre" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Négyzetes képpontok (aránytartás)" + +msgid "&Integer scale" +msgstr "&Egész tényezős nagyítás" + +msgid "E&GA/(S)VGA settings" +msgstr "E&GA/(S)VGA beállítások" + +msgid "&Inverted VGA monitor" +msgstr "&Invertált VGA kijelző" + +msgid "VGA screen &type" +msgstr "VGA képernyő &típusa" + +msgid "RGB &Color" +msgstr "RGB &színes" + +msgid "&RGB Grayscale" +msgstr "&RGB szürkeárnyalatos" + +msgid "&Amber monitor" +msgstr "&Gyömbér kijelző" + +msgid "&Green monitor" +msgstr "&Zöld kijelző" + +msgid "&White monitor" +msgstr "&Fehér kijelző" + +msgid "Grayscale &conversion type" +msgstr "Szürkéskála &konzerziós eljárás" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Átlag szerint" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA túlpásztázás" + +msgid "Change contrast for &monochrome display" +msgstr "Kontraszt illesztése &monokróm kijelzőhöz" + +msgid "&Media" +msgstr "&Média" + +msgid "&Tools" +msgstr "&Eszközök" + +msgid "&Settings..." +msgstr "&Konfigurálás..." + +msgid "&Update status bar icons" +msgstr "Állapotsori ikonok &frissítése" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "&Képernyőkép készítése\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Beállítások..." + +msgid "Enable &Discord integration" +msgstr "&Discord integráció engedélyezése" + +msgid "Sound &gain..." +msgstr "&Hangerőszabályzó..." + +msgid "Begin trace\tCtrl+T" +msgstr "Nyomkövetés megkezdése\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Nyomkövetés befejezése\tCtrl+T" + +msgid "&Logging" +msgstr "&Naplózás" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "BusLogic naplók engedélyezése\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "CD-ROM naplók engedélyezése\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Hajlékonylemez (86F) naplók engedélyezése\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Hajlékonylemez-vezérlő naplók engedélyezése\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "IDE naplók engedélyezése\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Soros port naplók engedélyezése\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Hálózati naplók engedélyezése\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "Töréspontok &naplózása\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "&Videómemória lementése\tCtrl+F1" + +msgid "&Help" +msgstr "&Súgó" + +msgid "&Documentation..." +msgstr "&Dokumentáció..." + +msgid "&About 86Box..." +msgstr "A 86Box &névjegye..." + +msgid "&New image..." +msgstr "&Új képfájl létrehozása..." + +msgid "&Existing image..." +msgstr "Meglévő képfájl &megnyitása..." + +msgid "Existing image (&Write-protected)..." +msgstr "Meglévő képfájl megnyitása (&írásvédett)..." + +msgid "&Record" +msgstr "&Felvétel" + +msgid "&Play" +msgstr "&Lejátszás" + +msgid "&Rewind to the beginning" +msgstr "&Visszatekerés az elejére" + +msgid "&Fast forward to the end" +msgstr "&Előretekerés a végére" + +msgid "E&ject" +msgstr "&Kiadás" + +msgid "&Image..." +msgstr "Kép&fájl..." + +msgid "E&xport to 86F..." +msgstr "E&xportálás 86F formátumba..." + +msgid "&Mute" +msgstr "&Némítás" + +msgid "E&mpty" +msgstr "&Kiadás" + +msgid "&Reload previous image" +msgstr "Előző képfájl &újratöltése" + +msgid "&Image" +msgstr "&Meglévő képfájl &megnyitása..." + +msgid "Target &framerate" +msgstr "Cél &képkockasebesség" + +msgid "&Sync with video" +msgstr "&Szinkronizálás a videóval " + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "Shader &kiválasztása..." + +msgid "&Remove shader" +msgstr "Shader &eltávolítása" + +msgid "Preferences" +msgstr "Beállítások" + +msgid "Sound Gain" +msgstr "Hangerőszabályzó" + +msgid "New Image" +msgstr "Új képfájl létrehozása" + +msgid "Settings" +msgstr "Konfigurálás" + +msgid "Specify Main Window Dimensions" +msgstr "Főablak méreteinek megadása" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Mégse" + +msgid "Save these settings as &global defaults" +msgstr "Beállítások mentése &globális alapértékként" + +msgid "&Default" +msgstr "&Alapértelmezett" + +msgid "Language:" +msgstr "Nyelv:" + +msgid "Icon set:" +msgstr "Ikonkészlet:" + +msgid "Gain" +msgstr "Hangerő" + +msgid "File name:" +msgstr "Fájlnév:" + +msgid "Disk size:" +msgstr "Méret:" + +msgid "RPM mode:" +msgstr "RPM-mód:" + +msgid "Progress:" +msgstr "Folyamat:" + +msgid "Width:" +msgstr "Szélesség:" + +msgid "Height:" +msgstr "Magasság:" + +msgid "Lock to this size" +msgstr "Rögzítés a megadott méretre" + +msgid "Machine type:" +msgstr "Géptípus:" + +msgid "Machine:" +msgstr "Számítógép:" + +msgid "Configure" +msgstr "Beállítások..." + +msgid "CPU type:" +msgstr "Processzor:" + +msgid "Speed:" +msgstr "Seb.:" + +msgid "FPU:" +msgstr "FPU-egység:" + +msgid "Wait states:" +msgstr "Várak. ciklusok:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Memória:" + +msgid "Time synchronization" +msgstr "Idő szinkronizáció" + +msgid "Disabled" +msgstr "Letiltva" + +msgid "Enabled (local time)" +msgstr "Engedélyezve (helyi idő)" + +msgid "Enabled (UTC)" +msgstr "Engedélyezve (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dinamikus újrafordítás" + +msgid "Video:" +msgstr "Videokártya:" + +msgid "Voodoo Graphics" +msgstr "Voodoo-gyorsítókártya" + +msgid "Mouse:" +msgstr "Egér:" + +msgid "Joystick:" +msgstr "Játékvezérlő:" + +msgid "Joystick 1..." +msgstr "Játékvez. 1..." + +msgid "Joystick 2..." +msgstr "Játékvez. 2..." + +msgid "Joystick 3..." +msgstr "Játékvez. 3..." + +msgid "Joystick 4..." +msgstr "Játékvez. 4..." + +msgid "Sound card:" +msgstr "Hangkártya:" + +msgid "MIDI Out Device:" +msgstr "MIDI-kimenet:" + +msgid "MIDI In Device:" +msgstr "MIDI-bemenet:" + +msgid "Standalone MPU-401" +msgstr "Különálló MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "FLOAT32 használata" + +msgid "Network type:" +msgstr "Hálózati típusa:" + +msgid "PCap device:" +msgstr "PCap eszköz:" + +msgid "Network adapter:" +msgstr "Hálózati kártya:" + +msgid "COM1 Device:" +msgstr "COM1 eszköz:" + +msgid "COM2 Device:" +msgstr "COM2 eszköz:" + +msgid "COM3 Device:" +msgstr "COM3 eszköz:" + +msgid "COM4 Device:" +msgstr "COM4 eszköz:" + +msgid "LPT1 Device:" +msgstr "LPT1 eszköz:" + +msgid "LPT2 Device:" +msgstr "LPT2 eszköz:" + +msgid "LPT3 Device:" +msgstr "LPT3 eszköz:" + +msgid "LPT4 Device:" +msgstr "LPT4 eszköz:" + +msgid "Serial port 1" +msgstr "Soros port 1" + +msgid "Serial port 2" +msgstr "Soros port 2" + +msgid "Serial port 3" +msgstr "Soros port 3" + +msgid "Serial port 4" +msgstr "Soros port 4" + +msgid "Parallel port 1" +msgstr "Párhuzamos port 1" + +msgid "Parallel port 2" +msgstr "Párhuzamos port 2" + +msgid "Parallel port 3" +msgstr "Párhuzamos port 3" + +msgid "Parallel port 4" +msgstr "Párhuzamos port 4" + +msgid "HD Controller:" +msgstr "Merevl.-vezérlő:" + +msgid "FD Controller:" +msgstr "Floppy-vezérlő:" + +msgid "Tertiary IDE Controller" +msgstr "Harmadlagos IDE-vezérlő" + +msgid "Quaternary IDE Controller" +msgstr "Negyedleges IDE-vezérlő" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Gazdaadapt. 1:" + +msgid "Controller 2:" +msgstr "Gazdaadapt. 2:" + +msgid "Controller 3:" +msgstr "Gazdaadapt. 3:" + +msgid "Controller 4:" +msgstr "Gazdaadapt. 4:" + +msgid "Cassette" +msgstr "Magnókazetta" + +msgid "Hard disks:" +msgstr "Merevlemezek:" + +msgid "&New..." +msgstr "&Új..." + +msgid "&Existing..." +msgstr "&Megnyitás..." + +msgid "&Remove" +msgstr "&Eltávolítás" + +msgid "Bus:" +msgstr "Busz:" + +msgid "Channel:" +msgstr "Csatorna:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Kiválasztás..." + +msgid "Sectors:" +msgstr "Szektor:" + +msgid "Heads:" +msgstr "Fej:" + +msgid "Cylinders:" +msgstr "Cilinder:" + +msgid "Size (MB):" +msgstr "Méret (MB):" + +msgid "Type:" +msgstr "Típus:" + +msgid "Image Format:" +msgstr "Formátum:" + +msgid "Block Size:" +msgstr "Blokkméret:" + +msgid "Floppy drives:" +msgstr "Floppy-meghajtók:" + +msgid "Turbo timings" +msgstr "Turbó időzítés" + +msgid "Check BPB" +msgstr "BPB ellenőrzés" + +msgid "CD-ROM drives:" +msgstr "CD-ROM meghajtók:" + +msgid "MO drives:" +msgstr "MO-meghajtók:" + +msgid "ZIP drives:" +msgstr "ZIP-meghajtók:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC (óra):" + +msgid "ISA Memory Expansion" +msgstr "ISA memóriabővítők" + +msgid "Card 1:" +msgstr "Kártya 1:" + +msgid "Card 2:" +msgstr "Kártya 2:" + +msgid "Card 3:" +msgstr "Kártya 3:" + +msgid "Card 4:" +msgstr "Kártya 4:" + +msgid "ISABugger device" +msgstr "ISABugger eszköz" + +msgid "POST card" +msgstr "POST kártya" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Hiba" + +msgid "Fatal error" +msgstr "Végzetes hiba" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Használja a CTRL+ALT+PAGE DOWN gombokat az ablakhoz való visszatéréshez." + +msgid "Speed" +msgstr "Sebesség" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIP-lemezképek" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "A 86Box nem talált használható ROM-képeket\n\nKérem töltse le a ROM készletet és bontsa ki a \"roms\" könyvtárba." + +msgid "(empty)" +msgstr "(üres)" + +msgid "All files" +msgstr "Minden fájl" + +msgid "Turbo" +msgstr "Turbó" + +msgid "On" +msgstr "Bekapcsolva" + +msgid "Off" +msgstr "Kikapcsolva" + +msgid "All images" +msgstr "Minden képfájl" + +msgid "Basic sector images" +msgstr "Alapvető szektor képfájlok" + +msgid "Surface images" +msgstr "Felületi képfájlok" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "A számítógép \"%hs\" nem elérhető a \"roms/machines\" mappából hiányzó ROM-képek miatt. Ehelyett egy másik gép kerül futtatásra." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "A videokártya \"%hs\" nem elérhető a \"roms/video\" mappából hiányzó ROM-képek miatt. Ehelyett egy másik kártya kerül futtatásra." + +msgid "Machine" +msgstr "Számítógép" + +msgid "Display" +msgstr "Megjelenítő" + +msgid "Input devices" +msgstr "Beviteli eszközök" + +msgid "Sound" +msgstr "Hang" + +msgid "Network" +msgstr "Hálózat" + +msgid "Ports (COM & LPT)" +msgstr "Portok (COM és LPT)" + +msgid "Storage controllers" +msgstr "Tárolóvezérlők" + +msgid "Hard disks" +msgstr "Merevlemezek" + +msgid "Floppy & CD-ROM drives" +msgstr "Floppy és CD-ROM meghajtók" + +msgid "Other removable devices" +msgstr "Egyéb cserélhető tárolók" + +msgid "Other peripherals" +msgstr "Egyéb perifériák" + +msgid "Click to capture mouse" +msgstr "Kattintson az egér elfogásához" + +msgid "Press F8+F12 to release mouse" +msgstr "Nyomja meg az F8+F12-t az egér elengédéséhez" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Nyomja meg az F8+F12-t vagy a középső gombot az egér elengédéséhez" + +msgid "Unable to initialize FluidSynth" +msgstr "Nem sikerült a FluidSynth inicializálása" + +msgid "Bus" +msgstr "Busz" + +msgid "File" +msgstr "Fájl" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Nem sikerült inicializálni a videó megjelenítőt." + +msgid "Default" +msgstr "Alapértelmezett" + +msgid "%i Wait state(s)" +msgstr "%i várakozási ciklus(ok)" + +msgid "Type" +msgstr "Típus" + +msgid "Failed to set up PCap" +msgstr "Nem sikerült a PCap beállítása" + +msgid "No PCap devices found" +msgstr "Nem találhatóak PCap eszközök" + +msgid "Invalid PCap device" +msgstr "Érvénytelen PCap eszköz" + +msgid "Standard 2-button joystick(s)" +msgstr "Szabványos 2-gombos játékvezérlő(k)" + +msgid "Standard 4-button joystick" +msgstr "Szabványos 4-gombos játékvezérlő" + +msgid "Standard 6-button joystick" +msgstr "Szabványos 6-gombos játékvezérlő" + +msgid "Standard 8-button joystick" +msgstr "Szabványos 8-gombos játékvezérlő" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Nincs" + +msgid "Unable to load keyboard accelerators." +msgstr "Nem lehet betölteni a billentyűzetgyorsítókat." + +msgid "Unable to register raw input." +msgstr "A közvetlen nyers bevitel regisztrálása nem sikerült." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Floppy %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Továbbfejlesztett szektor képek" + +msgid "Flux images" +msgstr "Flux képekfájlok" + +msgid "Unable to initialize FreeType" +msgstr "A FreeType inicializálása nem lehetséges" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Az SDL inicializálása nem lehetséges, az SDL2.dll fájl szükséges" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Biztosan szeretné újraindítani az emulált gépet?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Biztos benne, hogy ki szeretne lépni a 86Box-ból?" + +msgid "Unable to initialize Ghostscript" +msgstr "Nem sikerült inicializálni a Ghostscript-et" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "MO-képfájlok" + +msgid "Welcome to 86Box!" +msgstr "Üdvözli önt az 86Box!" + +msgid "Internal controller" +msgstr "Integrált vezérlő" + +msgid "Exit" +msgstr "Kilépés" + +msgid "No ROMs found" +msgstr "Nem találhatóak meg a ROM-képek" + +msgid "Do you want to save the settings?" +msgstr "Szeretné menteni a beállításokat?" + +msgid "This will hard reset the emulated machine." +msgstr "Ezzel hardveresen újraindítja az emulált gépet." + +msgid "Save" +msgstr "Mentés" + +msgid "About 86Box" +msgstr "A 86Box névjegye" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Régi számítógépek emulátora\n\nFejlesztők: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nFordította: Laci bá'\n\nMegjelent a GNU General Public License v2 vagy újabb alatt. További információért lásd a LICENSE fájlt." + +msgid "Hardware not available" +msgstr "Hardver nem elérhető" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Győződjön meg hogy a(z) libpcap telepítve van és jelenleg a libpcap-kompatibilis kapcsolatot használja." + +msgid "Invalid configuration" +msgstr "Érvénytelen konfiguráció" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " szükséges az ESC/P nyomtató emulációhoz." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " szükséges a PostScript fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PostScript nyomtatóra küldött dokumentumok PostScript (.ps) fájlként kerülnek mentésre." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " szükséges a FluidSynth MIDI kimenethez." + +msgid "Entering fullscreen mode" +msgstr "Teljes képernyős módra váltás" + +msgid "Don't show this message again" +msgstr "Ne jelenítse meg újra ezt az üzenetet " + +msgid "Don't exit" +msgstr "Ne lépjen ki" + +msgid "Reset" +msgstr "Újraindítás" + +msgid "Don't reset" +msgstr "Ne indítsa újra" + +msgid "CD-ROM images" +msgstr "CD-ROM-képek" + +msgid "%hs Device Configuration" +msgstr "%hs eszközkonfiguráció" + +msgid "Monitor in sleep mode" +msgstr "Képernyő alvó módban" + +msgid "OpenGL Shaders" +msgstr "OpenGL Shaderek" + +msgid "OpenGL options" +msgstr "OpenGL beállítások" + +msgid "You are loading an unsupported configuration" +msgstr "Egy nem támogatott konfigurációt tölt be" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "A kiválasztott gépen alapuló CPU-típusszűrés le van tiltva ezen az emulált gépen.\n\nEz lehetővé teszi olyan CPU kiválasztását, amely egyébként nem kompatibilis a kiválasztott géppel. Előfordulhat azonban, hogy nem kompatibilis a gép BIOS-ával vagy más szoftverekkel.\n\nA beállítás engedélyezése hivatalosan nem támogatott, és a benyújtott hibajelentéseket érvénytelenként lezárhatjuk." + +msgid "Continue" +msgstr "Folytatás" + +msgid "Cassette: %s" +msgstr "Magnókazetta: %s" + +msgid "Cassette images" +msgstr "Magnókazetta-képek" + +msgid "Cartridge %i: %ls" +msgstr "ROM-kazetta %i: %ls" + +msgid "Cartridge images" +msgstr "ROM-kazetta képek" + +msgid "Error initializing renderer" +msgstr "Hiba történt a renderelő inicializálásakor" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Az OpenGL (3.0 Core) megjelenítő-motort nem sikerült inicializálni. Kérem használjon másik renderelőt." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "Merevlemez (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLL vagy ESDI CD-ROM meghajtók soha nem léteztek" + +msgid "Custom..." +msgstr "Egyéni..." + +msgid "Custom (large)..." +msgstr "Egyéni (nagy)..." + +msgid "Add New Hard Disk" +msgstr "Új merevlemez hozzáadása" + +msgid "Add Existing Hard Disk" +msgstr "Meglévő merevlemez hozzáadása" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "A HDI lemezképek nem lehetnek nagyobbak 4 GB-nál." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "A lemezképek mérete nem haladhatja meg a 127 GB-ot." + +msgid "Hard disk images" +msgstr "Merevlemez-képfájlok" + +msgid "Unable to read file" +msgstr "A fájl nem olvasható" + +msgid "Unable to write file" +msgstr "A fájl nem írható" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Az 512-től eltérő szektorméretű HDI vagy HDX képek nem támogatottak." + +msgid "USB is not yet supported" +msgstr "Az USB még nem támogatott" + +msgid "Disk image file already exists" +msgstr "A lemezképfájl már létezik" + +msgid "Please specify a valid file name." +msgstr "Adjon meg egy érvényes fájlnevet." + +msgid "Disk image created" +msgstr "A lemezképfájl létrehozásra került" + +msgid "Make sure the file exists and is readable." +msgstr "Győződjön meg arról, hogy a fájl létezik és olvasható." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Győződjön meg arról, hogy a fájlt egy írható könyvtárba menti." + +msgid "Disk image too large" +msgstr "A lemezképfájl túl nagy" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Ne felejtse el particionálni és formázni az újonnan létrehozott meghajtót." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "A kiválasztott fájl felülírásra kerül. Biztos, hogy ezt kívánja használni?" + +msgid "Unsupported disk image" +msgstr "Nem támogatott lemezkép" + +msgid "Overwrite" +msgstr "Felülírás" + +msgid "Don't overwrite" +msgstr "Ne írja felül" + +msgid "Raw image (.img)" +msgstr "Nyers lemezkép (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI-lemezkép (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX-lemezkép (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "Rögzített méretű VHD (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "Dinamikusan bővülő VHD (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Különbség-VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Nagy blokkméret (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Kis blokkméret (512 KB)" + +msgid "VHD files" +msgstr "VHD fájlok" + +msgid "Select the parent VHD" +msgstr "Válassza ki a szülő VHD-t" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Ez azt jelentheti, hogy a szülőkép módosult az eltérő kép létrehozása után.\n\nEz akkor is előfordulhat, ha a képfájlokat áthelyezték vagy másolták, vagy a lemezt létrehozó program hibája miatt.\n\nSzeretné kijavítani az időbélyegeket?" + +msgid "Parent and child disk timestamps do not match" +msgstr "A szülő- és a gyermeklemez időbélyegei nem egyeznek" + +msgid "Could not fix VHD timestamp." +msgstr "Nem sikerült kijavítani a VHD időbélyegét." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (1024 klaszter)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (2048 klaszter)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "Tökéletes RPM" + +msgid "1%% below perfect RPM" +msgstr "1%%-kal a tökéletes RPM alatt" + +msgid "1.5%% below perfect RPM" +msgstr "1.5%%-kal a tökéletes RPM alatt" + +msgid "2%% below perfect RPM" +msgstr "2%%-kal a tökéletes RPM alatt" + +msgid "(System Default)" +msgstr "(A rendszer nyelve)" + diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po new file mode 100644 index 000000000..c60a0635a --- /dev/null +++ b/src/qt/languages/it-IT.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Azione" + +msgid "&Keyboard requires capture" +msgstr "&Tastiera richiede la cattura" + +msgid "&Right CTRL is left ALT" +msgstr "&CTRL destro è ALT sinistro" + +msgid "&Hard Reset..." +msgstr "&Riavvia..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pausa" + +msgid "E&xit..." +msgstr "E&sci..." + +msgid "&View" +msgstr "&Visualizza" + +msgid "&Hide status bar" +msgstr "&Nascondi barra di stato" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "&Finestra ridimensionabile" + +msgid "R&emember size && position" +msgstr "R&icorda dimensioni e posizione" + +msgid "Re&nderer" +msgstr "Re&nderer" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Specifica dimensioni..." + +msgid "F&orce 4:3 display ratio" +msgstr "F&orza display 4:3" + +msgid "&Window scale factor" +msgstr "&Fattore scalare della finestra" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Metodo filtro" + +msgid "&Nearest" +msgstr "&Dal più vicino" + +msgid "&Linear" +msgstr "&Lineare" + +msgid "Hi&DPI scaling" +msgstr "Scala Hi&DPI" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Schermo intero\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "Modalità adattamento &schermo intero" + +msgid "&Full screen stretch" +msgstr "&Adatta a schermo intero" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Pixel quadrati (mantiene l'aspetto)" + +msgid "&Integer scale" +msgstr "&Scala intera" + +msgid "E&GA/(S)VGA settings" +msgstr "Impostazioni E&GA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "&Invertire monitor VGA" + +msgid "VGA screen &type" +msgstr "Schermi VGA &" + +msgid "RGB &Color" +msgstr "RGB &Color" + +msgid "&RGB Grayscale" +msgstr "&RGB Monocroma" + +msgid "&Amber monitor" +msgstr "&Monitor ambra" + +msgid "&Green monitor" +msgstr "&Monitor verde" + +msgid "&White monitor" +msgstr "&Monitor bianco" + +msgid "Grayscale &conversion type" +msgstr "Conversione &scala grigia" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&AMedia" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "Sovrascansione CGA/PCjr/Tandy/E&GA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Cambia il contrasto per &display monocromatici" + +msgid "&Media" +msgstr "&Dispositivi" + +msgid "&Tools" +msgstr "&Strumenti" + +msgid "&Settings..." +msgstr "&Impostazioni..." + +msgid "&Update status bar icons" +msgstr "&Aggiorna icone della barra di stato" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Cattura schermata\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Preferenze..." + +msgid "Enable &Discord integration" +msgstr "Abilita &integrazione Discord" + +msgid "Sound &gain..." +msgstr "Guadagno &suono..." + +msgid "Begin trace\tCtrl+T" +msgstr "Inizia traccia\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Ferma traccia\tCtrl+T" + +msgid "&Logging" +msgstr "&Registra" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Attiva registrazione di BusLogic\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Attiva registrazione del CD-ROM\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Attiva registrazione del floppy (86F)\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Attiva registrazione del controller floppy\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Attiva registrazione di IDE\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Attiva registrazione della porta seriale\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Attiva registrazione della rete\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Punto di interruzione del registro\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "Scarica &la RAM video\tCtrl+F1" + +msgid "&Help" +msgstr "&?" + +msgid "&Documentation..." +msgstr "&Documentazione..." + +msgid "&About 86Box..." +msgstr "&Informazioni su 86Box..." + +msgid "&New image..." +msgstr "&Nuova immagine..." + +msgid "&Existing image..." +msgstr "&Immagine esistente..." + +msgid "Existing image (&Write-protected)..." +msgstr "Immagine esistente (&protezione contro scrittura)..." + +msgid "&Record" +msgstr "&Registra" + +msgid "&Play" +msgstr "R&iproduci" + +msgid "&Rewind to the beginning" +msgstr "Ri&avvolgi all'inizio" + +msgid "&Fast forward to the end" +msgstr "A&vanti veloce alla fine" + +msgid "E&ject" +msgstr "&Espelli" + +msgid "&Image..." +msgstr "&Immagine..." + +msgid "E&xport to 86F..." +msgstr "E&sporta in 86F..." + +msgid "&Mute" +msgstr "&Muto" + +msgid "E&mpty" +msgstr "&Espelli" + +msgid "&Reload previous image" +msgstr "&Ricarica l'immagine precedente" + +msgid "&Image" +msgstr "&Immagine" + +msgid "Target &framerate" +msgstr "Imposta obiettivo &fotogrammi" + +msgid "&Sync with video" +msgstr "&Sincronizza col video" + +msgid "&25 fps" +msgstr "&25 FPS" + +msgid "&30 fps" +msgstr "&30 FPS" + +msgid "&50 fps" +msgstr "&50 FPS" + +msgid "&60 fps" +msgstr "&60 FPS" + +msgid "&75 fps" +msgstr "&75 FPS" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Seleziona shader..." + +msgid "&Remove shader" +msgstr "&Rimuovi shader" + +msgid "Preferences" +msgstr "Preferenze" + +msgid "Sound Gain" +msgstr "Guadagno del suono" + +msgid "New Image" +msgstr "Nuova immagine" + +msgid "Settings" +msgstr "Impostazioni" + +msgid "Specify Main Window Dimensions" +msgstr "Specifica dimensioni della finestra principale" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Annulla" + +msgid "Save these settings as &global defaults" +msgstr "Salva queste impostazioni come &predefinite globali" + +msgid "&Default" +msgstr "&Predefinito" + +msgid "Language:" +msgstr "Lingua:" + +msgid "Icon set:" +msgstr "Pacchetto di icone:" + +msgid "Gain" +msgstr "Guadagno" + +msgid "File name:" +msgstr "Nome file:" + +msgid "Disk size:" +msgstr "Dimensioni disco:" + +msgid "RPM mode:" +msgstr "Modalità RPM:" + +msgid "Progress:" +msgstr "Progresso:" + +msgid "Width:" +msgstr "Larghezza:" + +msgid "Height:" +msgstr "Altezza:" + +msgid "Lock to this size" +msgstr "Blocca in queste dimensioni" + +msgid "Machine type:" +msgstr "Tipo di piastra madre:" + +msgid "Machine:" +msgstr "Piastra madre:" + +msgid "Configure" +msgstr "Configura" + +msgid "CPU type:" +msgstr "Tipo del CPU:" + +msgid "Speed:" +msgstr "Veloc.:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Stati di attesa:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Memoria:" + +msgid "Time synchronization" +msgstr "Sincronizzazione dell'ora" + +msgid "Disabled" +msgstr "Disabilitata" + +msgid "Enabled (local time)" +msgstr "Abilitata (ora locale)" + +msgid "Enabled (UTC)" +msgstr "Abilitata (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Ricompilatore dinamico" + +msgid "Video:" +msgstr "Video:" + +msgid "Voodoo Graphics" +msgstr "Grafica Voodoo" + +msgid "Mouse:" +msgstr "Mouse:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card:" +msgstr "Scheda audio:" + +msgid "MIDI Out Device:" +msgstr "Uscita MIDI:" + +msgid "MIDI In Device:" +msgstr "Entrata MIDI:" + +msgid "Standalone MPU-401" +msgstr "MPU-401 autonomo" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "Usa suono FLOAT32" + +msgid "Network type:" +msgstr "Tipo di rete:" + +msgid "PCap device:" +msgstr "Dispositivo PCap:" + +msgid "Network adapter:" +msgstr "Scheda di rete:" + +msgid "COM1 Device:" +msgstr "Dispositivo COM1:" + +msgid "COM2 Device:" +msgstr "Dispositivo COM2:" + +msgid "COM3 Device:" +msgstr "Dispositivo COM3:" + +msgid "COM4 Device:" +msgstr "Dispositivo COM4:" + +msgid "LPT1 Device:" +msgstr "Dispositivo LPT1:" + +msgid "LPT2 Device:" +msgstr "Dispositivo LPT2:" + +msgid "LPT3 Device:" +msgstr "Dispositivo LPT3:" + +msgid "LPT4 Device:" +msgstr "Dispositivo LPT4:" + +msgid "Serial port 1" +msgstr "Porta seriale 1" + +msgid "Serial port 2" +msgstr "Porta seriale 2" + +msgid "Serial port 3" +msgstr "Porta seriale 3" + +msgid "Serial port 4" +msgstr "Porta seriale 4" + +msgid "Parallel port 1" +msgstr "Porta parallela 1" + +msgid "Parallel port 2" +msgstr "Porta parallela 2" + +msgid "Parallel port 3" +msgstr "Porta parallela 3" + +msgid "Parallel port 4" +msgstr "Porta parallela 4" + +msgid "HD Controller:" +msgstr "Controller HD:" + +msgid "FD Controller:" +msgstr "Controller FD:" + +msgid "Tertiary IDE Controller" +msgstr "Controller IDE terziario" + +msgid "Quaternary IDE Controller" +msgstr "Controller IDE quaternario" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Controller 1:" + +msgid "Controller 2:" +msgstr "Controller 2:" + +msgid "Controller 3:" +msgstr "Controller 3:" + +msgid "Controller 4:" +msgstr "Controller 4:" + +msgid "Cassette" +msgstr "Cassetta" + +msgid "Hard disks:" +msgstr "Hard disk:" + +msgid "&New..." +msgstr "&Nuovo..." + +msgid "&Existing..." +msgstr "&Esistente..." + +msgid "&Remove" +msgstr "&Rimouvi" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Canale:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Specifica..." + +msgid "Sectors:" +msgstr "Settori:" + +msgid "Heads:" +msgstr "Testine:" + +msgid "Cylinders:" +msgstr "Cilindri:" + +msgid "Size (MB):" +msgstr "Dimensioni (MB):" + +msgid "Type:" +msgstr "Tipo:" + +msgid "Image Format:" +msgstr "Formato immagine:" + +msgid "Block Size:" +msgstr "Dimensioni blocco:" + +msgid "Floppy drives:" +msgstr "Unità floppy:" + +msgid "Turbo timings" +msgstr "Turbo" + +msgid "Check BPB" +msgstr "Verifica BPB" + +msgid "CD-ROM drives:" +msgstr "Unità CD-ROM:" + +msgid "MO drives:" +msgstr "Unità magneto-ottiche:" + +msgid "ZIP drives:" +msgstr "Unità ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "RTC ISA:" + +msgid "ISA Memory Expansion" +msgstr "Espansione memoria ISA" + +msgid "Card 1:" +msgstr "Scheda 1:" + +msgid "Card 2:" +msgstr "Scheda 2:" + +msgid "Card 3:" +msgstr "Scheda 3:" + +msgid "Card 4:" +msgstr "Scheda 4:" + +msgid "ISABugger device" +msgstr "Dispositivo ISABugger" + +msgid "POST card" +msgstr "Scheda POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Errore" + +msgid "Fatal error" +msgstr "Errore fatale" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Usa CTRL+ALT+PAGE DOWN per tornare alla modalità finestra." + +msgid "Speed" +msgstr "Velocità" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Immagini ZIP" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box non può trovare immagini ROM utilizzabili.\n\nPlease download a ROM set and extract it into the \"roms\" directory." + +msgid "(empty)" +msgstr "(empty)" + +msgid "All files" +msgstr "Tutti i file" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Acceso" + +msgid "Off" +msgstr "Spento" + +msgid "All images" +msgstr "Tutte le immagini" + +msgid "Basic sector images" +msgstr "Immagini di settori base" + +msgid "Surface images" +msgstr "Immagini di superficie" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "La macchina \"%hs\" non è disponibile a causa di immagini ROM mancanti nella directory roms/machines. Cambiando ad una macchina disponibile." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "La scheda video \"%hs\" non è disponibile a causa di immagini ROM mancanti nella directory roms/video. Cambiando ad una scheda video disponibile." + +msgid "Machine" +msgstr "Piastra madre" + +msgid "Display" +msgstr "Schermo" + +msgid "Input devices" +msgstr "Dispositivi di entrata" + +msgid "Sound" +msgstr "Audio" + +msgid "Network" +msgstr "Rete" + +msgid "Ports (COM & LPT)" +msgstr "Porte (COM & LPT)" + +msgid "Storage controllers" +msgstr "Controller memoria" + +msgid "Hard disks" +msgstr "Hard disk" + +msgid "Floppy & CD-ROM drives" +msgstr "Unità CD-ROM e Floppy" + +msgid "Other removable devices" +msgstr "Altri dispositivi rimuovibili" + +msgid "Other peripherals" +msgstr "Altre periferiche" + +msgid "Click to capture mouse" +msgstr "Fare clic per catturare mouse" + +msgid "Press F8+F12 to release mouse" +msgstr "Premi F8+F12 per rilasciare il mouse" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Premi F8+F12 o pulsante centrale per rilasciare il mouse" + +msgid "Unable to initialize FluidSynth" +msgstr "Impossibile inizializzare FluidSynth" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "File" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Impossibile inizializzare il renderer video." + +msgid "Default" +msgstr "Predefinito" + +msgid "%i Wait state(s)" +msgstr "%i stati d'attesa" + +msgid "Type" +msgstr "Tipo" + +msgid "Failed to set up PCap" +msgstr "Impossibile impostare PCap" + +msgid "No PCap devices found" +msgstr "Nessun dispositivo PCap trovato" + +msgid "Invalid PCap device" +msgstr "Dispositivo PCap invalido" + +msgid "Standard 2-button joystick(s)" +msgstr "Joystick comune da 2 pulsanti" + +msgid "Standard 4-button joystick" +msgstr "Joystick comune da 4 pulsanti" + +msgid "Standard 6-button joystick" +msgstr "Joystick comune da 6 pulsanti" + +msgid "Standard 8-button joystick" +msgstr "Joystick comune da 8 pulsanti" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Nessuno" + +msgid "Unable to load keyboard accelerators." +msgstr "Impossibile caricare gli acceleratori da tastiera." + +msgid "Unable to register raw input." +msgstr "Impossibile registrare input raw." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Floppy %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Immagini da settori avanzati" + +msgid "Flux images" +msgstr "Immagini flusso" + +msgid "Unable to initialize FreeType" +msgstr "Impossibile inizializzare FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Impossibile inizializzare SDL, SDL2.dll è necessario" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Sei sicuro di voler riavviare la macchina emulata?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Sei sicuro di voler uscire da 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Impossibile inizializzare Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Immagini MO" + +msgid "Welcome to 86Box!" +msgstr "Benvenuti in 86Box!" + +msgid "Internal controller" +msgstr "Controller interno" + +msgid "Exit" +msgstr "Esci" + +msgid "No ROMs found" +msgstr "Nessune immagini ROM trovate" + +msgid "Do you want to save the settings?" +msgstr "Vuole salvare queste impostazioni?" + +msgid "This will hard reset the emulated machine." +msgstr "Questo riavvierà la macchina emulata." + +msgid "Save" +msgstr "Salva" + +msgid "About 86Box" +msgstr "Informazioni su 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Un emulatore di computer vecchi\n\nAutori: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nTradotto da: explorerdotexe\n\nRilasciato sotto la Licenza Pubblica GNU versione 2 o dopo. Vedi LICENSE per maggior informazioni." + +msgid "Hardware not available" +msgstr "Hardware non disponibile" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Controlla se libpcap è installato e che tu sia connesso ad una connessione libpcap compatibile." + +msgid "Invalid configuration" +msgstr "Configurazione invalida" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " è richesto per l'emuazione di stampanti ESC/P." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " è richiesto per la conversione automatica di file PostScript a file PDF.\n\nQualsiasi documento mandato alla stampante generica PostScript sarà salvato come file PostScript. (.ps)" + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " è richiesto per l'output FluidSynth MIDI." + +msgid "Entering fullscreen mode" +msgstr "Entrando nella modalità schermo intero" + +msgid "Don't show this message again" +msgstr "Non mostrare più questo messaggio" + +msgid "Don't exit" +msgstr "Non uscire" + +msgid "Reset" +msgstr "Riavvia" + +msgid "Don't reset" +msgstr "Non riavviare" + +msgid "CD-ROM images" +msgstr "Immagini CD-ROM" + +msgid "%hs Device Configuration" +msgstr "Configurazione del dispositivo %hs" + +msgid "Monitor in sleep mode" +msgstr "Monitor in modalità riposo" + +msgid "OpenGL Shaders" +msgstr "Shader OpenGL" + +msgid "OpenGL options" +msgstr "Impostazioni OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Stai caricando una configurazione non supportata" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Il filtraggio della tipologia di CPU è disabilitato per la macchina selezionata.\n\nQuesto lo rende possibile scegliere un CPU che è altrimenti incompatibile con la macchina selezionata. Tuttavia, portresti incorrere in incompatibilità con il BIOS della macchina o altri programmi. \n\nL'abilitare di questa impostazione non è ufficialmente supportato e tutte le segnalazioni di errori saranno considerate invalide." + +msgid "Continue" +msgstr "Continua" + +msgid "Cassette: %s" +msgstr "Cassetta: %s" + +msgid "Cassette images" +msgstr "Immagini cassetta" + +msgid "Cartridge %i: %ls" +msgstr "Cartuccia %i: %ls" + +msgid "Cartridge images" +msgstr "Immagini cartuccia" + +msgid "Error initializing renderer" +msgstr "Error initializing renderer" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "Hard disk (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "Le unità CD-ROM MFM/RLL o ESDI non sono mai esistite." + +msgid "Custom..." +msgstr "Personalizzata..." + +msgid "Custom (large)..." +msgstr "Personalizzata (grande)..." + +msgid "Add New Hard Disk" +msgstr "Aggiungi un nuovo disco rigido" + +msgid "Add Existing Hard Disk" +msgstr "Aggiungi un disco rigido esistente" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Le immagini HDI non possono essere più grandi di 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Le immmagini disco non possono essere più grandi di 127 GB." + +msgid "Hard disk images" +msgstr "Immagini disco rigido" + +msgid "Unable to read file" +msgstr "Impossibile leggere il file" + +msgid "Unable to write file" +msgstr "Impossibile scrivere al file" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Le immagini HDI o HDX con settori di dimensioni diverse da 512 non sono supportati." + +msgid "USB is not yet supported" +msgstr "USB non è ancora supportato" + +msgid "Disk image file already exists" +msgstr "Immagine disco già esiste" + +msgid "Please specify a valid file name." +msgstr "Specifica un nome file valido." + +msgid "Disk image created" +msgstr "Immagine disco creata" + +msgid "Make sure the file exists and is readable." +msgstr "Controlla che il file esiste e che sia leggibile." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Controlla che il file viene salvato ad un percorso con diritti di scrittura" + +msgid "Disk image too large" +msgstr "Immagine disco troppo grande" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Ricordati di partizionare e formattare il disco appena creato." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Il file selezionato sarà sovrascritto, sei sicuro di volerlo usare?" + +msgid "Unsupported disk image" +msgstr "Immagine disco non supportata" + +msgid "Overwrite" +msgstr "Sovrascrivi" + +msgid "Don't overwrite" +msgstr "Non sovrascrivere" + +msgid "Raw image (.img)" +msgstr "Immagine raw (.img)" + +msgid "HDI image (.hdi)" +msgstr "Immagine HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Immagine HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD di dimensioni fisse (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD di dimensioni dinamiche (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "VHD differenziato (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Blocchi larghi (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Blocchi piccoli (512 KB)" + +msgid "VHD files" +msgstr "File VHD" + +msgid "Select the parent VHD" +msgstr "Seleziona il VHD padre." + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Questo potrebbe significare che l'immagine padre sia stata modificata dopo la creazione dell'immagine di differenziazione.\n\nPuò anche succedere se i file immagini sono stati spostati o copiati, o da un errore nel programma che ha creato questo disco.\n\nVuoi aggiustare le marcature di tempo?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Le marcature di tempo padre e figlio non corrispondono" + +msgid "Could not fix VHD timestamp." +msgstr "Impossibile aggiustare marcature di tempo VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "RPM perfette" + +msgid "1%% below perfect RPM" +msgstr "RPM 1%% sotto perfezione" + +msgid "1.5%% below perfect RPM" +msgstr "RPM 1.5%% sotto perfezione" + +msgid "2%% below perfect RPM" +msgstr "RPM 2%% sotto perfezione" + +msgid "(System Default)" +msgstr "(Predefinito del sistema)" + diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po new file mode 100644 index 000000000..758ddec6e --- /dev/null +++ b/src/qt/languages/ja-JP.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "動作(&A)" + +msgid "&Keyboard requires capture" +msgstr "キーボードはキャプチャが必要(&K)" + +msgid "&Right CTRL is left ALT" +msgstr "右CTRLを左ALTへ(&R)" + +msgid "&Hard Reset..." +msgstr "ハードリセット(&H)..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "Ctrl+Alt+Del(&C)\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+Esc(&E)" + +msgid "&Pause" +msgstr "一時停止(&P)" + +msgid "E&xit..." +msgstr "終了(&X)..." + +msgid "&View" +msgstr "表示(&V)" + +msgid "&Hide status bar" +msgstr "ステータスバーを隠す(&H)" + +msgid "Hide &toolbar" +msgstr "ツールバーを隠す(&T)" + +msgid "&Resizeable window" +msgstr "ウィンドウのサイズをリサイズ可能(&R)" + +msgid "R&emember size && position" +msgstr "ウィンドウのサイズと位置を記憶(&E)" + +msgid "Re&nderer" +msgstr "レンダラー(&N)" + +msgid "&SDL (Software)" +msgstr "SDL (ソフトウェア)(&S)" + +msgid "SDL (&Hardware)" +msgstr "SDL (ハードウェア)(&H)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (OpenGL)(&O)" + +msgid "Open&GL (3.0 Core)" +msgstr "OpenGL (3.0コア)(&G)" + +msgid "&VNC" +msgstr "VNC(&V)" + +msgid "Specify dimensions..." +msgstr "ウィンドウのサイズを指定..." + +msgid "F&orce 4:3 display ratio" +msgstr "4:3アスペクト比を固定(&O)" + +msgid "&Window scale factor" +msgstr "ウィンドウの表示倍率(&W)" + +msgid "&0.5x" +msgstr "0.5x(&0)" + +msgid "&1x" +msgstr "1x(&1)" + +msgid "1.&5x" +msgstr "1.5x(&5)" + +msgid "&2x" +msgstr "2x(&2)" + +msgid "Filter method" +msgstr "フィルター方式" + +msgid "&Nearest" +msgstr "最近傍補間(&N)" + +msgid "&Linear" +msgstr "線形補間(&L)" + +msgid "Hi&DPI scaling" +msgstr "HiDPIスケーリング(&D)" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "フルスクリーン(&F)\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "フルスクリーンのスケール(&S)" + +msgid "&Full screen stretch" +msgstr "フルスクリーンに拡大(&F)" + +msgid "&4:3" +msgstr "4:3(&4)" + +msgid "&Square pixels (Keep ratio)" +msgstr "正方形ピクセル(アスペクト比を維持)(&S)" + +msgid "&Integer scale" +msgstr "整数倍(&I)" + +msgid "E&GA/(S)VGA settings" +msgstr "E&GA/(S)VGAの設定" + +msgid "&Inverted VGA monitor" +msgstr "色を反転(&I)" + +msgid "VGA screen &type" +msgstr "画面タイプ(&T)" + +msgid "RGB &Color" +msgstr "RGB(カラー)(&C)" + +msgid "&RGB Grayscale" +msgstr "RGB(グレースケール)(&R)" + +msgid "&Amber monitor" +msgstr "モニター(琥珀色)(&A)" + +msgid "&Green monitor" +msgstr "モニター(緑色)(&G)" + +msgid "&White monitor" +msgstr "モニター(白色)(&W)" + +msgid "Grayscale &conversion type" +msgstr "グレースケール変換タイプ(&C)" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT601 (NTSC/PAL)(&6)" + +msgid "BT&709 (HDTV)" +msgstr "BT709 (HDTV)(&7)" + +msgid "&Average" +msgstr "平均(&A)" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "CGA/PCjr/Tandy/EGA/(S)VGAオーバースキャン(&G)" + +msgid "Change contrast for &monochrome display" +msgstr "単色モニター用コントラストを変更(&M)" + +msgid "&Media" +msgstr "メディア(&M)" + +msgid "&Tools" +msgstr "ツール(&T)" + +msgid "&Settings..." +msgstr "設定(&S)..." + +msgid "&Update status bar icons" +msgstr "ステータスバーのアイコンを更新(&U)" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "スクリーンショットを撮る(&C)\tCtrl+F11" + +msgid "&Preferences..." +msgstr "環境設定(&P)..." + +msgid "Enable &Discord integration" +msgstr "Discordとの連携機能(&D)" + +msgid "Sound &gain..." +msgstr "音量を調節(&G)..." + +msgid "Begin trace\tCtrl+T" +msgstr "トレース開始\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "トレース終了\tCtrl+T" + +msgid "&Logging" +msgstr "ログ(&L)" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "BusLogicのログを有効\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "CD-ROMのログを有効\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "フロッピー(86F)のログを有効\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "フロッピーコントローラーのログを有効\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "IDEのログを有効\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "シリアルポートのログを有効\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "ネットワークのログを有効\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "ブレークポイントのログを有効(&L)\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "ビデオRAMのダンプを有効(&V)\tCtrl+F1" + +msgid "&Help" +msgstr "ヘルプ(&H)" + +msgid "&Documentation..." +msgstr "ドキュメント(&D)..." + +msgid "&About 86Box..." +msgstr "86Boxのバージョン情報(&A)..." + +msgid "&New image..." +msgstr "新規イメージ(&N)..." + +msgid "&Existing image..." +msgstr "既存のイメージを開く(&E)..." + +msgid "Existing image (&Write-protected)..." +msgstr "既存のイメージを開く(書き込み保護)(&W)..." + +msgid "&Record" +msgstr "録音(&R)" + +msgid "&Play" +msgstr "再生(&P)" + +msgid "&Rewind to the beginning" +msgstr "冒頭に巻き戻す(&R)" + +msgid "&Fast forward to the end" +msgstr "最後まで早送り(&F)" + +msgid "E&ject" +msgstr "取り出す(&J)" + +msgid "&Image..." +msgstr "イメージ(&I)..." + +msgid "E&xport to 86F..." +msgstr "86Fイメージにエクスポート(&X)..." + +msgid "&Mute" +msgstr "ミュート(&M)" + +msgid "E&mpty" +msgstr "空(&M)" + +msgid "&Reload previous image" +msgstr "前のイメージを再読み込み(&R)" + +msgid "&Image" +msgstr "イメージ(&I)" + +msgid "Target &framerate" +msgstr "目標フレームレート(&F)" + +msgid "&Sync with video" +msgstr "ビデオと同期(&S)" + +msgid "&25 fps" +msgstr "25 fps(&2)" + +msgid "&30 fps" +msgstr "30 fps(&3)" + +msgid "&50 fps" +msgstr "50 fps(&5)" + +msgid "&60 fps" +msgstr "60 fps(&6)" + +msgid "&75 fps" +msgstr "75 fps(&7)" + +msgid "&VSync" +msgstr "垂直同期(VSync)(&V)" + +msgid "&Select shader..." +msgstr "シェーダーを選択(&S)..." + +msgid "&Remove shader" +msgstr "シェーダーを削除(&R)" + +msgid "Preferences" +msgstr "環境設定" + +msgid "Sound Gain" +msgstr "音量ゲイン" + +msgid "New Image" +msgstr "新規のイメージ" + +msgid "Settings" +msgstr "設定" + +msgid "Specify Main Window Dimensions" +msgstr "メインウィンドウのサイズ指定" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "キャンセル" + +msgid "Save these settings as &global defaults" +msgstr "これらの設定をグローバル既定値として保存する(&G)" + +msgid "&Default" +msgstr "既定値(&D)" + +msgid "Language:" +msgstr "言語:" + +msgid "Icon set:" +msgstr "アイコンセット:" + +msgid "Gain" +msgstr "ゲイン値" + +msgid "File name:" +msgstr "ファイル名:" + +msgid "Disk size:" +msgstr "ディスクサイズ:" + +msgid "RPM mode:" +msgstr "回転数モード:" + +msgid "Progress:" +msgstr "進行状況:" + +msgid "Width:" +msgstr "幅:" + +msgid "Height:" +msgstr "高さ:" + +msgid "Lock to this size" +msgstr "このサイズをロックする" + +msgid "Machine type:" +msgstr "マシンタイプ:" + +msgid "Machine:" +msgstr "マシン:" + +msgid "Configure" +msgstr "設定" + +msgid "CPU type:" +msgstr "CPUタイプ:" + +msgid "Speed:" +msgstr "速度:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "待機状態:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "メモリ:" + +msgid "Time synchronization" +msgstr "時刻同期機能" + +msgid "Disabled" +msgstr "無効にする" + +msgid "Enabled (local time)" +msgstr "有効にする (現地時間)" + +msgid "Enabled (UTC)" +msgstr "有効にする (UTC)" + +msgid "Dynamic Recompiler" +msgstr "動的リコンパイラ" + +msgid "Video:" +msgstr "ビデオカード:" + +msgid "Voodoo Graphics" +msgstr "Voodooグラフィック" + +msgid "Mouse:" +msgstr "マウス:" + +msgid "Joystick:" +msgstr "ジョイスティック:" + +msgid "Joystick 1..." +msgstr "ジョイスティック1..." + +msgid "Joystick 2..." +msgstr "ジョイスティック2..." + +msgid "Joystick 3..." +msgstr "ジョイスティック3..." + +msgid "Joystick 4..." +msgstr "ジョイスティック4..." + +msgid "Sound card:" +msgstr "サウンドカード:" + +msgid "MIDI Out Device:" +msgstr "MIDI出力デバイス:" + +msgid "MIDI In Device:" +msgstr "MIDI入力デバイス:" + +msgid "Standalone MPU-401" +msgstr "独立型MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "FLOAT32サウンドを使用する" + +msgid "Network type:" +msgstr "ネットワークタイプ:" + +msgid "PCap device:" +msgstr "PCapデバイス:" + +msgid "Network adapter:" +msgstr "ネットワークアダプター:" + +msgid "COM1 Device:" +msgstr "COM1デバイス:" + +msgid "COM2 Device:" +msgstr "COM2デバイス:" + +msgid "COM3 Device:" +msgstr "COM3デバイス:" + +msgid "COM4 Device:" +msgstr "COM4デバイス:" + +msgid "LPT1 Device:" +msgstr "LPT1デバイス:" + +msgid "LPT2 Device:" +msgstr "LPT2デバイス:" + +msgid "LPT3 Device:" +msgstr "LPT3デバイス:" + +msgid "LPT4 Device:" +msgstr "LPT4デバイス:" + +msgid "Serial port 1" +msgstr "シリアルポート1" + +msgid "Serial port 2" +msgstr "シリアルポート2" + +msgid "Serial port 3" +msgstr "シリアルポート3" + +msgid "Serial port 4" +msgstr "シリアルポート4" + +msgid "Parallel port 1" +msgstr "パラレルポート1" + +msgid "Parallel port 2" +msgstr "パラレルポート2" + +msgid "Parallel port 3" +msgstr "パラレルポート3" + +msgid "Parallel port 4" +msgstr "パラレルポート4" + +msgid "HD Controller:" +msgstr "HDコントローラー:" + +msgid "FD Controller:" +msgstr "FDコントローラー:" + +msgid "Tertiary IDE Controller" +msgstr "第三のIDEコントローラー" + +msgid "Quaternary IDE Controller" +msgstr "第四のIDEコントローラー" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "コントローラー1:" + +msgid "Controller 2:" +msgstr "コントローラー2:" + +msgid "Controller 3:" +msgstr "コントローラー3:" + +msgid "Controller 4:" +msgstr "コントローラー4:" + +msgid "Cassette" +msgstr "カセット" + +msgid "Hard disks:" +msgstr "ハードディスク:" + +msgid "&New..." +msgstr "新規(&N)..." + +msgid "&Existing..." +msgstr "既定(&E)..." + +msgid "&Remove" +msgstr "除去(&R)" + +msgid "Bus:" +msgstr "バス:" + +msgid "Channel:" +msgstr "チャンネル:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "参照(&S)..." + +msgid "Sectors:" +msgstr "セクター:" + +msgid "Heads:" +msgstr "ヘッド:" + +msgid "Cylinders:" +msgstr "シリンダー:" + +msgid "Size (MB):" +msgstr "サイズ(MB):" + +msgid "Type:" +msgstr "タイプ:" + +msgid "Image Format:" +msgstr "イメージ形式:" + +msgid "Block Size:" +msgstr "ブロックサイズ:" + +msgid "Floppy drives:" +msgstr "フロッピードライブ:" + +msgid "Turbo timings" +msgstr "高速タイミング" + +msgid "Check BPB" +msgstr "BPBをチェック" + +msgid "CD-ROM drives:" +msgstr "CD-ROMドライブ:" + +msgid "MO drives:" +msgstr "光磁気ドライブ:" + +msgid "ZIP drives:" +msgstr "ZIPドライブ:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTCカード:" + +msgid "ISA Memory Expansion" +msgstr "ISAメモリー拡張カード" + +msgid "Card 1:" +msgstr "カード1:" + +msgid "Card 2:" +msgstr "カード2:" + +msgid "Card 3:" +msgstr "カード3:" + +msgid "Card 4:" +msgstr "カード4:" + +msgid "ISABugger device" +msgstr "ISABuggerデバイス" + +msgid "POST card" +msgstr "POSTカード" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Meiryo UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "エラー" + +msgid "Fatal error" +msgstr "致命的なエラー" + +msgid "" +msgstr "<予約済み>" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "CTRL+ALT+PAGE DOWNでウィンドウモードに戻ります。" + +msgid "Speed" +msgstr "速度" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIPイメージ" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Boxで使用可能なROMイメージが見つかりませんでした。\n\nROMセットをダウンロードして、「roms」ディレクトリに解凍してください。" + +msgid "(empty)" +msgstr "(空)" + +msgid "All files" +msgstr "すべてのファイル" + +msgid "Turbo" +msgstr "高速" + +msgid "On" +msgstr "オン" + +msgid "Off" +msgstr "オフ" + +msgid "All images" +msgstr "すべてのイメージ" + +msgid "Basic sector images" +msgstr "基本的なセクターイメージ" + +msgid "Surface images" +msgstr "表面イメージ" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "roms/machinesディレクトリにROMがないため、マシン「%hs」は使用できません。使用可能なマシンに切り替えます。" + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "roms/videoディレクトリにROMがないため、ビデオカード「%hs」は使用できません。使用可能なビデオカードに切り替えます。" + +msgid "Machine" +msgstr "マシン" + +msgid "Display" +msgstr "画面表示" + +msgid "Input devices" +msgstr "入力デバイス" + +msgid "Sound" +msgstr "サウンド" + +msgid "Network" +msgstr "ネットワーク" + +msgid "Ports (COM & LPT)" +msgstr "ポート (COM & LPT)" + +msgid "Storage controllers" +msgstr "ストレージコントローラ" + +msgid "Hard disks" +msgstr "ハードディスク" + +msgid "Floppy & CD-ROM drives" +msgstr "フロッピー/CD-ROMドライブ" + +msgid "Other removable devices" +msgstr "その他のリムーバブルデバイス" + +msgid "Other peripherals" +msgstr "その他の周辺装置" + +msgid "Click to capture mouse" +msgstr "クリックするとマウスをキャプチャします" + +msgid "Press F8+F12 to release mouse" +msgstr "F8+F12キーでマウスを解放します" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "F8+F12キーまたは中ボタンでマウスを解放します" + +msgid "Unable to initialize FluidSynth" +msgstr "FluidSynthが初期化できません" + +msgid "Bus" +msgstr "バス" + +msgid "File" +msgstr "ファイル" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "ビデオレンダラーが初期化できません。" + +msgid "Default" +msgstr "既定値" + +msgid "%i Wait state(s)" +msgstr "%iつの待機状態" + +msgid "Type" +msgstr "タイプ" + +msgid "Failed to set up PCap" +msgstr "PCapのセットアップに失敗しました" + +msgid "No PCap devices found" +msgstr "PCapデバイスがありません" + +msgid "Invalid PCap device" +msgstr "不正なPCapデバイスです" + +msgid "Standard 2-button joystick(s)" +msgstr "標準ジョイスティック(2ボタン)" + +msgid "Standard 4-button joystick" +msgstr "標準ジョイスティック(4ボタン)" + +msgid "Standard 6-button joystick" +msgstr "標準ジョイスティック(6ボタン)" + +msgid "Standard 8-button joystick" +msgstr "標準ジョイスティック(8ボタン)" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "なし" + +msgid "Unable to load keyboard accelerators." +msgstr "キーボードアクセラレータを読み込めません。" + +msgid "Unable to register raw input." +msgstr "生の入力が登録できません。" + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "フロッピー %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "アドバンスドセクターイメージ" + +msgid "Flux images" +msgstr "フラックスイメージ" + +msgid "Unable to initialize FreeType" +msgstr "FreeTypeが初期化できません" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "SDLが初期化できません。SDL2.dllが必要です" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "使用中のマシンをハードリセットしますか?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "86Boxを終了しますか?" + +msgid "Unable to initialize Ghostscript" +msgstr "Ghostscriptが初期化できません" + +msgid "MO %i (%ls): %ls" +msgstr "光磁気 %i (%ls): %ls" + +msgid "MO images" +msgstr "光磁気イメージ" + +msgid "Welcome to 86Box!" +msgstr "86Boxへようこそ!" + +msgid "Internal controller" +msgstr "内蔵コントローラー" + +msgid "Exit" +msgstr "終了" + +msgid "No ROMs found" +msgstr "ROMが見つかりません" + +msgid "Do you want to save the settings?" +msgstr "設定を保存しますか?" + +msgid "This will hard reset the emulated machine." +msgstr "保存すると使用中のマシンがハードリセットされます。" + +msgid "Save" +msgstr "保存" + +msgid "About 86Box" +msgstr "86Boxのバージョン情報" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "古いパソコンのエミュレーター\n\n著者: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public License version 2以降でリリースされています。詳しくは LICENSE をご覧ください。" + +msgid "Hardware not available" +msgstr "ハードウェアが利用できません" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "がインストールされてるか、libpcapに対応したネットワークに接続されてるか確認してください。" + +msgid "Invalid configuration" +msgstr "不正な設定です" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr "ESC/Pプリンタのエミュレーションにはlibfreetypeが必要です。" + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "PostScriptファイルをPDFに自動変換するにはlibgsが必要です。\n\n汎用PostScriptプリンターに送信されたドキュメントは、PostScript(.ps)ファイルとして保存されます。" + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr "FluidSynthのMIDI出力にはlibfluidsynthが必要です。" + +msgid "Entering fullscreen mode" +msgstr "フルスクリーンに切り替えています" + +msgid "Don't show this message again" +msgstr "今後、このメッセージを表示しない" + +msgid "Don't exit" +msgstr "終了しない" + +msgid "Reset" +msgstr "リセット" + +msgid "Don't reset" +msgstr "リセットしない" + +msgid "CD-ROM images" +msgstr "CD-ROMイメージ" + +msgid "%hs Device Configuration" +msgstr "%hs デバイスの設定" + +msgid "Monitor in sleep mode" +msgstr "モニターのスリープモード" + +msgid "OpenGL Shaders" +msgstr "OpenGLシェーダー" + +msgid "OpenGL options" +msgstr "OpenGL設定" + +msgid "You are loading an unsupported configuration" +msgstr "サポートされていない設定を読み込んでいます" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "選択したマシンに基づくCPUタイプのフィルタリングは、このエミュレートされたマシンでは無効になっています。\n\nこれにより、選択したマシンと互換性のないCPUが選択できます。ただし、マシンのBIOSまたは他のソフトウェアとの互換性が失われる可能性があります。\n\nこの設定の有効化は公式サポートができません。また、バグレポートが無効として閉じられる場合があります。" + +msgid "Continue" +msgstr "続行" + +msgid "Cassette: %s" +msgstr "カセット: %s" + +msgid "Cassette images" +msgstr "カセットイメージ" + +msgid "Cartridge %i: %ls" +msgstr "カートリッジ %i: %ls" + +msgid "Cartridge images" +msgstr "カートリッジイメージ" + +msgid "Error initializing renderer" +msgstr "レンダラーの初期化エラー" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0コア) レンダラーが初期化できませんでした。別のレンダラーを使用してください。" + +msgid "Resume execution" +msgstr "実行を再開" + +msgid "Pause execution" +msgstr "実行を一時停止" + +msgid "Press Ctrl+Alt+Del" +msgstr "Ctrl+Alt+DELを押し" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Ctrl+Alt+Escを押し" + +msgid "Hard reset" +msgstr "ハードリセット" + +msgid "ACPI shutdown" +msgstr "ACPIシャットダウン" + +msgid "Hard disk (%s)" +msgstr "ハードディスク (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLLまたはESDIのCD-ROMドライブが存在しません" + +msgid "Custom..." +msgstr "カスタム..." + +msgid "Custom (large)..." +msgstr "カスタム (大型)..." + +msgid "Add New Hard Disk" +msgstr "新規のディスクを追加" + +msgid "Add Existing Hard Disk" +msgstr "既定のディスクを追加" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "HDIディスクイメージは4GBを超えることはできません。" + +msgid "Disk images cannot be larger than 127 GB." +msgstr "ディスクイメージは127GBを超えることはできません。" + +msgid "Hard disk images" +msgstr "ハードディスクイメージ" + +msgid "Unable to read file" +msgstr "ファイルの読み込みができません" + +msgid "Unable to write file" +msgstr "ファイルの書き込みができません" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "512以外のセクタサイズを持つHDIまたはHDXイメージはサポートされていません。" + +msgid "USB is not yet supported" +msgstr "USBはまだサポートされていません" + +msgid "Disk image file already exists" +msgstr "ディスクイメージファイルが既に存在します" + +msgid "Please specify a valid file name." +msgstr "有効なファイル名を指定してください。" + +msgid "Disk image created" +msgstr "ディスクイメージが作成されました" + +msgid "Make sure the file exists and is readable." +msgstr "ファイルが存在し、読み取り可能であることを確認してください。" + +msgid "Make sure the file is being saved to a writable directory." +msgstr "ファイルが書き込み可能なディレクトリに保存されていることを確認してください。" + +msgid "Disk image too large" +msgstr "ディスクイメージのサイズが大きすぎます" + +msgid "Remember to partition and format the newly-created drive." +msgstr "新規ドライブをパーティション分割し、フォーマットを必ずしといてください。" + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "選択したファイルが上書きされます。使っていいですか?" + +msgid "Unsupported disk image" +msgstr "サポートされていないディスクイメージ" + +msgid "Overwrite" +msgstr "上書き" + +msgid "Don't overwrite" +msgstr "上書きしない" + +msgid "Raw image (.img)" +msgstr "Rawイメージ (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDIイメージ (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDXイメージ (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD(容量固定)(.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD(容量可変)(.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "VHD(差分)(.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "大型ブロック (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "小型ブロック (512 KB)" + +msgid "VHD files" +msgstr "VHDファイル" + +msgid "Select the parent VHD" +msgstr "親VHDの選択" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "親イメージがディファレンシングイメージの作成の後に修正した可能性があります。\n\nイメージファイルの移動、コピーまたはこのディスクを作成したプログラムにバグが発生した可能性があります。\n\nタイムスタンプを修正しますか?" + +msgid "Parent and child disk timestamps do not match" +msgstr "親ディスクと子ディスクのタイムスタンプが一致しません" + +msgid "Could not fix VHD timestamp." +msgstr "VHD のタイムスタンプを修正できませんでした。" + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (クラスター1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (クラスター2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "規定の回転数" + +msgid "1%% below perfect RPM" +msgstr "1%低い回転数" + +msgid "1.5%% below perfect RPM" +msgstr "1.5%低い回転数" + +msgid "2%% below perfect RPM" +msgstr "2%低い回転数" + +msgid "(System Default)" +msgstr "(システム既定値)" + diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po new file mode 100644 index 000000000..4664e5cc6 --- /dev/null +++ b/src/qt/languages/ko-KR.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "동작(&A)" + +msgid "&Keyboard requires capture" +msgstr "키보드는 캡쳐가 필요함(&K)" + +msgid "&Right CTRL is left ALT" +msgstr "우측CTRL로 좌측ALT 입력(&R)" + +msgid "&Hard Reset..." +msgstr "재시작(&H)..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "Ctrl+Alt+Del(&C)\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+Esc(&E)" + +msgid "&Pause" +msgstr "일시정지(&P)" + +msgid "E&xit..." +msgstr "끝내기(&X)..." + +msgid "&View" +msgstr "표시(&V)" + +msgid "&Hide status bar" +msgstr "상태 바 숨기기(&H)" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "창 크기 조절 가능하게 하기(&R)" + +msgid "R&emember size && position" +msgstr "창 크기와 위치를 기억하기(&E)" + +msgid "Re&nderer" +msgstr "렌더러(&N)" + +msgid "&SDL (Software)" +msgstr "SDL (소프트웨어)(&S)" + +msgid "SDL (&Hardware)" +msgstr "SDL (하드웨어)(&H)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (OpenGL)(&O)" + +msgid "Open&GL (3.0 Core)" +msgstr "OpenGL (3.0 코어)(&G)" + +msgid "&VNC" +msgstr "VNC(&V)" + +msgid "Specify dimensions..." +msgstr "창 크기 지정하기..." + +msgid "F&orce 4:3 display ratio" +msgstr "화면 비율을 4:3으로 맞추기(&O)" + +msgid "&Window scale factor" +msgstr "창 표시 배율(&W)" + +msgid "&0.5x" +msgstr "0.5배(&0)" + +msgid "&1x" +msgstr "1배(&1)" + +msgid "1.&5x" +msgstr "1.5배(&5)" + +msgid "&2x" +msgstr "2배(&2)" + +msgid "Filter method" +msgstr "필터 형식" + +msgid "&Nearest" +msgstr "최근방 이웃 보간법(&N)" + +msgid "&Linear" +msgstr "선형 보간법(&L)" + +msgid "Hi&DPI scaling" +msgstr "HiDPI 스케일링(&D)" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "전체 화면(&F)\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "전체 화면 비율(&S)" + +msgid "&Full screen stretch" +msgstr "전체 화면으로 확대(&F)" + +msgid "&4:3" +msgstr "4:3(&4)" + +msgid "&Square pixels (Keep ratio)" +msgstr "정사각형 픽셀 (비율 유지)(&S)" + +msgid "&Integer scale" +msgstr "정수배 확대(&I)" + +msgid "E&GA/(S)VGA settings" +msgstr "E&GA/(S)VGA 설정" + +msgid "&Inverted VGA monitor" +msgstr "색상 반전된 VGA 모니터(&I)" + +msgid "VGA screen &type" +msgstr "VGA 화면 종류(&T)" + +msgid "RGB &Color" +msgstr "RGB 천연색(&C)" + +msgid "&RGB Grayscale" +msgstr "RGB 회색조(&R)" + +msgid "&Amber monitor" +msgstr "주황색 모니터(&A)" + +msgid "&Green monitor" +msgstr "녹색 모니터(&G)" + +msgid "&White monitor" +msgstr "흰색 모니터(&W)" + +msgid "Grayscale &conversion type" +msgstr "회색조 표현방식(&C)" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT601 (NTSC/PAL)(&6)" + +msgid "BT&709 (HDTV)" +msgstr "BT709 (HDTV)(&7)" + +msgid "&Average" +msgstr "평균값(&A)" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "CGA/PCjr/Tandy/EGA/(S)VGA 오버스캔(&G)" + +msgid "Change contrast for &monochrome display" +msgstr "흑백 표시를 위한 밝기 조정(&M)" + +msgid "&Media" +msgstr "미디어(&M)" + +msgid "&Tools" +msgstr "도구(&T)" + +msgid "&Settings..." +msgstr "설정(&S)..." + +msgid "&Update status bar icons" +msgstr "상태 바 아이콘 갱신하기(&U)" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "스크린샷 찍기(&C)\tCtrl+F11" + +msgid "&Preferences..." +msgstr "환경설정(&P)..." + +msgid "Enable &Discord integration" +msgstr "디스코드 연동 활성화하기(&D)" + +msgid "Sound &gain..." +msgstr "음량 증폭(&G)..." + +msgid "Begin trace\tCtrl+T" +msgstr "추적 시작하기\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "추적 끝내기\tCtrl+T" + +msgid "&Logging" +msgstr "로그(&L)" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "BusLogic 로그 켜기\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "CD-ROM 로그 켜기\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "플로피 (86F) 로그 켜기\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "플로피 컨트롤러 로그 켜기\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "IDE 로그 켜기\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "직렬 포트 로그 켜기\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "네트워크 로그 켜기\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "중단점 로그 켜기(&L)\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "비디오 RAM 덤프 켜기(&V)\tCtrl+F1" + +msgid "&Help" +msgstr "도움말(&H)" + +msgid "&Documentation..." +msgstr "문서(&D)..." + +msgid "&About 86Box..." +msgstr "86Box에 대해(&A)..." + +msgid "&New image..." +msgstr "새 이미지(&N)..." + +msgid "&Existing image..." +msgstr "이미지 불러오기(&E)..." + +msgid "Existing image (&Write-protected)..." +msgstr "이미지 불러오기 (쓰기방지)(&W)..." + +msgid "&Record" +msgstr "녹음하기(&R)" + +msgid "&Play" +msgstr "재생하기(&P)" + +msgid "&Rewind to the beginning" +msgstr "맨앞으로 되감기(&R)" + +msgid "&Fast forward to the end" +msgstr "맨끝으로 빨리감기(&F)" + +msgid "E&ject" +msgstr "꺼내기(&J)" + +msgid "&Image..." +msgstr "이미지(&I)..." + +msgid "E&xport to 86F..." +msgstr "86F로 보내기(&X)..." + +msgid "&Mute" +msgstr "음소거(&M)" + +msgid "E&mpty" +msgstr "비었음(&M)" + +msgid "&Reload previous image" +msgstr "이전 이미지 다시 불러오기(&R)" + +msgid "&Image" +msgstr "이미지(&I)" + +msgid "Target &framerate" +msgstr "목표 프레임 레이트(&F)" + +msgid "&Sync with video" +msgstr "비디오와 동기(&S)" + +msgid "&25 fps" +msgstr "25 fps(&2)" + +msgid "&30 fps" +msgstr "30 fps(&3)" + +msgid "&50 fps" +msgstr "50 fps(&5)" + +msgid "&60 fps" +msgstr "60 fps(&6)" + +msgid "&75 fps" +msgstr "75 fps(&7)" + +msgid "&VSync" +msgstr "수직 동기화(&V)" + +msgid "&Select shader..." +msgstr "쉐이더 불러오기(&S)..." + +msgid "&Remove shader" +msgstr "쉐이더 끄기(&R)" + +msgid "Preferences" +msgstr "환경설정" + +msgid "Sound Gain" +msgstr "음량 증폭" + +msgid "New Image" +msgstr "새 이미지" + +msgid "Settings" +msgstr "설정" + +msgid "Specify Main Window Dimensions" +msgstr "창 크기 지정" + +msgid "OK" +msgstr "확인" + +msgid "Cancel" +msgstr "취소" + +msgid "Save these settings as &global defaults" +msgstr "이 설정들을 전역 기본값으로 저장하기(&G)" + +msgid "&Default" +msgstr "기본값(&D)" + +msgid "Language:" +msgstr "언어:" + +msgid "Icon set:" +msgstr "아이콘셋:" + +msgid "Gain" +msgstr "증가값" + +msgid "File name:" +msgstr "파일명:" + +msgid "Disk size:" +msgstr "디스크 용량:" + +msgid "RPM mode:" +msgstr "RPM 모드:" + +msgid "Progress:" +msgstr "진행:" + +msgid "Width:" +msgstr "가로:" + +msgid "Height:" +msgstr "세로:" + +msgid "Lock to this size" +msgstr "크기 고정" + +msgid "Machine type:" +msgstr "머신 종류:" + +msgid "Machine:" +msgstr "기종:" + +msgid "Configure" +msgstr "설정" + +msgid "CPU type:" +msgstr "CPU 종류:" + +msgid "Speed:" +msgstr "속도:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "대기 상태:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "메모리:" + +msgid "Time synchronization" +msgstr "시간 동기화" + +msgid "Disabled" +msgstr "사용하지 않음" + +msgid "Enabled (local time)" +msgstr "사용 (현지 시간)" + +msgid "Enabled (UTC)" +msgstr "사용 (UTC)" + +msgid "Dynamic Recompiler" +msgstr "동적 재컴파일" + +msgid "Video:" +msgstr "비디오 카드:" + +msgid "Voodoo Graphics" +msgstr "Voodoo 그래픽" + +msgid "Mouse:" +msgstr "마우스:" + +msgid "Joystick:" +msgstr "조이스틱:" + +msgid "Joystick 1..." +msgstr "조이스틱 1..." + +msgid "Joystick 2..." +msgstr "조이스틱 2..." + +msgid "Joystick 3..." +msgstr "조이스틱 3..." + +msgid "Joystick 4..." +msgstr "조이스틱 4..." + +msgid "Sound card:" +msgstr "사운드 카드:" + +msgid "MIDI Out Device:" +msgstr "MIDI 출력 장치:" + +msgid "MIDI In Device:" +msgstr "MIDI 입력 장치:" + +msgid "Standalone MPU-401" +msgstr "MPU-401 단독 사용" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "FLOAT32 사운드 사용" + +msgid "Network type:" +msgstr "네트워크 종류:" + +msgid "PCap device:" +msgstr "PCap 장치:" + +msgid "Network adapter:" +msgstr "네트워크 어댑터:" + +msgid "COM1 Device:" +msgstr "COM1 장치:" + +msgid "COM2 Device:" +msgstr "COM2 장치:" + +msgid "COM3 Device:" +msgstr "COM3 장치:" + +msgid "COM4 Device:" +msgstr "COM4 장치:" + +msgid "LPT1 Device:" +msgstr "LPT1 장치:" + +msgid "LPT2 Device:" +msgstr "LPT2 장치:" + +msgid "LPT3 Device:" +msgstr "LPT3 장치:" + +msgid "LPT4 Device:" +msgstr "LPT4 장치:" + +msgid "Serial port 1" +msgstr "직렬 포트 1" + +msgid "Serial port 2" +msgstr "직렬 포트 2" + +msgid "Serial port 3" +msgstr "직렬 포트 3" + +msgid "Serial port 4" +msgstr "직렬 포트 4" + +msgid "Parallel port 1" +msgstr "병렬 포트 1" + +msgid "Parallel port 2" +msgstr "병렬 포트 2" + +msgid "Parallel port 3" +msgstr "병렬 포트 3" + +msgid "Parallel port 4" +msgstr "병렬 포트 4" + +msgid "HD Controller:" +msgstr "HD 컨트롤러:" + +msgid "FD Controller:" +msgstr "FD 컨트롤러:" + +msgid "Tertiary IDE Controller" +msgstr "제3의 IDE 컨트롤러" + +msgid "Quaternary IDE Controller" +msgstr "제4의 IDE 컨트롤러" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "컨트롤러 1:" + +msgid "Controller 2:" +msgstr "컨트롤러 2:" + +msgid "Controller 3:" +msgstr "컨트롤러 3:" + +msgid "Controller 4:" +msgstr "컨트롤러 4:" + +msgid "Cassette" +msgstr "카세트 테이프" + +msgid "Hard disks:" +msgstr "하드 디스크:" + +msgid "&New..." +msgstr "새로 만들기(&N)..." + +msgid "&Existing..." +msgstr "불러오기(&E)..." + +msgid "&Remove" +msgstr "목록에서 제거(&R)" + +msgid "Bus:" +msgstr "버스:" + +msgid "Channel:" +msgstr "채널:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "열기(&S)..." + +msgid "Sectors:" +msgstr "섹터:" + +msgid "Heads:" +msgstr "헤드:" + +msgid "Cylinders:" +msgstr "실린더:" + +msgid "Size (MB):" +msgstr "용량(MB):" + +msgid "Type:" +msgstr "형식:" + +msgid "Image Format:" +msgstr "이미지 포맷:" + +msgid "Block Size:" +msgstr "블록 크기:" + +msgid "Floppy drives:" +msgstr "플로피 드라이브:" + +msgid "Turbo timings" +msgstr "고속 동작" + +msgid "Check BPB" +msgstr "BPB 확인" + +msgid "CD-ROM drives:" +msgstr "CD-ROM 드라이브:" + +msgid "MO drives:" +msgstr "광자기 드라이브:" + +msgid "ZIP drives:" +msgstr "ZIP 드라이브:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC 카드:" + +msgid "ISA Memory Expansion" +msgstr "ISA 메모리 확장 카드" + +msgid "Card 1:" +msgstr "카드 1:" + +msgid "Card 2:" +msgstr "카드 2:" + +msgid "Card 3:" +msgstr "카드 3:" + +msgid "Card 4:" +msgstr "카드 4:" + +msgid "ISABugger device" +msgstr "ISABugger 장치" + +msgid "POST card" +msgstr "POST 카드" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Malgun Gothic" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "오류" + +msgid "Fatal error" +msgstr "치명적인 오류" + +msgid "" +msgstr "<예약됨>" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "CTRL+ALT+PAGE DOWN 키를 누르면 창 모드로 전환합니다." + +msgid "Speed" +msgstr "속도" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIP 이미지" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box에서 사용 가능한 ROM 이미지를 찾을 수 없습니다.\n\nROM 세트를다운로드 후 \"roms\" 디렉토리에 압축을 풀어 주세요." + +msgid "(empty)" +msgstr "(비었음)" + +msgid "All files" +msgstr "모든 파일" + +msgid "Turbo" +msgstr "터보" + +msgid "On" +msgstr "켜짐" + +msgid "Off" +msgstr "꺼짐" + +msgid "All images" +msgstr "모든 이미지" + +msgid "Basic sector images" +msgstr "기본 섹터 이미지" + +msgid "Surface images" +msgstr "표면 이미지" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "roms/machines 디렉토리에 필요한 롬파일이 없어 기종 \"%hs\"을(를) 사용할 수 없습니다. 사용 가능한 기종으로 변경합니다." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "roms/video 디렉토리에 필요한 롬파일이 없어 비디오 카드 \"%hs\"을(를) 사용할 수 없습니다. 사용 가능한 기종으로 변경합니다." + +msgid "Machine" +msgstr "기종" + +msgid "Display" +msgstr "디스플레이" + +msgid "Input devices" +msgstr "입력 장치" + +msgid "Sound" +msgstr "사운드" + +msgid "Network" +msgstr "네트워크" + +msgid "Ports (COM & LPT)" +msgstr "포트 (COM & LPT)" + +msgid "Storage controllers" +msgstr "장치 컨트롤러" + +msgid "Hard disks" +msgstr "하드 디스크" + +msgid "Floppy & CD-ROM drives" +msgstr "플로피 / CD-ROM" + +msgid "Other removable devices" +msgstr "기타 이동식 저장장치" + +msgid "Other peripherals" +msgstr "기타 주변기기" + +msgid "Click to capture mouse" +msgstr "이 창을 클릭하면 마우스를 사용합니다" + +msgid "Press F8+F12 to release mouse" +msgstr "F12+F8키를 누르면 마우스를 해제합니다" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "F12+F8키 또는 가운데 버튼을 클릭하면 마우스를 해제합니다" + +msgid "Unable to initialize FluidSynth" +msgstr "FluidSynth를 초기화할 수 없습니다" + +msgid "Bus" +msgstr "버스" + +msgid "File" +msgstr "파일" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "비디오 렌더러를 초기화할 수 없습니다." + +msgid "Default" +msgstr "기본값" + +msgid "%i Wait state(s)" +msgstr "%i 대기 상태" + +msgid "Type" +msgstr "형식" + +msgid "Failed to set up PCap" +msgstr "PCap 설정에 실패했습니다" + +msgid "No PCap devices found" +msgstr "PCap 장치가 없습니다" + +msgid "Invalid PCap device" +msgstr "PCap 장치가 올바르지 않습니다" + +msgid "Standard 2-button joystick(s)" +msgstr "표준 2버튼 조이스틱" + +msgid "Standard 4-button joystick" +msgstr "표준 4버튼 조이스틱" + +msgid "Standard 6-button joystick" +msgstr "표준 6버튼 조이스틱" + +msgid "Standard 8-button joystick" +msgstr "표준 8버튼 조이스틱" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "없음" + +msgid "Unable to load keyboard accelerators." +msgstr "키보드 가속기를 불러올 수 없습니다." + +msgid "Unable to register raw input." +msgstr "Raw 입력을 등록할 수 없습니다." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "플로피 %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "어드밴스드 섹터 이미지" + +msgid "Flux images" +msgstr "플럭스 이미지" + +msgid "Unable to initialize FreeType" +msgstr "FreeType을 초기화할 수 없습니다" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "SDL을 초기화할 수 없습니다. SDL2.dll이 필요합니다" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "실행중인 머신을 재시작하시겠습니까?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "86Box를 끝내시겠습니까?" + +msgid "Unable to initialize Ghostscript" +msgstr "Ghostscript를 초기화할 수 없습니다" + +msgid "MO %i (%ls): %ls" +msgstr "광자기 %i (%ls): %ls" + +msgid "MO images" +msgstr "광자기 이미지" + +msgid "Welcome to 86Box!" +msgstr "86Box에 어서오세요!" + +msgid "Internal controller" +msgstr "내부 컨트롤러" + +msgid "Exit" +msgstr "끝내기" + +msgid "No ROMs found" +msgstr "ROM을 불러올 수 없습니다" + +msgid "Do you want to save the settings?" +msgstr "설정을 저장하시겠습니까?" + +msgid "This will hard reset the emulated machine." +msgstr "사용중인 머신이 재부팅됩니다." + +msgid "Save" +msgstr "저장" + +msgid "About 86Box" +msgstr "86Box에 대해" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "고전 컴퓨터 에뮬레이터\n\n저자: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public 라이선스 (버전 2 이상)에 의해 배포되었습니다. 자세한 내용은 LICENSE 파일을 읽어 주세요." + +msgid "Hardware not available" +msgstr "하드웨어를 이용할 수 없습니다" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "이 설치되었는지 libpcap에 대응하는 네트워크에 접속되어 있는지 확인해 주세요." + +msgid "Invalid configuration" +msgstr "올바르지 않은 설정입니다" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr "ESC/P 프린터 에뮬레이션에 libfreetype이(가) 필요합니다." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "은(는) PostScript 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PostScript 프린터로 보내신 임의의 문서는 PostScript (.ps) 파일로 저장됩니다." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr "FluidSynth의 MIDI 출력에 libfluidsynth이(가) 필요합니다." + +msgid "Entering fullscreen mode" +msgstr "전체 화면으로 전환" + +msgid "Don't show this message again" +msgstr "이 메시지 그만 보기" + +msgid "Don't exit" +msgstr "끝내지 않기" + +msgid "Reset" +msgstr "재시작" + +msgid "Don't reset" +msgstr "재시작 안함" + +msgid "CD-ROM images" +msgstr "CD-ROM 이미지" + +msgid "%hs Device Configuration" +msgstr "%hs 장치 설정" + +msgid "Monitor in sleep mode" +msgstr "모니터 절전 모드" + +msgid "OpenGL Shaders" +msgstr "OpenGL 쉐이더" + +msgid "OpenGL options" +msgstr "OpenGL 설정" + +msgid "You are loading an unsupported configuration" +msgstr "지원하지 않는 설정입니다" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "이 에뮬레이트된 기종에 대해 선택한 기종을 기반으로 하는 CPU 종류 필터링이 사용되지 않도록 설정되었습니다.\n\n따라서 선택된 머신과 호환되지 않는 CPU를 선택하실 수 있습니다. 하지만 BIOS 또는 다른 소프트웨어와 호환되지 않을 수 있습니다.\n\n이 설정을 활성화하는 것은 공식적으로 지원되지 않으며, 제출된 버그 보고서는 유효하지 않음으로 닫힐 수 있습니다." + +msgid "Continue" +msgstr "계속" + +msgid "Cassette: %s" +msgstr "카세트: %s" + +msgid "Cassette images" +msgstr "카세트 이미지" + +msgid "Cartridge %i: %ls" +msgstr "카트리지 %i: %ls" + +msgid "Cartridge images" +msgstr "카트리지 이미지" + +msgid "Error initializing renderer" +msgstr "Error initializing renderer" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "하드 디스크 (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLL 또는 ESDI CD-ROM 드라이브가 존재하지 않습니다" + +msgid "Custom..." +msgstr "사용자 설정..." + +msgid "Custom (large)..." +msgstr "사용자 설정 (대용량)..." + +msgid "Add New Hard Disk" +msgstr "새로 생성" + +msgid "Add Existing Hard Disk" +msgstr "기존 이미지 사용" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "HDI 디스크 이미지는 4GB 이상으로 지정할 수 없습니다" + +msgid "Disk images cannot be larger than 127 GB." +msgstr "디스크 이미지는 127GB 이상으로 지정할 수 없습니다" + +msgid "Hard disk images" +msgstr "하드 디스크 이미지" + +msgid "Unable to read file" +msgstr "파일을 읽을 수 없습니다" + +msgid "Unable to write file" +msgstr "파일을 저장할 수 없습니다" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "512 바이트 이외의 섹터 크기를 가진 HDI 또는 HDX 형식의 이미지를 생성할 수 없습니다" + +msgid "USB is not yet supported" +msgstr "USB는 아직 지원하지 않습니다" + +msgid "Disk image file already exists" +msgstr "디스크 이미지 파일이 이미 존재합니다" + +msgid "Please specify a valid file name." +msgstr "올바른 파일명을 지정해 주세요." + +msgid "Disk image created" +msgstr "디스크 이미지가 생성되었습니다" + +msgid "Make sure the file exists and is readable." +msgstr "파일이 존재하며 읽을 수 있는지 확인합니다." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "파일이 쓰기 가능한 디렉토리에 저장되고 있는지 확인합니다." + +msgid "Disk image too large" +msgstr "디스크 이미지가 너무 큽니다" + +msgid "Remember to partition and format the newly-created drive." +msgstr "새로 생성한 드라이브의 파티션 설정과 포맷을 꼭 해주세요." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "선택하신 파일을 덮어씌웁니다. 사용하시겠습니까?" + +msgid "Unsupported disk image" +msgstr "지원하지 않는 디스크 이미지입니다" + +msgid "Overwrite" +msgstr "덮어쓰기" + +msgid "Don't overwrite" +msgstr "덮어쓰지 않음" + +msgid "Raw image (.img)" +msgstr "Raw 이미지 (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI 이미지 (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX 이미지 (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "고정 사이즈 VHD (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "동적 사이즈 VHD (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "디퍼런싱 VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "대형 블록 (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "소형 블록 (512 KB)" + +msgid "VHD files" +msgstr "VHD 파일" + +msgid "Select the parent VHD" +msgstr "부모 VHD 선택" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "이는 디퍼런싱 이미지가 생성된 후 부모 이미지가 수정되었음을 의미할 수 있습니다.\n\n이미지 파일이 이동 또는 복사된 경우 또는 이 디스크를 만든 프로그램의 버그로 인해 발생할 수도 있습니다.\n\n타임스탬프를 수정하시겠습니까?" + +msgid "Parent and child disk timestamps do not match" +msgstr "부모 디스크와 자식 디스크의 타임스탬프가 일치하지 않습니다" + +msgid "Could not fix VHD timestamp." +msgstr "VHD 타임스탬프를 고칠 수 없습니다" + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (클러스터 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (클러스터 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "완벽한 회전수" + +msgid "1%% below perfect RPM" +msgstr "1% 낮은 회전수" + +msgid "1.5%% below perfect RPM" +msgstr "1.5% 낮은 회전수" + +msgid "2%% below perfect RPM" +msgstr "2% 낮은 회전수" + +msgid "(System Default)" +msgstr "(시스템 기본값)" + diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po new file mode 100644 index 000000000..c576cf883 --- /dev/null +++ b/src/qt/languages/pl-PL.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Akcje" + +msgid "&Keyboard requires capture" +msgstr "&Klawaitura wymaga przechwytu myszy" + +msgid "&Right CTRL is left ALT" +msgstr "&Prawy CTRL to lewy Alt" + +msgid "&Hard Reset..." +msgstr "&Twardy reset..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pauza" + +msgid "E&xit..." +msgstr "W&yjdź..." + +msgid "&View" +msgstr "&Widok" + +msgid "&Hide status bar" +msgstr "&Ukryj pasek statusu" + +msgid "Hide &toolbar" +msgstr "Ukryj &pasek narzędzi" + +msgid "&Resizeable window" +msgstr "&Okno o zmiennym rozmiarze" + +msgid "R&emember size && position" +msgstr "P&amiętaj rozmiar &i pozycję" + +msgid "Re&nderer" +msgstr "Re&nderer" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Określ rozmiary..." + +msgid "F&orce 4:3 display ratio" +msgstr "&Wymuś proporcje wyświetlania 4:3" + +msgid "&Window scale factor" +msgstr "&Czynnik skalowania okna" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Metoda filtrowania" + +msgid "&Nearest" +msgstr "&Nearest" + +msgid "&Linear" +msgstr "&Linear" + +msgid "Hi&DPI scaling" +msgstr "Skalowanie Hi&DPI" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Pełny ekran\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "Fullscreen &stretch mode" + +msgid "&Full screen stretch" +msgstr "&Tryb rozciągania na pełnym ekranie" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Kwadratowe piksele (Zachowaj proporcje)" + +msgid "&Integer scale" +msgstr "&Skalowanie całkowite" + +msgid "E&GA/(S)VGA settings" +msgstr "Ustawienia E&GA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "&Odwrócony monitor VGA" + +msgid "VGA screen &type" +msgstr "Rodzaj ekranu &VGA" + +msgid "RGB &Color" +msgstr "RGB - &Kolorowy" + +msgid "&RGB Grayscale" +msgstr "&RGB - Skala szarości" + +msgid "&Amber monitor" +msgstr "&Bursztynowy monitor" + +msgid "&Green monitor" +msgstr "&Zielony monitor" + +msgid "&White monitor" +msgstr "&Biały monitor" + +msgid "Grayscale &conversion type" +msgstr "Typ konwersji &w skali szarości" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Średni" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "Overscan dla CGA/PCjr/Tandy/E&GA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Zmień kontrast dla &monochromatycznego ekranu" + +msgid "&Media" +msgstr "&Nośnik" + +msgid "&Tools" +msgstr "&Narzędzia" + +msgid "&Settings..." +msgstr "&Ustawienia..." + +msgid "&Update status bar icons" +msgstr "&Aktualizuj ikony na pasku statusu" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Zrób &zrzut ekranu\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Preferencje..." + +msgid "Enable &Discord integration" +msgstr "Włącz integrację z &Discord" + +msgid "Sound &gain..." +msgstr "Wzmocnienie &dźwięku..." + +msgid "Begin trace\tCtrl+T" +msgstr "Rozpocznij śledzenie\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Zakończ śledzenie\tCtrl+T" + +msgid "&Logging" +msgstr "&Logowanie" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Włącz logu BusLogic\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Włącz logi CD-ROM\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Włącz logi dyskietek (86F)\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Włącz logi kontrolera dyskietek\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Włącz logi IDE\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Włącz logi portu szeregowego\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Włącz logi sieci\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Punkt przerwania dziennika\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "Zrzuć pamięć &wideo\tCtrl+F1" + +msgid "&Help" +msgstr "&Pomoc" + +msgid "&Documentation..." +msgstr "&Dokumentacja..." + +msgid "&About 86Box..." +msgstr "&O 86Box..." + +msgid "&New image..." +msgstr "&Nowy obraz..." + +msgid "&Existing image..." +msgstr "&Istniejący obraz..." + +msgid "Existing image (&Write-protected)..." +msgstr "Istniejący obraz (&Chroniony przed zapisem)..." + +msgid "&Record" +msgstr "&Nagraj" + +msgid "&Play" +msgstr "&Odtwórz" + +msgid "&Rewind to the beginning" +msgstr "&Przewiń do początku" + +msgid "&Fast forward to the end" +msgstr "&Przewiń do końca" + +msgid "E&ject" +msgstr "W&yjmij" + +msgid "&Image..." +msgstr "&Obraz..." + +msgid "E&xport to 86F..." +msgstr "E&ksportuj do 86F..." + +msgid "&Mute" +msgstr "&Ścisz" + +msgid "E&mpty" +msgstr "P&usty" + +msgid "&Reload previous image" +msgstr "&Przeładuj poprzedni obraz" + +msgid "&Image" +msgstr "&Obraz" + +msgid "Target &framerate" +msgstr "Docelowa &liczba klatek na sekundę" + +msgid "&Sync with video" +msgstr "&Zsynchronizuj z wideo" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Wybierz shader..." + +msgid "&Remove shader" +msgstr "&Usuń shader" + +msgid "Preferences" +msgstr "Preferencje" + +msgid "Sound Gain" +msgstr "Wzmocnienie dźwięku" + +msgid "New Image" +msgstr "Nowy obraz" + +msgid "Settings" +msgstr "Ustawienia" + +msgid "Specify Main Window Dimensions" +msgstr "Określ rozmiary okna" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Anuluj" + +msgid "Save these settings as &global defaults" +msgstr "Zapisz ustawienia jako &globalne ustawienia domyślne" + +msgid "&Default" +msgstr "&Domyślny" + +msgid "Language:" +msgstr "Język:" + +msgid "Icon set:" +msgstr "Zestaw ikon:" + +msgid "Gain" +msgstr "Wzmacniacz" + +msgid "File name:" +msgstr "Nazwa pliku:" + +msgid "Disk size:" +msgstr "Rozmiar dysku:" + +msgid "RPM mode:" +msgstr "Tryb RPM:" + +msgid "Progress:" +msgstr "Postęp:" + +msgid "Width:" +msgstr "Szerokość:" + +msgid "Height:" +msgstr "Wysokość:" + +msgid "Lock to this size" +msgstr "Stały rozmiar" + +msgid "Machine type:" +msgstr "Rodzaj maszyny:" + +msgid "Machine:" +msgstr "Maszyna:" + +msgid "Configure" +msgstr "Konfiguruj" + +msgid "CPU type:" +msgstr "Rodzaj procesora:" + +msgid "Speed:" +msgstr "Szybkość:" + +msgid "FPU:" +msgstr "Jednostka FPU:" + +msgid "Wait states:" +msgstr "Stany oczekiwania:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Pamięć:" + +msgid "Time synchronization" +msgstr "Synchronizacja czasu" + +msgid "Disabled" +msgstr "Wyłączona" + +msgid "Enabled (local time)" +msgstr "Włączona (czas lokalny)" + +msgid "Enabled (UTC)" +msgstr "Włączona (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dynamiczny rekompilator" + +msgid "Video:" +msgstr "Wideo:" + +msgid "Voodoo Graphics" +msgstr "Grafika Voodoo" + +msgid "Mouse:" +msgstr "Mysz:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card:" +msgstr "Karta dźwiękowa:" + +msgid "MIDI Out Device:" +msgstr "Urządzenie wyjściowe MIDI:" + +msgid "MIDI In Device:" +msgstr "Urządzenie wejściowe MIDI:" + +msgid "Standalone MPU-401" +msgstr "Samodzielne urządzenie MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "Użyj dźwięku FLOAT32" + +msgid "Network type:" +msgstr "Rodzaj sieci:" + +msgid "PCap device:" +msgstr "Urządzenie PCap:" + +msgid "Network adapter:" +msgstr "Karta sieciowa:" + +msgid "COM1 Device:" +msgstr "Urządzenie COM1:" + +msgid "COM2 Device:" +msgstr "Urządzenie COM2:" + +msgid "COM3 Device:" +msgstr "Urządzenie COM3:" + +msgid "COM4 Device:" +msgstr "Urządzenie COM4:" + +msgid "LPT1 Device:" +msgstr "Urządzenie LPT1:" + +msgid "LPT2 Device:" +msgstr "Urządzenie LPT2:" + +msgid "LPT3 Device:" +msgstr "Urządzenie LPT3:" + +msgid "LPT4 Device:" +msgstr "Urządzenie LPT4:" + +msgid "Serial port 1" +msgstr "Port szeregowy 1" + +msgid "Serial port 2" +msgstr "Port szeregowy 2" + +msgid "Serial port 3" +msgstr "Port szeregowy 3" + +msgid "Serial port 4" +msgstr "Port Szeregowy 4" + +msgid "Parallel port 1" +msgstr "Port równoległy 1" + +msgid "Parallel port 2" +msgstr "Port równoległy 2" + +msgid "Parallel port 3" +msgstr "Port równoległy 3" + +msgid "Parallel port 4" +msgstr "Port równoległy 4" + +msgid "HD Controller:" +msgstr "Kontroler dysku twardego:" + +msgid "FD Controller:" +msgstr "Kontroler dyskietek:" + +msgid "Tertiary IDE Controller" +msgstr "Trzeciorzędowy kontroler IDE" + +msgid "Quaternary IDE Controller" +msgstr "Czwartorzędowy kontroler IDE" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Kontroler 1:" + +msgid "Controller 2:" +msgstr "Kontroler 2:" + +msgid "Controller 3:" +msgstr "Kontroler 3:" + +msgid "Controller 4:" +msgstr "Kontroler 4:" + +msgid "Cassette" +msgstr "Kaseta" + +msgid "Hard disks:" +msgstr "Dyski twarde:" + +msgid "&New..." +msgstr "&Nowy..." + +msgid "&Existing..." +msgstr "&Istniejący..." + +msgid "&Remove" +msgstr "&Usuń" + +msgid "Bus:" +msgstr "Magistrala:" + +msgid "Channel:" +msgstr "Kanał:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Określ..." + +msgid "Sectors:" +msgstr "Sektory:" + +msgid "Heads:" +msgstr "Głowice:" + +msgid "Cylinders:" +msgstr "Cylindry:" + +msgid "Size (MB):" +msgstr "Rozmiar (MB):" + +msgid "Type:" +msgstr "Rodzaj:" + +msgid "Image Format:" +msgstr "Format obrazu:" + +msgid "Block Size:" +msgstr "Rozmiar bloku:" + +msgid "Floppy drives:" +msgstr "Napędy dyskietek:" + +msgid "Turbo timings" +msgstr "Rozrządy Turbo" + +msgid "Check BPB" +msgstr "Sprawdzaj BPB" + +msgid "CD-ROM drives:" +msgstr "Napędy CD-ROM:" + +msgid "MO drives:" +msgstr "Napędy MO:" + +msgid "ZIP drives:" +msgstr "Napędy ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "Rozszerzenie pamięci ISA" + +msgid "Card 1:" +msgstr "Karta 1:" + +msgid "Card 2:" +msgstr "Karta 2:" + +msgid "Card 3:" +msgstr "Karta 3:" + +msgid "Card 4:" +msgstr "Karta 4:" + +msgid "ISABugger device" +msgstr "Urządzenie ISABugger" + +msgid "POST card" +msgstr "Karta POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Błąd" + +msgid "Fatal error" +msgstr "Fatalny błąd" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Naciśnij klawisze CTRL+ALT+PAGE DOWN aby wrócić to trybu okna." + +msgid "Speed" +msgstr "Szybkość" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Obrazy ZIP" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box nie może znaleźć obrazów ROM nadających się do użytku.\n\nProszę pobrać zestaw obrazów ROM ze strony download, i rozpakować je do katalogu \"roms\"." + +msgid "(empty)" +msgstr "(pusty)" + +msgid "All files" +msgstr "Wszystkie pliki" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Włącz" + +msgid "Off" +msgstr "Wyłącz" + +msgid "All images" +msgstr "Wszystkie obrazy" + +msgid "Basic sector images" +msgstr "Podstawowe obrazy sektorów" + +msgid "Surface images" +msgstr "Obrazy powierzchniowe" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Maszyna \"%hs\" nie jest dostępna, ponieważ brakuje obrazów ROM w katalogu roms/machines. Przełączanie na dostępną maszynę." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Karta wideo \"%hs\" nie jest dostępna, ponieważ brakuje obrazów ROM w katalogu roms/video. Przełączanie na dostępną kartę wideo." + +msgid "Machine" +msgstr "Maszyna" + +msgid "Display" +msgstr "Ekran" + +msgid "Input devices" +msgstr "Urządzenia wejściowe" + +msgid "Sound" +msgstr "Dźwięk" + +msgid "Network" +msgstr "Sieć" + +msgid "Ports (COM & LPT)" +msgstr "Porty (COM & LPT)" + +msgid "Storage controllers" +msgstr "Kontrolery pamięci" + +msgid "Hard disks" +msgstr "Dyski twarde" + +msgid "Floppy & CD-ROM drives" +msgstr "Napędy dyskietek i CD-ROM" + +msgid "Other removable devices" +msgstr "Inne urządzenia wymienne" + +msgid "Other peripherals" +msgstr "Inne urządzenia peryferyjne" + +msgid "Click to capture mouse" +msgstr "Kliknij w celu przechwycenia myszy" + +msgid "Press F8+F12 to release mouse" +msgstr "Naciśnij klawisze F8+F12 w celu uwolnienia myszy" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Naciśnij klawisze F8+F12 lub środkowy przycisk w celu uwolnienia myszy" + +msgid "Unable to initialize FluidSynth" +msgstr "Nie można zainicjować FluidSynth" + +msgid "Bus" +msgstr "Magistrala" + +msgid "File" +msgstr "Plik" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Nie można zainicjować renderera wideo." + +msgid "Default" +msgstr "Domyślny" + +msgid "%i Wait state(s)" +msgstr "%i Stany oczekiwania" + +msgid "Type" +msgstr "Rodzaj" + +msgid "Failed to set up PCap" +msgstr "Nie udało się ustawić PCap" + +msgid "No PCap devices found" +msgstr "Nie znaleziono urządzeń PCap" + +msgid "Invalid PCap device" +msgstr "Nieprawidłowe urządzenie PCap" + +msgid "Standard 2-button joystick(s)" +msgstr "Standardowe joysticki 2-przyciskowe" + +msgid "Standard 4-button joystick" +msgstr "Standardowy joystick 4-przyciskowy" + +msgid "Standard 6-button joystick" +msgstr "Standardowy joystick 6-przyciskowy" + +msgid "Standard 8-button joystick" +msgstr "Standardowy joystick 8-przyciskowy" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Żaden" + +msgid "Unable to load keyboard accelerators." +msgstr "Nie można załadować akceleratorów klawiaturowych." + +msgid "Unable to register raw input." +msgstr "Nie można zarejestrować surowych danych wejściowych." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Dyskietka %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Zaawansowane obrazy sektorów" + +msgid "Flux images" +msgstr "Flux images" + +msgid "Unable to initialize FreeType" +msgstr "Nie można zainicjować FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Nie można zainicjować SDL, wymagany SDL2.dll" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Jesteś pewien że chcesz wykonać twardy reset emulowanej maszyny?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Jesteś pewien że chcesz zakończyć 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Nie można zainicjować Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Obrazy MO" + +msgid "Welcome to 86Box!" +msgstr "Witamy w 86Box!" + +msgid "Internal controller" +msgstr "Kontroler wewnętrzny" + +msgid "Exit" +msgstr "Zakończ" + +msgid "No ROMs found" +msgstr "Nie znaleziono obrazów ROM" + +msgid "Do you want to save the settings?" +msgstr "Czy chcesz zapisać ustawienia?" + +msgid "This will hard reset the emulated machine." +msgstr "To spowoduje twardy reset wirtualnej maszyny." + +msgid "Save" +msgstr "Zapisz" + +msgid "About 86Box" +msgstr "O 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Emulator starych komputerów\n\nAutorzy: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, i inni.\n\nPrzetłumaczony przez: Fanta-Shokata\n\nWydany na licencji GNU General Public License w wersji 2 lub nowszej. Zobacz LICENSE aby uzyskać więcej informacji." + +msgid "Hardware not available" +msgstr "Sprzęt niedostępny" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Sprawdź, czy libpcap jest zainstalowany i czy posiadasz połączenie sieciowe kompatybilne z libpcap." + +msgid "Invalid configuration" +msgstr "Nieprawidłowa konfiguracja" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " jest wymagany do emulacji drukarki ESC-P." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do ogólnej drukarki PostScript zostaną zapisane jako pliki PostScript (.ps)." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " jest wymagany dla wyjścia FluidSynth MIDI." + +msgid "Entering fullscreen mode" +msgstr "Przechodzenie do trybu pełnoekranowego" + +msgid "Don't show this message again" +msgstr "Nie pokazuj więcej tego komunikatu" + +msgid "Don't exit" +msgstr "Nie kończ" + +msgid "Reset" +msgstr "Przywróć" + +msgid "Don't reset" +msgstr "Nie przywracaj" + +msgid "CD-ROM images" +msgstr "Obrazy CD-ROM" + +msgid "%hs Device Configuration" +msgstr "Konfiguracja urządzenia %hs" + +msgid "Monitor in sleep mode" +msgstr "Monitor w trybie czuwania" + +msgid "OpenGL Shaders" +msgstr "Shadery OpenGL" + +msgid "OpenGL options" +msgstr "Opcje OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Ładujesz nieobsługiwaną konfigurację" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Wybór rodzaju procesora oparty na wybranej maszynie jest wyłączony dla tej emulowanej maszyny.\n\nPozwala to na wybór procesora który jest niekompatybilny z wybraną maszyną. Jednak możesz napotkać niezgodności z BIOS-em maszyny lub innym oprogramowaniem.\n\nAktywacja tego ustawienia nie jest wspierana i każde zgłoszenie błędu może zostać zamknięte jako nieważne." + +msgid "Continue" +msgstr "Kontynuuj" + +msgid "Cassette: %s" +msgstr "Kaseta: %s" + +msgid "Cassette images" +msgstr "Obrazy kaset" + +msgid "Cartridge %i: %ls" +msgstr "Kartrydż %i: %ls" + +msgid "Cartridge images" +msgstr "Obrazy kartrydżu" + +msgid "Error initializing renderer" +msgstr "Błąd inicjalizacji renderera" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Nie można zainicjować renderera OpenGL (3.0 Core). Użyj innego." + +msgid "Resume execution" +msgstr "Wznów wykonywanie" + +msgid "Pause execution" +msgstr "Zatrzymaj wykonywanie" + +msgid "Press Ctrl+Alt+Del" +msgstr "Naciśnij Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Naciśnij Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Twardy reset" + +msgid "ACPI shutdown" +msgstr "Wyłączenie ACPI" + +msgid "Hard disk (%s)" +msgstr "Dysk twardy (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "Napędy CD-ROM MFM/RLL lub ESDI nigdy nie istniały" + +msgid "Custom..." +msgstr "Niestandardowy..." + +msgid "Custom (large)..." +msgstr "Niestandardowy (duży)..." + +msgid "Add New Hard Disk" +msgstr "Dodaj nowy dysk twardy" + +msgid "Add Existing Hard Disk" +msgstr "Dodaj istniejący dysk twardy" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Obrazy dysków HDI nie mogą być większe niż 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Obrazy dysków nie mogą być większe niż 127 GB." + +msgid "Hard disk images" +msgstr "Obrazy dysku twardego" + +msgid "Unable to read file" +msgstr "Nie można odczytać pliku" + +msgid "Unable to write file" +msgstr "Nie można zapisać pliku" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Obrazy HDI lub HDX z rozmiarem sektora innym niż 512 nie są wspierane." + +msgid "USB is not yet supported" +msgstr "USB nie jest jeszcze wspierane" + +msgid "Disk image file already exists" +msgstr "Plik obrazu dysku już istnieje" + +msgid "Please specify a valid file name." +msgstr "Określ prawidłową nazwę pliku." + +msgid "Disk image created" +msgstr "Utworzono obraz dysku" + +msgid "Make sure the file exists and is readable." +msgstr "Sprawdź, czy plik istnieje i nadaje się do odczytu." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Sprawdź, czy plik jest zapiyswany w katalogu z możliwością zapisu." + +msgid "Disk image too large" +msgstr "Obraz dysku jest za duży" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Nie zapomnij o partycjonowaniu u sformatowaniu nowo utworzego dysku" + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Wybrany plik zostanie nadpisany. Czy na pewno chcesz użyć tego pliku?" + +msgid "Unsupported disk image" +msgstr "Niewspierany obraz dysku" + +msgid "Overwrite" +msgstr "Nadpisz" + +msgid "Don't overwrite" +msgstr "Nie nadpisuj" + +msgid "Raw image (.img)" +msgstr "Obraz surowy (.img)" + +msgid "HDI image (.hdi)" +msgstr "Obraz HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Obraz HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD o stałym rozmiarze (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD o dynamicznym rozmiarze (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "VHD różnicujący (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Duże bloki (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Małe bloki (512 KB)" + +msgid "VHD files" +msgstr "Pliki VHD" + +msgid "Select the parent VHD" +msgstr "Wybierz nadrzędny plik VHD" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Może to oznaczać, że obraz nadrzędny został zmodyfikowany po utworzeniu obrazu różnicującego.\n\nMoże się to również zdarzyć, jeśli pliki obrazów przeniesione lub skopiowane, lub wystąpił błąd w programie, który utworzył ten dysk\n\nCzy chcesz naprawić sygnatury czasowe?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Sygnatury czasowe dysku nadrzędnego i podrzędnego nie zgadzają się" + +msgid "Could not fix VHD timestamp." +msgstr "Nie można naprawić sygnatury czasowej VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1,2 MB" + +msgid "1.25 MB" +msgstr "1,25 MB" + +msgid "1.44 MB" +msgstr "1,44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (klaster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (klaster 2048)" + +msgid "2.88 MB" +msgstr "2,88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1,3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2,3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1,3Gb M.O." + +msgid "Perfect RPM" +msgstr "Idealne obroty" + +msgid "1%% below perfect RPM" +msgstr "1%% poniżej idealnych obrotów" + +msgid "1.5%% below perfect RPM" +msgstr "1.5%% poniżej idealnych obrotów" + +msgid "2%% below perfect RPM" +msgstr "2%% poniżej idealnych obrotów" + +msgid "(System Default)" +msgstr "(Domyślne ustawienie systemowe)" + diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po new file mode 100644 index 000000000..7a1f33529 --- /dev/null +++ b/src/qt/languages/pt-BR.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Ação" + +msgid "&Keyboard requires capture" +msgstr "&Teclado requer captura" + +msgid "&Right CTRL is left ALT" +msgstr "CTRL &direito é o ALT esquerdo" + +msgid "&Hard Reset..." +msgstr "&Reinicialização completa..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pausar" + +msgid "E&xit..." +msgstr "&Sair..." + +msgid "&View" +msgstr "&Exibir" + +msgid "&Hide status bar" +msgstr "&Ocultar barra de status" + +msgid "Hide &toolbar" +msgstr "Ocultar &barra de ferramenta" + +msgid "&Resizeable window" +msgstr "&Janela redimensionável" + +msgid "R&emember size && position" +msgstr "&Lembrar tamanho e posição" + +msgid "Re&nderer" +msgstr "&Renderizador" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (Núcleo 3.0)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Especificar as dimensões..." + +msgid "F&orce 4:3 display ratio" +msgstr "F&orçar proporção de tela em 4:3" + +msgid "&Window scale factor" +msgstr "&Fator de redimensionamento da janela" + +msgid "&0.5x" +msgstr "&0,5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1,&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Método de filtragem" + +msgid "&Nearest" +msgstr "&Mais próximo" + +msgid "&Linear" +msgstr "&Linear" + +msgid "Hi&DPI scaling" +msgstr "Escala Hi&DPI" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Tela cheia\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "Modo de &redimensionamento da tela cheia" + +msgid "&Full screen stretch" +msgstr "&Tela cheia esticada" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "Pixel&s quadrados (manter proporção)" + +msgid "&Integer scale" +msgstr "&Redimensionamento com valores inteiros" + +msgid "E&GA/(S)VGA settings" +msgstr "Configurações E&GA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "Monitor VGA &invertido" + +msgid "VGA screen &type" +msgstr "&Tipo de tela VGA" + +msgid "RGB &Color" +msgstr "&Cor RGB" + +msgid "&RGB Grayscale" +msgstr "Tons de cinza &RGB" + +msgid "&Amber monitor" +msgstr "Monitor &âmbar" + +msgid "&Green monitor" +msgstr "Monitor &verde" + +msgid "&White monitor" +msgstr "Monitor &branco" + +msgid "Grayscale &conversion type" +msgstr "Tipo de &conversão de tons de cinza" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Média" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "Overscan do CGA/PCjr/Tandy/E&GA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Alterar contraste para exibição &monocromática" + +msgid "&Media" +msgstr "&Mídia" + +msgid "&Tools" +msgstr "&Ferramentas" + +msgid "&Settings..." +msgstr "&Configurações..." + +msgid "&Update status bar icons" +msgstr "&Atualizar ícones da barra de status" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Capturar &tela\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Preferências..." + +msgid "Enable &Discord integration" +msgstr "Ativar integração com o &Discord" + +msgid "Sound &gain..." +msgstr "&Ganho de som..." + +msgid "Begin trace\tCtrl+T" +msgstr "Inicio do rastreamento\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Fim do rastreamento\tCtrl+T" + +msgid "&Logging" +msgstr "&Registros" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Ativar registros da BusLogic\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Ativar registros do CD-ROM\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Ativar registros do disquete (86F)\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Ativar registros do controlador de disquete\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Ativar registros da IDE\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Ativar registros da porta serial\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Ativar registros da rede\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Ponto de parada no registo\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "Despejo da RAM de &vídeo\tCtrl+F1" + +msgid "&Help" +msgstr "&Ajuda" + +msgid "&Documentation..." +msgstr "&Documentação..." + +msgid "&About 86Box..." +msgstr "&Sobre o 86Box..." + +msgid "&New image..." +msgstr "&Nova imagem..." + +msgid "&Existing image..." +msgstr "&Imagem existente..." + +msgid "Existing image (&Write-protected)..." +msgstr "Imagem existente (&protegida contra escrita)..." + +msgid "&Record" +msgstr "&Gravar" + +msgid "&Play" +msgstr "&Reproduzir" + +msgid "&Rewind to the beginning" +msgstr "&Rebobinar até o começo" + +msgid "&Fast forward to the end" +msgstr "&Avançar até o fim" + +msgid "E&ject" +msgstr "E&jetar" + +msgid "&Image..." +msgstr "&Imagem..." + +msgid "E&xport to 86F..." +msgstr "E&xportar para 86F..." + +msgid "&Mute" +msgstr "&Sem som" + +msgid "E&mpty" +msgstr "&Vazio" + +msgid "&Reload previous image" +msgstr "&Recarregar imagem anterior" + +msgid "&Image" +msgstr "&Imagem" + +msgid "Target &framerate" +msgstr "&Taxa de quadro pretendida" + +msgid "&Sync with video" +msgstr "&Sincronizar com vídeo" + +msgid "&25 fps" +msgstr "&25 qps" + +msgid "&30 fps" +msgstr "&30 qps" + +msgid "&50 fps" +msgstr "&50 qps" + +msgid "&60 fps" +msgstr "&60 qps" + +msgid "&75 fps" +msgstr "&75 qps" + +msgid "&VSync" +msgstr "Sincronização &vertical" + +msgid "&Select shader..." +msgstr "&Selecionar shader..." + +msgid "&Remove shader" +msgstr "&Remover shader" + +msgid "Preferences" +msgstr "Preferências" + +msgid "Sound Gain" +msgstr "Ganho de som" + +msgid "New Image" +msgstr "Nova imagem de disquete" + +msgid "Settings" +msgstr "Configurações" + +msgid "Specify Main Window Dimensions" +msgstr "Especifique as dimensões da janela principal" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Cancelar" + +msgid "Save these settings as &global defaults" +msgstr "Usar estas configurações como &padrões globais" + +msgid "&Default" +msgstr "&Padrão" + +msgid "Language:" +msgstr "Idioma:" + +msgid "Icon set:" +msgstr "Pacote de ícones:" + +msgid "Gain" +msgstr "Ganho" + +msgid "File name:" +msgstr "Nome:" + +msgid "Disk size:" +msgstr "Tamanho:" + +msgid "RPM mode:" +msgstr "Modo RPM:" + +msgid "Progress:" +msgstr "Progresso:" + +msgid "Width:" +msgstr "Largura:" + +msgid "Height:" +msgstr "Altura:" + +msgid "Lock to this size" +msgstr "Travar nesse tamanho" + +msgid "Machine type:" +msgstr "Tipo de máquina:" + +msgid "Machine:" +msgstr "Máquina:" + +msgid "Configure" +msgstr "Configurar" + +msgid "CPU type:" +msgstr "Tipo de CPU:" + +msgid "Speed:" +msgstr "Veloc.:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Estados de espera:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Memória:" + +msgid "Time synchronization" +msgstr "Sincronização da hora" + +msgid "Disabled" +msgstr "Desativada" + +msgid "Enabled (local time)" +msgstr "Ativada (hora local)" + +msgid "Enabled (UTC)" +msgstr "Ativada (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Recompilador dinâmico" + +msgid "Video:" +msgstr "Vídeo:" + +msgid "Voodoo Graphics" +msgstr "3DFX Voodoo" + +msgid "Mouse:" +msgstr "Mouse:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card:" +msgstr "Placa de som:" + +msgid "MIDI Out Device:" +msgstr "Disp. saída MIDI:" + +msgid "MIDI In Device:" +msgstr "Disp. entrada MIDI:" + +msgid "Standalone MPU-401" +msgstr "MPU-401 autônomo" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "Usar som FLOAT32" + +msgid "Network type:" +msgstr "Tipo de rede:" + +msgid "PCap device:" +msgstr "Dispositivo PCap:" + +msgid "Network adapter:" +msgstr "Adaptador de rede:" + +msgid "COM1 Device:" +msgstr "Dispositivo COM1:" + +msgid "COM2 Device:" +msgstr "Dispositivo COM2:" + +msgid "COM3 Device:" +msgstr "Dispositivo COM3:" + +msgid "COM4 Device:" +msgstr "Dispositivo COM4:" + +msgid "LPT1 Device:" +msgstr "Dispositivo LPT1:" + +msgid "LPT2 Device:" +msgstr "Dispositivo LPT2:" + +msgid "LPT3 Device:" +msgstr "Dispositivo LPT3:" + +msgid "LPT4 Device:" +msgstr "Dispositivo LPT4:" + +msgid "Serial port 1" +msgstr "Porta serial 1" + +msgid "Serial port 2" +msgstr "Porta serial 2" + +msgid "Serial port 3" +msgstr "Porta serial 3" + +msgid "Serial port 4" +msgstr "Porta serial 4" + +msgid "Parallel port 1" +msgstr "Porta paralela 1" + +msgid "Parallel port 2" +msgstr "Porta paralela 2" + +msgid "Parallel port 3" +msgstr "Porta paralela 3" + +msgid "Parallel port 4" +msgstr "Porta paralela 4" + +msgid "HD Controller:" +msgstr "Controlador HD:" + +msgid "FD Controller:" +msgstr "Controlador FD:" + +msgid "Tertiary IDE Controller" +msgstr "Controlador IDE terciário" + +msgid "Quaternary IDE Controller" +msgstr "Controlador IDE quaternário" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Controlador 1:" + +msgid "Controller 2:" +msgstr "Controlador 2:" + +msgid "Controller 3:" +msgstr "Controlador 3:" + +msgid "Controller 4:" +msgstr "Controlador 4:" + +msgid "Cassette" +msgstr "Cassete" + +msgid "Hard disks:" +msgstr "Discos rígidos:" + +msgid "&New..." +msgstr "&Novo..." + +msgid "&Existing..." +msgstr "&Existente..." + +msgid "&Remove" +msgstr "&Remover" + +msgid "Bus:" +msgstr "Bar.:" + +msgid "Channel:" +msgstr "Canal:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Especificar..." + +msgid "Sectors:" +msgstr "Setores:" + +msgid "Heads:" +msgstr "Cabeças:" + +msgid "Cylinders:" +msgstr "Cilindros:" + +msgid "Size (MB):" +msgstr "Tamanho (MB):" + +msgid "Type:" +msgstr "Tipo:" + +msgid "Image Format:" +msgstr "Formato:" + +msgid "Block Size:" +msgstr "Bloco:" + +msgid "Floppy drives:" +msgstr "Unidades de disquete:" + +msgid "Turbo timings" +msgstr "Turbo" + +msgid "Check BPB" +msgstr "Verificar BPB" + +msgid "CD-ROM drives:" +msgstr "Unidades de CD-ROM:" + +msgid "MO drives:" +msgstr "Unidades magneto-ópticas:" + +msgid "ZIP drives:" +msgstr "Unidades ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "RTC ISA:" + +msgid "ISA Memory Expansion" +msgstr "Expansão de memória ISA" + +msgid "Card 1:" +msgstr "Placa 1:" + +msgid "Card 2:" +msgstr "Placa 2:" + +msgid "Card 3:" +msgstr "Placa 3:" + +msgid "Card 4:" +msgstr "Placa 4:" + +msgid "ISABugger device" +msgstr "Dispositivo ISABugger" + +msgid "POST card" +msgstr "Placa de diagnóstico" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Erro" + +msgid "Fatal error" +msgstr "Erro fatal" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Use CTRL+ALT+PAGE DOWN para retornar ao modo janela" + +msgid "Speed" +msgstr "Velocidade" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Imagens ZIP" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "O 86Box não conseguiu encontrar nenhuma imagem de ROM utilizável.\n\nPor favor, baixe um conjunto de ROM e extraia no diretório \"roms\"." + +msgid "(empty)" +msgstr "(vazio)" + +msgid "All files" +msgstr "Todos os arquivos" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Lig." + +msgid "Off" +msgstr "Desl." + +msgid "All images" +msgstr "Todas as imagens" + +msgid "Basic sector images" +msgstr "Imagens de setor básico" + +msgid "Surface images" +msgstr "Imagens de superfície" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "A máquina \"%hs\" não está disponível devido à falta de ROMs no diretório roms/machines. Mudando para uma máquina disponível." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "A placa de vídeo \"%hs\" não está disponível devido à falta de ROMs no diretório roms/video. Mudando para uma placa de vídeo disponível." + +msgid "Machine" +msgstr "Máquina" + +msgid "Display" +msgstr "Vídeo" + +msgid "Input devices" +msgstr "Dispositivos de entrada" + +msgid "Sound" +msgstr "Som" + +msgid "Network" +msgstr "Rede" + +msgid "Ports (COM & LPT)" +msgstr "Portas (COM & LPT)" + +msgid "Storage controllers" +msgstr "Controladores de armaz." + +msgid "Hard disks" +msgstr "Discos rígidos" + +msgid "Floppy & CD-ROM drives" +msgstr "Disquete & CD-ROM" + +msgid "Other removable devices" +msgstr "Dispos. removíveis" + +msgid "Other peripherals" +msgstr "Outros periféricos" + +msgid "Click to capture mouse" +msgstr "Clique para capturar o mouse" + +msgid "Press F8+F12 to release mouse" +msgstr "Aperte F8+F12 para liberar o mouse" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Aperte F8+F12 ou botão do meio para liberar o mouse" + +msgid "Unable to initialize FluidSynth" +msgstr "Não foi possível inicializar o FluidSynth" + +msgid "Bus" +msgstr "Barramento" + +msgid "File" +msgstr "Arquivo" + +msgid "C" +msgstr "CI" + +msgid "H" +msgstr "CA" + +msgid "S" +msgstr "SE" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Não foi possível inicializar o renderizador de vídeo." + +msgid "Default" +msgstr "Padrão" + +msgid "%i Wait state(s)" +msgstr "%i estado(s) de espera" + +msgid "Type" +msgstr "Tipo" + +msgid "Failed to set up PCap" +msgstr "Não foi possível configurar o PCap" + +msgid "No PCap devices found" +msgstr "Nenhum dispositivo PCap encontrado" + +msgid "Invalid PCap device" +msgstr "Dispositivo PCap inválido" + +msgid "Standard 2-button joystick(s)" +msgstr "Joystick padrão de 2 botões" + +msgid "Standard 4-button joystick" +msgstr "Joystick padrão de 4 botões" + +msgid "Standard 6-button joystick" +msgstr "Joystick padrão de 6 botões" + +msgid "Standard 8-button joystick" +msgstr "Joystick padrão de 8 botões" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Nada" + +msgid "Unable to load keyboard accelerators." +msgstr "Não foi possível carregar os aceleradores do teclado." + +msgid "Unable to register raw input." +msgstr "Não foi possível registrar a entrada bruta." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Disquete %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Imagens de setor avançado" + +msgid "Flux images" +msgstr "Imagens de fluxo" + +msgid "Unable to initialize FreeType" +msgstr "Não foi possível inicializar o FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Não é possível inicializar o SDL, é necessário o SDL2.dll" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Tem certeza de que deseja reiniciar completamente a máquina emulada?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Tem certeza de que deseja sair do 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Não é possível inicializar o Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "Magneto-óptico %i (%ls): %ls" + +msgid "MO images" +msgstr "Imagens magneto-ópticas" + +msgid "Welcome to 86Box!" +msgstr "Bem-vindo ao 86Box!" + +msgid "Internal controller" +msgstr "Controlador interno" + +msgid "Exit" +msgstr "Sair" + +msgid "No ROMs found" +msgstr "Nenhum ROM encontrada" + +msgid "Do you want to save the settings?" +msgstr "Você deseja salvar as configurações?" + +msgid "This will hard reset the emulated machine." +msgstr "Isto fará com que a máquina emulada seja reinicializada." + +msgid "Save" +msgstr "Salvar" + +msgid "About 86Box" +msgstr "Sobre o 86Box" + +msgid "86Box v" +msgstr "86Box versão" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Um emulador de computadores antigos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva\n\nLançado sob a Licença Pública Geral GNU versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." + +msgid "Hardware not available" +msgstr "Hardware não disponível" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Certifique-se de que libpcap esteja instalado e que você tenha uma conexão de rede compatível com libpcap." + +msgid "Invalid configuration" +msgstr "Configuração inválida" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " é necessário para emulação de impressora ESC/P." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " é necessário para a conversão automática de arquivos PostScript para PDF.\n\nQualquer documento enviado para a impressora genérica PostScript será salvo como arquivos PostScript (.ps)." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " é necessário para a saída MIDI FluidSynth." + +msgid "Entering fullscreen mode" +msgstr "Entrando no modo de tela cheia" + +msgid "Don't show this message again" +msgstr "Não exibir esta mensagem novamente" + +msgid "Don't exit" +msgstr "Não sair" + +msgid "Reset" +msgstr "Reiniciar" + +msgid "Don't reset" +msgstr "Não reiniciar" + +msgid "CD-ROM images" +msgstr "Imagens de CD-ROM" + +msgid "%hs Device Configuration" +msgstr "Configuração do dispositivo %hs" + +msgid "Monitor in sleep mode" +msgstr "Monitor em modo de suspensão" + +msgid "OpenGL Shaders" +msgstr "Shaders OpenGL" + +msgid "OpenGL options" +msgstr "Opções do OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Você está carregando uma configuração não suportada" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "A filtragem do tipo CPU baseada na máquina selecionada é desativada para esta máquina emulada.\n\nIsto torna possível escolher uma CPU que de outra forma seria incompatível com a máquina selecionada. Entretanto, você pode encontrar incompatibilidades com a BIOS da máquina ou outro software.\n\nA ativação desta configuração não é oficialmente suportada e qualquer relatório de erro arquivado pode ser fechado como inválido." + +msgid "Continue" +msgstr "Continuar" + +msgid "Cassette: %s" +msgstr "Cassete: %s" + +msgid "Cassette images" +msgstr "Imagens de cassete" + +msgid "Cartridge %i: %ls" +msgstr "Cartucho %i: %ls" + +msgid "Cartridge images" +msgstr "Imagens de cartucho" + +msgid "Error initializing renderer" +msgstr "Erro ao inicializar o renderizador" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "O renderizador OpenGL (Núcleo 3.0) não pôde ser inicializado. Use outro renderizador." + +msgid "Resume execution" +msgstr "Continuar a execução" + +msgid "Pause execution" +msgstr "Pausar a execução" + +msgid "Press Ctrl+Alt+Del" +msgstr "Pressionar Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Pressionar Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Reinicialização completa" + +msgid "ACPI shutdown" +msgstr "Desligamento por ACPI" + +msgid "Hard disk (%s)" +msgstr "Disco rígido (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "As unidades de CD-ROM MFM/RLL ou ESDI nunca existiram" + +msgid "Custom..." +msgstr "Personalizado..." + +msgid "Custom (large)..." +msgstr "Personalizado (grande)..." + +msgid "Add New Hard Disk" +msgstr "Adicionar novo disco rígido" + +msgid "Add Existing Hard Disk" +msgstr "Adicionar disco rígido existente" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "As imagens de disco HDI não podem ser maiores do que 4GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "As imagens de disco não podem ser maiores do que 127GB." + +msgid "Hard disk images" +msgstr "Imagens de disco rígido" + +msgid "Unable to read file" +msgstr "Não foi possível ler o arquivo" + +msgid "Unable to write file" +msgstr "Não foi possível escrever o arquivo" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Imagens HDI ou HDX com um tamanho de setor que não seja 512 não são suportadas." + +msgid "USB is not yet supported" +msgstr "O USB ainda não é suportado" + +msgid "Disk image file already exists" +msgstr "Esta imagem existe" + +msgid "Please specify a valid file name." +msgstr "Digite um nome de arquivo válido." + +msgid "Disk image created" +msgstr "A imagem foi criada com sucesso" + +msgid "Make sure the file exists and is readable." +msgstr "Certifique-se de que o arquivo existe e é legível." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Certifique-se de que o arquivo está sendo salvo em um diretório gravável." + +msgid "Disk image too large" +msgstr "A imagem do disco é muito grande" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Lembre-se de particionar e formatar a unidade recém-criada." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "O arquivo selecionado será sobrescrito. Você tem certeza de que deseja usá-lo?" + +msgid "Unsupported disk image" +msgstr "Imagem de disco sem suporte" + +msgid "Overwrite" +msgstr "Sobrescrever" + +msgid "Don't overwrite" +msgstr "Não sobrescrever" + +msgid "Raw image (.img)" +msgstr "Imagem bruta (.img)" + +msgid "HDI image (.hdi)" +msgstr "Imagem HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Imagem HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD de tamanho fixo (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD de tamanho dinâmico (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "VHD diferencial (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Blocos grandes (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Blocos pequenos (512 KB)" + +msgid "VHD files" +msgstr "Arquivos VHD" + +msgid "Select the parent VHD" +msgstr "Selecione o VHD pai" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Isto pode significar que a imagem de origem foi modificada após a criação da imagem diferencial.\n\nTambém pode acontecer caso os arquivos de imagem tenham sido movidos ou copiados, ou por um erro no programa que criou este disco.\n\nVocê quer consertar os marcadores de tempo?" + +msgid "Parent and child disk timestamps do not match" +msgstr "A data/hora dos arquivos de pais e filhos não correspondem" + +msgid "Could not fix VHD timestamp." +msgstr "Não foi possível consertar o carimbo de data/hora da VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "RPM perfeita" + +msgid "1%% below perfect RPM" +msgstr "1%% abaixo das RPM perfeita" + +msgid "1.5%% below perfect RPM" +msgstr "1.5%% abaixo das RPM perfeita" + +msgid "2%% below perfect RPM" +msgstr "2%% abaixo das RPM perfeita" + +msgid "(System Default)" +msgstr "(Padrão do sistema)" + diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po new file mode 100644 index 000000000..bc2ced0c2 --- /dev/null +++ b/src/qt/languages/pt-PT.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Ação" + +msgid "&Keyboard requires capture" +msgstr "&Teclado requere captura" + +msgid "&Right CTRL is left ALT" +msgstr "&CTRL direito é ALT esquerdo" + +msgid "&Hard Reset..." +msgstr "&Reinicialização completa..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pausa" + +msgid "E&xit..." +msgstr "&Sair..." + +msgid "&View" +msgstr "&Ver" + +msgid "&Hide status bar" +msgstr "&Ocultar barra de estado" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "&Janela redimensionável" + +msgid "R&emember size && position" +msgstr "&Lembrar tamanho e posição" + +msgid "Re&nderer" +msgstr "&Renderizador" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (Núcleo 3.0)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "&Especificar dimensões..." + +msgid "F&orce 4:3 display ratio" +msgstr "&Forçar rácio de visualização 4:3" + +msgid "&Window scale factor" +msgstr "F&actor de escala de janela" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Método de filtragem" + +msgid "&Nearest" +msgstr "&Mais próximo" + +msgid "&Linear" +msgstr "&Linear" + +msgid "Hi&DPI scaling" +msgstr "Escala Hi&DPI" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "E&crã cheio\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "Modo &de estiramento em ecrã cheio" + +msgid "&Full screen stretch" +msgstr "&Estiramento em ecrã cheio" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "Pixels &quadrados (Manter rácio)" + +msgid "&Integer scale" +msgstr "Escala &inteira" + +msgid "E&GA/(S)VGA settings" +msgstr "Definições E&GA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "Monitor VGA &invertido" + +msgid "VGA screen &type" +msgstr "&Tipo de ecrã VGA" + +msgid "RGB &Color" +msgstr "&Cores RGB" + +msgid "&RGB Grayscale" +msgstr "&RGB em escala de cinzentos" + +msgid "&Amber monitor" +msgstr "Monitor âmb&ar" + +msgid "&Green monitor" +msgstr "Monitor &verde" + +msgid "&White monitor" +msgstr "Monitor &branco" + +msgid "Grayscale &conversion type" +msgstr "Tipo de &conversão para escala de cinzentos" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Media" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "Overscan de CGA/PCjr/Tandy/E&GA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Mudar &contraste para ecrã monocromático" + +msgid "&Media" +msgstr "&Media" + +msgid "&Tools" +msgstr "&Ferramentas" + +msgid "&Settings..." +msgstr "&Definições..." + +msgid "&Update status bar icons" +msgstr "&Atualizar ícones da barra de estado" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Gravar imagem de ecrã\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Preferências..." + +msgid "Enable &Discord integration" +msgstr "Ativar integração com &Discord" + +msgid "Sound &gain..." +msgstr "&Ganho de som..." + +msgid "Begin trace\tCtrl+T" +msgstr "Iniciar o rastreio\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Terminar o rastreio\tCtrl+T" + +msgid "&Logging" +msgstr "&Registo" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Ativar registo BusLogic\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Ativar registo do CD-ROM\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Ativar registo de disquetes (86F)\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Ativar registo do controlador de disquetes\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Ativar registo IDE\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Ativar registo da porta série\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Ativar registo de rede\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Ponto de paragem no registo\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "Despejo de RAM &vídeo\tCtrl+F1" + +msgid "&Help" +msgstr "&Ajuda" + +msgid "&Documentation..." +msgstr "&Documentação..." + +msgid "&About 86Box..." +msgstr "&Acerca do 86Box..." + +msgid "&New image..." +msgstr "&Nova imagem..." + +msgid "&Existing image..." +msgstr "Imagem &existente..." + +msgid "Existing image (&Write-protected)..." +msgstr "Imagem existente (&Proteção contra escrita)..." + +msgid "&Record" +msgstr "&Gravar" + +msgid "&Play" +msgstr "&Reproduzir" + +msgid "&Rewind to the beginning" +msgstr "Re&bobinar para o início" + +msgid "&Fast forward to the end" +msgstr "&Avanço rápido para o fim" + +msgid "E&ject" +msgstr "E&jetar" + +msgid "&Image..." +msgstr "&Imagem..." + +msgid "E&xport to 86F..." +msgstr "E&xportar para 86F..." + +msgid "&Mute" +msgstr "&Mute" + +msgid "E&mpty" +msgstr "&CDROM vazio" + +msgid "&Reload previous image" +msgstr "&Recarregar imagem anterior" + +msgid "&Image" +msgstr "&Imagem" + +msgid "Target &framerate" +msgstr "&Taxa de quadros de destino" + +msgid "&Sync with video" +msgstr "&Sincronizar com vídeo" + +msgid "&25 fps" +msgstr "&25 q/s" + +msgid "&30 fps" +msgstr "&30 q/s" + +msgid "&50 fps" +msgstr "&50 q/s" + +msgid "&60 fps" +msgstr "&60 q/s" + +msgid "&75 fps" +msgstr "&75 q/s" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Selecionar shader..." + +msgid "&Remove shader" +msgstr "&Remover shader" + +msgid "Preferences" +msgstr "Preferências" + +msgid "Sound Gain" +msgstr "Ganho de som" + +msgid "New Image" +msgstr "Nova imagem" + +msgid "Settings" +msgstr "Definições" + +msgid "Specify Main Window Dimensions" +msgstr "Especificar dimensões da janela principal" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Cancelar" + +msgid "Save these settings as &global defaults" +msgstr "Guardar estas definições como padrões &globais" + +msgid "&Default" +msgstr "&Padrão" + +msgid "Language:" +msgstr "Idioma:" + +msgid "Icon set:" +msgstr "Pacote de ícones:" + +msgid "Gain" +msgstr "Ganho" + +msgid "File name:" +msgstr "Nome:" + +msgid "Disk size:" +msgstr "Tamanho:" + +msgid "RPM mode:" +msgstr "Modo RPM:" + +msgid "Progress:" +msgstr "Progresso:" + +msgid "Width:" +msgstr "Largura:" + +msgid "Height:" +msgstr "Altura:" + +msgid "Lock to this size" +msgstr "Fixar neste tamanho" + +msgid "Machine type:" +msgstr "Tipo de máquina:" + +msgid "Machine:" +msgstr "Máquina:" + +msgid "Configure" +msgstr "Configurar" + +msgid "CPU type:" +msgstr "Tipo do CPU:" + +msgid "Speed:" +msgstr "Velocidade:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Estados de espera:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Memória:" + +msgid "Time synchronization" +msgstr "Sincronização da hora" + +msgid "Disabled" +msgstr "Desativada" + +msgid "Enabled (local time)" +msgstr "Ativada (hora local)" + +msgid "Enabled (UTC)" +msgstr "Ativada (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Recompilador dinâmico" + +msgid "Video:" +msgstr "Vídeo:" + +msgid "Voodoo Graphics" +msgstr "Gráficos Voodoo" + +msgid "Mouse:" +msgstr "Rato:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card:" +msgstr "Placa de som:" + +msgid "MIDI Out Device:" +msgstr "Disp. saída MIDI:" + +msgid "MIDI In Device:" +msgstr "Disp. entrada MIDI:" + +msgid "Standalone MPU-401" +msgstr "MPU-401 autónomo" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "Utilizar som FLOAT32" + +msgid "Network type:" +msgstr "Tipo de rede:" + +msgid "PCap device:" +msgstr "Dispositivo PCap:" + +msgid "Network adapter:" +msgstr "Placa de rede:" + +msgid "COM1 Device:" +msgstr "Dispositivo COM1:" + +msgid "COM2 Device:" +msgstr "Dispositivo COM2:" + +msgid "COM3 Device:" +msgstr "Dispositivo COM3:" + +msgid "COM4 Device:" +msgstr "Dispositivo COM4:" + +msgid "LPT1 Device:" +msgstr "Dispositivo LPT1:" + +msgid "LPT2 Device:" +msgstr "Dispositivo LPT2:" + +msgid "LPT3 Device:" +msgstr "Dispositivo LPT3:" + +msgid "LPT4 Device:" +msgstr "Dispositivo LPT4:" + +msgid "Serial port 1" +msgstr "Porta de série 1" + +msgid "Serial port 2" +msgstr "Porta de série 2" + +msgid "Serial port 3" +msgstr "Porta de série 3" + +msgid "Serial port 4" +msgstr "Porta de série 4" + +msgid "Parallel port 1" +msgstr "Porta paralela 1" + +msgid "Parallel port 2" +msgstr "Porta paralela 2" + +msgid "Parallel port 3" +msgstr "Porta paralela 3" + +msgid "Parallel port 4" +msgstr "Porta paralela 4" + +msgid "HD Controller:" +msgstr "Controlador HD:" + +msgid "FD Controller:" +msgstr "Controlador FD:" + +msgid "Tertiary IDE Controller" +msgstr "Controlador IDE terciário" + +msgid "Quaternary IDE Controller" +msgstr "Controlador IDE quaternário" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Controlador 1:" + +msgid "Controller 2:" +msgstr "Controlador 2:" + +msgid "Controller 3:" +msgstr "Controlador 3:" + +msgid "Controller 4:" +msgstr "Controlador 4:" + +msgid "Cassette" +msgstr "Cassete" + +msgid "Hard disks:" +msgstr "Discos rígidos:" + +msgid "&New..." +msgstr "&Novo..." + +msgid "&Existing..." +msgstr "&Existente..." + +msgid "&Remove" +msgstr "&Remover" + +msgid "Bus:" +msgstr "Barram.:" + +msgid "Channel:" +msgstr "Canal:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Especificar..." + +msgid "Sectors:" +msgstr "Sectores:" + +msgid "Heads:" +msgstr "Cabeças:" + +msgid "Cylinders:" +msgstr "Cilindros:" + +msgid "Size (MB):" +msgstr "Tamanho (MB):" + +msgid "Type:" +msgstr "Tipo:" + +msgid "Image Format:" +msgstr "Formato de imagem:" + +msgid "Block Size:" +msgstr "Tamanho de bloco:" + +msgid "Floppy drives:" +msgstr "Unidades de disquete:" + +msgid "Turbo timings" +msgstr "Velocidade turbo" + +msgid "Check BPB" +msgstr "Verificar BPB" + +msgid "CD-ROM drives:" +msgstr "Unidades CD-ROM:" + +msgid "MO drives:" +msgstr "Unidades magneto-ópticas:" + +msgid "ZIP drives:" +msgstr "Unidades ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "Expansão de memória ISA" + +msgid "Card 1:" +msgstr "Placa 1:" + +msgid "Card 2:" +msgstr "Placa 2:" + +msgid "Card 3:" +msgstr "Placa 3:" + +msgid "Card 4:" +msgstr "Placa 4:" + +msgid "ISABugger device" +msgstr "Dispositivo ISABugger" + +msgid "POST card" +msgstr "Placa POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Erro" + +msgid "Fatal error" +msgstr "Erro fatal" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Pressione CTRL+ALT+PAGE DOWN para voltar ao modo de janela." + +msgid "Speed" +msgstr "Velocidade" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Imagens ZIP" + +msgid "86Box could not find any usable ROM images.\n\nPlease download 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 um pacote ROM e instale-o na pasta \"roms\"." + +msgid "(empty)" +msgstr "(empty)" + +msgid "All files" +msgstr "Todos os ficheiros" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Ativado" + +msgid "Off" +msgstr "Desativado" + +msgid "All images" +msgstr "Todas as imagens" + +msgid "Basic sector images" +msgstr "Imagens básicas de sector" + +msgid "Surface images" +msgstr "Imagens de superfície" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "A máquina \"%hs\" não está disponível devido à falta de ROMs na pasta roms/machines. A mudar para uma máquina disponível." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "A placa vídeo \"%hs\" não está disponível devido à falta de ROMs na pasta roms/video. A mudar para uma placa vídeo disponível." + +msgid "Machine" +msgstr "Máquina" + +msgid "Display" +msgstr "Apresentação" + +msgid "Input devices" +msgstr "Dispositivos de entrada" + +msgid "Sound" +msgstr "Som" + +msgid "Network" +msgstr "Rede" + +msgid "Ports (COM & LPT)" +msgstr "Portas (COM e LPT)" + +msgid "Storage controllers" +msgstr "Dispositivos de armazenamento" + +msgid "Hard disks" +msgstr "Discos rígidos" + +msgid "Floppy & CD-ROM drives" +msgstr "Unidades de disquete e CD-ROM" + +msgid "Other removable devices" +msgstr "Outros dispostivos removíveis" + +msgid "Other peripherals" +msgstr "Outros dispositivos" + +msgid "Click to capture mouse" +msgstr "Clique para capturar o rato" + +msgid "Press F8+F12 to release mouse" +msgstr "Pressione F8+F12 para soltar o rato" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Pressione F8+F12 ou tecla média para soltar o rato" + +msgid "Unable to initialize FluidSynth" +msgstr "Não foi possível inicializar o FluidSynth" + +msgid "Bus" +msgstr "Barramento" + +msgid "File" +msgstr "Ficheiro" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "C" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Não foi possível inicializar o renderizador vídeo." + +msgid "Default" +msgstr "Padrão" + +msgid "%i Wait state(s)" +msgstr "%i estado(s) de espera" + +msgid "Type" +msgstr "Tipo" + +msgid "Failed to set up PCap" +msgstr "Falha na configuração de PCap" + +msgid "No PCap devices found" +msgstr "Não foi encontrado um dispositivo PCap" + +msgid "Invalid PCap device" +msgstr "Dispositivo PCap inválido" + +msgid "Standard 2-button joystick(s)" +msgstr "Joystick(s) standard de 2 botões" + +msgid "Standard 4-button joystick" +msgstr "Joystick(s) standard de 4 botões" + +msgid "Standard 6-button joystick" +msgstr "Joystick(s) standard de 6 botões" + +msgid "Standard 8-button joystick" +msgstr "Joystick(s) standard de 8 botões" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Nenhum" + +msgid "Unable to load keyboard accelerators." +msgstr "Não foi possível inicializar os aceleradores de teclado." + +msgid "Unable to register raw input." +msgstr "Não foi possível registar a entrada bruta." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CCS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Disquete %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Imagens avançadas de sector" + +msgid "Flux images" +msgstr "Imagens de fluxo" + +msgid "Unable to initialize FreeType" +msgstr "Não foi possível inicializar o FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Não foi possível inicializar o SDL. O ficheiro SDL2.dll é necessário!" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Tem a certeza de que quer um reinício completo da máquina emulada?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Tem a certeza de que quer sair do 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Não foi possível inicializar o Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "Magneto-óptico %i (%ls): %ls" + +msgid "MO images" +msgstr "Imagens magneto-ópticas" + +msgid "Welcome to 86Box!" +msgstr "Bem-vindos ao 86Box!" + +msgid "Internal controller" +msgstr "Controlador interno" + +msgid "Exit" +msgstr "Sair" + +msgid "No ROMs found" +msgstr "Não foi encontrada nenhuma ROM" + +msgid "Do you want to save the settings?" +msgstr "Deseja guardar as definições?" + +msgid "This will hard reset the emulated machine." +msgstr "Isto irá causar um reinício completo da máquina emulada." + +msgid "Save" +msgstr "Guardar" + +msgid "About 86Box" +msgstr "Acerca do 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Um emulador de computadores antigos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nUsado sob a licença GNU General Public License versão 2 ou posterior. Veja o ficheiro LICENSE para mais informações." + +msgid "Hardware not available" +msgstr "Hardware não disponível" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Certifique-se de que a biblioteca libpcap está instalada e de que está a utilizar uma ligação de rede compatível com a biblioteca libpcap." + +msgid "Invalid configuration" +msgstr "Configuração inválida" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " é requerida para a emulação de impressora ESC/P." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " é requerido para a conversão automática de ficheiros PostScript para ficheiros PDF.\n\nQualquer documento enviado para a impressora PostScript genérica será gravado como um ficheiro PostScript (.ps)." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " é necessário para a saída MIDI FluidSynth MIDI." + +msgid "Entering fullscreen mode" +msgstr "A entrar no modo de ecrã cheio" + +msgid "Don't show this message again" +msgstr "Não mostrar mais esta mensagem" + +msgid "Don't exit" +msgstr "Não sair" + +msgid "Reset" +msgstr "Reiniciar" + +msgid "Don't reset" +msgstr "Não reiniciar" + +msgid "CD-ROM images" +msgstr "Imagens CD-ROM" + +msgid "%hs Device Configuration" +msgstr "Configuração de dispositivo %hs" + +msgid "Monitor in sleep mode" +msgstr "Ecrã em modo de sono" + +msgid "OpenGL Shaders" +msgstr "Shaders OpenGL" + +msgid "OpenGL options" +msgstr "Opções de OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Está a carregar uma configuração sem suporte!" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "A filtragem do tipo de CPU baseada na máquina escolhida está desativada para esta máquina emulada.\n\nIsto torna possível escolher um CPU que, de outra forma, não seria compatível com a máquina escolhida. No entanto, pode não ser compatível com a BIOS da máquina ou outros programas.\n\nA activação desta definição não tem suporte oficial e qualquer relatório de erros pode ser fechado como inválido." + +msgid "Continue" +msgstr "Continuar" + +msgid "Cassette: %s" +msgstr "Cassete: %s" + +msgid "Cassette images" +msgstr "Imagens de cassete" + +msgid "Cartridge %i: %ls" +msgstr "Cartucho %i: %ls" + +msgid "Cartridge images" +msgstr "Imagens de cartucho" + +msgid "Error initializing renderer" +msgstr "Error initializing renderer" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "Disco rígido (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "Unidades CD-ROM com barramento MFM/RLL ou ESDI nunca existiram!" + +msgid "Custom..." +msgstr "Personalizado..." + +msgid "Custom (large)..." +msgstr "Personalizado (grande)..." + +msgid "Add New Hard Disk" +msgstr "Adicionar novo disco rígido" + +msgid "Add Existing Hard Disk" +msgstr "Adicionar disco rígido existente" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "As imagens de disco HDI não podem ter mais de 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "As imagens de disco não podem ter mais de 127 GB." + +msgid "Hard disk images" +msgstr "Imagens de disco rígido" + +msgid "Unable to read file" +msgstr "Não foi possível ler o ficheiro" + +msgid "Unable to write file" +msgstr "Não foi possível escrever o ficheiro" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Imagens HDI ou HDX com um tamanho de sector diferente de 512 não são suportadas." + +msgid "USB is not yet supported" +msgstr "O barramento USB ainda não tem suporte" + +msgid "Disk image file already exists" +msgstr "A imagem de disco já existe" + +msgid "Please specify a valid file name." +msgstr "Por favor, especifique um nome de ficheiro válido." + +msgid "Disk image created" +msgstr "Imagem de disco criada" + +msgid "Make sure the file exists and is readable." +msgstr "Certifique-se de que o ficheiro existe e é legível." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Certifique-se de que o ficheiro está a ser guardado numa pasta editável." + +msgid "Disk image too large" +msgstr "Imagem de disco muito grande" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Lembre-se de particionar e formatar o novo disco criado." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "O ficheiro selecionado será sobrescrito. Tem a certeza de que quer utilizá-lo?" + +msgid "Unsupported disk image" +msgstr "Imagem de disco sem suporte" + +msgid "Overwrite" +msgstr "Sobrescrever" + +msgid "Don't overwrite" +msgstr "Não sobrescrever" + +msgid "Raw image (.img)" +msgstr "Imagem bruta (.img)" + +msgid "HDI image (.hdi)" +msgstr "Imagem HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Imagem HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD com tamanho fixo (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD com tamanho dinâmico (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "VHD diferenciador (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Blocos grandes (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Blocos pequenos (512 KB)" + +msgid "VHD files" +msgstr "Ficheiros VHD" + +msgid "Select the parent VHD" +msgstr "Seleccione o VHD pai" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Isto pode significar que a imagem pai foi modificada depois da criação da imagem diferenciadora.\n\nTambém pode acontecer se os ficheiros da imagem foram movidos ou copiados ou por causa de um erro no programa que criou este disco.\n\nQuer corrigir os carimbos de data/hora?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Os carimbos de data/hora dos discos pai e filho não correspondem!" + +msgid "Could not fix VHD timestamp." +msgstr "Não foi possível corrigir o carimbo de data/hora do VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "RPM perfeito" + +msgid "1%% below perfect RPM" +msgstr "RPM 1%% abaixo do RPM perfeito" + +msgid "1.5%% below perfect RPM" +msgstr "RPM 1.5%% abaixo do RPM perfeito" + +msgid "2%% below perfect RPM" +msgstr "RPM 2%% abaixo do RPM perfeito" + +msgid "(System Default)" +msgstr "(Padrão do sistema)" + diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po new file mode 100644 index 000000000..443c6f28c --- /dev/null +++ b/src/qt/languages/ru-RU.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Действие" + +msgid "&Keyboard requires capture" +msgstr "&Клавиатура требует захвата" + +msgid "&Right CTRL is left ALT" +msgstr "&Правый CTRL - это левый ALT" + +msgid "&Hard Reset..." +msgstr "&Холодная перезагрузка..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Пауза" + +msgid "E&xit..." +msgstr "&Выход..." + +msgid "&View" +msgstr "&Вид" + +msgid "&Hide status bar" +msgstr "&Скрыть строку состояния" + +msgid "Hide &toolbar" +msgstr "С&крыть панель инструментов" + +msgid "&Resizeable window" +msgstr "&Изменяемый размер окна" + +msgid "R&emember size && position" +msgstr "&Запомнить размер и положение" + +msgid "Re&nderer" +msgstr "&Рендеринг" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "&Указать размеры..." + +msgid "F&orce 4:3 display ratio" +msgstr "У&становить соотношение сторон 4:3" + +msgid "&Window scale factor" +msgstr "&Масштаб окна" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Метод фильтрации" + +msgid "&Nearest" +msgstr "&Ближайший" + +msgid "&Linear" +msgstr "&Линейный" + +msgid "Hi&DPI scaling" +msgstr "Масштабирование Hi&DPI" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Полноэкранный режим\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "&Растягивание в полноэкранном режиме" + +msgid "&Full screen stretch" +msgstr "&На весь экран" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Квадратные пиксели (сохранить соотношение)" + +msgid "&Integer scale" +msgstr "&Целочисленное масштабирование" + +msgid "E&GA/(S)VGA settings" +msgstr "Настройки E&GA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "&Инвертировать цвета VGA" + +msgid "VGA screen &type" +msgstr "&Тип экрана VGA" + +msgid "RGB &Color" +msgstr "RGB &цветной" + +msgid "&RGB Grayscale" +msgstr "&RGB монохромный" + +msgid "&Amber monitor" +msgstr "&Янтарный оттенок" + +msgid "&Green monitor" +msgstr "&Зелёный оттенок" + +msgid "&White monitor" +msgstr "&Белый оттенок" + +msgid "Grayscale &conversion type" +msgstr "Тип монохромного &конвертирования" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Усреднённый" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "Вылеты развёртки CGA/PCjr/Tandy/E&GA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Изменить контрастность &монохромного дисплея" + +msgid "&Media" +msgstr "&Носители" + +msgid "&Tools" +msgstr "&Инструменты" + +msgid "&Settings..." +msgstr "&Настройки машины..." + +msgid "&Update status bar icons" +msgstr "&Обновление значков строки состояния" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Сделать с&криншот\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Параметры..." + +msgid "Enable &Discord integration" +msgstr "Включить интеграцию &Discord" + +msgid "Sound &gain..." +msgstr "&Усиление звука..." + +msgid "Begin trace\tCtrl+T" +msgstr "Начать трассировку\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Завершить трассировку\tCtrl+T" + +msgid "&Logging" +msgstr "&Ведение журнала" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Включить журналы BusLogic\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Включить журналы CD-ROM\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Включить журналы дискет (86F)\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Включить журналы контроллера дискет\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Включить журналы IDE\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Включить журналы COM порта\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Включить журналы сети\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Точка останова журнала\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "&Выгрузка дампа видеопамяти\tCtrl+F1" + +msgid "&Help" +msgstr "&Помощь" + +msgid "&Documentation..." +msgstr "&Документация..." + +msgid "&About 86Box..." +msgstr "&О программе 86Box..." + +msgid "&New image..." +msgstr "&Новый образ..." + +msgid "&Existing image..." +msgstr "&Выбрать образ..." + +msgid "Existing image (&Write-protected)..." +msgstr "Выбрать образ (&Защита от записи)..." + +msgid "&Record" +msgstr "&Запись" + +msgid "&Play" +msgstr "&Воспроизведение" + +msgid "&Rewind to the beginning" +msgstr "&Перемотка на начало" + +msgid "&Fast forward to the end" +msgstr "&Перемотка в конец" + +msgid "E&ject" +msgstr "И&звлечь" + +msgid "&Image..." +msgstr "&Образ..." + +msgid "E&xport to 86F..." +msgstr "Э&кспорт в 86F..." + +msgid "&Mute" +msgstr "О&тключить звук" + +msgid "E&mpty" +msgstr "П&устой" + +msgid "&Reload previous image" +msgstr "&Снова загрузить предыдущий образ" + +msgid "&Image" +msgstr "&Образ..." + +msgid "Target &framerate" +msgstr "Целевая &частота кадров" + +msgid "&Sync with video" +msgstr "&Синхронизация с видео" + +msgid "&25 fps" +msgstr "&25 кадров в секунду" + +msgid "&30 fps" +msgstr "&30 кадров в секунду" + +msgid "&50 fps" +msgstr "&50 кадров в секунду" + +msgid "&60 fps" +msgstr "&60 кадров в секунду" + +msgid "&75 fps" +msgstr "&75 кадров в секунду" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Выбрать шейдер..." + +msgid "&Remove shader" +msgstr "&Удалить шейдер" + +msgid "Preferences" +msgstr "Параметры" + +msgid "Sound Gain" +msgstr "Усиление звука" + +msgid "New Image" +msgstr "Новый образ" + +msgid "Settings" +msgstr "Настройки" + +msgid "Specify Main Window Dimensions" +msgstr "Указать размеры главного окна" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Отмена" + +msgid "Save these settings as &global defaults" +msgstr "Сохранить эти параметры как &глобальные по умолчанию" + +msgid "&Default" +msgstr "&По умолчанию" + +msgid "Language:" +msgstr "Язык:" + +msgid "Icon set:" +msgstr "Набор иконок:" + +msgid "Gain" +msgstr "Усиление" + +msgid "File name:" +msgstr "Имя файла:" + +msgid "Disk size:" +msgstr "Размер диска:" + +msgid "RPM mode:" +msgstr "RPM режим:" + +msgid "Progress:" +msgstr "Прогресс:" + +msgid "Width:" +msgstr "Ширина:" + +msgid "Height:" +msgstr "Высота:" + +msgid "Lock to this size" +msgstr "Зафиксировать размер" + +msgid "Machine type:" +msgstr "Тип машины:" + +msgid "Machine:" +msgstr "Системная плата:" + +msgid "Configure" +msgstr "Настройка" + +msgid "CPU type:" +msgstr "Тип ЦП:" + +msgid "Speed:" +msgstr "Скорость:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Циклы ожидания:" + +msgid "MB" +msgstr "МБ" + +msgid "Memory:" +msgstr "Память:" + +msgid "Time synchronization" +msgstr "Синхронизация времени" + +msgid "Disabled" +msgstr "Отключить" + +msgid "Enabled (local time)" +msgstr "Включить (местное)" + +msgid "Enabled (UTC)" +msgstr "Включить (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Динамический рекомпилятор" + +msgid "Video:" +msgstr "Видеокарта:" + +msgid "Voodoo Graphics" +msgstr "Ускоритель Voodoo" + +msgid "Mouse:" +msgstr "Мышь:" + +msgid "Joystick:" +msgstr "Джойстик:" + +msgid "Joystick 1..." +msgstr "Джойстик 1..." + +msgid "Joystick 2..." +msgstr "Джойстик 2..." + +msgid "Joystick 3..." +msgstr "Джойстик 3..." + +msgid "Joystick 4..." +msgstr "Джойстик 4..." + +msgid "Sound card:" +msgstr "Звуковая карта:" + +msgid "MIDI Out Device:" +msgstr "MIDI Out устр-во:" + +msgid "MIDI In Device:" +msgstr "MIDI In устр-во:" + +msgid "Standalone MPU-401" +msgstr "Отдельный MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "FLOAT32 звук" + +msgid "Network type:" +msgstr "Тип сети:" + +msgid "PCap device:" +msgstr "Устройство PCap:" + +msgid "Network adapter:" +msgstr "Сетевая карта:" + +msgid "COM1 Device:" +msgstr "Устройство COM1:" + +msgid "COM2 Device:" +msgstr "Устройство COM2:" + +msgid "COM3 Device:" +msgstr "Устройство COM3:" + +msgid "COM4 Device:" +msgstr "Устройство COM4:" + +msgid "LPT1 Device:" +msgstr "Устройство LPT1:" + +msgid "LPT2 Device:" +msgstr "Устройство LPT2:" + +msgid "LPT3 Device:" +msgstr "Устройство LPT3:" + +msgid "LPT4 Device:" +msgstr "Устройство LPT4:" + +msgid "Serial port 1" +msgstr "Последов. порт COM1" + +msgid "Serial port 2" +msgstr "Последов. порт COM2" + +msgid "Serial port 3" +msgstr "Последов. порт COM3" + +msgid "Serial port 4" +msgstr "Последов. порт COM4" + +msgid "Parallel port 1" +msgstr "Параллельный порт LPT1" + +msgid "Parallel port 2" +msgstr "Параллельный порт LPT2" + +msgid "Parallel port 3" +msgstr "Параллельный порт LPT3" + +msgid "Parallel port 4" +msgstr "Параллельный порт LPT4" + +msgid "HD Controller:" +msgstr "Контроллер HD:" + +msgid "FD Controller:" +msgstr "Контроллер FD:" + +msgid "Tertiary IDE Controller" +msgstr "Третичный IDE контроллер" + +msgid "Quaternary IDE Controller" +msgstr "Четвертичный IDE контроллер" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Контроллер 1:" + +msgid "Controller 2:" +msgstr "Контроллер 2:" + +msgid "Controller 3:" +msgstr "Контроллер 3:" + +msgid "Controller 4:" +msgstr "Контроллер 4:" + +msgid "Cassette" +msgstr "Кассета" + +msgid "Hard disks:" +msgstr "Жёсткие диски:" + +msgid "&New..." +msgstr "&Создать..." + +msgid "&Existing..." +msgstr "&Выбрать..." + +msgid "&Remove" +msgstr "&Убрать" + +msgid "Bus:" +msgstr "Шина:" + +msgid "Channel:" +msgstr "Канал:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Указать..." + +msgid "Sectors:" +msgstr "Сектора:" + +msgid "Heads:" +msgstr "Головки:" + +msgid "Cylinders:" +msgstr "Цилиндры:" + +msgid "Size (MB):" +msgstr "Размер (МБ):" + +msgid "Type:" +msgstr "Тип:" + +msgid "Image Format:" +msgstr "Тип образа:" + +msgid "Block Size:" +msgstr "Размер блока:" + +msgid "Floppy drives:" +msgstr "Гибкие диски:" + +msgid "Turbo timings" +msgstr "Турбо тайминги" + +msgid "Check BPB" +msgstr "Проверять BPB" + +msgid "CD-ROM drives:" +msgstr "Дисководы CD-ROM:" + +msgid "MO drives:" +msgstr "Магнитооптические дисководы:" + +msgid "ZIP drives:" +msgstr "ZIP дисководы:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "Карта расширения памяти (ISA)" + +msgid "Card 1:" +msgstr "Карта 1:" + +msgid "Card 2:" +msgstr "Карта 2:" + +msgid "Card 3:" +msgstr "Карта 3:" + +msgid "Card 4:" +msgstr "Карта 4:" + +msgid "ISABugger device" +msgstr "Устройство ISABugger" + +msgid "POST card" +msgstr "Карта POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Ошибка" + +msgid "Fatal error" +msgstr "Неустранимая ошибка" + +msgid "" +msgstr "<зарезервировано>" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Нажмите CTRL + ALT + PAGE DOWN для возврата в оконный режим." + +msgid "Speed" +msgstr "Скорость" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Образы ZIP" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box не смог найти ни одного подходящего для использования файла с ПЗУ.\n\nПожалуйста скачайте набор ПЗУ и извлеките его в каталог \"roms\"." + +msgid "(empty)" +msgstr "(пусто)" + +msgid "All files" +msgstr "Все файлы" + +msgid "Turbo" +msgstr "Турбо" + +msgid "On" +msgstr "Вкл" + +msgid "Off" +msgstr "Выкл" + +msgid "All images" +msgstr "Все образы" + +msgid "Basic sector images" +msgstr "Простые посекторные образы" + +msgid "Surface images" +msgstr "Surface образы" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Системная плата \"%hs\" недоступна из-за отсутствия файла её ПЗУ в каталоге roms/machines. Переключение на доступную системную плату." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Видеокарта \"%hs\" недоступна из-за отсутствия файла её ПЗУ в каталоге roms/video. Переключение на доступную видеокарту." + +msgid "Machine" +msgstr "Компьютер" + +msgid "Display" +msgstr "Дисплей" + +msgid "Input devices" +msgstr "Устройства ввода" + +msgid "Sound" +msgstr "Звук" + +msgid "Network" +msgstr "Сеть" + +msgid "Ports (COM & LPT)" +msgstr "Порты (COM и LPT)" + +msgid "Storage controllers" +msgstr "Контроллеры дисков" + +msgid "Hard disks" +msgstr "Жёсткие диски" + +msgid "Floppy & CD-ROM drives" +msgstr "Гибкие диски и CD-ROM" + +msgid "Other removable devices" +msgstr "Другие съёмные устр-ва" + +msgid "Other peripherals" +msgstr "Другая периферия" + +msgid "Click to capture mouse" +msgstr "Щёлкните мышью для захвата курсора" + +msgid "Press F8+F12 to release mouse" +msgstr "Нажмите F8+F12 чтобы освободить курсор" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Нажмите F8+F12 или среднюю кнопку мыши чтобы освободить курсор" + +msgid "Unable to initialize FluidSynth" +msgstr "Невозможно инициализировать FluidSynth" + +msgid "Bus" +msgstr "Шина" + +msgid "File" +msgstr "Файл" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "КБ" + +msgid "Could not initialize the video renderer." +msgstr "Не удалось инициализировать рендерер видео." + +msgid "Default" +msgstr "По умолчанию" + +msgid "%i Wait state(s)" +msgstr "%i WS" + +msgid "Type" +msgstr "Тип" + +msgid "Failed to set up PCap" +msgstr "Не удалось настроить PCap" + +msgid "No PCap devices found" +msgstr "Устройства PCap не найдены" + +msgid "Invalid PCap device" +msgstr "Неверное устройство PCap" + +msgid "Standard 2-button joystick(s)" +msgstr "Стандартный 2-кнопочный джойстик" + +msgid "Standard 4-button joystick" +msgstr "Стандартный 4-кнопочный джойстик" + +msgid "Standard 6-button joystick" +msgstr "Стандартный 6-кнопочный джойстик" + +msgid "Standard 8-button joystick" +msgstr "Стандартный 8-кнопочный джойстик" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Система управления полетом Thrustmaster" + +msgid "None" +msgstr "Нет" + +msgid "Unable to load keyboard accelerators." +msgstr "Невозможно загрузить ускорители клавиатуры." + +msgid "Unable to register raw input." +msgstr "Невозможно зарегистрировать необработанный (RAW) ввод." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u МБ (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Дисковод %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Расширенные образы секторов" + +msgid "Flux images" +msgstr "Образы Flux" + +msgid "Unable to initialize FreeType" +msgstr "Невозможно инициализировать FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Невозможно инициализировать SDL, требуется SDL2.dll" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Вы уверены, что хотите выполнить холодную перезагрузку эмулируемой машины?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Вы уверены, что хотите выйти из 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Невозможно инициализировать Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "Магнитооптический %i (%ls): %ls" + +msgid "MO images" +msgstr "Образы магнитооптических дисков" + +msgid "Welcome to 86Box!" +msgstr "Добро пожаловать в 86Box!" + +msgid "Internal controller" +msgstr "Встроенный контроллер" + +msgid "Exit" +msgstr "Выход" + +msgid "No ROMs found" +msgstr "ПЗУ не найдены" + +msgid "Do you want to save the settings?" +msgstr "Хотите ли вы сохранить настройки?" + +msgid "This will hard reset the emulated machine." +msgstr "Это приведет к холодной перезагрузке эмулируемой машины." + +msgid "Save" +msgstr "Сохранить" + +msgid "About 86Box" +msgstr "О 86Box" + +msgid "86Box v" +msgstr "86Box v." + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Эмулятор старых компьютеров\n\nАвторы: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nВыпускается под лицензией GNU General Public License версии 2 или более поздней. Дополнительную информацию см. в файле LICENSE." + +msgid "Hardware not available" +msgstr "Оборудование недоступно" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Убедитесь, что libpcap установлен и ваше сетевое соединение, совместимо с libpcap." + +msgid "Invalid configuration" +msgstr "Недопустимая конфигурация" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr "Для эмуляции принтера ESC/P требуется libfreetype." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " требуется для автоматического преобразования файлов PostScript в PDF.\n\nВсе документы, отправленные на общий принтер PostScript, будут сохранены в виде файлов PostScript (.ps)." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr "Для FluidSynth MIDI-вывода требуется libfluidsynth." + +msgid "Entering fullscreen mode" +msgstr "Вход в полноэкранный режим" + +msgid "Don't show this message again" +msgstr "Больше не показывать это сообщение" + +msgid "Don't exit" +msgstr "Не выходить" + +msgid "Reset" +msgstr "Перезагрузить" + +msgid "Don't reset" +msgstr "Не перезагружать" + +msgid "CD-ROM images" +msgstr "Образы CD-ROM" + +msgid "%hs Device Configuration" +msgstr "Конфигурация устройства %hs" + +msgid "Monitor in sleep mode" +msgstr "Монитор в спящем режиме" + +msgid "OpenGL Shaders" +msgstr "Шейдеры OpenGL" + +msgid "OpenGL options" +msgstr "Параметры OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Вы загружаете неподдерживаемую конфигурацию" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Выбор типов ЦП для этой системной платы на данной эмулируемой машине отключен.\n\nЭто позволяет выбрать процессор, который в противном случае несовместим с выбранной материнской платой. Однако, вы можете столкнуться с несовместимостью с BIOS материнской платы или другим ПО.\n\nВключение этого параметра официально не поддерживается, и все поданные отчеты об ошибках могут быть закрыты как недействительные." + +msgid "Continue" +msgstr "Продолжить" + +msgid "Cassette: %s" +msgstr "Кассета: %s" + +msgid "Cassette images" +msgstr "Образы кассет" + +msgid "Cartridge %i: %ls" +msgstr "Картридж %i: %ls" + +msgid "Cartridge images" +msgstr "Образы картриджей" + +msgid "Error initializing renderer" +msgstr "Ошибка инициализации рендерера" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Невозможно инициализировать рендерер OpenGL (3.0). Пожалуйста, используйте другой рендерер." + +msgid "Resume execution" +msgstr "Возобновить выполнение" + +msgid "Pause execution" +msgstr "Приостановить выполнение" + +msgid "Press Ctrl+Alt+Del" +msgstr "Нажать Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Нажать Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Холодная перезагрузка" + +msgid "ACPI shutdown" +msgstr "Сигнал завершения ACPI" + +msgid "Hard disk (%s)" +msgstr "Жёсткий диск (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLL или ESDI дисководов CD-ROM никогда не существовало" + +msgid "Custom..." +msgstr "Задать вручную..." + +msgid "Custom (large)..." +msgstr "Задать вручную (large)..." + +msgid "Add New Hard Disk" +msgstr "Создать новый жёсткий диск" + +msgid "Add Existing Hard Disk" +msgstr "Выбрать существующий жёсткий диск" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Размер образов дисков HDI не может превышать 4 ГБ." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Размер образов дисков не может превышать 127 ГБ." + +msgid "Hard disk images" +msgstr "Образы жёстких дисков" + +msgid "Unable to read file" +msgstr "Невозможно прочитать файл" + +msgid "Unable to write file" +msgstr "Невозможно записать файл" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Образы HDI или HDX с размером сектора, отличным от 512, не поддерживаются." + +msgid "USB is not yet supported" +msgstr "USB пока не поддерживается" + +msgid "Disk image file already exists" +msgstr "Файл образа диска уже существует" + +msgid "Please specify a valid file name." +msgstr "Пожалуйста, укажите правильное имя файла." + +msgid "Disk image created" +msgstr "Образ диска создан" + +msgid "Make sure the file exists and is readable." +msgstr "Убедитесь, что файл существует и доступен для чтения." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Убедитесь, что файл сохраняется в директории доступной для записи." + +msgid "Disk image too large" +msgstr "Слишком большой образ диска" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Не забудьте разметить и отформатировать вновь созданный диск." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Выбранный файл будет перезаписан. Вы уверены, что хотите использовать его?" + +msgid "Unsupported disk image" +msgstr "Неподдерживаемый образ диска" + +msgid "Overwrite" +msgstr "Перезаписать" + +msgid "Don't overwrite" +msgstr "Не перезаписывать" + +msgid "Raw image (.img)" +msgstr "RAW образ (.img)" + +msgid "HDI image (.hdi)" +msgstr "Образ HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Образ HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD фиксированного размера (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD динамического размера (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Дифференцированный образ VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Большие блоки (2 МБ)" + +msgid "Small blocks (512 KB)" +msgstr "Маленькие блоки (512 КБ)" + +msgid "VHD files" +msgstr "Файлы VHD" + +msgid "Select the parent VHD" +msgstr "Выберите родительский VHD" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Это может означать, что родительский образ был изменён после того, как был создан дифференцированный образ.\n\nЭто также может произойти, если файлы образа были перемещены или скопированы, или из-за ошибки в программе, создавшей этот диск.\n\nВы хотите исправить временные метки?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Временные метки родительского и дочернего дисков не совпадают" + +msgid "Could not fix VHD timestamp." +msgstr "Не удалось исправить временную метку VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 кБ" + +msgid "180 kB" +msgstr "180 кБ" + +msgid "320 kB" +msgstr "320 кБ" + +msgid "360 kB" +msgstr "360 кБ" + +msgid "640 kB" +msgstr "640 кБ" + +msgid "720 kB" +msgstr "720 кБ" + +msgid "1.2 MB" +msgstr "1.2 МБ" + +msgid "1.25 MB" +msgstr "1.25 МБ" + +msgid "1.44 MB" +msgstr "1.44 МБ" + +msgid "DMF (cluster 1024)" +msgstr "DMF (кластер 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (кластер 2048)" + +msgid "2.88 MB" +msgstr "2.88 МБ" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Мб M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Мб M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Мб M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Мб M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Гб M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Гб M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Мб M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Мб M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Гб M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Гб M.O." + +msgid "Perfect RPM" +msgstr "Точный RPM" + +msgid "1%% below perfect RPM" +msgstr "На 1% медленнее точного RPM" + +msgid "1.5%% below perfect RPM" +msgstr "На 1.5% медленнее точного RPM" + +msgid "2%% below perfect RPM" +msgstr "На 2% медленнее точного RPM" + +msgid "(System Default)" +msgstr "(Системный)" + diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po new file mode 100644 index 000000000..6bb8a66d2 --- /dev/null +++ b/src/qt/languages/sl-SI.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Dejanja" + +msgid "&Keyboard requires capture" +msgstr "&Tipkovnica potrebuje zajem" + +msgid "&Right CTRL is left ALT" +msgstr "&Desni CTRL je levi ALT" + +msgid "&Hard Reset..." +msgstr "&Ponovni zagon..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Premor" + +msgid "E&xit..." +msgstr "Iz&hod..." + +msgid "&View" +msgstr "&Pogled" + +msgid "&Hide status bar" +msgstr "&Skrij statusno vrstico" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "S&premenljiva velikost okna" + +msgid "R&emember size && position" +msgstr "&Zapomni si velikost in položaj" + +msgid "Re&nderer" +msgstr "&Upodabljanje" + +msgid "&SDL (Software)" +msgstr "&SDL (programsko)" + +msgid "SDL (&Hardware)" +msgstr "SDL (s&trojno)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (Jedro 3.0)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "&Določi velikost..." + +msgid "F&orce 4:3 display ratio" +msgstr "&Vsili 4:3 razmerje zaslona" + +msgid "&Window scale factor" +msgstr "&Faktor velikosti okna" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "&Metoda filtriranja" + +msgid "&Nearest" +msgstr "&Najbližja" + +msgid "&Linear" +msgstr "&Linearna" + +msgid "Hi&DPI scaling" +msgstr "&Raztezanje za visok DPI" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Celozaslonski način\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "&Način celozaslonskega raztezanja" + +msgid "&Full screen stretch" +msgstr "&Raztegni na celoten zaslon" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Kvadratni piksli (ohrani razmerje)" + +msgid "&Integer scale" +msgstr "&Celoštevilsko raztezanje" + +msgid "E&GA/(S)VGA settings" +msgstr "Nastavitve E&GA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "&Obrni barve zaslona VGA" + +msgid "VGA screen &type" +msgstr "&Vrsta zaslona VGA" + +msgid "RGB &Color" +msgstr "&Barvni RGB" + +msgid "&RGB Grayscale" +msgstr "&Sivinski RGB" + +msgid "&Amber monitor" +msgstr "&Rumeni zaslon" + +msgid "&Green monitor" +msgstr "&Zeleni zaslon" + +msgid "&White monitor" +msgstr "B&eli zaslon" + +msgid "Grayscale &conversion type" +msgstr "V&rsta pretvorbe sivin" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Povprečje" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "&Presežek slike CGA/PCjr/Tandy/EGA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "&Spremeni contrast za črno-beli zaslon" + +msgid "&Media" +msgstr "&Mediji" + +msgid "&Tools" +msgstr "&Orodja" + +msgid "&Settings..." +msgstr "&Nastavitve..." + +msgid "&Update status bar icons" +msgstr "&Posodabljaj ikone statusne vrstice" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "&Zajemi posnetek zaslona\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Možnosti..." + +msgid "Enable &Discord integration" +msgstr "Omogoči integracijo s programom &Discord" + +msgid "Sound &gain..." +msgstr "&Ojačanje zvoka..." + +msgid "Begin trace\tCtrl+T" +msgstr "Z&ačni sledenje\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "&Končaj sledenje\tCtrl+T" + +msgid "&Logging" +msgstr "&Beleženje" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Omogoči beleženje za BusLogic\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Omogoči beleženje za CD-ROM\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Omogoči beleženje za diskete (86F)\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Omogoči beleženje za disketni krmilnik\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Omogoči beleženje za IDE\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Omogoči beleženje za serijska vrata\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Omogoči beleženje za omrežje\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Zabeleži prelomno točko\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "&Izvozi pomnilnik zaslona\tCtrl+F1" + +msgid "&Help" +msgstr "&Pomoč" + +msgid "&Documentation..." +msgstr "&Dokumentacija..." + +msgid "&About 86Box..." +msgstr "&O programu 86Box..." + +msgid "&New image..." +msgstr "&Nova slika..." + +msgid "&Existing image..." +msgstr "&Obstoječa slika..." + +msgid "Existing image (&Write-protected)..." +msgstr "Obstoječa slika (&samo za branje)..." + +msgid "&Record" +msgstr "Snemaj" + +msgid "&Play" +msgstr "Predvajaj" + +msgid "&Rewind to the beginning" +msgstr "Previj na začetek" + +msgid "&Fast forward to the end" +msgstr "Preskoči na konec" + +msgid "E&ject" +msgstr "Izvrzi" + +msgid "&Image..." +msgstr "Slika..." + +msgid "E&xport to 86F..." +msgstr "&Izvozi v 86F..." + +msgid "&Mute" +msgstr "&Utišaj" + +msgid "E&mpty" +msgstr "&Prazen" + +msgid "&Reload previous image" +msgstr "&Naloži zadnjo sliko" + +msgid "&Image" +msgstr "&Slika" + +msgid "Target &framerate" +msgstr "&Ciljno št. sličic na sekundo" + +msgid "&Sync with video" +msgstr "&Sinhroniziraj z videom" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Izberi senčilnik..." + +msgid "&Remove shader" +msgstr "&Odstrani senčilnik" + +msgid "Preferences" +msgstr "Možnosti" + +msgid "Sound Gain" +msgstr "Ojačanje zvoka" + +msgid "New Image" +msgstr "Nova slika" + +msgid "Settings" +msgstr "Nastavitve" + +msgid "Specify Main Window Dimensions" +msgstr "Določi velikost glavnega okna" + +msgid "OK" +msgstr "V redu" + +msgid "Cancel" +msgstr "Prekliči" + +msgid "Save these settings as &global defaults" +msgstr "Shrani te nastavitve kot globalne privzete" + +msgid "&Default" +msgstr "Privzeto" + +msgid "Language:" +msgstr "Jezik:" + +msgid "Icon set:" +msgstr "Komplet ikon:" + +msgid "Gain" +msgstr "Ojačanje" + +msgid "File name:" +msgstr "Ime datoteke:" + +msgid "Disk size:" +msgstr "Velikost diska:" + +msgid "RPM mode:" +msgstr "Način števila obratov:" + +msgid "Progress:" +msgstr "Napredek:" + +msgid "Width:" +msgstr "Širina:" + +msgid "Height:" +msgstr "Višina:" + +msgid "Lock to this size" +msgstr "Zakleni na to velikost" + +msgid "Machine type:" +msgstr "Vrsta sistema:" + +msgid "Machine:" +msgstr "Sistem:" + +msgid "Configure" +msgstr "Nastavi" + +msgid "CPU type:" +msgstr "Vrsta procesorja:" + +msgid "Speed:" +msgstr "Hitrost:" + +msgid "FPU:" +msgstr "Procesor plavajoče vejice:" + +msgid "Wait states:" +msgstr "Čakalna stanja:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Spomin:" + +msgid "Time synchronization" +msgstr "Sinhronizacija časa" + +msgid "Disabled" +msgstr "Onemogočeno" + +msgid "Enabled (local time)" +msgstr "Omogočeno (lokalni čas)" + +msgid "Enabled (UTC)" +msgstr "Omogočeno (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dinamični prevajalnik" + +msgid "Video:" +msgstr "Video:" + +msgid "Voodoo Graphics" +msgstr "Voodoo grafika" + +msgid "Mouse:" +msgstr "Miška:" + +msgid "Joystick:" +msgstr "Igralna palica:" + +msgid "Joystick 1..." +msgstr "Igralna palica 1..." + +msgid "Joystick 2..." +msgstr "Igralna palica 2..." + +msgid "Joystick 3..." +msgstr "Igralna palica 3..." + +msgid "Joystick 4..." +msgstr "Igralna palica 4..." + +msgid "Sound card:" +msgstr "Zvočna kartica:" + +msgid "MIDI Out Device:" +msgstr "Izhodna naprava MIDI:" + +msgid "MIDI In Device:" +msgstr "Vhodna naprava MIDI:" + +msgid "Standalone MPU-401" +msgstr "Samostojen MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "Uporabi FLOAT32 za zvok" + +msgid "Network type:" +msgstr "Vrsta omrežja:" + +msgid "PCap device:" +msgstr "Naprava PCap:" + +msgid "Network adapter:" +msgstr "Omrežna kartica:" + +msgid "COM1 Device:" +msgstr "Naprava COM1:" + +msgid "COM2 Device:" +msgstr "Naprava COM2:" + +msgid "COM3 Device:" +msgstr "Naprava COM3:" + +msgid "COM4 Device:" +msgstr "Naprava COM4:" + +msgid "LPT1 Device:" +msgstr "Naprava LPT1:" + +msgid "LPT2 Device:" +msgstr "Naprava LPT2:" + +msgid "LPT3 Device:" +msgstr "Naprava LPT3:" + +msgid "LPT4 Device:" +msgstr "Naprava LPT4:" + +msgid "Serial port 1" +msgstr "Serijska vrata 1" + +msgid "Serial port 2" +msgstr "Serijska vrata 2" + +msgid "Serial port 3" +msgstr "Serijska vrata 3" + +msgid "Serial port 4" +msgstr "Serijska vrata 4" + +msgid "Parallel port 1" +msgstr "Paralelna vrata 1" + +msgid "Parallel port 2" +msgstr "Paralelna vrata 2" + +msgid "Parallel port 3" +msgstr "Paralelna vrata 3" + +msgid "Parallel port 4" +msgstr "Paralelna vrata 4" + +msgid "HD Controller:" +msgstr "Krmilnik trdega diska:" + +msgid "FD Controller:" +msgstr "Krmilnik disketnika:" + +msgid "Tertiary IDE Controller" +msgstr "Terciarni krmilnik IDE" + +msgid "Quaternary IDE Controller" +msgstr "Kvartarni krmilnik IDE" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Krmilnik 1:" + +msgid "Controller 2:" +msgstr "Krmilnik 2:" + +msgid "Controller 3:" +msgstr "Krmilnik 3:" + +msgid "Controller 4:" +msgstr "Krmilnik 4:" + +msgid "Cassette" +msgstr "Kasetnik" + +msgid "Hard disks:" +msgstr "Trdi diski:" + +msgid "&New..." +msgstr "Nov..." + +msgid "&Existing..." +msgstr "Obstoječ..." + +msgid "&Remove" +msgstr "Odstrani" + +msgid "Bus:" +msgstr "Vodilo:" + +msgid "Channel:" +msgstr "Kanal:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "Določi..." + +msgid "Sectors:" +msgstr "Sektorji:" + +msgid "Heads:" +msgstr "Glave:" + +msgid "Cylinders:" +msgstr "Cilindri:" + +msgid "Size (MB):" +msgstr "Velikost (MB):" + +msgid "Type:" +msgstr "Vrsta:" + +msgid "Image Format:" +msgstr "Format slike:" + +msgid "Block Size:" +msgstr "Velikost bloka:" + +msgid "Floppy drives:" +msgstr "Disketni pogoni:" + +msgid "Turbo timings" +msgstr "Turbo časovniki" + +msgid "Check BPB" +msgstr "Preverjaj BPB" + +msgid "CD-ROM drives:" +msgstr "Pogoni CD-ROM:" + +msgid "MO drives:" +msgstr "Magnetno-optični pogoni:" + +msgid "ZIP drives:" +msgstr "Pogoni ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "Ura v realnem času ISA:" + +msgid "ISA Memory Expansion" +msgstr "Razširitev spomina ISA" + +msgid "Card 1:" +msgstr "Kartica 1:" + +msgid "Card 2:" +msgstr "Kartica 2:" + +msgid "Card 3:" +msgstr "Kartica 3:" + +msgid "Card 4:" +msgstr "Kartica 4:" + +msgid "ISABugger device" +msgstr "Naprava ISABugger" + +msgid "POST card" +msgstr "Kartica POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Napaka" + +msgid "Fatal error" +msgstr "Kritična napaka" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Pritisnite CTRL+ALT+PAGE DOWN za povratek iz celozaslonskega načina." + +msgid "Speed" +msgstr "Hitrost" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIP slike" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box ni našel nobenih uporabnih ROM slik.\n\nProsim prenesite set ROM-ov in ga razširite v mapo \"roms\"." + +msgid "(empty)" +msgstr "(prazno)" + +msgid "All files" +msgstr "Vse datoteke" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Vključeno" + +msgid "Off" +msgstr "Izključeno" + +msgid "All images" +msgstr "Vse slike" + +msgid "Basic sector images" +msgstr "Osnovne sektorske slike" + +msgid "Surface images" +msgstr "Površinske slike" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Sistem \"%hs\" ni na voljo zaradi manjkajočih ROM-ov v mapi roms/machines. Preklapljam na drug sistem, ki je na voljo." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Grafična kartica \"%hs\" ni na voljo zaradi manjkajočih ROM-ov v mapi roms/video. Preklapljam na drugo grafično kartico, ki je na voljo.." + +msgid "Machine" +msgstr "Sistem" + +msgid "Display" +msgstr "Zaslon" + +msgid "Input devices" +msgstr "Vhodne naprave" + +msgid "Sound" +msgstr "Zvok" + +msgid "Network" +msgstr "Omrežje" + +msgid "Ports (COM & LPT)" +msgstr "Vrata (COM & LPT)" + +msgid "Storage controllers" +msgstr "Krmilniki shrambe" + +msgid "Hard disks" +msgstr "Trdi diski" + +msgid "Floppy & CD-ROM drives" +msgstr "Disketni in CD-ROM pogoni" + +msgid "Other removable devices" +msgstr "Druge odstranljive naprave" + +msgid "Other peripherals" +msgstr "Druga periferija" + +msgid "Click to capture mouse" +msgstr "Kliknite za zajem miške" + +msgid "Press F8+F12 to release mouse" +msgstr "Pritisnite F8+F12 za izpust miške" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Pritisnite F8+F12 ali srednji gumb za izpust miške" + +msgid "Unable to initialize FluidSynth" +msgstr "Ne morem inicializirati FluidSynth" + +msgid "Bus" +msgstr "Vodilo" + +msgid "File" +msgstr "Datoteka" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Ne morem inicializirati pogona upodabljanja." + +msgid "Default" +msgstr "Privzeto" + +msgid "%i Wait state(s)" +msgstr "%i stanj čakanja" + +msgid "Type" +msgstr "Vrsta" + +msgid "Failed to set up PCap" +msgstr "Nastavitev PCap ni uspela" + +msgid "No PCap devices found" +msgstr "Nobena naprava PCap ni bila najdena" + +msgid "Invalid PCap device" +msgstr "Neveljavna naprava PCap" + +msgid "Standard 2-button joystick(s)" +msgstr "Standardna krmilna palica z 2 gumboma" + +msgid "Standard 4-button joystick" +msgstr "Standardna krmilna palica s 4 gumbi" + +msgid "Standard 6-button joystick" +msgstr "Standardna krmilna palica s 6 gumbi" + +msgid "Standard 8-button joystick" +msgstr "Standardna krmilna palica z 8 gumbi" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Brez" + +msgid "Unable to load keyboard accelerators." +msgstr "Ne morem naložiti pospeševalnikov tipkovnice." + +msgid "Unable to register raw input." +msgstr "Ne morem registrirati neobdelanega vnosa." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Disketa %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Napredne sektorske slike" + +msgid "Flux images" +msgstr "Tokovne slike" + +msgid "Unable to initialize FreeType" +msgstr "Ne morem inicializirati FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Ne morem inicializirati SDL, potrebna je knjižica SDL2.dll" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Ste prepričani, da želite ponovno zagnati emulirani sistem?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Ste prepričani, da želite zapreti 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Ne morem inicializirati Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Slike MO" + +msgid "Welcome to 86Box!" +msgstr "Dobrodošli v 86Box!" + +msgid "Internal controller" +msgstr "Notranji krmilnik" + +msgid "Exit" +msgstr "Izhod" + +msgid "No ROMs found" +msgstr "Nobeni ROM-i niso bili najdeni" + +msgid "Do you want to save the settings?" +msgstr "Želite shraniti nastavitve?" + +msgid "This will hard reset the emulated machine." +msgstr "To bo ponovno zagnalo emuliran sistem." + +msgid "Save" +msgstr "Shrani" + +msgid "About 86Box" +msgstr "O programu 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Emulator starih računalnikov\n\nAvtorji: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho in drugi.\n\nIzdano pod licenco GNU General Public License različica 2 ali novejša. Glej datoteko LICENSE za več informacij." + +msgid "Hardware not available" +msgstr "Strojna oprema ni na voljo" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Prepičajte se, da je nameščen libpcap in da ste na omrežni povezavi, združljivi z " + +msgid "Invalid configuration" +msgstr "Neveljavna konfiguracija" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " je potreben za emuliranje ESC/P tiskalnika." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " je potreben za samodejno pretvorbo PostScript datotek v PDF.\n\nVsi dokumenti, poslani generičnemu PostScript tiskalniku bodo shranjeni kot PostScript (.ps) datoteke." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " je potreben za FluidSynth MIDI izhod." + +msgid "Entering fullscreen mode" +msgstr "Preklapljam v celozaslonski način" + +msgid "Don't show this message again" +msgstr "Ne pokaži več tega sporočila" + +msgid "Don't exit" +msgstr "Prekliči izhod" + +msgid "Reset" +msgstr "Resetiraj" + +msgid "Don't reset" +msgstr "Ne resetiraj" + +msgid "CD-ROM images" +msgstr "Slike CD-ROM" + +msgid "%hs Device Configuration" +msgstr "Konfiguracija naprave %hs" + +msgid "Monitor in sleep mode" +msgstr "Zaslon v načinu spanja" + +msgid "OpenGL Shaders" +msgstr "Senčilniki OpenGL" + +msgid "OpenGL options" +msgstr "Možnosti OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Nalagate nepodprto konfiguracijo" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Filtriranje vrste procesorja glede na izbran sistem je onemogočeno za ta emuliran sistem.\n\nTako lahko izberete procesor, ki je sicer nezdružljiv z izbranim sistemom. Vendar lahko naletite na nezdružljivosti z BIOS-om sistema ali drugo programsko opremo\n\nOmogočanje te nastavitve ni uradno podprto, vsa poročila o hroščih iz tega naslova pa bodo zaprta kot neveljavna." + +msgid "Continue" +msgstr "Nadaljuj" + +msgid "Cassette: %s" +msgstr "Kaseta: %s" + +msgid "Cassette images" +msgstr "Slike kaset" + +msgid "Cartridge %i: %ls" +msgstr "Spominski vložek %i: %ls" + +msgid "Cartridge images" +msgstr "Slike spominskega vložka" + +msgid "Error initializing renderer" +msgstr "Error initializing renderer" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "Trdi disk (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLL ali ESDI pogoni CD-ROM niso nikoli obstajali" + +msgid "Custom..." +msgstr "Po meri..." + +msgid "Custom (large)..." +msgstr "Po meri (velik)..." + +msgid "Add New Hard Disk" +msgstr "Dodaj nov trdi disk" + +msgid "Add Existing Hard Disk" +msgstr "Dodaj obstoječ trdi disk" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Slike diska HDI ne morejo biti večje od 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Slike diska ne morejo biti večje od 127 GB." + +msgid "Hard disk images" +msgstr "Slike trdega diska" + +msgid "Unable to read file" +msgstr "Ne morem prebrati datoteke" + +msgid "Unable to write file" +msgstr "Ne morem pisati v datoteko" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Slike HDI ali HDX, ki nimajo sektorjev velikosti 512 bajtov, niso podprte." + +msgid "USB is not yet supported" +msgstr "USB še ni podprt" + +msgid "Disk image file already exists" +msgstr "Datoteka s sliko diska že obstaja" + +msgid "Please specify a valid file name." +msgstr "Prosim, navedite veljavno ime datoteke." + +msgid "Disk image created" +msgstr "Slika diska ustvarjena" + +msgid "Make sure the file exists and is readable." +msgstr "Prepričajte se, da datoteka obstaja in je berljiva." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Prepričajte se, da datoteko shranjujete v zapisljivo mapo." + +msgid "Disk image too large" +msgstr "Slika diska je prevelika" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Ne pozabite na novem disku ustvariti particij in jih formatirati." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Izbrana datoteka bo prepisana. Ali jo res želite uporabiti?" + +msgid "Unsupported disk image" +msgstr "Nepodprta slika diska" + +msgid "Overwrite" +msgstr "Prepiši" + +msgid "Don't overwrite" +msgstr "Ne prepiši" + +msgid "Raw image (.img)" +msgstr "Surova slika (.img)" + +msgid "HDI image (.hdi)" +msgstr "Slika HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Slika HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD fiksne velikosti (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "Dinamičen VHD (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Diferencialni VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Veliki bloki (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Mali bloki (512 KB)" + +msgid "VHD files" +msgstr "Datoteke VHD" + +msgid "Select the parent VHD" +msgstr "Izberite starševsko sliko VHD" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "To lahko pomeni, da je bila starševska slika spremenjena potem, ko je že bila ustvarjena diferencialna slika.\n\nDo tega lahko pride tudi kadar so datoteke slik diska premaknjene ali kopirane, ali pa gre za hrošča v programu, ki je ustvaril ta disk.\n\nŽelite popraviti časovni žig?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Časovna žiga starševske slike diska in slike diska otroka se ne ujemata" + +msgid "Could not fix VHD timestamp." +msgstr "Ne morem popraviti časovnega žiga slike VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (grozd 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (grozd 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "Popolni obrati na minuto" + +msgid "1%% below perfect RPM" +msgstr "1%% pod popolnimi obrati" + +msgid "1.5%% below perfect RPM" +msgstr "1.5%% pod popolnimi obrati" + +msgid "2%% below perfect RPM" +msgstr "2%% pod popolnimi obrati" + +msgid "(System Default)" +msgstr "(Sistemsko privzeto)" + diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po new file mode 100644 index 000000000..a6c36ac77 --- /dev/null +++ b/src/qt/languages/tr-TR.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Komutlar" + +msgid "&Keyboard requires capture" +msgstr "&Klavye sadece fare yakalandığında çalışsın" + +msgid "&Right CTRL is left ALT" +msgstr "&Sağ CTRL tuşunu sol ALT tuşu olarak ayarla" + +msgid "&Hard Reset..." +msgstr "&Makineyi yeniden başlat..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Duraklat" + +msgid "E&xit..." +msgstr "Emülatörden &çık..." + +msgid "&View" +msgstr "&Görüntüleme" + +msgid "&Hide status bar" +msgstr "&Durum çubuğunu gizle" + +msgid "Hide &toolbar" +msgstr "Hide &toolbar" + +msgid "&Resizeable window" +msgstr "&Yeniden boyutlandırılabilir pencere" + +msgid "R&emember size && position" +msgstr "&Pencere boyut ve pozisyonunu hatırla" + +msgid "Re&nderer" +msgstr "&İşleyici" + +msgid "&SDL (Software)" +msgstr "&SDL (Yazılım)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Donanım)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Pencere &boyutunu belirle..." + +msgid "F&orce 4:3 display ratio" +msgstr "&4:3 görüntüleme oranına zorla" + +msgid "&Window scale factor" +msgstr "Pencere &ölçek çarpanı" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "&Filtre metodu" + +msgid "&Nearest" +msgstr "&Nearest (En yakın)" + +msgid "&Linear" +msgstr "&Linear (Doğrusal)" + +msgid "Hi&DPI scaling" +msgstr "Hi&DPI ölçeklemesi" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Tam ekran\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "Tam ekran &germe modu" + +msgid "&Full screen stretch" +msgstr "&Tam ekrana ger" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Kare piksel (ölçeği koru)" + +msgid "&Integer scale" +msgstr "Tam &sayı ölçeklemesi" + +msgid "E&GA/(S)VGA settings" +msgstr "EGA/&(S)VGA ayarları" + +msgid "&Inverted VGA monitor" +msgstr "Ters &renk VGA monitör" + +msgid "VGA screen &type" +msgstr "VGA ekran &tipi" + +msgid "RGB &Color" +msgstr "RGB (&renkli)" + +msgid "&RGB Grayscale" +msgstr "RGB (&gri tonlama)" + +msgid "&Amber monitor" +msgstr "&Kehribar rengi monitör" + +msgid "&Green monitor" +msgstr "&Yeşil renk monitör" + +msgid "&White monitor" +msgstr "&Beyaz renk monitör" + +msgid "Grayscale &conversion type" +msgstr "&Gri tonlama dönüştürme tipi" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Ortalama" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA aşırı taraması" + +msgid "Change contrast for &monochrome display" +msgstr "Gri to&nlamalı görüntü için kontrastı değiştir" + +msgid "&Media" +msgstr "&Medya" + +msgid "&Tools" +msgstr "&Araçlar" + +msgid "&Settings..." +msgstr "&Ayarlar..." + +msgid "&Update status bar icons" +msgstr "Durum &çubuğu ikonlarını güncelle" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "&Ekran görüntüsü al\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Tercihler..." + +msgid "Enable &Discord integration" +msgstr "&Discord entegrasyonunu etkinleştir" + +msgid "Sound &gain..." +msgstr "&Ses yükseltici..." + +msgid "Begin trace\tCtrl+T" +msgstr "Begin trace\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "End trace\tCtrl+T" + +msgid "&Logging" +msgstr "&Logging" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "BusLogic kayıtlarını etkinleştir\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "CD-ROM kayıtlarını etkinleştir\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Disket (86F) kayıtlarını etkinleştir\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Disket kontrolcüsü kayıtlarını etkinleştir\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "IDE kayıtlarını etkinleştir\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Seri Port kayıtlarını etkinleştir\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Ağ kayıtlarını etkinleştir\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&breakpoint'i kayıtla\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "&Video belleğini depola\tCtrl+F1" + +msgid "&Help" +msgstr "&Yardım" + +msgid "&Documentation..." +msgstr "&Dökümanlar..." + +msgid "&About 86Box..." +msgstr "&86Box Hakkında..." + +msgid "&New image..." +msgstr "&Yeni imaj oluştur..." + +msgid "&Existing image..." +msgstr "&İmaj seç..." + +msgid "Existing image (&Write-protected)..." +msgstr "İmaj &seç (Yazma-korumalı)..." + +msgid "&Record" +msgstr "&Kaydet" + +msgid "&Play" +msgstr "&Oynat" + +msgid "&Rewind to the beginning" +msgstr "&Başlangıca geri sar" + +msgid "&Fast forward to the end" +msgstr "Sona doğru &ileri sar" + +msgid "E&ject" +msgstr "&Çıkar" + +msgid "&Image..." +msgstr "&İmaj..." + +msgid "E&xport to 86F..." +msgstr "&86F dosyası olarak aktar..." + +msgid "&Mute" +msgstr "&Sesi kapat" + +msgid "E&mpty" +msgstr "İmajı &çıkar" + +msgid "&Reload previous image" +msgstr "&Önceki imajı seç" + +msgid "&Image" +msgstr "&İmaj seç" + +msgid "Target &framerate" +msgstr "Hedef &kare oranı" + +msgid "&Sync with video" +msgstr "Video ile &senkronize et" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "Gölgelendirici &seç..." + +msgid "&Remove shader" +msgstr "&Gölgelendiriciyi kaldır" + +msgid "Preferences" +msgstr "Tercihler" + +msgid "Sound Gain" +msgstr "Ses Artırma" + +msgid "New Image" +msgstr "Yeni İmaj" + +msgid "Settings" +msgstr "Ayarlar" + +msgid "Specify Main Window Dimensions" +msgstr "Ana Pencere Boyutunu Belirle" + +msgid "OK" +msgstr "Tamam" + +msgid "Cancel" +msgstr "İptal et" + +msgid "Save these settings as &global defaults" +msgstr "Bu ayarları &varsayılan olarak kaydet" + +msgid "&Default" +msgstr "&Varsayılan" + +msgid "Language:" +msgstr "Dil:" + +msgid "Icon set:" +msgstr "Simge seti:" + +msgid "Gain" +msgstr "Artırma" + +msgid "File name:" +msgstr "Dosya adı:" + +msgid "Disk size:" +msgstr "Disk boyutu:" + +msgid "RPM mode:" +msgstr "RPM modu:" + +msgid "Progress:" +msgstr "İşlem:" + +msgid "Width:" +msgstr "Genişlik:" + +msgid "Height:" +msgstr "Yükseklik:" + +msgid "Lock to this size" +msgstr "Bu boyuta kilitle" + +msgid "Machine type:" +msgstr "Makine türü:" + +msgid "Machine:" +msgstr "Makine:" + +msgid "Configure" +msgstr "Ayarla" + +msgid "CPU type:" +msgstr "CPU türü:" + +msgid "Speed:" +msgstr "Hız:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Bekleme süreleri:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Bellek:" + +msgid "Time synchronization" +msgstr "Zaman senkronizasyonu" + +msgid "Disabled" +msgstr "Devre dışı" + +msgid "Enabled (local time)" +msgstr "Etkin (yerel zaman)" + +msgid "Enabled (UTC)" +msgstr "Etkin (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dinamik Derleyici" + +msgid "Video:" +msgstr "Ekran kartı:" + +msgid "Voodoo Graphics" +msgstr "Voodoo Grafikleri" + +msgid "Mouse:" +msgstr "Fare:" + +msgid "Joystick:" +msgstr "Oyun kolu:" + +msgid "Joystick 1..." +msgstr "Oyun kolu 1..." + +msgid "Joystick 2..." +msgstr "Oyun kolu 2..." + +msgid "Joystick 3..." +msgstr "Oyun kolu 3..." + +msgid "Joystick 4..." +msgstr "Oyun kolu 4..." + +msgid "Sound card:" +msgstr "Ses kartı:" + +msgid "MIDI Out Device:" +msgstr "MIDI Çıkış Cihazı:" + +msgid "MIDI In Device:" +msgstr "MIDI Giriş Cihazı:" + +msgid "Standalone MPU-401" +msgstr "Bağımsız MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "FLOAT32 ses kullan" + +msgid "Network type:" +msgstr "Ağ tipi:" + +msgid "PCap device:" +msgstr "PCap cihazı:" + +msgid "Network adapter:" +msgstr "Ağ cihazı:" + +msgid "COM1 Device:" +msgstr "COM1 Cihazı:" + +msgid "COM2 Device:" +msgstr "COM2 Cihazı:" + +msgid "COM3 Device:" +msgstr "COM3 Cihazı:" + +msgid "COM4 Device:" +msgstr "COM4 Cihazı:" + +msgid "LPT1 Device:" +msgstr "LPT1 Cihazı:" + +msgid "LPT2 Device:" +msgstr "LPT2 Cihazı:" + +msgid "LPT3 Device:" +msgstr "LPT3 Cihazı:" + +msgid "LPT4 Device:" +msgstr "LPT4 Cihazı:" + +msgid "Serial port 1" +msgstr "Seri port 1" + +msgid "Serial port 2" +msgstr "Seri port 2" + +msgid "Serial port 3" +msgstr "Seri port 3" + +msgid "Serial port 4" +msgstr "Seri port 4" + +msgid "Parallel port 1" +msgstr "Paralel port 1" + +msgid "Parallel port 2" +msgstr "Paralel port 2" + +msgid "Parallel port 3" +msgstr "Paralel port 3" + +msgid "Parallel port 4" +msgstr "Paralel port 4" + +msgid "HD Controller:" +msgstr "HD Kontrolcüsü:" + +msgid "FD Controller:" +msgstr "FD Kontrolcüsü:" + +msgid "Tertiary IDE Controller" +msgstr "Üçlü IDE Kontrolcüsü" + +msgid "Quaternary IDE Controller" +msgstr "Dörtlü IDE Kontrolcüsü" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Kontrolcü 1:" + +msgid "Controller 2:" +msgstr "Kontrolcü 2:" + +msgid "Controller 3:" +msgstr "Kontrolcü 3:" + +msgid "Controller 4:" +msgstr "Kontrolcü 4:" + +msgid "Cassette" +msgstr "Kaset" + +msgid "Hard disks:" +msgstr "Hard diskler:" + +msgid "&New..." +msgstr "&Yeni..." + +msgid "&Existing..." +msgstr "&Var olan..." + +msgid "&Remove" +msgstr "&Kaldır" + +msgid "Bus:" +msgstr "Veri yolu:" + +msgid "Channel:" +msgstr "Kanal:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Belirle..." + +msgid "Sectors:" +msgstr "Sektörler:" + +msgid "Heads:" +msgstr "Veri Kafaları:" + +msgid "Cylinders:" +msgstr "Silindirler:" + +msgid "Size (MB):" +msgstr "Boyut (MB):" + +msgid "Type:" +msgstr "Tip:" + +msgid "Image Format:" +msgstr "İmaj Düzeni:" + +msgid "Block Size:" +msgstr "Blok Boyutu:" + +msgid "Floppy drives:" +msgstr "Disket sürücüleri:" + +msgid "Turbo timings" +msgstr "Turbo zamanlamaları" + +msgid "Check BPB" +msgstr "BPB'yi denetle" + +msgid "CD-ROM drives:" +msgstr "CD-ROM sürücüleri:" + +msgid "MO drives:" +msgstr "MO sürücüleri:" + +msgid "ZIP drives:" +msgstr "ZIP sürücüleri:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "ISA Bellek Artırma" + +msgid "Card 1:" +msgstr "Kart 1:" + +msgid "Card 2:" +msgstr "Kart 2:" + +msgid "Card 3:" +msgstr "Kart 3:" + +msgid "Card 4:" +msgstr "Kart 4:" + +msgid "ISABugger device" +msgstr "ISABugger cihazı" + +msgid "POST card" +msgstr "POST kartı" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Hata" + +msgid "Fatal error" +msgstr "Kritik hata" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Pencere moduna geri dönmek için CTRL+ALT+PAGE DOWN tuşlarına basın." + +msgid "Speed" +msgstr "Hız" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIP imajları" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box hiç bir kullanılabilir ROM imajı bulamadı.\n\nLütfen ROM setini indirin ve onu \"Roms\" klasörüne çıkarın." + +msgid "(empty)" +msgstr "(empty)" + +msgid "All files" +msgstr "All files" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Açık" + +msgid "Off" +msgstr "Kapalı" + +msgid "All images" +msgstr "Tüm imajlar" + +msgid "Basic sector images" +msgstr "Basit sektör imajları" + +msgid "Surface images" +msgstr "Yüzey imajları" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "\"%hs\" makinesi roms/machines klasöründe mevcut olmayan ROM imajı yüzünden mevcut değil. Mevcut olan bir makineye geçiş yapılıyor." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "\"%hs\" ekran kartı roms/video klasöründe mevcut olmayan ROM imajı yüzünden mevcut değil. Mevcut olan bir ekran kartına geçiş yapılıyor." + +msgid "Machine" +msgstr "Makine" + +msgid "Display" +msgstr "Görüntü" + +msgid "Input devices" +msgstr "Giriş aygıtları" + +msgid "Sound" +msgstr "Ses" + +msgid "Network" +msgstr "Ağ" + +msgid "Ports (COM & LPT)" +msgstr "Portlar (COM & LPT)" + +msgid "Storage controllers" +msgstr "Depolama kontrolcüleri" + +msgid "Hard disks" +msgstr "Hard diskler" + +msgid "Floppy & CD-ROM drives" +msgstr "Disket & CD-ROM sürücüleri" + +msgid "Other removable devices" +msgstr "Diğer kaldırılabilir cihazlar" + +msgid "Other peripherals" +msgstr "Diğer cihazlar" + +msgid "Click to capture mouse" +msgstr "Farenin yakalanması için tıklayın" + +msgid "Press F8+F12 to release mouse" +msgstr "Farenin bırakılması için F8+F12 tuşlarına basın" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Farenin bırakılması için F8+F12 veya farenin orta tuşuna basın" + +msgid "Unable to initialize FluidSynth" +msgstr "FluidSynth başlatılamadı" + +msgid "Bus" +msgstr "Veri yolu" + +msgid "File" +msgstr "Dosya" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Video işleyici başlatılamadı." + +msgid "Default" +msgstr "Varsayılan" + +msgid "%i Wait state(s)" +msgstr "%i Bekleme durumları" + +msgid "Type" +msgstr "Tür" + +msgid "Failed to set up PCap" +msgstr "PCap ayarlanamadı" + +msgid "No PCap devices found" +msgstr "Herhangi bir PCap cihazı bulunamadı" + +msgid "Invalid PCap device" +msgstr "Geçersiz PCap cihazı" + +msgid "Standard 2-button joystick(s)" +msgstr "Standart 2-button oyun kolları" + +msgid "Standard 4-button joystick" +msgstr "Standart 4-button oyun kolu" + +msgid "Standard 6-button joystick" +msgstr "Standart 6-button oyun kolu" + +msgid "Standard 8-button joystick" +msgstr "Standart 8-button oyun kolu" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Kontrol Sistemi" + +msgid "None" +msgstr "Hiçbiri" + +msgid "Unable to load keyboard accelerators." +msgstr "Klavye ivdirgeçleri yüklenemedi." + +msgid "Unable to register raw input." +msgstr "Ham girdi kaydedilemedi." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Disket %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Gelişmiş sektör imajları" + +msgid "Flux images" +msgstr "Flux images" + +msgid "Unable to initialize FreeType" +msgstr "FreeType başlatılamadı" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "SDL başlatılamadı, SDL2.dll gerekmektedir" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Emüle edilen makineyi yeniden başlatmak istediğinizden emin misiniz?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "86Box'tan çıkmak istediğinize emin misiniz?" + +msgid "Unable to initialize Ghostscript" +msgstr "Ghostscript başlatılamadı" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "MO imajları" + +msgid "Welcome to 86Box!" +msgstr "86Box'a hoşgeldiniz!" + +msgid "Internal controller" +msgstr "Dahili kontrolcü" + +msgid "Exit" +msgstr "Çıkış" + +msgid "No ROMs found" +msgstr "Hiçbir ROM imajı bulunamadı" + +msgid "Do you want to save the settings?" +msgstr "Ayarları kaydetmek istediğinizden emin misiniz?" + +msgid "This will hard reset the emulated machine." +msgstr "Bu makineyi yeniden başlatacak." + +msgid "Save" +msgstr "Kaydet" + +msgid "About 86Box" +msgstr "86Box Hakkında" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Bir eski bilgisayar emülatörü\n\nYapanlar: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, ve diğerleri.\n\nGNU Genel Kamu Lisansı versiyon 2 veya sonrası altında yayınlanmıştır. Daha fazla bilgi için LICENSE'ı gözden geçirin." + +msgid "Hardware not available" +msgstr "Donanım mevcut değil" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "libpcap kurulu olduğundan ve libpcap-uyumlu bir internet ağında bulunduğunuzdan emin olun." + +msgid "Invalid configuration" +msgstr "Geçersiz konfigürasyon" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr " ESC/P yazıcı emülasyonu için gereklidir." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " PostScript dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyaları olarak kaydedilecektir." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr " FluidSynth MIDI çıkışı için gereklidir." + +msgid "Entering fullscreen mode" +msgstr "Tam ekran moduna geçiliyor" + +msgid "Don't show this message again" +msgstr "Bu mesajı bir daha gösterme" + +msgid "Don't exit" +msgstr "Çıkış yapma" + +msgid "Reset" +msgstr "Yeniden başlat" + +msgid "Don't reset" +msgstr "Yeniden başlatma" + +msgid "CD-ROM images" +msgstr "CD-ROM imajları" + +msgid "%hs Device Configuration" +msgstr "%hs Cihaz Konfigürasyonu" + +msgid "Monitor in sleep mode" +msgstr "Monitör uyku modunda" + +msgid "OpenGL Shaders" +msgstr "OpenGL Gölgelendiricileri" + +msgid "OpenGL options" +msgstr "OpenGL ayarları" + +msgid "You are loading an unsupported configuration" +msgstr "Desteklenmeyen bir konfigürasyon yüklüyorsunuz" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Seçtiğiniz makineye uygun CPU (işlemci) türü filtrelemesi bu emülasyon için devre dışı bırakıldı.\n\nBu, normalde seçilen makine ile uyumlu olmayan bir CPU seçmenizi mümkün kılmaktadır. Ancak, bundan dolayı seçilen makinenin BIOS'u veya diğer yazılımlar ile uyumsuzluk sorunu yaşayabilirsiniz.\n\nBu filtrelemeyi devre dışı bırakmak emülatör tarafından resmi olarak desteklenmemektedir ve açtığınız bug (hata) raporları geçersiz olarak kapatılabilir." + +msgid "Continue" +msgstr "Devam et" + +msgid "Cassette: %s" +msgstr "Kaset: %s" + +msgid "Cassette images" +msgstr "Kaset imajları" + +msgid "Cartridge %i: %ls" +msgstr "Kartuş %i: %ls" + +msgid "Cartridge images" +msgstr "Kartuş imajları" + +msgid "Error initializing renderer" +msgstr "Error initializing renderer" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + +msgid "Resume execution" +msgstr "Resume execution" + +msgid "Pause execution" +msgstr "Pause execution" + +msgid "Press Ctrl+Alt+Del" +msgstr "Press Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Press Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Hard reset" + +msgid "ACPI shutdown" +msgstr "ACPI shutdown" + +msgid "Hard disk (%s)" +msgstr "Hard disk (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLL veya ESDI CD-ROM sürücüleri hiçbir zaman var olmamıştır" + +msgid "Custom..." +msgstr "Diğer..." + +msgid "Custom (large)..." +msgstr "Diğer (büyük)..." + +msgid "Add New Hard Disk" +msgstr "Yeni Hard Disk Dosyası Oluştur" + +msgid "Add Existing Hard Disk" +msgstr "Var Olan Hard Disk Dosyası Ekle" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "HDI disk imajları 4 GB'tan daha büyük olamaz." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Disk imajları 127 GB'tan daha büyük olamaz." + +msgid "Hard disk images" +msgstr "Hard disk imajları" + +msgid "Unable to read file" +msgstr "Dosya okunamıyor" + +msgid "Unable to write file" +msgstr "Dosyanın üzerine yazılamıyor" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "512 dışında sektör boyutu olan HDI veya HDX imajları desteklenmemektedir." + +msgid "USB is not yet supported" +msgstr "USB şu anda desteklenmemektedir" + +msgid "Disk image file already exists" +msgstr "Disk imaj dosyası zaten var olmakta" + +msgid "Please specify a valid file name." +msgstr "Lütfen geçerli bir dosya ismi belirleyin." + +msgid "Disk image created" +msgstr "Disk imajı oluşturuldu" + +msgid "Make sure the file exists and is readable." +msgstr "Dosyanın var olduğuna ve okunabildiğine emin olun." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Dosyanın yazılabilir bir klasöre kaydedildiğinden emin olun." + +msgid "Disk image too large" +msgstr "Disk imajı çok büyük" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Yeni oluşturulan diski bölmeyi ve formatlamayı unutmayın." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Seçili dosyanın üzerine yazılacaktır. Bunu yapmak istediğinizden emin misiniz?" + +msgid "Unsupported disk image" +msgstr "Desteklenmeyen disk imajı" + +msgid "Overwrite" +msgstr "Üzerine yaz" + +msgid "Don't overwrite" +msgstr "Üzerine yazma" + +msgid "Raw image (.img)" +msgstr "Ham imaj (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI imajı (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX imajı (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "Sabit-boyutlu VHD (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "Dinamik-boyutlu VHD (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Differencing VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Büyük bloklar (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Küçük bloklar (512 KB)" + +msgid "VHD files" +msgstr "VHD dosyaları" + +msgid "Select the parent VHD" +msgstr "Ana VHD dosyasını seçin" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Bu, farkı alınan imaj oluşturulduktan sonra ana imaj dosyasının düzenlendiği anlamına geliyor olabilir.\n\nBu durum ayrıca imaj dosyaları kopyalandığında veya yerleri değiştirildiğinde veya imaj dosyalarını oluşturan programdaki bir hatadan dolayı olmuş olabilir.\n\nZaman damgalarını düzeltmek ister misiniz?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Ana ve ek disk zaman damgaları uyuşmuyor" + +msgid "Could not fix VHD timestamp." +msgstr "VHD zaman damgası düzeltilemedi." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Mb M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Mb M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Mb M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Mb M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Gb M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Gb M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Mb M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Mb M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Gb M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Gb M.O." + +msgid "Perfect RPM" +msgstr "Mükemmel RPM" + +msgid "1%% below perfect RPM" +msgstr "mükemmel RPM değerinin 1%% altı" + +msgid "1.5%% below perfect RPM" +msgstr "mükemmel RPM değerinin 1.5%% altı" + +msgid "2%% below perfect RPM" +msgstr "mükemmel RPM değerinin 2%% altı" + +msgid "(System Default)" +msgstr "(Sistem Varsayılanı)" + diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po new file mode 100644 index 000000000..a8dc7bd0f --- /dev/null +++ b/src/qt/languages/uk-UA.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "&Дія" + +msgid "&Keyboard requires capture" +msgstr "&Клавіатура потребує захвату" + +msgid "&Right CTRL is left ALT" +msgstr "&Правий CTRL - це лівий ALT" + +msgid "&Hard Reset..." +msgstr "&Холодне перезавантаження..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Пауза" + +msgid "E&xit..." +msgstr "&Вихід..." + +msgid "&View" +msgstr "&Вигляд" + +msgid "&Hide status bar" +msgstr "&Приховати рядок стану" + +msgid "Hide &toolbar" +msgstr "&Приховати панель інструментів" + +msgid "&Resizeable window" +msgstr "&Змінний розмір вікна" + +msgid "R&emember size && position" +msgstr "&Запам'ятати розмір і становище" + +msgid "Re&nderer" +msgstr "&Рендеринг" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "&Вказати розміри..." + +msgid "F&orce 4:3 display ratio" +msgstr "&Встановити відношення сторін 4:3" + +msgid "&Window scale factor" +msgstr "&Масштаб вікна" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "Filter method" +msgstr "Метод фільтрації" + +msgid "&Nearest" +msgstr "&Найближчий" + +msgid "&Linear" +msgstr "&Лінійний" + +msgid "Hi&DPI scaling" +msgstr "Масштабування Hi&DPI" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "&Повноекранний режим\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "&Розстягування у повноекранному режимі" + +msgid "&Full screen stretch" +msgstr "&На весь екран" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Квадратні пікселі (зберегти відношення)" + +msgid "&Integer scale" +msgstr "&Цілісночисленне масштабування" + +msgid "E&GA/(S)VGA settings" +msgstr "Налаштування E&GA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "&Інвертувати кольори VGA" + +msgid "VGA screen &type" +msgstr "&Тип екрана VGA" + +msgid "RGB &Color" +msgstr "RGB &кольоровий" + +msgid "&RGB Grayscale" +msgstr "&RGB монохромний" + +msgid "&Amber monitor" +msgstr "&Бурштиновий відтінок" + +msgid "&Green monitor" +msgstr "&Зелений відтінок" + +msgid "&White monitor" +msgstr "&Білий відтінок" + +msgid "Grayscale &conversion type" +msgstr "Тип монохромного &конвертування" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Усереднений" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "Вильоти розгортки CGA/PCjr/Tandy/E&GA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Змінити контрастність &монохромного дисплея" + +msgid "&Media" +msgstr "&Носії" + +msgid "&Tools" +msgstr "&Інструменти" + +msgid "&Settings..." +msgstr "&Налаштування машини..." + +msgid "&Update status bar icons" +msgstr "&Обновлення значків рядка стану" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Зробити &знімок\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Параметри..." + +msgid "Enable &Discord integration" +msgstr "Увімкнути інтеграцію &Discord" + +msgid "Sound &gain..." +msgstr "&Посилення звуку..." + +msgid "Begin trace\tCtrl+T" +msgstr "Почати трасування\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Завершити трасування\tCtrl+T" + +msgid "&Logging" +msgstr "&Ведення журнала" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "Увімкнути журнали BusLogic\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "Увімкнути журнали CD-ROM\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "Увімкнути журнали дискет (86F)\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "Увімкнути журнали контролера дискет\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "Увімкнути журнали IDE\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "Увімкнути журнали COM порту\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "Увімкнути журнали мережі\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "&Точка зупинка журналу\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "&Вивантаження дампа відеопам'яті\tCtrl+F1" + +msgid "&Help" +msgstr "&Допомога" + +msgid "&Documentation..." +msgstr "&Документація..." + +msgid "&About 86Box..." +msgstr "&Про програму 86Box..." + +msgid "&New image..." +msgstr "&Новий образ..." + +msgid "&Existing image..." +msgstr "&Вибрати образ..." + +msgid "Existing image (&Write-protected)..." +msgstr "Вибрати образ (&Захист від запису)..." + +msgid "&Record" +msgstr "&Запис" + +msgid "&Play" +msgstr "&Відтворення" + +msgid "&Rewind to the beginning" +msgstr "&Перемотування на початок" + +msgid "&Fast forward to the end" +msgstr "&Перемотування у кінець" + +msgid "E&ject" +msgstr "&Вилучити" + +msgid "&Image..." +msgstr "&Образ..." + +msgid "E&xport to 86F..." +msgstr "&Експорт в 86F..." + +msgid "&Mute" +msgstr "&Відключити звук" + +msgid "E&mpty" +msgstr "&Пустий" + +msgid "&Reload previous image" +msgstr "&Знову завантажити попередній образ" + +msgid "&Image" +msgstr "&Образ..." + +msgid "Target &framerate" +msgstr "Цільова &частота кадрів" + +msgid "&Sync with video" +msgstr "&Синхронізація з відео" + +msgid "&25 fps" +msgstr "&25 кадрів в секунду" + +msgid "&30 fps" +msgstr "&30 кадрів в секунду" + +msgid "&50 fps" +msgstr "&50 кадрів в секунду" + +msgid "&60 fps" +msgstr "&60 кадрів в секунду" + +msgid "&75 fps" +msgstr "&75 кадрів в секунду" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Вибрати шейдер..." + +msgid "&Remove shader" +msgstr "&Видалити шейдер" + +msgid "Preferences" +msgstr "Параметри" + +msgid "Sound Gain" +msgstr "Посилення звуку" + +msgid "New Image" +msgstr "Новий образ" + +msgid "Settings" +msgstr "Налаштування" + +msgid "Specify Main Window Dimensions" +msgstr "Вказати розміри головного вікна" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Відміна" + +msgid "Save these settings as &global defaults" +msgstr "Зберегти ці параметри як &глобальні за замовчуванням" + +msgid "&Default" +msgstr "&За замовчуванням" + +msgid "Language:" +msgstr "Язык:" + +msgid "Icon set:" +msgstr "Набір іконок:" + +msgid "Gain" +msgstr "Посилення" + +msgid "File name:" +msgstr "Ім'я файлу:" + +msgid "Disk size:" +msgstr "Розмір диска:" + +msgid "RPM mode:" +msgstr "RPM режим:" + +msgid "Progress:" +msgstr "Прогрес:" + +msgid "Width:" +msgstr "Ширина:" + +msgid "Height:" +msgstr "Висота:" + +msgid "Lock to this size" +msgstr "Зафіксувати розмір" + +msgid "Machine type:" +msgstr "Тип машини:" + +msgid "Machine:" +msgstr "Системна плата:" + +msgid "Configure" +msgstr "Налаштування" + +msgid "CPU type:" +msgstr "Тип ЦП:" + +msgid "Speed:" +msgstr "Швидкість:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Цикли очікування:" + +msgid "MB" +msgstr "МБ" + +msgid "Memory:" +msgstr "Пам'ять:" + +msgid "Time synchronization" +msgstr "Синхронізація часу" + +msgid "Disabled" +msgstr "Відключити" + +msgid "Enabled (local time)" +msgstr "Увімкнути (місцеве)" + +msgid "Enabled (UTC)" +msgstr "Увімкнути (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Динамічний рекомпілятор" + +msgid "Video:" +msgstr "Відеокарта:" + +msgid "Voodoo Graphics" +msgstr "Прискорювач Voodoo" + +msgid "Mouse:" +msgstr "Миша:" + +msgid "Joystick:" +msgstr "Джойстик:" + +msgid "Joystick 1..." +msgstr "Джойстик 1..." + +msgid "Joystick 2..." +msgstr "Джойстик 2..." + +msgid "Joystick 3..." +msgstr "Джойстик 3..." + +msgid "Joystick 4..." +msgstr "Джойстик 4..." + +msgid "Sound card:" +msgstr "Звукова карта:" + +msgid "MIDI Out Device:" +msgstr "MIDI Out при-ій:" + +msgid "MIDI In Device:" +msgstr "MIDI In при-ій:" + +msgid "Standalone MPU-401" +msgstr "Окремий MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "FLOAT32 звук" + +msgid "Network type:" +msgstr "Тип мережі:" + +msgid "PCap device:" +msgstr "Пристрій PCap:" + +msgid "Network adapter:" +msgstr "Мережева карта:" + +msgid "COM1 Device:" +msgstr "Пристрій COM1:" + +msgid "COM2 Device:" +msgstr "Пристрій COM2:" + +msgid "COM3 Device:" +msgstr "Пристрій COM3:" + +msgid "COM4 Device:" +msgstr "Пристрій COM4:" + +msgid "LPT1 Device:" +msgstr "Пристрій LPT1:" + +msgid "LPT2 Device:" +msgstr "Пристрій LPT2:" + +msgid "LPT3 Device:" +msgstr "Пристрій LPT3:" + +msgid "LPT4 Device:" +msgstr "Пристрій LPT4:" + +msgid "Serial port 1" +msgstr "Послідов. порт COM1" + +msgid "Serial port 2" +msgstr "Послідов. порт COM2" + +msgid "Serial port 3" +msgstr "Послідов. порт COM3" + +msgid "Serial port 4" +msgstr "Послідов. порт COM4" + +msgid "Parallel port 1" +msgstr "Паралельний порт LPT1" + +msgid "Parallel port 2" +msgstr "Паралельний порт LPT2" + +msgid "Parallel port 3" +msgstr "Паралельний порт LPT3" + +msgid "Parallel port 4" +msgstr "Паралельний порт LPT4" + +msgid "HD Controller:" +msgstr "Контролер HD:" + +msgid "FD Controller:" +msgstr "Контролер FD:" + +msgid "Tertiary IDE Controller" +msgstr "Третинний IDE контролер" + +msgid "Quaternary IDE Controller" +msgstr "Четвертинний IDE контролер" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Контролер 1:" + +msgid "Controller 2:" +msgstr "Контролер 2:" + +msgid "Controller 3:" +msgstr "Контролер 3:" + +msgid "Controller 4:" +msgstr "Контролер 4:" + +msgid "Cassette" +msgstr "Касета" + +msgid "Hard disks:" +msgstr "Жорсткі диски:" + +msgid "&New..." +msgstr "&Створити..." + +msgid "&Existing..." +msgstr "&Вибрати..." + +msgid "&Remove" +msgstr "&Прибрати" + +msgid "Bus:" +msgstr "Шина:" + +msgid "Channel:" +msgstr "Канал:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Вказати..." + +msgid "Sectors:" +msgstr "Сектора:" + +msgid "Heads:" +msgstr "Головки:" + +msgid "Cylinders:" +msgstr "Циліндри:" + +msgid "Size (MB):" +msgstr "Розмір (МБ):" + +msgid "Type:" +msgstr "Тип:" + +msgid "Image Format:" +msgstr "Тип образу:" + +msgid "Block Size:" +msgstr "Розмір блоку:" + +msgid "Floppy drives:" +msgstr "Гнучкі диски:" + +msgid "Turbo timings" +msgstr "Турбо таймінги" + +msgid "Check BPB" +msgstr "Перевіряти BPB" + +msgid "CD-ROM drives:" +msgstr "Дисководи CD-ROM:" + +msgid "MO drives:" +msgstr "Магнітооптичні дисководи:" + +msgid "ZIP drives:" +msgstr "ZIP дисководи:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "Карта розширення пам'яті (ISA)" + +msgid "Card 1:" +msgstr "Карта 1:" + +msgid "Card 2:" +msgstr "Карта 2:" + +msgid "Card 3:" +msgstr "Карта 3:" + +msgid "Card 4:" +msgstr "Карта 4:" + +msgid "ISABugger device" +msgstr "Пристрій ISABugger" + +msgid "POST card" +msgstr "Карта POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Помилка" + +msgid "Fatal error" +msgstr "Непереробна помилка" + +msgid "" +msgstr "<зарезервовано>" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "Натисніть CTRL + ALT + PAGE DOWN для повернення у віконний режим." + +msgid "Speed" +msgstr "Швидкість" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Образи ZIP" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box не зміг знайти жодного відповідного для використання файлу з ПЗУ.\n\nБудь ласка завантажте набір ПЗУ і витягніть його в каталог \"roms\"." + +msgid "(empty)" +msgstr "(порожньо)" + +msgid "All files" +msgstr "Всі файли" + +msgid "Turbo" +msgstr "Турбо" + +msgid "On" +msgstr "Увімк" + +msgid "Off" +msgstr "Вимк" + +msgid "All images" +msgstr "Всі образи" + +msgid "Basic sector images" +msgstr "Прості посекторні образи" + +msgid "Surface images" +msgstr "Образ поверхні" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Системна плата \"%hs\" недоступна через відсутність файлу її ПЗУ в каталозі roms/machines. Переключення на доступну системну плату." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Відеокарта \"%hs\" недоступна через відсутність файлу її ПЗУ в каталозі roms/video. Переключення на доступну відеокарту." + +msgid "Machine" +msgstr "Комп'ютер" + +msgid "Display" +msgstr "Дисплей" + +msgid "Input devices" +msgstr "Пристрій введення" + +msgid "Sound" +msgstr "Звук" + +msgid "Network" +msgstr "Мережа" + +msgid "Ports (COM & LPT)" +msgstr "Порти (COM и LPT)" + +msgid "Storage controllers" +msgstr "Контролери дисків" + +msgid "Hard disks" +msgstr "Жорсткі диски" + +msgid "Floppy & CD-ROM drives" +msgstr "Гнучкі диски і CD-ROM" + +msgid "Other removable devices" +msgstr "Інші знімні при-ої" + +msgid "Other peripherals" +msgstr "Інша периферія" + +msgid "Click to capture mouse" +msgstr "Клацніть мишею для захвату курсора" + +msgid "Press F8+F12 to release mouse" +msgstr "Натисніть F8+F12, щоб звільнити курсор" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Натисніть F8+F12 або середню кнопку миші, щоб звільнити курсор" + +msgid "Unable to initialize FluidSynth" +msgstr "Неможливо ініціалізувати FluidSynth" + +msgid "Bus" +msgstr "Шина" + +msgid "File" +msgstr "Файл" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "КБ" + +msgid "Could not initialize the video renderer." +msgstr "Не вдалося ініціалізувати рендер відео." + +msgid "Default" +msgstr "За замовчуванням" + +msgid "%i Wait state(s)" +msgstr "%i WS" + +msgid "Type" +msgstr "Тип" + +msgid "Failed to set up PCap" +msgstr "Не вдалося налаштувати PCap" + +msgid "No PCap devices found" +msgstr "Пристрої PCap не знайдені" + +msgid "Invalid PCap device" +msgstr "Невірний пристрій PCap" + +msgid "Standard 2-button joystick(s)" +msgstr "Стандартний 2-кнопковий джойстик" + +msgid "Standard 4-button joystick" +msgstr "Стандартний 4-кнопковий джойстик" + +msgid "Standard 6-button joystick" +msgstr "Стандартний 6-кнопковий джойстик" + +msgid "Standard 8-button joystick" +msgstr "Стандартний 8-кнопковий джойстик" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Система управління польотом Thrustmaster" + +msgid "None" +msgstr "Ні" + +msgid "Unable to load keyboard accelerators." +msgstr "Неможливо завантажити прискорювачі клавіатури." + +msgid "Unable to register raw input." +msgstr "Неможливо зарреєструвати необроблене (RAW) введення." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u МБ (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Дисковод %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Розширені образи секторів" + +msgid "Flux images" +msgstr "Образи Flux" + +msgid "Unable to initialize FreeType" +msgstr "Неможливо ініціалізувати FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Неможливо ініціалізувати SDL, потрібно SDL2.dll" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Ви впевнені, що хочете вийти з 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Неможливо ініціалізувати Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "Магнітооптичний %i (%ls): %ls" + +msgid "MO images" +msgstr "Образи магнітооптичних дисків" + +msgid "Welcome to 86Box!" +msgstr "Ласкаво просимо в 86Box!" + +msgid "Internal controller" +msgstr "Вбудований контролер" + +msgid "Exit" +msgstr "Вихід" + +msgid "No ROMs found" +msgstr "ПЗУ не знайдені" + +msgid "Do you want to save the settings?" +msgstr "Чи бажаєте ви зберегти налаштування?" + +msgid "This will hard reset the emulated machine." +msgstr "Це призведе до холодної перезагрузки емульованої машини." + +msgid "Save" +msgstr "Зберегти" + +msgid "About 86Box" +msgstr "Про 86Box" + +msgid "86Box v" +msgstr "86Box v." + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Емулятор старих комп'ютерів\n\nАвтори: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nВипускаєтся під ліцензією GNU General Public License версії 2 або більше пізніше. Додадкову інформацію см. у файлі LICENSE." + +msgid "Hardware not available" +msgstr "Обладнання недоступне" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Переконайтесь, що libpcap встановлений і ваше мережеве з'єднання, сумісне з libpcap." + +msgid "Invalid configuration" +msgstr "Неприпустима конфігурація" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr "Для емуляції принтера ESC/P потрібно libfreetype." + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nВсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr "Для FluidSynth MIDI-висновку потрібно libfluidsynth." + +msgid "Entering fullscreen mode" +msgstr "Вхід у повноекранний режим" + +msgid "Don't show this message again" +msgstr "Більше не показувати це повідомлення" + +msgid "Don't exit" +msgstr "Не виходити" + +msgid "Reset" +msgstr "Перезавантажити" + +msgid "Don't reset" +msgstr "Не перезавантажувати" + +msgid "CD-ROM images" +msgstr "Образи CD-ROM" + +msgid "%hs Device Configuration" +msgstr "Конфігурація пристрою %hs" + +msgid "Monitor in sleep mode" +msgstr "Монітор у сплячому режимі" + +msgid "OpenGL Shaders" +msgstr "Шейдери OpenGL" + +msgid "OpenGL options" +msgstr "Параметри OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Ви завантажуєте непідтримувану конфігурацію" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Вибір типів ЦП для цієї системної плати на даній емульованій машині відключено.\n\nЦе дозволяє вибрати процесор, який в іншому випадку не сумісний з вибраною материнською платою. Однак, ви можете зіткнутися з несумісністю з BIOS материнської плати або іншим ПО.\n\nВключення цього параметра офіційно не підтримується, і всі подані звіти про помилки можуть бути закриті як недійсні." + +msgid "Continue" +msgstr "Продовжити" + +msgid "Cassette: %s" +msgstr "Касета: %s" + +msgid "Cassette images" +msgstr "Образи касет" + +msgid "Cartridge %i: %ls" +msgstr "Картридж %i: %ls" + +msgid "Cartridge images" +msgstr "Образи картриджів" + +msgid "Error initializing renderer" +msgstr "Помилка ініціалізації рендерера" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Неможливо ініціалізувати рендерер OpenGL (3.0). Будь ласка, використовуйте інший рендерер." + +msgid "Resume execution" +msgstr "Відновити виконання" + +msgid "Pause execution" +msgstr "Призупинити виконання" + +msgid "Press Ctrl+Alt+Del" +msgstr "Натиснути Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Натиснути Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Холодне перезавантаження" + +msgid "ACPI shutdown" +msgstr "Сигнал завершення ACPI" + +msgid "Hard disk (%s)" +msgstr "Жорсткий диск (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLL або ESDI дисководів CD-ROM ніколи не існувало" + +msgid "Custom..." +msgstr "Задати вручну..." + +msgid "Custom (large)..." +msgstr "Задати вручну (large)..." + +msgid "Add New Hard Disk" +msgstr "Створити новий жорсткий диск" + +msgid "Add Existing Hard Disk" +msgstr "Вибрати існуючий жорсткий диск" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Розмір образів дисків HDI не може перевищувати 4 ГБ." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Розмір образів дисків не може перевищувати 127 ГБ." + +msgid "Hard disk images" +msgstr "Образи жорстких дисків" + +msgid "Unable to read file" +msgstr "Неможливо прочитати файл" + +msgid "Unable to write file" +msgstr "Неможливо записати файл" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Образи HDI або HDX з розміром сектора, відмінним від 512, не підтримуються." + +msgid "USB is not yet supported" +msgstr "USB поки не підтримується" + +msgid "Disk image file already exists" +msgstr "Файл образу диска вже існує" + +msgid "Please specify a valid file name." +msgstr "Вкажіть правильне ім'я файлу." + +msgid "Disk image created" +msgstr "Образ диску створено" + +msgid "Make sure the file exists and is readable." +msgstr "Переконайтеся, що файл є доступним для читання." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Переконайтеся, що файл зберігається в каталог, який є доступним для запису." + +msgid "Disk image too large" +msgstr "Занадто великий образ диска" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Не забудьте розмітити та відформатувати новостворений диск." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Вибраний файл буде перезаписано. Ви впевнені, що хочете використовувати його?" + +msgid "Unsupported disk image" +msgstr "Образ диска, що не підтримується" + +msgid "Overwrite" +msgstr "Перезаписати" + +msgid "Don't overwrite" +msgstr "Не перезаписувати" + +msgid "Raw image (.img)" +msgstr "RAW образ (.img)" + +msgid "HDI image (.hdi)" +msgstr "Образ HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Образ HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD фіксованого розміру (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD динамічного розміру (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Диференційований образ VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Великі блоки (2 МБ)" + +msgid "Small blocks (512 KB)" +msgstr "Маленькі блоки (512 КБ)" + +msgid "VHD files" +msgstr "Файли VHD" + +msgid "Select the parent VHD" +msgstr "Виберіть батьківський VHD" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Це може означати, що батьківський образ був змінений після того, як було створено диференційований образ.\n\nЦе також може статися, якщо файли зображення були переміщені або скопійовані, або через помилку в програмі, що створила цей диск.\n \nВи хочете виправити тимчасові позначки?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Тимчасові мітки батьківського та дочірнього дисків не співпадають" + +msgid "Could not fix VHD timestamp." +msgstr "Не вдалося виправити тимчасову позначку VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 кБ" + +msgid "180 kB" +msgstr "180 кБ" + +msgid "320 kB" +msgstr "320 кБ" + +msgid "360 kB" +msgstr "360 кБ" + +msgid "640 kB" +msgstr "640 кБ" + +msgid "720 kB" +msgstr "720 кБ" + +msgid "1.2 MB" +msgstr "1.2 МБ" + +msgid "1.25 MB" +msgstr "1.25 МБ" + +msgid "1.44 MB" +msgstr "1.44 МБ" + +msgid "DMF (cluster 1024)" +msgstr "DMF (кластер 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (кластер 2048)" + +msgid "2.88 MB" +msgstr "2.88 МБ" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5\" 128Мб M.O. (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5\" 230Мб M.O. (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5\" 540Мб M.O. (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5\" 640Мб M.O. (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5\" 1.3Гб M.O. (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5\" 2.3Гб M.O. (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25\" 600Мб M.O." + +msgid "5.25\" 650Mb M.O." +msgstr "5.25\" 650Мб M.O." + +msgid "5.25\" 1Gb M.O." +msgstr "5.25\" 1Гб M.O." + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25\" 1.3Гб M.O." + +msgid "Perfect RPM" +msgstr "Точний RPM" + +msgid "1%% below perfect RPM" +msgstr "На 1% повільніше точного RPM" + +msgid "1.5%% below perfect RPM" +msgstr "На 1.5% повільніше точного RPM" + +msgid "2%% below perfect RPM" +msgstr "На 2% повільніше точного RPM" + +msgid "(System Default)" +msgstr "(Системний)" + diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po new file mode 100644 index 000000000..1d5a94da7 --- /dev/null +++ b/src/qt/languages/zh-CN.po @@ -0,0 +1,1215 @@ +msgid "&Action" +msgstr "操作(&A)" + +msgid "&Keyboard requires capture" +msgstr "键盘需要捕捉(&K)" + +msgid "&Right CTRL is left ALT" +msgstr "将右 CTRL 键映射为左 ALT 键(&R)" + +msgid "&Hard Reset..." +msgstr "硬重置(&H)..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "Ctrl+Alt+Del(&C)\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+Esc(&E)" + +msgid "&Pause" +msgstr "暂停(&P)" + +msgid "E&xit..." +msgstr "退出(&X)..." + +msgid "&View" +msgstr "查看(&V)" + +msgid "&Hide status bar" +msgstr "隐藏状态栏(&H)" + +msgid "Hide &toolbar" +msgstr "隐藏工具栏(&T)" + +msgid "&Resizeable window" +msgstr "窗口大小可调(&R)" + +msgid "R&emember size && position" +msgstr "记住窗口大小和位置(&E)" + +msgid "Re&nderer" +msgstr "渲染器(&N)" + +msgid "&SDL (Software)" +msgstr "SDL (软件)(&S)" + +msgid "SDL (&Hardware)" +msgstr "SDL (硬件)(&H)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (OpenGL)(&O)" + +msgid "Open&GL (3.0 Core)" +msgstr "OpenGL (3.0 核心)(&G)" + +msgid "&VNC" +msgstr "VNC(&V)" + +msgid "Specify dimensions..." +msgstr "指定窗口大小..." + +msgid "F&orce 4:3 display ratio" +msgstr "强制 4:3 显示比例(&O)" + +msgid "&Window scale factor" +msgstr "窗口缩放系数(&W)" + +msgid "&0.5x" +msgstr "0.5x(&0)" + +msgid "&1x" +msgstr "1x(&1)" + +msgid "1.&5x" +msgstr "1.5x(&5)" + +msgid "&2x" +msgstr "2x(&2)" + +msgid "Filter method" +msgstr "过滤方式" + +msgid "&Nearest" +msgstr "邻近(&N)" + +msgid "&Linear" +msgstr "线性(&L)" + +msgid "Hi&DPI scaling" +msgstr "HiDPI 缩放(&D)" + +msgid "&Fullscreen\tCtrl+Alt+PageUP" +msgstr "全屏(&F)\tCtrl+Alt+PageUP" + +msgid "Fullscreen &stretch mode" +msgstr "全屏拉伸模式(&S)" + +msgid "&Full screen stretch" +msgstr "全屏拉伸(&F)" + +msgid "&4:3" +msgstr "4:3(&4)" + +msgid "&Square pixels (Keep ratio)" +msgstr "保持比例(&S)" + +msgid "&Integer scale" +msgstr "整数比例(&I)" + +msgid "E&GA/(S)VGA settings" +msgstr "EGA/(S)VGA 设置(&G)" + +msgid "&Inverted VGA monitor" +msgstr "VGA 显示器反色显示(&I)" + +msgid "VGA screen &type" +msgstr "VGA 屏幕类型(&T)" + +msgid "RGB &Color" +msgstr "RGB 彩色(&C)" + +msgid "&RGB Grayscale" +msgstr "RGB 灰度(&R)" + +msgid "&Amber monitor" +msgstr "琥珀色单色显示器(&A)" + +msgid "&Green monitor" +msgstr "绿色单色显示器(&G)" + +msgid "&White monitor" +msgstr "白色单色显示器(&W)" + +msgid "Grayscale &conversion type" +msgstr "灰度转换类型(&C)" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT601 (NTSC/PAL)(&6)" + +msgid "BT&709 (HDTV)" +msgstr "BT709 (HDTV)(&7)" + +msgid "&Average" +msgstr "平均(&A)" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "CGA/PCjr/Tandy/EGA/(S)VGA 过扫描(&G)" + +msgid "Change contrast for &monochrome display" +msgstr "更改单色显示对比度(&M)" + +msgid "&Media" +msgstr "介质(&M)" + +msgid "&Tools" +msgstr "工具(&T)" + +msgid "&Settings..." +msgstr "设置(&S)..." + +msgid "&Update status bar icons" +msgstr "更新状态栏图标(&U)" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "截图(&C)\tCtrl+F11" + +msgid "&Preferences..." +msgstr "首选项(&P)..." + +msgid "Enable &Discord integration" +msgstr "启用 Discord 集成(&D)" + +msgid "Sound &gain..." +msgstr "音量增益(&G)..." + +msgid "Begin trace\tCtrl+T" +msgstr "开始追踪\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "结束追踪\tCtrl+T" + +msgid "&Logging" +msgstr "记录日志(&L)" + +msgid "Enable BusLogic logs\tCtrl+F4" +msgstr "启用 BusLogic 日志\tCtrl+F4" + +msgid "Enable CD-ROM logs\tCtrl+F5" +msgstr "启用 CD-ROM 日志\tCtrl+F5" + +msgid "Enable floppy (86F) logs\tCtrl+F6" +msgstr "启用软盘 (86F) 日志\tCtrl+F6" + +msgid "Enable floppy controller logs\tCtrl+F7" +msgstr "启用软盘控制器日志\tCtrl+F7" + +msgid "Enable IDE logs\tCtrl+F8" +msgstr "启用 IDE 日志\tCtrl+F8" + +msgid "Enable Serial Port logs\tCtrl+F3" +msgstr "启用串口日志\tCtrl+F3" + +msgid "Enable Network logs\tCtrl+F9" +msgstr "启用网络日志\tCtrl+F9" + +msgid "&Log breakpoint\tCtrl+F10" +msgstr "日志断点(&L)\tCtrl+F10" + +msgid "Dump &video RAM\tCtrl+F1" +msgstr "创建显卡内存转储(&V)\tCtrl+F1" + +msgid "&Help" +msgstr "帮助(&H)" + +msgid "&Documentation..." +msgstr "文档(&D)..." + +msgid "&About 86Box..." +msgstr "关于 86Box(&A)..." + +msgid "&New image..." +msgstr "新建镜像(&N)..." + +msgid "&Existing image..." +msgstr "打开已存在的镜像(&E)..." + +msgid "Existing image (&Write-protected)..." +msgstr "打开已存在的镜像并写保护(&W)..." + +msgid "&Record" +msgstr "录制(&R)" + +msgid "&Play" +msgstr "播放(&P)" + +msgid "&Rewind to the beginning" +msgstr "倒带至起点(&R)" + +msgid "&Fast forward to the end" +msgstr "快进至终点(&F)" + +msgid "E&ject" +msgstr "弹出(&J)" + +msgid "&Image..." +msgstr "镜像(&I)..." + +msgid "E&xport to 86F..." +msgstr "导出为 86F 格式(&x)..." + +msgid "&Mute" +msgstr "静音(&M)" + +msgid "E&mpty" +msgstr "空置驱动器(&M)" + +msgid "&Reload previous image" +msgstr "载入上一个镜像(&R)" + +msgid "&Image" +msgstr "镜像(&I)" + +msgid "Target &framerate" +msgstr "目标帧率(&F)" + +msgid "&Sync with video" +msgstr "与视频同步(&S)" + +msgid "&25 fps" +msgstr "25 fps(&2)" + +msgid "&30 fps" +msgstr "30 fps(&3)" + +msgid "&50 fps" +msgstr "50 fps(&5)" + +msgid "&60 fps" +msgstr "60 fps(&6)" + +msgid "&75 fps" +msgstr "75 fps(&7)" + +msgid "&VSync" +msgstr "垂直同步(&V)" + +msgid "&Select shader..." +msgstr "选择着色器(&S)..." + +msgid "&Remove shader" +msgstr "移除着色器(&R)" + +msgid "Preferences" +msgstr "首选项" + +msgid "Sound Gain" +msgstr "音量增益" + +msgid "New Image" +msgstr "新建镜像" + +msgid "Settings" +msgstr "设置" + +msgid "Specify Main Window Dimensions" +msgstr "指定主窗口大小" + +msgid "OK" +msgstr "确定" + +msgid "Cancel" +msgstr "取消" + +msgid "Save these settings as &global defaults" +msgstr "将以上设置存储为全局默认值(&G)" + +msgid "&Default" +msgstr "默认(&D)" + +msgid "Language:" +msgstr "语言:" + +msgid "Icon set:" +msgstr "图标集:" + +msgid "Gain" +msgstr "增益" + +msgid "File name:" +msgstr "文件名:" + +msgid "Disk size:" +msgstr "磁盘大小:" + +msgid "RPM mode:" +msgstr "转速 (RPM) 模式:" + +msgid "Progress:" +msgstr "进度:" + +msgid "Width:" +msgstr "宽度:" + +msgid "Height:" +msgstr "高度:" + +msgid "Lock to this size" +msgstr "锁定此大小" + +msgid "Machine type:" +msgstr "机器类型:" + +msgid "Machine:" +msgstr "机型:" + +msgid "Configure" +msgstr "配置" + +msgid "CPU type:" +msgstr "CPU 类型:" + +msgid "Speed:" +msgstr "速度:" + +msgid "FPU:" +msgstr "浮点处理器 (FPU):" + +msgid "Wait states:" +msgstr "等待状态 (WS):" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "内存:" + +msgid "Time synchronization" +msgstr "时间同步" + +msgid "Disabled" +msgstr "禁用" + +msgid "Enabled (local time)" +msgstr "启用 (本地时间)" + +msgid "Enabled (UTC)" +msgstr "启用 (UTC)" + +msgid "Dynamic Recompiler" +msgstr "动态重编译器" + +msgid "Video:" +msgstr "显卡:" + +msgid "Voodoo Graphics" +msgstr "Voodoo Graphics" + +msgid "Mouse:" +msgstr "鼠标:" + +msgid "Joystick:" +msgstr "操纵杆:" + +msgid "Joystick 1..." +msgstr "操纵杆 1..." + +msgid "Joystick 2..." +msgstr "操纵杆 2..." + +msgid "Joystick 3..." +msgstr "操纵杆 3..." + +msgid "Joystick 4..." +msgstr "操纵杆 4..." + +msgid "Sound card:" +msgstr "声卡:" + +msgid "MIDI Out Device:" +msgstr "MIDI 输出设备:" + +msgid "MIDI In Device:" +msgstr "MIDI 输入设备:" + +msgid "Standalone MPU-401" +msgstr "独立 MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "使用单精度浮点 (FLOAT32)" + +msgid "Network type:" +msgstr "网络类型:" + +msgid "PCap device:" +msgstr "PCap 设备:" + +msgid "Network adapter:" +msgstr "网络适配器:" + +msgid "COM1 Device:" +msgstr "COM1 设备:" + +msgid "COM2 Device:" +msgstr "COM2 设备:" + +msgid "COM3 Device:" +msgstr "COM3 设备:" + +msgid "COM4 Device:" +msgstr "COM4 设备:" + +msgid "LPT1 Device:" +msgstr "LPT1 设备:" + +msgid "LPT2 Device:" +msgstr "LPT2 设备:" + +msgid "LPT3 Device:" +msgstr "LPT3 设备:" + +msgid "LPT4 Device:" +msgstr "LPT4 设备:" + +msgid "Serial port 1" +msgstr "串口 1" + +msgid "Serial port 2" +msgstr "串口 2" + +msgid "Serial port 3" +msgstr "串口 3" + +msgid "Serial port 4" +msgstr "串口 4" + +msgid "Parallel port 1" +msgstr "并口 1" + +msgid "Parallel port 2" +msgstr "并口 2" + +msgid "Parallel port 3" +msgstr "并口 3" + +msgid "Parallel port 4" +msgstr "并口 4" + +msgid "HD Controller:" +msgstr "硬盘控制器:" + +msgid "FD Controller:" +msgstr "软盘控制器:" + +msgid "Tertiary IDE Controller" +msgstr "第三 IDE 控制器" + +msgid "Quaternary IDE Controller" +msgstr "第四 IDE 控制器" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "控制器 1:" + +msgid "Controller 2:" +msgstr "控制器 2:" + +msgid "Controller 3:" +msgstr "控制器 3:" + +msgid "Controller 4:" +msgstr "控制器 4:" + +msgid "Cassette" +msgstr "磁带" + +msgid "Hard disks:" +msgstr "硬盘:" + +msgid "&New..." +msgstr "新建(&N)..." + +msgid "&Existing..." +msgstr "已有镜像(&E)..." + +msgid "&Remove" +msgstr "移除(&R)" + +msgid "Bus:" +msgstr "总线:" + +msgid "Channel:" +msgstr "通道:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "指定(&S)..." + +msgid "Sectors:" +msgstr "扇区(S):" + +msgid "Heads:" +msgstr "磁头(H):" + +msgid "Cylinders:" +msgstr "柱面(C):" + +msgid "Size (MB):" +msgstr "大小 (MB):" + +msgid "Type:" +msgstr "类型:" + +msgid "Image Format:" +msgstr "镜像格式:" + +msgid "Block Size:" +msgstr "块大小:" + +msgid "Floppy drives:" +msgstr "软盘驱动器:" + +msgid "Turbo timings" +msgstr "加速时序" + +msgid "Check BPB" +msgstr "检查 BPB" + +msgid "CD-ROM drives:" +msgstr "光盘驱动器:" + +msgid "MO drives:" +msgstr "磁光盘驱动器:" + +msgid "ZIP drives:" +msgstr "ZIP 驱动器:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA 实时时钟:" + +msgid "ISA Memory Expansion" +msgstr "ISA 内存扩充" + +msgid "Card 1:" +msgstr "扩展卡 1:" + +msgid "Card 2:" +msgstr "扩展卡 2:" + +msgid "Card 3:" +msgstr "扩展卡 3:" + +msgid "Card 4:" +msgstr "扩展卡 4:" + +msgid "ISABugger device" +msgstr "ISABugger 设备" + +msgid "POST card" +msgstr "自检 (POST) 卡" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Microsoft YaHei" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "错误" + +msgid "Fatal error" +msgstr "致命错误" + +msgid "" +msgstr "" + +msgid "Press CTRL+ALT+PAGE DOWN to return to windowed mode." +msgstr "按 CTRL+ALT+PAGE DOWN 组合键返回到窗口模式。" + +msgid "Speed" +msgstr "速度" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIP 镜像" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box 找不到任何可用的 ROM 镜像。\n\n请下载ROM 包并将其解压到 \"roms\" 文件夹。" + +msgid "(empty)" +msgstr "(空)" + +msgid "All files" +msgstr "所有文件" + +msgid "Turbo" +msgstr "加速" + +msgid "On" +msgstr "开" + +msgid "Off" +msgstr "关" + +msgid "All images" +msgstr "所有镜像" + +msgid "Basic sector images" +msgstr "基本扇区镜像" + +msgid "Surface images" +msgstr "表面镜像" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "由于 roms/machines 文件夹中缺少合适的 ROM,机型 \"%hs\" 不可用。将切换到其他可用机型。" + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "由于 roms/video 文件夹中缺少合适的 ROM,显卡 \"%hs\" 不可用。将切换到其他可用显卡。" + +msgid "Machine" +msgstr "机型" + +msgid "Display" +msgstr "显示" + +msgid "Input devices" +msgstr "输入设备" + +msgid "Sound" +msgstr "声音" + +msgid "Network" +msgstr "网络" + +msgid "Ports (COM & LPT)" +msgstr "端口 (COM 和 LPT)" + +msgid "Storage controllers" +msgstr "存储控制器" + +msgid "Hard disks" +msgstr "硬盘" + +msgid "Floppy & CD-ROM drives" +msgstr "软盘/光盘驱动器" + +msgid "Other removable devices" +msgstr "其他可移动设备" + +msgid "Other peripherals" +msgstr "其他外围设备" + +msgid "Click to capture mouse" +msgstr "单击窗口捕捉鼠标" + +msgid "Press F8+F12 to release mouse" +msgstr "按 F8+F12 释放鼠标" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "按 F8+F12 或鼠标中键释放鼠标" + +msgid "Unable to initialize FluidSynth" +msgstr "无法初始化 FluidSynth" + +msgid "Bus" +msgstr "总线" + +msgid "File" +msgstr "文件" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "无法初始化视频渲染器。" + +msgid "Default" +msgstr "默认" + +msgid "%i Wait state(s)" +msgstr "%i 等待状态 (WS)" + +msgid "Type" +msgstr "类型" + +msgid "Failed to set up PCap" +msgstr "设置 PCap 失败" + +msgid "No PCap devices found" +msgstr "未找到 PCap 设备" + +msgid "Invalid PCap device" +msgstr "无效 PCap 设备" + +msgid "Standard 2-button joystick(s)" +msgstr "标准 2 键操纵杆" + +msgid "Standard 4-button joystick" +msgstr "标准 4 键操纵杆" + +msgid "Standard 6-button joystick" +msgstr "标准 6 键操纵杆" + +msgid "Standard 8-button joystick" +msgstr "标准 8 键操纵杆" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "无" + +msgid "Unable to load keyboard accelerators." +msgstr "无法加载键盘加速器。" + +msgid "Unable to register raw input." +msgstr "无法注册原始输入。" + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "软盘 %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "高级扇区镜像" + +msgid "Flux images" +msgstr "Flux 镜像" + +msgid "Unable to initialize FreeType" +msgstr "无法初始化 FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "无法初始化 SDL,需要 SDL2.dll" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "确定要硬重置模拟器吗?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "确定要退出 86Box 吗?" + +msgid "Unable to initialize Ghostscript" +msgstr "无法初始化 Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "磁光盘 %i (%ls): %ls" + +msgid "MO images" +msgstr "磁光盘镜像" + +msgid "Welcome to 86Box!" +msgstr "欢迎使用 86Box!" + +msgid "Internal controller" +msgstr "内部控制器" + +msgid "Exit" +msgstr "退出" + +msgid "No ROMs found" +msgstr "找不到 ROM" + +msgid "Do you want to save the settings?" +msgstr "要保存设置吗?" + +msgid "This will hard reset the emulated machine." +msgstr "此操作将硬重置模拟器。" + +msgid "Save" +msgstr "保存" + +msgid "About 86Box" +msgstr "关于 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "一个旧式计算机模拟器\n\n作者: Sarah Walker、Miran Grca、Fred N. van Kempen (waltje)、SA1988、Tiseno100、reenigne、leilei、JohnElliott、greatpsycho 等人。\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布。详情见 LICENSE 文件。" + +msgid "Hardware not available" +msgstr "硬件不可用" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "请确认 libpcap 已安装且使用兼容 libpcap 的网络连接。" + +msgid "Invalid configuration" +msgstr "无效配置" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr "ESC/P 打印机模拟需要" + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr "FluidSynth MIDI 输出需要" + +msgid "Entering fullscreen mode" +msgstr "正在进入全屏模式" + +msgid "Don't show this message again" +msgstr "不要再显示此消息" + +msgid "Don't exit" +msgstr "不退出" + +msgid "Reset" +msgstr "重置" + +msgid "Don't reset" +msgstr "不重置" + +msgid "CD-ROM images" +msgstr "光盘镜像" + +msgid "%hs Device Configuration" +msgstr "%hs 设备配置" + +msgid "Monitor in sleep mode" +msgstr "显示器处在睡眠状态" + +msgid "OpenGL Shaders" +msgstr "OpenGL 着色器" + +msgid "OpenGL options" +msgstr "OpenGL 选项" + +msgid "You are loading an unsupported configuration" +msgstr "正在载入一个不受支持的配置" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "此模拟计算机禁用了基于选定计算机的 CPU 类型过滤。\n\n能够选中与所选机器本不兼容的 CPU,但是可能会遇到与机器 BIOS 或其他软件不兼容的问题。\n\n启用此设置不受官方支持,并且提交的任何错误报告可能会视为无效而关闭。" + +msgid "Continue" +msgstr "继续" + +msgid "Cassette: %s" +msgstr "磁带: %s" + +msgid "Cassette images" +msgstr "磁带镜像" + +msgid "Cartridge %i: %ls" +msgstr "卡带 %i: %ls" + +msgid "Cartridge images" +msgstr "卡带镜像" + +msgid "Error initializing renderer" +msgstr "初始化渲染器时出错" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "无法初始化 OpenGL (3.0 核心) 渲染器。请使用其他渲染器。" + +msgid "Resume execution" +msgstr "恢复执行" + +msgid "Pause execution" +msgstr "暂停执行" + +msgid "Press Ctrl+Alt+Del" +msgstr "按 Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "按 Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "硬重置" + +msgid "ACPI shutdown" +msgstr "ACPI 关机" + +msgid "Hard disk (%s)" +msgstr "硬盘 (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "不存在 MFM/RLL 或 ESDI CD-ROM 驱动器" + +msgid "Custom..." +msgstr "自定义..." + +msgid "Custom (large)..." +msgstr "自定义 (大容量)..." + +msgid "Add New Hard Disk" +msgstr "添加新硬盘" + +msgid "Add Existing Hard Disk" +msgstr "添加已存在的硬盘" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "HDI 磁盘镜像不能超过 4 GB。" + +msgid "Disk images cannot be larger than 127 GB." +msgstr "磁盘镜像不能超过 127 GB。" + +msgid "Hard disk images" +msgstr "硬盘镜像" + +msgid "Unable to read file" +msgstr "无法读取文件" + +msgid "Unable to write file" +msgstr "无法写入文件" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "不支持非 512 字节扇区大小的 HDI 或 HDX 镜像。" + +msgid "USB is not yet supported" +msgstr "尚未支持 USB" + +msgid "Disk image file already exists" +msgstr "磁盘镜像文件已存在" + +msgid "Please specify a valid file name." +msgstr "请指定有效的文件名。" + +msgid "Disk image created" +msgstr "已创建磁盘镜像" + +msgid "Make sure the file exists and is readable." +msgstr "请确定此文件已存在并可读取。" + +msgid "Make sure the file is being saved to a writable directory." +msgstr "请确定此文件保存在可写目录中。" + +msgid "Disk image too large" +msgstr "磁盘镜像太大" + +msgid "Remember to partition and format the newly-created drive." +msgstr "请记得为新创建的镜像分区并格式化。" + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "选定的文件将被覆盖。确定继续使用此文件吗?" + +msgid "Unsupported disk image" +msgstr "不支持的磁盘镜像" + +msgid "Overwrite" +msgstr "覆盖" + +msgid "Don't overwrite" +msgstr "不覆盖" + +msgid "Raw image (.img)" +msgstr "原始镜像 (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI 镜像 (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX 镜像 (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "固定大小 VHD (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "动态大小 VHD (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "差分 VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "大块 (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "小块 (512 KB)" + +msgid "VHD files" +msgstr "VHD 文件" + +msgid "Select the parent VHD" +msgstr "选择父 VHD 文件" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "父映像可能在创建差异镜像后被修改。\n\n如果镜像文件被移动或复制,或创建此磁盘的程序中存在错误,也可能发生这种情况。\n\n是否需要修复时间戳?" + +msgid "Parent and child disk timestamps do not match" +msgstr "父盘与子盘的时间戳不匹配" + +msgid "Could not fix VHD timestamp." +msgstr "无法修复 VHD 时间戳。" + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "光盘 %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (1024 簇)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (2048 簇)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128Mb M.O. (ISO 10090)" +msgstr "3.5 英寸 128Mb 磁光盘 (ISO 10090)" + +msgid "3.5\" 230Mb M.O. (ISO 13963)" +msgstr "3.5 英寸 230Mb 磁光盘 (ISO 13963)" + +msgid "3.5\" 540Mb M.O. (ISO 15498)" +msgstr "3.5 英寸 540Mb 磁光盘 (ISO 15498)" + +msgid "3.5\" 640Mb M.O. (ISO 15498)" +msgstr "3.5 英寸 640Mb 磁光盘 (ISO 15498)" + +msgid "3.5\" 1.3Gb M.O. (GigaMO)" +msgstr "3.5 英寸 1.3Gb 磁光盘 (GigaMO)" + +msgid "3.5\" 2.3Gb M.O. (GigaMO 2)" +msgstr "3.5 英寸 2.3Gb 磁光盘 (GigaMO 2)" + +msgid "5.25\" 600Mb M.O." +msgstr "5.25 英寸 600Mb 磁光盘" + +msgid "5.25\" 650Mb M.O." +msgstr "5.25 英寸 650Mb 磁光盘" + +msgid "5.25\" 1Gb M.O." +msgstr "5.25 英寸 1Gb 磁光盘" + +msgid "5.25\" 1.3Gb M.O." +msgstr "5.25 英寸 1.3Gb 磁光盘" + +msgid "Perfect RPM" +msgstr "标准转速 (RPM)" + +msgid "1%% below perfect RPM" +msgstr "低于标准转速的 1%%" + +msgid "1.5%% below perfect RPM" +msgstr "低于标准转速的 1.5%%" + +msgid "2%% below perfect RPM" +msgstr "低于标准转速的 2%%" + +msgid "(System Default)" +msgstr "(系统默认)" + diff --git a/src/qt/macos_event_filter.mm b/src/qt/macos_event_filter.mm new file mode 100644 index 000000000..0ea799f99 --- /dev/null +++ b/src/qt/macos_event_filter.mm @@ -0,0 +1,103 @@ +#include +//#include "86box/plat.h" +#include "cocoa_mouse.hpp" +#import +extern "C" +{ +#include <86box/86box.h> +#include <86box/keyboard.h> +#include <86box/mouse.h> +#include <86box/config.h> +//#include <86box/plat.h> +#include <86box/plat_dynld.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/ui.h> +#include <86box/video.h> +extern int mouse_capture; +extern void plat_mouse_capture(int); +} + +typedef struct mouseinputdata +{ + int deltax, deltay, deltaz; + int mousebuttons; +} mouseinputdata; + +static mouseinputdata mousedata; + +CocoaEventFilter::~CocoaEventFilter() +{ + +} + +bool CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) +{ + if (mouse_capture) + { + if (eventType == "mac_generic_NSEvent") + { + NSEvent* event = (NSEvent*)message; + if ([event type] == NSEventTypeMouseMoved + || [event type] == NSEventTypeLeftMouseDragged + || [event type] == NSEventTypeRightMouseDragged + || [event type] == NSEventTypeOtherMouseDragged) + { + mousedata.deltax += [event deltaX]; + mousedata.deltay += [event deltaY]; + return true; + } + if ([event type] == NSEventTypeScrollWheel) + { + mousedata.deltaz += [event deltaY]; + return true; + } + switch ([event type]) + { + default: return false; + case NSEventTypeLeftMouseDown: + { + mousedata.mousebuttons |= 1; + break; + } + case NSEventTypeLeftMouseUp: + { + mousedata.mousebuttons &= ~1; + break; + } + case NSEventTypeRightMouseDown: + { + mousedata.mousebuttons |= 2; + break; + } + case NSEventTypeRightMouseUp: + { + mousedata.mousebuttons &= ~2; + break; + } + case NSEventTypeOtherMouseDown: + { + mousedata.mousebuttons |= 4; + break; + } + case NSEventTypeOtherMouseUp: + { + if (mouse_get_buttons() < 3) { plat_mouse_capture(0); return true; } + mousedata.mousebuttons &= ~4; + break; + } + } + return true; + } + } + return false; +} + +extern "C" void macos_poll_mouse() +{ + mouse_x = mousedata.deltax; + mouse_y = mousedata.deltay; + mouse_z = mousedata.deltaz; + mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; + mouse_buttons = mousedata.mousebuttons; +} diff --git a/src/qt/qt.c b/src/qt/qt.c new file mode 100644 index 000000000..507645c84 --- /dev/null +++ b/src/qt/qt.c @@ -0,0 +1,63 @@ +/* + * C functionality for Qt platform, where the C equivalent is not easily + * implemented in Qt + */ +#if !defined(_WIN32) || !defined(__clang__) +#include +#endif +#include +#include +#include + +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/plat.h> +#include <86box/timer.h> +#include <86box/nvr.h> + +int qt_nvr_save(void) { + return nvr_save(); +} + +char icon_set[256] = ""; /* name of the iconset to be used */ + +int +plat_vidapi(char* api) { + if (!strcasecmp(api, "default") || !strcasecmp(api, "system")) { + return 0; + } else if (!strcasecmp(api, "qt_software")) { + return 0; + } else if (!strcasecmp(api, "qt_opengl")) { + return 1; + } else if (!strcasecmp(api, "qt_opengles")) { + return 2; + } else if (!strcasecmp(api, "qt_opengl3")) { + return 3; + } + + return 0; +} + +char* plat_vidapi_name(int api) { + char* name = "default"; + + switch (api) { + case 0: + name = "qt_software"; + break; + case 1: + name = "qt_opengl"; + break; + case 2: + name = "qt_opengles"; + break; + case 3: + name = "qt_opengl3"; + break; + default: + fatal("Unknown renderer: %i\n", api); + break; + } + + return name; +} diff --git a/src/qt/qt_cdrom.c b/src/qt/qt_cdrom.c new file mode 100644 index 000000000..a15e9c600 --- /dev/null +++ b/src/qt/qt_cdrom.c @@ -0,0 +1,55 @@ +/* + * 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. + * + * Handle the platform-side of CDROM/ZIP/MO drives. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. + */ + +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/config.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/cassette.h> +#include <86box/cartridge.h> +#include <86box/fdd.h> +#include <86box/hdd.h> +#include <86box/scsi_device.h> +#include <86box/cdrom.h> +#include <86box/mo.h> +#include <86box/zip.h> +#include <86box/scsi_disk.h> +#include <86box/plat.h> +#include <86box/ui.h> + +void +plat_cdrom_ui_update(uint8_t id, uint8_t reload) +{ + cdrom_t *drv = &cdrom[id]; + + if (drv->host_drive == 0) { + ui_sb_update_icon_state(SB_CDROM|id, 1); + } else { + ui_sb_update_icon_state(SB_CDROM|id, 0); + } + + //media_menu_update_cdrom(id); + ui_sb_update_tip(SB_CDROM|id); +} diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp new file mode 100644 index 000000000..32e202e76 --- /dev/null +++ b/src/qt/qt_deviceconfig.cpp @@ -0,0 +1,213 @@ +#include "qt_deviceconfig.hpp" +#include "ui_qt_deviceconfig.h" + +#include +#include +#include +#include +#include + +extern "C" { +#include <86box/86box.h> +#include <86box/config.h> +#include <86box/device.h> +#include <86box/midi_rtmidi.h> +} + +#include "qt_filefield.hpp" +#include "qt_models_common.hpp" + +DeviceConfig::DeviceConfig(QWidget *parent) : + QDialog(parent), + ui(new Ui::DeviceConfig) +{ + ui->setupUi(this); +} + +DeviceConfig::~DeviceConfig() +{ + delete ui; +} + +void DeviceConfig::ConfigureDevice(const _device_* device, int instance) { + DeviceConfig dc; + dc.setWindowTitle(QString("%1 Device Configuration").arg(device->name)); + + device_context_t device_context; + device_set_context(&device_context, device, instance); + + const auto* config = device->config; + while (config->type != -1) { + switch (config->type) { + case CONFIG_BINARY: + { + auto value = config_get_int(device_context.name, const_cast(config->name), config->default_int); + auto* cbox = new QCheckBox(); + cbox->setObjectName(config->name); + cbox->setChecked(value > 0); + dc.ui->formLayout->addRow(config->description, cbox); + break; + } + case CONFIG_MIDI: + { + auto* cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto* model = cbox->model(); + int currentIndex = -1; + int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); + for (int i = 0; i < rtmidi_get_num_devs(); i++) { + char midiName[512] = { 0 }; + rtmidi_get_dev_name(i, midiName); + + Models::AddEntry(model, midiName, i); + if (selected == i) { + currentIndex = i; + } + } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } + case CONFIG_MIDI_IN: + { + auto* cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto* model = cbox->model(); + int currentIndex = -1; + int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); + for (int i = 0; i < rtmidi_in_get_num_devs(); i++) { + char midiName[512] = { 0 }; + rtmidi_in_get_dev_name(i, midiName); + + Models::AddEntry(model, midiName, i); + if (selected == i) { + currentIndex = i; + } + } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } + case CONFIG_SELECTION: + case CONFIG_HEX16: + case CONFIG_HEX20: + { + auto* cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto* model = cbox->model(); + int currentIndex = -1; + int selected; + switch (config->type) { + case CONFIG_SELECTION: + selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); + break; + case CONFIG_HEX16: + selected = config_get_hex16(device_context.name, const_cast(config->name), config->default_int); + break; + case CONFIG_HEX20: + selected = config_get_hex20(device_context.name, const_cast(config->name), config->default_int); + break; + } + + for (auto* sel = config->selection; (sel->description != nullptr) && (strlen(sel->description) > 0); ++sel) { + int row = Models::AddEntry(model, sel->description, sel->value); + if (selected == sel->value) { + currentIndex = row; + } + } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } + case CONFIG_SPINNER: + { + int value = config_get_int(device_context.name, const_cast(config->name), config->default_int); + auto* spinBox = new QSpinBox(); + spinBox->setObjectName(config->name); + spinBox->setMaximum(config->spinner.max); + spinBox->setMinimum(config->spinner.min); + if (config->spinner.step > 0) { + spinBox->setSingleStep(config->spinner.step); + } + spinBox->setValue(value); + dc.ui->formLayout->addRow(config->description, spinBox); + break; + } + case CONFIG_FNAME: + { + auto* fileName = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); + auto* fileField = new FileField(); + fileField->setObjectName(config->name); + fileField->setFileName(fileName); + fileField->setFilter(QString(config->file_filter).left(strcspn(config->file_filter, "|"))); + dc.ui->formLayout->addRow(config->description, fileField); + break; + } + } + ++config; + } + + dc.setFixedSize(dc.minimumSizeHint()); + int res = dc.exec(); + if (res == QDialog::Accepted) { + config = device->config; + while (config->type != -1) { + switch (config->type) { + case CONFIG_BINARY: + { + auto* cbox = dc.findChild(config->name); + config_set_int(device_context.name, const_cast(config->name), cbox->isChecked() ? 1 : 0); + break; + } + case CONFIG_MIDI: + case CONFIG_MIDI_IN: + case CONFIG_SELECTION: + { + auto* cbox = dc.findChild(config->name); + config_set_int(device_context.name, const_cast(config->name), cbox->currentData().toInt()); + break; + } + case CONFIG_HEX16: + { + auto* cbox = dc.findChild(config->name); + config_set_hex16(device_context.name, const_cast(config->name), cbox->currentData().toInt()); + break; + } + case CONFIG_HEX20: + { + auto* cbox = dc.findChild(config->name); + config_set_hex20(device_context.name, const_cast(config->name), cbox->currentData().toInt()); + break; + } + case CONFIG_FNAME: + { + auto* fbox = dc.findChild(config->name); + auto fileName = fbox->fileName().toUtf8(); + config_set_string(device_context.name, const_cast(config->name), fileName.data()); + break; + } + case CONFIG_SPINNER: + { + auto* spinBox = dc.findChild(config->name); + config_set_int(device_context.name, const_cast(config->name), spinBox->value()); + break; + } + } + config++; + } + } +} + +QString DeviceConfig::DeviceName(const _device_* device, const char *internalName, int bus) { + if (QStringLiteral("none") == internalName) { + return tr("None"); + } else if (QStringLiteral("internal") == internalName) { + return tr("Internal controller"); + } else if (device == nullptr) { + return QString(); + } else { + char temp[512]; + device_get_name(device, bus, temp); + return tr(temp, nullptr, 512); + } +} diff --git a/src/qt/qt_deviceconfig.hpp b/src/qt/qt_deviceconfig.hpp new file mode 100644 index 000000000..8062c1851 --- /dev/null +++ b/src/qt/qt_deviceconfig.hpp @@ -0,0 +1,28 @@ +#ifndef QT_DEVICECONFIG_HPP +#define QT_DEVICECONFIG_HPP + +#include + +extern "C" { +struct _device_; +} + +namespace Ui { +class DeviceConfig; +} + +class DeviceConfig : public QDialog +{ + Q_OBJECT + +public: + explicit DeviceConfig(QWidget *parent = nullptr); + ~DeviceConfig(); + + static void ConfigureDevice(const _device_* device, int instance = 0); + static QString DeviceName(const _device_* device, const char* internalName, int bus); +private: + Ui::DeviceConfig *ui; +}; + +#endif // QT_DEVICECONFIG_HPP diff --git a/src/qt/qt_deviceconfig.ui b/src/qt/qt_deviceconfig.ui new file mode 100644 index 000000000..0a7e7d974 --- /dev/null +++ b/src/qt/qt_deviceconfig.ui @@ -0,0 +1,74 @@ + + + DeviceConfig + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + DeviceConfig + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DeviceConfig + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/qt_filefield.cpp b/src/qt/qt_filefield.cpp new file mode 100644 index 000000000..770a244e0 --- /dev/null +++ b/src/qt/qt_filefield.cpp @@ -0,0 +1,41 @@ +#include "qt_filefield.hpp" +#include "ui_qt_filefield.h" + +#include + +FileField::FileField(QWidget *parent) : + QWidget(parent), + ui(new Ui::FileField) +{ + ui->setupUi(this); + + connect(ui->label, &QLineEdit::editingFinished, this, [this] () { + fileName_ = ui->label->text(); + emit fileSelected(ui->label->text()); + }); +} + +FileField::~FileField() +{ + delete ui; +} + +void FileField::setFileName(const QString &fileName) { + fileName_ = fileName; + ui->label->setText(fileName); +} + +void FileField::on_pushButton_clicked() { + QString fileName; + if (createFile_) { + fileName = QFileDialog::getSaveFileName(this, QString(), QString(), filter_, &selectedFilter_); + } else { + fileName = QFileDialog::getOpenFileName(this, QString(), QString(), filter_, &selectedFilter_); + } + + if (!fileName.isNull()) { + fileName_ = fileName; + ui->label->setText(fileName); + emit fileSelected(fileName); + } +} diff --git a/src/qt/qt_filefield.hpp b/src/qt/qt_filefield.hpp new file mode 100644 index 000000000..00c4a5e12 --- /dev/null +++ b/src/qt/qt_filefield.hpp @@ -0,0 +1,41 @@ +#ifndef QT_FILEFIELD_HPP +#define QT_FILEFIELD_HPP + +#include + +namespace Ui { +class FileField; +} + +class FileField : public QWidget +{ + Q_OBJECT + +public: + explicit FileField(QWidget *parent = nullptr); + ~FileField(); + + QString fileName() const { return fileName_; } + void setFileName(const QString& fileName); + + void setFilter(const QString& filter) { filter_ = filter; } + QString selectedFilter() const { return selectedFilter_; } + + void setCreateFile(bool createFile) { createFile_ = createFile; } + bool createFile() { return createFile_; } + +signals: + void fileSelected(const QString& fileName); + +private slots: + void on_pushButton_clicked(); + +private: + Ui::FileField *ui; + QString fileName_; + QString selectedFilter_; + QString filter_; + bool createFile_ = false; +}; + +#endif // QT_FILEFIELD_HPP diff --git a/src/qt/qt_filefield.ui b/src/qt/qt_filefield.ui new file mode 100644 index 000000000..457e3916a --- /dev/null +++ b/src/qt/qt_filefield.ui @@ -0,0 +1,62 @@ + + + FileField + + + + 0 + 0 + 354 + 25 + + + + + 0 + 0 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + &Specify... + + + + + + + + diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp new file mode 100644 index 000000000..2ed784a42 --- /dev/null +++ b/src/qt/qt_harddiskdialog.cpp @@ -0,0 +1,739 @@ +#include "qt_harddiskdialog.hpp" +#include "ui_qt_harddiskdialog.h" + +extern "C" { +#include <86box/86box.h> +#include <86box/hdd.h> +#include "../disk/minivhd/minivhd.h" +#include "../disk/minivhd/minivhd_util.h" +} + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "qt_harddrive_common.hpp" +#include "qt_models_common.hpp" +#include "qt_util.hpp" + +HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) : + QDialog(parent), + ui(new Ui::HarddiskDialog) +{ + ui->setupUi(this); + + ui->fileField->setFilter(tr("Hard disk images") % util::DlgFilter({ "hd?","im?","vhd" }) % tr("All files") % util::DlgFilter({ "*" }, true)); + if (existing) { + setWindowTitle(tr("Add Existing Hard Disk")); + ui->lineEditCylinders->setEnabled(false); + ui->lineEditHeads->setEnabled(false); + ui->lineEditSectors->setEnabled(false); + ui->lineEditSize->setEnabled(false); + ui->comboBoxType->setEnabled(false); + + ui->comboBoxFormat->hide(); + ui->labelFormat->hide(); + + connect(ui->fileField, &FileField::fileSelected, this, &HarddiskDialog::onExistingFileSelected); + } else { + setWindowTitle(tr("Add New Hard Disk")); + ui->fileField->setCreateFile(true); + } + + auto* model = ui->comboBoxFormat->model(); + model->insertRows(0, 6); + model->setData(model->index(0, 0), tr("Raw image (.img)")); + model->setData(model->index(1, 0), tr("HDI image (.hdi)")); + model->setData(model->index(2, 0), tr("HDX image (.hdx)")); + model->setData(model->index(3, 0), tr("Fixed-size VHD (.vhd)")); + model->setData(model->index(4, 0), tr("Dynamic-size VHD (.vhd)")); + model->setData(model->index(5, 0), tr("Differencing VHD (.vhd)")); + + model = ui->comboBoxBlockSize->model(); + model->insertRows(0, 2); + model->setData(model->index(0, 0), tr("Large blocks (2 MB)")); + model->setData(model->index(1, 0), tr("Small blocks (512 KB)")); + + ui->comboBoxBlockSize->hide(); + ui->labelBlockSize->hide(); + + Harddrives::populateBuses(ui->comboBoxBus->model()); + ui->comboBoxBus->setCurrentIndex(3); + + model = ui->comboBoxType->model(); + for (int i = 0; i < 127; i++) { + uint64_t size = ((uint64_t) hdd_table[i][0]) * hdd_table[i][1] * hdd_table[i][2]; + uint32_t size_mb = size >> 11LL; + //QString text = QString("%1 MiB (CHS: %2, %3, %4)").arg(size_mb).arg(hdd_table[i][0]).arg(hdd_table[i][1]).arg(hdd_table[i][2]); + QString text = QString::asprintf(tr("%u MB (CHS: %i, %i, %i)").toUtf8().constData(), (size_mb), (hdd_table[i][0]), (hdd_table[i][1]), (hdd_table[i][2])); + Models::AddEntry(model, text, i); + } + Models::AddEntry(model, tr("Custom..."), 127); + Models::AddEntry(model, tr("Custom (large)..."), 128); + + ui->lineEditSize->setValidator(new QIntValidator()); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + if (!existing) connect(ui->fileField, &FileField::fileSelected, this, [this] { + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); + }); +} + +HarddiskDialog::~HarddiskDialog() +{ + delete ui; +} + +uint8_t HarddiskDialog::bus() const { + return static_cast(ui->comboBoxBus->currentData().toUInt()); +} + +uint8_t HarddiskDialog::channel() const { + return static_cast(ui->comboBoxChannel->currentData().toUInt()); +} + +QString HarddiskDialog::fileName() const { + return ui->fileField->fileName(); +} + +void HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index) { + bool enabled; + if (index == 5) { /* They switched to a diff VHD; disable the geometry fields. */ + enabled = false; + ui->lineEditCylinders->setText(tr("(N/A)")); + ui->lineEditHeads->setText(tr("(N/A)")); + ui->lineEditSectors->setText(tr("(N/A)")); + ui->lineEditSize->setText(tr("(N/A)")); + } else { + enabled = true; + ui->lineEditCylinders->setText(QString::number(cylinders_)); + ui->lineEditHeads->setText(QString::number(heads_)); + ui->lineEditSectors->setText(QString::number(sectors_)); + recalcSize(); + } + ui->lineEditCylinders->setEnabled(enabled); + ui->lineEditHeads->setEnabled(enabled); + ui->lineEditSectors->setEnabled(enabled); + ui->lineEditSize->setEnabled(enabled); + ui->comboBoxType->setEnabled(enabled); + + if (index < 4) { + ui->comboBoxBlockSize->hide(); + ui->labelBlockSize->hide(); + } else { + ui->comboBoxBlockSize->show(); + ui->labelBlockSize->show(); + } +} + +/* If the disk geometry requested in the 86Box GUI is not compatible with the internal VHD geometry, + * we adjust it to the next-largest size that is compatible. On average, this will be a difference + * of about 21 MB, and should only be necessary for VHDs larger than 31.5 GB, so should never be more + * than a tenth of a percent change in size. + */ +static void adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry) +{ + if (_86box_geometry->cyl <= 65535) { + vhd_geometry->cyl = _86box_geometry->cyl; + vhd_geometry->heads = _86box_geometry->heads; + vhd_geometry->spt = _86box_geometry->spt; + return; + } + + int desired_sectors = _86box_geometry->cyl * _86box_geometry->heads * _86box_geometry->spt; + if (desired_sectors > 267321600) + desired_sectors = 267321600; + + int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */ + if (remainder > 0) + desired_sectors += (85680 - remainder); + + _86box_geometry->cyl = desired_sectors / (16 * 63); + _86box_geometry->heads = 16; + _86box_geometry->spt = 63; + + vhd_geometry->cyl = desired_sectors / (16 * 255); + vhd_geometry->heads = 16; + vhd_geometry->spt = 255; +} + +static HarddiskDialog* callbackPtr = nullptr; +static MVHDGeom create_drive_vhd_fixed(const QString& fileName, HarddiskDialog* p, uint16_t cyl, uint8_t heads, uint8_t spt) { + MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt }; + MVHDGeom vhd_geometry; + adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry); + + int vhd_error = 0; + QByteArray filenameBytes = fileName.toUtf8(); + callbackPtr = p; + MVHDMeta *vhd = mvhd_create_fixed(filenameBytes.data(), vhd_geometry, &vhd_error, [](uint32_t current_sector, uint32_t total_sectors) { + callbackPtr->fileProgress((current_sector * 100) / total_sectors); + }); + callbackPtr = nullptr; + + if (vhd == NULL) { + _86box_geometry.cyl = 0; + _86box_geometry.heads = 0; + _86box_geometry.spt = 0; + } else { + mvhd_close(vhd); + } + + return _86box_geometry; +} + +static MVHDGeom create_drive_vhd_dynamic(const QString& fileName, uint16_t cyl, uint8_t heads, uint8_t spt, int blocksize) { + MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt }; + MVHDGeom vhd_geometry; + adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry); + int vhd_error = 0; + QByteArray filenameBytes = fileName.toUtf8(); + MVHDCreationOptions options; + options.block_size_in_sectors = blocksize; + options.path = filenameBytes.data(); + options.size_in_bytes = 0; + options.geometry = vhd_geometry; + options.type = MVHD_TYPE_DYNAMIC; + + MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); + if (vhd == NULL) { + _86box_geometry.cyl = 0; + _86box_geometry.heads = 0; + _86box_geometry.spt = 0; + } else { + mvhd_close(vhd); + } + + return _86box_geometry; +} + +static MVHDGeom create_drive_vhd_diff(const QString& fileName, const QString& parentFileName, int blocksize) { + int vhd_error = 0; + QByteArray filenameBytes = fileName.toUtf8(); + QByteArray parentFilenameBytes = fileName.toUtf8(); + MVHDCreationOptions options; + options.block_size_in_sectors = blocksize; + options.path = filenameBytes.data(); + options.parent_path = parentFilenameBytes.data(); + options.type = MVHD_TYPE_DIFF; + + MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); + MVHDGeom vhd_geometry; + if (vhd == NULL) { + vhd_geometry.cyl = 0; + vhd_geometry.heads = 0; + vhd_geometry.spt = 0; + } else { + vhd_geometry = mvhd_get_geometry(vhd); + + if (vhd_geometry.spt > 63) { + vhd_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63); + vhd_geometry.heads = 16; + vhd_geometry.spt = 63; + } + + mvhd_close(vhd); + } + + return vhd_geometry; +} + +void HarddiskDialog::onCreateNewFile() { + + for (auto& curObject : children()) + { + if (qobject_cast(curObject)) qobject_cast(curObject)->setDisabled(true); + } + + ui->progressBar->setEnabled(true); + setResult(QDialog::Rejected); + qint64 size = ui->lineEditSize->text().toUInt() << 20U; + if (size > 0x1FFFFFFE00ll) { + QMessageBox::critical(this, tr("Disk image too large"), tr("Disk images cannot be larger than 127 GB.")); + return; + } + + int img_format = ui->comboBoxFormat->currentIndex(); + uint32_t zero = 0; + uint32_t base = 0x1000; + uint32_t sector_size = 512; + + auto fileName = ui->fileField->fileName(); + QString expectedSuffix; + switch (img_format) { + case 1: + expectedSuffix = "hdi"; + break; + case 2: + expectedSuffix = "hdx"; + break; + case 3: + case 4: + case 5: + expectedSuffix = "vhd"; + break; + } + if (! expectedSuffix.isEmpty()) { + QFileInfo fileInfo(fileName); + if (fileInfo.suffix().compare(expectedSuffix, Qt::CaseInsensitive) != 0) { + fileName = QString("%1.%2").arg(fileName, expectedSuffix); + ui->fileField->setFileName(fileName); + } + } + + QFile file(fileName); + if (! file.open(QIODevice::WriteOnly)) { + QMessageBox::critical(this, tr("Unable to write file"), tr("Make sure the file is being saved to a writable directory.")); + return; + } + + if (img_format == 1) { /* HDI file */ + QDataStream stream(&file); + stream.setByteOrder(QDataStream::LittleEndian); + if (size >= 0x100000000ll) { + QMessageBox::critical(this, tr("Disk image too large"), tr("HDI disk images cannot be larger than 4 GB.")); + return; + } + uint32_t s = static_cast(size); + stream << zero; /* 00000000: Zero/unknown */ + stream << zero; /* 00000004: Zero/unknown */ + stream << base; /* 00000008: Offset at which data starts */ + stream << s; /* 0000000C: Full size of the data (32-bit) */ + stream << sector_size; /* 00000010: Sector size in bytes */ + stream << sectors_; /* 00000014: Sectors per cylinder */ + stream << heads_; /* 00000018: Heads per cylinder */ + stream << cylinders_; /* 0000001C: Cylinders */ + + for (int i = 0; i < 0x3f8; i++) { + stream << zero; + } + } else if (img_format == 2) { /* HDX file */ + QDataStream stream(&file); + stream.setByteOrder(QDataStream::LittleEndian); + quint64 signature = 0xD778A82044445459; + stream << signature; /* 00000000: Signature */ + stream << size; /* 00000008: Full size of the data (64-bit) */ + stream << sector_size; /* 00000010: Sector size in bytes */ + stream << sectors_; /* 00000014: Sectors per cylinder */ + stream << heads_; /* 00000018: Heads per cylinder */ + stream << cylinders_; /* 0000001C: Cylinders */ + stream << zero; /* 00000020: [Translation] Sectors per cylinder */ + stream << zero; /* 00000004: [Translation] Heads per cylinder */ + } else if (img_format >= 3) { /* VHD file */ + file.close(); + + MVHDGeom _86box_geometry{}; + int block_size = ui->comboBoxBlockSize->currentIndex() == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; + switch (img_format) { + case 3: + { + connect(this, &HarddiskDialog::fileProgress, this, [this] (int value) { ui->progressBar->setValue(value); QApplication::processEvents(); } ); + ui->progressBar->setVisible(true); + [&_86box_geometry, fileName, this] { + _86box_geometry = create_drive_vhd_fixed(fileName, this, cylinders_, heads_, sectors_); + }(); + } + break; + case 4: + _86box_geometry = create_drive_vhd_dynamic(fileName, cylinders_, heads_, sectors_, block_size); + break; + case 5: + QString vhdParent = QFileDialog::getOpenFileName( + this, + tr("Select the parent VHD"), + QString(), + tr("VHD files") % + util::DlgFilter({ "vhd" }) % + tr("All files") % + util::DlgFilter({ "*" }, true)); + + if (vhdParent.isEmpty()) { + return; + } + _86box_geometry = create_drive_vhd_diff(fileName, vhdParent, block_size); + break; + } + + if (_86box_geometry.cyl == 0 && + _86box_geometry.heads == 0 && + _86box_geometry.spt == 0) + { + QMessageBox::critical(this, tr("Unable to write file"), tr("Make sure the file is being saved to a writable directory.")); + return; + } + else if (img_format != 5) { + QMessageBox::information(this, tr("Disk image created"), tr("Remember to partition and format the newly-created drive.")); + } + + ui->lineEditCylinders->setText(QString::number(_86box_geometry.cyl)); + ui->lineEditHeads->setText(QString::number(_86box_geometry.heads)); + ui->lineEditSectors->setText(QString::number(_86box_geometry.spt)); + cylinders_ = _86box_geometry.cyl; + heads_ = _86box_geometry.heads; + sectors_ = _86box_geometry.spt; + setResult(QDialog::Accepted); + + return; + } + + // formats 0, 1 and 2 + connect(this, &HarddiskDialog::fileProgress, this, [this] (int value) { ui->progressBar->setValue(value); QApplication::processEvents(); } ); + ui->progressBar->setVisible(true); + [size, &file, this] { + QDataStream stream(&file); + stream.setByteOrder(QDataStream::LittleEndian); + + QByteArray buf(1048576, 0); + uint64_t mibBlocks = size >> 20; + uint64_t restBlock = size & 0xfffff; + + if (restBlock) { + stream.writeRawData(buf.data(), restBlock); + } + + if (mibBlocks) { + for (uint64_t i = 0; i < mibBlocks; ++i) { + stream.writeRawData(buf.data(), buf.size()); + emit fileProgress(static_cast((i * 100) / mibBlocks)); + } + } + emit fileProgress(100); + }(); + + QMessageBox::information(this, tr("Disk image created"), tr("Remember to partition and format the newly-created drive.")); + setResult(QDialog::Accepted); +} + +static void adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) { + if (vhd_geometry->spt <= 63) + return; + + int desired_sectors = vhd_geometry->cyl * vhd_geometry->heads * vhd_geometry->spt; + if (desired_sectors > 267321600) + desired_sectors = 267321600; + + int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */ + if (remainder > 0) + desired_sectors -= remainder; + + vhd_geometry->cyl = desired_sectors / (16 * 63); + vhd_geometry->heads = 16; + vhd_geometry->spt = 63; +} + +void HarddiskDialog::recalcSelection() { + int selection = 127; + for (int i = 0; i < 127; i++) { + if ((cylinders_ == hdd_table[i][0]) && + (heads_ == hdd_table[i][1]) && + (sectors_ == hdd_table[i][2])) + selection = i; + } + if ((selection == 127) && (heads_ == 16) && (sectors_ == 63)) { + selection = 128; + } + ui->comboBoxType->setCurrentIndex(selection); +} + +void HarddiskDialog::onExistingFileSelected(const QString &fileName) { + // TODO : Over to non-existing file selected + /* + if (!(existing & 1)) { + f = _wfopen(wopenfilestring, L"rb"); + if (f != NULL) { + fclose(f); + if (settings_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) / * yes * / + return FALSE; + } + } + + f = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); + if (f == NULL) { + hdd_add_file_open_error: + fclose(f); + settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108); + return TRUE; + } + */ + + uint64_t size = 0; + uint32_t sector_size = 0; + uint32_t sectors = 0; + uint32_t heads = 0; + uint32_t cylinders = 0; + int vhd_error = 0; + + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + QFile file(fileName); + if (! file.open(QIODevice::ReadOnly)) { + QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable.")); + return; + } + QByteArray fileNameUtf8 = fileName.toUtf8(); + + QFileInfo fi(file); + if (image_is_hdi(fileNameUtf8.data()) || image_is_hdx(fileNameUtf8.data(), 1)) { + file.seek(0x10); + QDataStream stream(&file); + stream.setByteOrder(QDataStream::LittleEndian); + stream >> sector_size; + if (sector_size != 512) { + QMessageBox::critical(this, tr("Unsupported disk image"), tr("HDI or HDX images with a sector size other than 512 are not supported.")); + return; + } + + sectors = heads = cylinders = 0; + stream >> sectors; + stream >> heads; + stream >> cylinders; + } else if (image_is_vhd(fileNameUtf8.data(), 1)) { + MVHDMeta* vhd = mvhd_open(fileNameUtf8.data(), 0, &vhd_error); + if (vhd == nullptr) { + QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable")); + return; + } else if (vhd_error == MVHD_ERR_TIMESTAMP) { + QMessageBox::StandardButton btn = QMessageBox::warning(this, tr("Parent and child disk timestamps do not match"), tr("This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?"), QMessageBox::Yes | QMessageBox::No); + if (btn == QMessageBox::Yes) { + int ts_res = mvhd_diff_update_par_timestamp(vhd, &vhd_error); + if (ts_res != 0) { + QMessageBox::critical(this, tr("Error"), tr("Could not fix VHD timestamp")); + mvhd_close(vhd); + return; + } + } else { + mvhd_close(vhd); + return; + } + } + + MVHDGeom vhd_geom = mvhd_get_geometry(vhd); + adjust_vhd_geometry_for_86box(&vhd_geom); + cylinders = vhd_geom.cyl; + heads = vhd_geom.heads; + sectors = vhd_geom.spt; + size = static_cast(cylinders * heads * sectors * 512); + mvhd_close(vhd); + } else { + size = file.size(); + if (((size % 17) == 0) && (size <= 142606336)) { + sectors = 17; + if (size <= 26738688) + heads = 4; + else if (((size % 3072) == 0) && (size <= 53477376)) + heads = 6; + else { + int i; + for (i = 5; i < 16; i++) { + if (((size % (i << 9)) == 0) && (size <= ((i * 17) << 19))) + break; + if (i == 5) + i++; + } + heads = i; + } + } else { + sectors = 63; + heads = 16; + } + + cylinders = ((size >> 9) / heads) / sectors; + } + + if ((sectors > max_sectors) || (heads > max_heads) || (cylinders > max_cylinders)) { + QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable")); + return; + } + + heads_ = heads; + sectors_ = sectors; + cylinders_ = cylinders; + ui->lineEditCylinders->setText(QString::number(cylinders)); + ui->lineEditHeads->setText(QString::number(heads)); + ui->lineEditSectors->setText(QString::number(sectors)); + recalcSize(); + recalcSelection(); + + ui->lineEditCylinders->setEnabled(true); + ui->lineEditHeads->setEnabled(true); + ui->lineEditSectors->setEnabled(true); + ui->lineEditSize->setEnabled(true); + ui->comboBoxType->setEnabled(true); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); +} + +void HarddiskDialog::recalcSize() { + uint64_t size = (static_cast(cylinders_) * static_cast(heads_) * static_cast(sectors_)) << 9; + ui->lineEditSize->setText(QString::number(size >> 20)); +} + +bool HarddiskDialog::checkAndAdjustSectors() { + if (sectors_ > max_sectors) { + sectors_ = max_sectors; + ui->lineEditSectors->setText(QString::number(max_sectors)); + recalcSize(); + recalcSelection(); + return false; + } + return true; +} + +bool HarddiskDialog::checkAndAdjustHeads() { + if (heads_ > max_heads) { + heads_ = max_heads; + ui->lineEditHeads->setText(QString::number(max_heads)); + recalcSize(); + recalcSelection(); + return false; + } + return true; +} + +bool HarddiskDialog::checkAndAdjustCylinders() { + if (cylinders_ > max_cylinders) { + cylinders_ = max_cylinders; + ui->lineEditCylinders->setText(QString::number(max_cylinders)); + recalcSize(); + recalcSelection(); + return false; + } + return true; +} + + +void HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) { + if (index < 0) { + return; + } + + switch (ui->comboBoxBus->currentData().toInt()) { + case HDD_BUS_DISABLED: + default: + max_sectors = max_heads = max_cylinders = 0; + break; + case HDD_BUS_MFM: + max_sectors = 26; /* 17 for MFM, 26 for RLL. */ + max_heads = 15; + max_cylinders = 2047; + break; + case HDD_BUS_XTA: + max_sectors = 63; + max_heads = 16; + max_cylinders = 1023; + break; + case HDD_BUS_ESDI: + max_sectors = 99; /* ESDI drives usually had 32 to 43 sectors per track. */ + max_heads = 16; + max_cylinders = 266305; + break; + case HDD_BUS_IDE: + max_sectors = 63; + max_heads = 255; + max_cylinders = 266305; + break; + case HDD_BUS_ATAPI: + case HDD_BUS_SCSI: + max_sectors = 99; + max_heads = 255; + max_cylinders = 266305; + break; + } + + checkAndAdjustCylinders(); + checkAndAdjustHeads(); + checkAndAdjustSectors(); + + if (ui->lineEditCylinders->validator() != nullptr) { + delete ui->lineEditCylinders->validator(); + } + if (ui->lineEditHeads->validator() != nullptr) { + delete ui->lineEditHeads->validator(); + } + if (ui->lineEditSectors->validator() != nullptr) { + delete ui->lineEditSectors->validator(); + } + + ui->lineEditCylinders->setValidator(new QIntValidator(1, max_cylinders, this)); + ui->lineEditHeads->setValidator(new QIntValidator(1, max_heads, this)); + ui->lineEditSectors->setValidator(new QIntValidator(1, max_sectors, this)); + + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt()); +} + +void HarddiskDialog::on_lineEditSize_textEdited(const QString &text) { + uint32_t size = text.toUInt(); + /* This is needed to ensure VHD standard compliance. */ + hdd_image_calc_chs(&cylinders_, &heads_, §ors_, size); + ui->lineEditCylinders->setText(QString::number(cylinders_)); + ui->lineEditHeads->setText(QString::number(heads_)); + ui->lineEditSectors->setText(QString::number(sectors_)); + recalcSelection(); + + checkAndAdjustCylinders(); + checkAndAdjustHeads(); + checkAndAdjustSectors(); +} + +void HarddiskDialog::on_lineEditCylinders_textEdited(const QString &text) { + cylinders_ = text.toUInt(); + if (checkAndAdjustCylinders()) { + recalcSize(); + recalcSelection(); + } +} + +void HarddiskDialog::on_lineEditHeads_textEdited(const QString &text) { + heads_ = text.toUInt(); + if (checkAndAdjustHeads()) { + recalcSize(); + recalcSelection(); + } +} + +void HarddiskDialog::on_lineEditSectors_textEdited(const QString &text) { + sectors_ = text.toUInt(); + if (checkAndAdjustSectors()) { + recalcSize(); + recalcSelection(); + } +} + +void HarddiskDialog::on_comboBoxType_currentIndexChanged(int index) { + if (index < 0) { + return; + } + + if ((index != 127) && (index != 128)) { + cylinders_ = hdd_table[index][0]; + heads_ = hdd_table[index][1]; + sectors_ = hdd_table[index][2]; + ui->lineEditCylinders->setText(QString::number(cylinders_)); + ui->lineEditHeads->setText(QString::number(heads_)); + ui->lineEditSectors->setText(QString::number(sectors_)); + recalcSize(); + } else if (index == 128) { + heads_ = 16; + sectors_ = 63; + ui->lineEditHeads->setText(QString::number(heads_)); + ui->lineEditSectors->setText(QString::number(sectors_)); + recalcSize(); + } + + checkAndAdjustCylinders(); + checkAndAdjustHeads(); + checkAndAdjustSectors(); +} + +void HarddiskDialog::accept() +{ + if (ui->fileField->createFile()) onCreateNewFile(); + else setResult(QDialog::Accepted); + QDialog::done(result()); +} diff --git a/src/qt/qt_harddiskdialog.hpp b/src/qt/qt_harddiskdialog.hpp new file mode 100644 index 000000000..321dc4708 --- /dev/null +++ b/src/qt/qt_harddiskdialog.hpp @@ -0,0 +1,59 @@ +#ifndef QT_HARDDISKDIALOG_HPP +#define QT_HARDDISKDIALOG_HPP + +#include + +namespace Ui { +class HarddiskDialog; +} + +class HarddiskDialog : public QDialog +{ + Q_OBJECT + +public: + explicit HarddiskDialog(bool existing, QWidget *parent = nullptr); + ~HarddiskDialog(); + + uint8_t bus() const; + uint8_t channel() const; + QString fileName() const; + uint32_t cylinders() const { return cylinders_; } + uint32_t heads() const { return heads_; } + uint32_t sectors() const { return sectors_; } + +signals: + void fileProgress(int i); + +public slots: + void accept() override; + +private slots: + void on_comboBoxType_currentIndexChanged(int index); + void on_lineEditSectors_textEdited(const QString &arg1); + void on_lineEditHeads_textEdited(const QString &arg1); + void on_lineEditCylinders_textEdited(const QString &arg1); + void on_lineEditSize_textEdited(const QString &arg1); + void on_comboBoxBus_currentIndexChanged(int index); + void on_comboBoxFormat_currentIndexChanged(int index); + void onCreateNewFile(); + void onExistingFileSelected(const QString& fileName); +private: + Ui::HarddiskDialog *ui; + + uint32_t cylinders_; + uint32_t heads_; + uint32_t sectors_; + + uint32_t max_sectors = 0; + uint32_t max_heads = 0; + uint32_t max_cylinders = 0; + + bool checkAndAdjustCylinders(); + bool checkAndAdjustHeads(); + bool checkAndAdjustSectors(); + void recalcSize(); + void recalcSelection(); +}; + +#endif // QT_HARDDISKDIALOG_HPP diff --git a/src/qt/qt_harddiskdialog.ui b/src/qt/qt_harddiskdialog.ui new file mode 100644 index 000000000..823652aa6 --- /dev/null +++ b/src/qt/qt_harddiskdialog.ui @@ -0,0 +1,285 @@ + + + HarddiskDialog + + + + 0 + 0 + 421 + 269 + + + + + 0 + 0 + + + + + 421 + 269 + + + + + 421 + 269 + + + + Dialog + + + + + + + + + Channel: + + + + + + + Sectors: + + + + + + + Type: + + + + + + + + 0 + 0 + + + + + 64 + 16777215 + + + + + + + + + 0 + 0 + + + + + 64 + 16777215 + + + + + + + + Size (MB): + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + Cylinders: + + + + + + + + 0 + 0 + + + + + 64 + 16777215 + + + + 32767 + + + + + + + Image Format: + + + + + + + Heads: + + + + + + + + + + Bus: + + + + + + + + + + + + + + 0 + 0 + + + + + 64 + 16777215 + + + + 32767 + + + + + + + + + + Block Size: + + + + + + + File name: + + + + + + + false + + + 0 + + + true + + + + + + + + FileField + QWidget +
qt_filefield.hpp
+ 1 +
+
+ + lineEditCylinders + lineEditHeads + lineEditSectors + lineEditSize + comboBoxType + comboBoxBus + comboBoxChannel + comboBoxFormat + comboBoxBlockSize + + + + + buttonBox + accepted() + HarddiskDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + HarddiskDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/src/qt/qt_harddrive_common.cpp b/src/qt/qt_harddrive_common.cpp new file mode 100644 index 000000000..fbc60f627 --- /dev/null +++ b/src/qt/qt_harddrive_common.cpp @@ -0,0 +1,101 @@ +#include "qt_harddrive_common.hpp" + +#include + +extern "C" { +#include <86box/hdd.h> +} + +#include + +void Harddrives::populateBuses(QAbstractItemModel *model) { + model->removeRows(0, model->rowCount()); + model->insertRows(0, 6); + model->setData(model->index(0, 0), "MFM/RLL"); + model->setData(model->index(1, 0), "XT IDE"); + model->setData(model->index(2, 0), "ESDI"); + model->setData(model->index(3, 0), "IDE"); + model->setData(model->index(4, 0), "ATAPI"); + model->setData(model->index(5, 0), "SCSI"); + + model->setData(model->index(0, 0), HDD_BUS_MFM, Qt::UserRole); + model->setData(model->index(1, 0), HDD_BUS_XTA, Qt::UserRole); + model->setData(model->index(2, 0), HDD_BUS_ESDI, Qt::UserRole); + model->setData(model->index(3, 0), HDD_BUS_IDE, Qt::UserRole); + model->setData(model->index(4, 0), HDD_BUS_ATAPI, Qt::UserRole); + model->setData(model->index(5, 0), HDD_BUS_SCSI, Qt::UserRole); +} + +void Harddrives::populateRemovableBuses(QAbstractItemModel *model) { + model->removeRows(0, model->rowCount()); + model->insertRows(0, 3); + model->setData(model->index(0, 0), QObject::tr("Disabled")); + model->setData(model->index(1, 0), QObject::tr("ATAPI")); + model->setData(model->index(2, 0), QObject::tr("SCSI")); + + model->setData(model->index(0, 0), HDD_BUS_DISABLED, Qt::UserRole); + model->setData(model->index(1, 0), HDD_BUS_ATAPI, Qt::UserRole); + model->setData(model->index(2, 0), HDD_BUS_SCSI, Qt::UserRole); +} + +void Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) { + model->removeRows(0, model->rowCount()); + + int busRows = 0; + int shifter = 1; + int orer = 1; + int subChannelWidth = 1; + switch (bus) { + case HDD_BUS_MFM: + case HDD_BUS_XTA: + case HDD_BUS_ESDI: + busRows = 2; + break; + case HDD_BUS_IDE: + case HDD_BUS_ATAPI: + busRows = 8; + break; + case HDD_BUS_SCSI: + shifter = 4; + orer = 15; + busRows = 64; + subChannelWidth = 2; + break; + } + + model->insertRows(0, busRows); + for (int i = 0; i < busRows; ++i) { + auto idx = model->index(i, 0); + model->setData(idx, QString("%1:%2").arg(i >> shifter).arg(i & orer, subChannelWidth, 10, QChar('0'))); + model->setData(idx, ((i >> shifter) << shifter) | (i & orer), Qt::UserRole); + } +} + +QString Harddrives::BusChannelName(uint8_t bus, uint8_t channel) { + QString busName; + switch(bus) { + case HDD_BUS_DISABLED: + busName = QString(QObject::tr("Disabled")); + break; + case HDD_BUS_MFM: + busName = QString("MFM/RLL (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_XTA: + busName = QString("XT IDE (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_ESDI: + busName = QString("ESDI (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_IDE: + busName = QString("IDE (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_ATAPI: + busName = QString("ATAPI (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_SCSI: + busName = QString("SCSI (%1:%2)").arg(channel >> 4).arg(channel & 15, 2, 10, QChar('0')); + break; + } + + return busName; +} diff --git a/src/qt/qt_harddrive_common.hpp b/src/qt/qt_harddrive_common.hpp new file mode 100644 index 000000000..5d4bbc9e0 --- /dev/null +++ b/src/qt/qt_harddrive_common.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include + +class QString; +class QAbstractItemModel; +class SettingsBusTracking; + +namespace Harddrives { + void populateBuses(QAbstractItemModel* model); + void populateRemovableBuses(QAbstractItemModel* model); + void populateBusChannels(QAbstractItemModel* model, int bus); + QString BusChannelName(uint8_t bus, uint8_t channel); + inline SettingsBusTracking* busTrackClass = nullptr; +}; diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp new file mode 100644 index 000000000..ca0e60efb --- /dev/null +++ b/src/qt/qt_hardwarerenderer.cpp @@ -0,0 +1,202 @@ +#include "qt_hardwarerenderer.hpp" +#include +#include +#include +#include + +extern "C" { +#include <86box/86box.h> +#include <86box/plat.h> +#include <86box/video.h> +} + +void HardwareRenderer::resizeGL(int w, int h) +{ + glViewport(0, 0, w * devicePixelRatio(), h * devicePixelRatio()); +} + +#define PROGRAM_VERTEX_ATTRIBUTE 0 +#define PROGRAM_TEXCOORD_ATTRIBUTE 1 + +void HardwareRenderer::initializeGL() +{ + m_context->makeCurrent(this); + initializeOpenGLFunctions(); + m_texture = new QOpenGLTexture(QImage(2048,2048, QImage::Format::Format_RGB32)); + m_blt = new QOpenGLTextureBlitter; + m_blt->setRedBlueSwizzle(true); + m_blt->create(); + QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); + const char *vsrc = + "attribute highp vec4 VertexCoord;\n" + "attribute mediump vec4 TexCoord;\n" + "varying mediump vec4 texc;\n" + "uniform mediump mat4 MVPMatrix;\n" + "void main(void)\n" + "{\n" + " gl_Position = MVPMatrix * VertexCoord;\n" + " texc = TexCoord;\n" + "}\n"; + QString vsrccore = + "in highp vec4 VertexCoord;\n" + "in mediump vec4 TexCoord;\n" + "out mediump vec4 texc;\n" + "uniform mediump mat4 MVPMatrix;\n" + "void main(void)\n" + "{\n" + " gl_Position = MVPMatrix * VertexCoord;\n" + " texc = TexCoord;\n" + "}\n"; + if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) + { + vsrccore.prepend("#version 300 es\n"); + vshader->compileSourceCode(vsrccore); + } + else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) + { + vsrccore.prepend("#version 130\n"); + vshader->compileSourceCode(vsrccore); + } + else vshader->compileSourceCode(vsrc); + + QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); + const char *fsrc = + "uniform sampler2D texture;\n" + "varying mediump vec4 texc;\n" + "void main(void)\n" + "{\n" + " gl_FragColor = texture2D(texture, texc.st).bgra;\n" + "}\n"; + QString fsrccore = + "uniform sampler2D texture;\n" + "in mediump vec4 texc;\n" + "out highp vec4 FragColor;\n" + "void main(void)\n" + "{\n" + " FragColor = texture2D(texture, texc.st).bgra;\n" + "}\n"; + if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) + { + fsrccore.prepend("#version 300 es\n"); + fshader->compileSourceCode(fsrccore); + } + else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) + { + fsrccore.prepend("#version 130\n"); + fshader->compileSourceCode(fsrccore); + } + else fshader->compileSourceCode(fsrc); + + m_prog = new QOpenGLShaderProgram; + m_prog->addShader(vshader); + m_prog->addShader(fshader); + m_prog->bindAttributeLocation("VertexCoord", PROGRAM_VERTEX_ATTRIBUTE); + m_prog->bindAttributeLocation("TexCoord", PROGRAM_TEXCOORD_ATTRIBUTE); + m_prog->link(); + + m_prog->bind(); + m_prog->setUniformValue("texture", 0); + + if (m_context->format().version() >= qMakePair(3, 0) && m_vao.create()) { + m_vao.bind(); + } + + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].create(); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].allocate(sizeof(QVector2D) * 4); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].create(); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].allocate(sizeof(QVector2D) * 4); + + pclog("OpenGL vendor: %s\n", glGetString(GL_VENDOR)); + pclog("OpenGL renderer: %s\n", glGetString(GL_RENDERER)); + pclog("OpenGL version: %s\n", glGetString(GL_VERSION)); + pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); + glClearColor(0, 0, 0, 1); +} + +void HardwareRenderer::paintGL() { + m_context->makeCurrent(this); + glClear(GL_COLOR_BUFFER_BIT); + QVector verts, texcoords; + QMatrix4x4 mat; + mat.setToIdentity(); + mat.ortho(QRect(0, 0, width(), height())); + verts.push_back(QVector2D((float)destination.x(), (float)destination.y())); + verts.push_back(QVector2D((float)destination.x(), (float)destination.y() + destination.height())); + verts.push_back(QVector2D((float)destination.x() + destination.width(), (float)destination.y() + destination.height())); + verts.push_back(QVector2D((float)destination.x() + destination.width(), (float)destination.y())); + texcoords.push_back(QVector2D((float)source.x() / 2048.f, (float)(source.y()) / 2048.f)); + texcoords.push_back(QVector2D((float)source.x() / 2048.f, (float)(source.y() + source.height()) / 2048.f)); + texcoords.push_back(QVector2D((float)(source.x() + source.width()) / 2048.f, (float)(source.y() + source.height()) / 2048.f)); + texcoords.push_back(QVector2D((float)(source.x() + source.width()) / 2048.f, (float)(source.y()) / 2048.f)); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].write(0, verts.data(), sizeof(QVector2D) * 4); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].write(0, texcoords.data(), sizeof(QVector2D) * 4); m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); + + m_prog->setUniformValue("MVPMatrix", mat); + m_prog->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE); + m_prog->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE); + + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); m_prog->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 2, 0); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); m_prog->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 0, 2, 0); m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); + m_texture->bind(); + m_texture->setMinMagFilters(video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest, video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +} + +void HardwareRenderer::setRenderType(RenderType type) { + QSurfaceFormat format; + switch (type) { + case RenderType::OpenGL3: + format.setVersion(3, 0); + format.setProfile(QSurfaceFormat::CoreProfile); + case RenderType::OpenGL: + format.setRenderableType(QSurfaceFormat::OpenGL); + break; + case RenderType::OpenGLES: + format.setRenderableType(QSurfaceFormat::OpenGLES); + break; + } + format.setSwapInterval(0); + setFormat(format); +} + +void HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { + auto tval = this; + void* nuldata = 0; + if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; + if (!m_texture || !m_texture->isCreated()) + { + buf_usage[buf_idx].clear(); + source.setRect(x, y, w, h); + return; + } + m_context->makeCurrent(this); + m_texture->setData(QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)imagebufs[buf_idx].get()); + buf_usage[buf_idx].clear(); + source.setRect(x, y, w, h); + update(); +} + +void HardwareRenderer::resizeEvent(QResizeEvent *event) { + onResize(width(), height()); + + QOpenGLWindow::resizeEvent(event); +} + +bool HardwareRenderer::event(QEvent *event) +{ + bool res = false; + if (!eventDelegate(event, res)) return QOpenGLWindow::event(event); + return res; +} + +std::vector> HardwareRenderer::getBuffers() +{ + std::vector> buffers; + + buffers.push_back(std::make_tuple(imagebufs[0].get(), &buf_usage[0])); + buffers.push_back(std::make_tuple(imagebufs[1].get(), &buf_usage[1])); + + return buffers; +} \ No newline at end of file diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp new file mode 100644 index 000000000..af4f05464 --- /dev/null +++ b/src/qt/qt_hardwarerenderer.hpp @@ -0,0 +1,92 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "qt_renderercommon.hpp" + +#ifdef WAYLAND +#include "wl_mouse.hpp" +#endif + +class HardwareRenderer : public QOpenGLWindow, protected QOpenGLFunctions, public RendererCommon +{ + Q_OBJECT + +private: + bool wayland = false; + QOpenGLContext* m_context; + QOpenGLTexture* m_texture{nullptr}; + QOpenGLShaderProgram* m_prog{nullptr}; + QOpenGLTextureBlitter* m_blt{nullptr}; + QOpenGLBuffer m_vbo[2]; + QOpenGLVertexArrayObject m_vao; +public: + enum class RenderType { + OpenGL, + OpenGLES, + OpenGL3, + }; + void resizeGL(int w, int h) override; + void initializeGL() override; + void paintGL() override; + std::vector> getBuffers() override; + HardwareRenderer(QWidget* parent = nullptr, RenderType rtype = RenderType::OpenGL) + : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()), QOpenGLFunctions() + { + imagebufs[0] = std::unique_ptr(new uint8_t[2048 * 2048 * 4]); + imagebufs[1] = std::unique_ptr(new uint8_t[2048 * 2048 * 4]); + + buf_usage = std::vector(2); + buf_usage[0].clear(); + buf_usage[1].clear(); + + setMinimumSize(QSize(16, 16)); + setFlags(Qt::FramelessWindowHint); + parentWidget = parent; + setRenderType(rtype); + + m_context = new QOpenGLContext(); + m_context->setFormat(format()); + m_context->create(); + } + ~HardwareRenderer() + { + m_context->makeCurrent(this); + if (m_blt) m_blt->destroy(); + m_prog->release(); + delete m_prog; + m_prog = nullptr; + m_context->doneCurrent(); + delete m_context; + } + + + void setRenderType(RenderType type); + +public slots: + void onBlit(int buf_idx, int x, int y, int w, int h); + +protected: + std::array, 2> imagebufs; + + void resizeEvent(QResizeEvent *event) override; + bool event(QEvent* event) override; +}; diff --git a/src/qt/qt_joystickconfiguration.cpp b/src/qt/qt_joystickconfiguration.cpp new file mode 100644 index 000000000..83b2f50be --- /dev/null +++ b/src/qt/qt_joystickconfiguration.cpp @@ -0,0 +1,186 @@ +#include "qt_joystickconfiguration.hpp" +#include "ui_qt_joystickconfiguration.h" + +extern "C" { +#include <86box/device.h> +#include <86box/gameport.h> +} + + +#include +#include +#include +#include "qt_models_common.hpp" + +JoystickConfiguration::JoystickConfiguration(int type, int joystick_nr, QWidget *parent) : + QDialog(parent), + ui(new Ui::JoystickConfiguration), + type(type), + joystick_nr(joystick_nr) +{ + ui->setupUi(this); + + auto model = ui->comboBoxDevice->model(); + Models::AddEntry(model, "None", 0); + for (int c = 0; c < joysticks_present; c++) { + Models::AddEntry(model, plat_joystick_state[c].name, c+1); + } + + ui->comboBoxDevice->setCurrentIndex(joystick_state[joystick_nr].plat_joystick_nr); + setFixedSize(minimumSizeHint()); +} + +JoystickConfiguration::~JoystickConfiguration() +{ + delete ui; +} + +int JoystickConfiguration::selectedDevice() { + return ui->comboBoxDevice->currentIndex(); +} + +int JoystickConfiguration::selectedAxis(int axis) { + auto* cbox = findChild(QString("cboxAxis%1").arg(QString::number(axis))); + if (cbox == nullptr) { + return 0; + } + return cbox->currentIndex(); +} + +int JoystickConfiguration::selectedButton(int button) { + auto* cbox = findChild(QString("cboxButton%1").arg(QString::number(button))); + if (cbox == nullptr) { + return 0; + } + return cbox->currentIndex(); +} + +int JoystickConfiguration::selectedPov(int pov) { + auto* cbox = findChild(QString("cboxPov%1").arg(QString::number(pov))); + if (cbox == nullptr) { + return 0; + } + return cbox->currentIndex(); +} + +void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) { + for (auto w : widgets) { + ui->ct->removeWidget(w); + } + + if (index == 0) { + return; + } + + int joystick = index - 1; + int row = 0; + for (int c = 0; c < joystick_get_axis_count(type); c++) { + /*Combo box*/ + auto label = new QLabel(joystick_get_axis_name(type, c), this); + auto cbox = new QComboBox(this); + cbox->setObjectName(QString("cboxAxis%1").arg(QString::number(c))); + auto model = cbox->model(); + + for (int d = 0; d < plat_joystick_state[joystick].nr_axes; d++) { + Models::AddEntry(model, plat_joystick_state[joystick].axis[d].name, 0); + } + + for (int d = 0; d < plat_joystick_state[joystick].nr_povs; d++) { + Models::AddEntry(model, QString("%1 (X axis)").arg(plat_joystick_state[joystick].pov[d].name), 0); + Models::AddEntry(model, QString("%1 (Y axis)").arg(plat_joystick_state[joystick].pov[d].name), 0); + } + + for (int d = 0; d < plat_joystick_state[joystick].nr_sliders; d++) { + Models::AddEntry(model, plat_joystick_state[joystick].slider[d].name, 0); + } + + int nr_axes = plat_joystick_state[joystick].nr_axes; + int nr_povs = plat_joystick_state[joystick].nr_povs; + int mapping = joystick_state[joystick_nr].axis_mapping[c]; + if (mapping & POV_X) + cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2); + else if (mapping & POV_Y) + cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2 + 1); + else if (mapping & SLIDER) + cbox->setCurrentIndex(nr_axes + nr_povs * 2 + (mapping & 3)); + else + cbox->setCurrentIndex(mapping); + + ui->ct->addWidget(label, row, 0); + ui->ct->addWidget(cbox, row, 1); + + widgets.append(label); + widgets.append(cbox); + + ++row; + } + + for (int c = 0; c < joystick_get_button_count(type); c++) { + auto label = new QLabel(joystick_get_button_name(type, c), this); + auto cbox = new QComboBox(this); + cbox->setObjectName(QString("cboxButton%1").arg(QString::number(c))); + auto model = cbox->model(); + + for (int d = 0; d < plat_joystick_state[joystick].nr_buttons; d++) { + Models::AddEntry(model, plat_joystick_state[joystick].button[d].name, 0); + } + + cbox->setCurrentIndex(joystick_state[joystick_nr].button_mapping[c]); + + ui->ct->addWidget(label, row, 0); + ui->ct->addWidget(cbox, row, 1); + + widgets.append(label); + widgets.append(cbox); + + ++row; + } + + for (int c = 0; c < joystick_get_pov_count(type) * 2; c++) { + QLabel* label; + if (c & 1) { + label = new QLabel(QString("%1 (Y axis)").arg(joystick_get_pov_name(type, c/2)), this); + } else { + label = new QLabel(QString("%1 (X axis)").arg(joystick_get_pov_name(type, c/2)), this); + } + auto cbox = new QComboBox(this); + cbox->setObjectName(QString("cboxPov%1").arg(QString::number(c))); + auto model = cbox->model(); + + for (int d = 0; d < plat_joystick_state[joystick].nr_povs; d++) { + Models::AddEntry(model, QString("%1 (X axis)").arg(plat_joystick_state[joystick].pov[d].name), 0); + Models::AddEntry(model, QString("%1 (Y axis)").arg(plat_joystick_state[joystick].pov[d].name), 0); + } + + for (int d = 0; d < plat_joystick_state[joystick].nr_axes; d++) { + Models::AddEntry(model, plat_joystick_state[joystick].axis[d].name, 0); + } + + int mapping = joystick_state[joystick_nr].pov_mapping[c][0]; + int nr_povs = plat_joystick_state[joystick].nr_povs; + if (mapping & POV_X) + cbox->setCurrentIndex((mapping & 3) * 2); + else if (mapping & POV_Y) + cbox->setCurrentIndex((mapping & 3)*2 + 1); + else + cbox->setCurrentIndex(mapping + nr_povs * 2); + + mapping = joystick_state[joystick_nr].pov_mapping[c][1]; + if (mapping & POV_X) + cbox->setCurrentIndex((mapping & 3)*2); + else if (mapping & POV_Y) + cbox->setCurrentIndex((mapping & 3)*2 + 1); + else + cbox->setCurrentIndex(mapping + nr_povs*2); + + ui->ct->addWidget(label, row, 0); + ui->ct->addWidget(cbox, row, 1); + + widgets.append(label); + widgets.append(cbox); + + ++row; + } + + setFixedSize(minimumSizeHint()); +} diff --git a/src/qt/qt_joystickconfiguration.hpp b/src/qt/qt_joystickconfiguration.hpp new file mode 100644 index 000000000..b6882c52b --- /dev/null +++ b/src/qt/qt_joystickconfiguration.hpp @@ -0,0 +1,32 @@ +#ifndef QT_JOYSTICKCONFIGURATION_HPP +#define QT_JOYSTICKCONFIGURATION_HPP + +#include + +namespace Ui { +class JoystickConfiguration; +} + +class JoystickConfiguration : public QDialog +{ + Q_OBJECT + +public: + explicit JoystickConfiguration(int type, int joystick_nr, QWidget *parent = nullptr); + ~JoystickConfiguration(); + + int selectedDevice(); + int selectedAxis(int axis); + int selectedButton(int button); + int selectedPov(int pov); +private slots: + void on_comboBoxDevice_currentIndexChanged(int index); + +private: + Ui::JoystickConfiguration *ui; + QList widgets; + int type; + int joystick_nr; +}; + +#endif // QT_JOYSTICKCONFIGURATION_HPP diff --git a/src/qt/qt_joystickconfiguration.ui b/src/qt/qt_joystickconfiguration.ui new file mode 100644 index 000000000..abe17b5cc --- /dev/null +++ b/src/qt/qt_joystickconfiguration.ui @@ -0,0 +1,87 @@ + + + JoystickConfiguration + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + Device + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + buttonBox + accepted() + JoystickConfiguration + accept() + + + 223 + 278 + + + 199 + 149 + + + + + buttonBox + rejected() + JoystickConfiguration + reject() + + + 223 + 278 + + + 199 + 149 + + + + + diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp new file mode 100644 index 000000000..b844ade83 --- /dev/null +++ b/src/qt/qt_machinestatus.cpp @@ -0,0 +1,571 @@ +#include "qt_machinestatus.hpp" + +extern "C" { +#define EMU_CPU_H // superhack - don't want timer.h to include cpu.h here, and some combo is preventing a compile +extern uint64_t tsc; + +#include <86box/hdd.h> +#include <86box/timer.h> +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/cartridge.h> +#include <86box/cassette.h> +#include <86box/cdrom.h> +#include <86box/fdd.h> +#include <86box/hdc.h> +#include <86box/scsi.h> +#include <86box/scsi_device.h> +#include <86box/zip.h> +#include <86box/mo.h> +#include <86box/plat.h> +#include <86box/machine.h> +#include <86box/network.h> +#include <86box/ui.h> +}; + +#include +#include +#include +#include +#include +#include + +#include "qt_mediamenu.hpp" +#include "qt_mainwindow.hpp" +#include "qt_soundgain.hpp" +#include "qt_progsettings.hpp" + +#include + +extern MainWindow* main_window; + +namespace { + struct PixmapSetActive { + QPixmap normal; + QPixmap active; + void load(const QString& basePath); + }; + struct PixmapSetEmpty { + QPixmap normal; + QPixmap empty; + void load(const QString& basePath); + }; + struct PixmapSetEmptyActive { + QPixmap normal; + QPixmap active; + QPixmap empty; + QPixmap empty_active; + void load(QString basePath); + }; + struct Pixmaps { + PixmapSetEmpty cartridge; + PixmapSetEmptyActive cassette; + PixmapSetEmptyActive floppy_disabled; + PixmapSetEmptyActive floppy_525; + PixmapSetEmptyActive floppy_35; + PixmapSetEmptyActive cdrom; + PixmapSetEmptyActive zip; + PixmapSetEmptyActive mo; + PixmapSetActive hd; + PixmapSetActive net; + QPixmap sound; + }; + + struct StateActive { + std::unique_ptr label; + QTimer timer; + PixmapSetActive* pixmaps = nullptr; + bool active = false; + + void setActive(bool b) { + active = b; + if (! label) { + return; + } + label->setPixmap(active ? pixmaps->active : pixmaps->normal); + timer.start(75); + } + }; + struct StateEmpty { + std::unique_ptr label; + PixmapSetEmpty* pixmaps = nullptr; + bool empty = false; + + void setEmpty(bool e) { + empty = e; + if (! label) { + return; + } + label->setPixmap(empty ? pixmaps->empty : pixmaps->normal); + } + }; + struct StateEmptyActive { + std::unique_ptr label; + QTimer timer; + PixmapSetEmptyActive* pixmaps = nullptr; + bool empty = false; + bool active = false; + + void setActive(bool b) { + active = b; + refresh(); + timer.start(75); + } + void setEmpty(bool b) { + empty = b; + refresh(); + } + void refresh() { + if (! label) { + return; + } + if (empty) { + label->setPixmap(active ? pixmaps->empty_active : pixmaps->empty); + } else { + label->setPixmap(active ? pixmaps->active : pixmaps->normal); + } + } + }; + + static const QSize pixmap_size(16, 16); + static const QString pixmap_empty = QStringLiteral("_empty"); + static const QString pixmap_active = QStringLiteral("_active"); + static const QString pixmap_empty_active = QStringLiteral("_empty_active"); + void PixmapSetEmpty::load(const QString &basePath) { + normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); + empty = ProgSettings::loadIcon(basePath.arg(pixmap_empty)).pixmap(pixmap_size); + } + + void PixmapSetActive::load(const QString &basePath) { + normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); + active = ProgSettings::loadIcon(basePath.arg(pixmap_active)).pixmap(pixmap_size); + } + + void PixmapSetEmptyActive::load(QString basePath) { + normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); + active = ProgSettings::loadIcon(basePath.arg(pixmap_active)).pixmap(pixmap_size); + empty = ProgSettings::loadIcon(basePath.arg(pixmap_empty)).pixmap(pixmap_size); + empty_active = ProgSettings::loadIcon(basePath.arg(pixmap_empty_active)).pixmap(pixmap_size); + } +} + +struct MachineStatus::States { + Pixmaps pixmaps; + + States(QObject* parent) { + pixmaps.cartridge.load("/cartridge%1.ico"); + pixmaps.cassette.load("/cassette%1.ico"); + pixmaps.floppy_disabled.normal = ProgSettings::loadIcon(QStringLiteral("/floppy_disabled.ico")).pixmap(pixmap_size); + pixmaps.floppy_disabled.active = pixmaps.floppy_disabled.normal; + pixmaps.floppy_disabled.empty = pixmaps.floppy_disabled.normal; + pixmaps.floppy_disabled.empty_active = pixmaps.floppy_disabled.normal; + pixmaps.floppy_525.load("/floppy_525%1.ico"); + pixmaps.floppy_35.load("/floppy_35%1.ico"); + pixmaps.cdrom.load("/cdrom%1.ico"); + pixmaps.zip.load("/zip%1.ico"); + pixmaps.mo.load("/mo%1.ico"); + pixmaps.hd.load("/hard_disk%1.ico"); + pixmaps.net.load("/network%1.ico"); + pixmaps.sound = ProgSettings::loadIcon("/sound.ico").pixmap(pixmap_size); + + cartridge[0].pixmaps = &pixmaps.cartridge; + cartridge[1].pixmaps = &pixmaps.cartridge; + cassette.pixmaps = &pixmaps.cassette; + QObject::connect(&cassette.timer, &QTimer::timeout, parent, [&]{ cassette.setActive(false); }); + for (auto& f : fdd) { + f.pixmaps = &pixmaps.floppy_disabled; + QObject::connect(&f.timer, &QTimer::timeout, parent, [&]{ f.setActive(false); }); + } + for (auto& c : cdrom) { + c.pixmaps = &pixmaps.cdrom; + QObject::connect(&c.timer, &QTimer::timeout, parent, [&]{ c.setActive(false); }); + } + for (auto& z : zip) { + z.pixmaps = &pixmaps.zip; + QObject::connect(&z.timer, &QTimer::timeout, parent, [&]{ z.setActive(false); }); + } + for (auto& m : mo) { + m.pixmaps = &pixmaps.mo; + QObject::connect(&m.timer, &QTimer::timeout, parent, [&]{ m.setActive(false); }); + } + for (auto& h : hdds) { + h.pixmaps = &pixmaps.hd; + QObject::connect(&h.timer, &QTimer::timeout, parent, [&]{ h.setActive(false); }); + } + net.pixmaps = &pixmaps.net; + } + + std::array cartridge; + StateEmptyActive cassette; + std::array fdd; + std::array cdrom; + std::array zip; + std::array mo; + std::array hdds; + StateActive net; + std::unique_ptr sound; + std::unique_ptr text; +}; + +MachineStatus::MachineStatus(QObject *parent) : + QObject(parent) +{ + d = std::make_unique(this); +} + +MachineStatus::~MachineStatus() = default; + +bool MachineStatus::hasCassette() { + return cassette_enable > 0 ? true : false; +} + +bool MachineStatus::hasIDE() { + return machine_has_flags(machine, MACHINE_IDE_QUAD) > 0; +} + +bool MachineStatus::hasSCSI() { + return machine_has_flags(machine, MACHINE_SCSI_DUAL) > 0; +} + +void MachineStatus::iterateFDD(const std::function &cb) { + for (int i = 0; i < FDD_NUM; ++i) { + if (fdd_get_type(i) != 0) { + cb(i); + } + } +} + +void MachineStatus::iterateCDROM(const std::function &cb) { + auto hdc_name = QString(hdc_get_internal_name(hdc_current)); + for (size_t i = 0; i < CDROM_NUM; i++) { + /* Could be Internal or External IDE.. */ + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && + !hasIDE() && hdc_name != QStringLiteral("ide") && + hdc_name != QStringLiteral("xtide")) + continue; + if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !hasSCSI() && + (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && + (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + continue; + if (cdrom[i].bus_type != 0) { + cb(i); + } + } +} + +void MachineStatus::iterateZIP(const std::function &cb) { + auto hdc_name = QString(hdc_get_internal_name(hdc_current)); + for (size_t i = 0; i < ZIP_NUM; i++) { + /* Could be Internal or External IDE.. */ + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && + !hasIDE() && hdc_name != QStringLiteral("ide") && + hdc_name != QStringLiteral("xtide")) + continue; + if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !hasSCSI() && + (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && + (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + continue; + if (zip_drives[i].bus_type != 0) { + cb(i); + } + } +} + +void MachineStatus::iterateMO(const std::function &cb) { + auto hdc_name = QString(hdc_get_internal_name(hdc_current)); + for (size_t i = 0; i < MO_NUM; i++) { + /* Could be Internal or External IDE.. */ + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && + !hasIDE() && hdc_name != QStringLiteral("ide") && + hdc_name != QStringLiteral("xtide")) + continue; + if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !hasSCSI() && + (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && + (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + continue; + if (mo_drives[i].bus_type != 0) { + cb(i); + } + } +} + +static int hdd_count(int bus) { + int c = 0; + int i; + + for (i = 0; i < HDD_NUM; i++) { + if (hdd[i].bus == bus) { + c++; + } + } + + return(c); +} + +void MachineStatus::refresh(QStatusBar* sbar) { + bool has_mfm = machine_has_flags(machine, MACHINE_MFM) > 0; + bool has_xta = machine_has_flags(machine, MACHINE_XTA) > 0; + bool has_esdi = machine_has_flags(machine, MACHINE_ESDI) > 0; + + int c_mfm = hdd_count(HDD_BUS_MFM); + int c_esdi = hdd_count(HDD_BUS_ESDI); + int c_xta = hdd_count(HDD_BUS_XTA); + int c_ide = hdd_count(HDD_BUS_IDE); + int c_scsi = hdd_count(HDD_BUS_SCSI); + int do_net = (network_type == NET_TYPE_NONE) || (network_card == 0); + + sbar->removeWidget(d->cassette.label.get()); + for (int i = 0; i < 2; ++i) { + sbar->removeWidget(d->cartridge[i].label.get()); + } + for (size_t i = 0; i < FDD_NUM; ++i) { + sbar->removeWidget(d->fdd[i].label.get()); + } + for (size_t i = 0; i < CDROM_NUM; i++) { + sbar->removeWidget(d->cdrom[i].label.get()); + } + for (size_t i = 0; i < ZIP_NUM; i++) { + sbar->removeWidget(d->zip[i].label.get()); + } + for (size_t i = 0; i < MO_NUM; i++) { + sbar->removeWidget(d->mo[i].label.get()); + } + for (size_t i = 0; i < HDD_BUS_USB; i++) { + sbar->removeWidget(d->hdds[i].label.get()); + } + sbar->removeWidget(d->net.label.get()); + sbar->removeWidget(d->sound.get()); + + if (cassette_enable) { + d->cassette.label = std::make_unique(); + d->cassette.setEmpty(QString(cassette_fname).isEmpty()); + connect((ClickableLabel*)d->cassette.label.get(), &ClickableLabel::clicked, [this](QPoint pos) { + MediaMenu::ptr->cassetteMenu->popup(pos - QPoint(0, MediaMenu::ptr->cassetteMenu->sizeHint().height())); + }); + d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title()); + sbar->addWidget(d->cassette.label.get()); + } + + if (machine_has_cartridge(machine)) { + for (int i = 0; i < 2; ++i) { + d->cartridge[i].label = std::make_unique(); + d->cartridge[i].setEmpty(QString(cart_fns[i]).isEmpty()); + connect((ClickableLabel*)d->cartridge[i].label.get(), &ClickableLabel::clicked, [this, i](QPoint pos) { + MediaMenu::ptr->cartridgeMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->cartridgeMenus[i]->sizeHint().height())); + }); + d->cartridge[i].label->setToolTip(MediaMenu::ptr->cartridgeMenus[i]->title()); + sbar->addWidget(d->cartridge[i].label.get()); + } + } + + iterateFDD([this, sbar](int i) { + int t = fdd_get_type(i); + if (t == 0) { + d->fdd[i].pixmaps = &d->pixmaps.floppy_disabled; + } else if (t >= 1 && t <= 6) { + d->fdd[i].pixmaps = &d->pixmaps.floppy_525; + } else { + d->fdd[i].pixmaps = &d->pixmaps.floppy_35; + } + d->fdd[i].label = std::make_unique(); + d->fdd[i].setEmpty(QString(floppyfns[i]).isEmpty()); + d->fdd[i].setActive(false); + connect((ClickableLabel*)d->fdd[i].label.get(), &ClickableLabel::clicked, [this, i](QPoint pos) { + MediaMenu::ptr->floppyMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->floppyMenus[i]->sizeHint().height())); + }); + d->fdd[i].label->setToolTip(MediaMenu::ptr->floppyMenus[i]->title()); + sbar->addWidget(d->fdd[i].label.get()); + }); + + iterateCDROM([this, sbar](int i) { + d->cdrom[i].label = std::make_unique(); + d->cdrom[i].setEmpty(cdrom[i].host_drive != 200 || QString(cdrom[i].image_path).isEmpty()); + d->cdrom[i].setActive(false); + connect((ClickableLabel*)d->cdrom[i].label.get(), &ClickableLabel::clicked, [this, i](QPoint pos) { + MediaMenu::ptr->cdromMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->cdromMenus[i]->sizeHint().height())); + }); + d->cdrom[i].label->setToolTip(MediaMenu::ptr->cdromMenus[i]->title()); + sbar->addWidget(d->cdrom[i].label.get()); + }); + + iterateZIP([this, sbar](int i) { + d->zip[i].label = std::make_unique(); + d->zip[i].setEmpty(QString(zip_drives[i].image_path).isEmpty()); + d->zip[i].setActive(false); + connect((ClickableLabel*)d->zip[i].label.get(), &ClickableLabel::clicked, [this, i](QPoint pos) { + MediaMenu::ptr->zipMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->zipMenus[i]->sizeHint().height())); + }); + d->zip[i].label->setToolTip(MediaMenu::ptr->zipMenus[i]->title()); + sbar->addWidget(d->zip[i].label.get()); + }); + + iterateMO([this, sbar](int i) { + d->mo[i].label = std::make_unique(); + d->mo[i].setEmpty(QString(mo_drives[i].image_path).isEmpty()); + d->mo[i].setActive(false); + connect((ClickableLabel*)d->mo[i].label.get(), &ClickableLabel::clicked, [this, i](QPoint pos) { + MediaMenu::ptr->moMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->moMenus[i]->sizeHint().height())); + }); + d->mo[i].label->setToolTip(MediaMenu::ptr->moMenus[i]->title()); + sbar->addWidget(d->mo[i].label.get()); + }); + + auto hdc_name = QString(hdc_get_internal_name(hdc_current)); + if ((has_mfm || hdc_name.left(5) == QStringLiteral("st506")) && c_mfm > 0) { + d->hdds[HDD_BUS_MFM].label = std::make_unique(); + d->hdds[HDD_BUS_MFM].setActive(false); + d->hdds[HDD_BUS_MFM].label->setToolTip(tr("Hard disk (%s)").replace("%s", "MFM/RLL")); + sbar->addWidget(d->hdds[HDD_BUS_MFM].label.get()); + } + if ((has_esdi || hdc_name.left(4) == QStringLiteral("esdi")) && c_esdi > 0) { + d->hdds[HDD_BUS_ESDI].label = std::make_unique(); + d->hdds[HDD_BUS_ESDI].setActive(false); + d->hdds[HDD_BUS_ESDI].label->setToolTip(tr("Hard disk (%s)").replace("%s", "ESDI")); + sbar->addWidget(d->hdds[HDD_BUS_ESDI].label.get()); + } + if ((has_xta || hdc_name.left(3) == QStringLiteral("xta")) && c_xta > 0) { + d->hdds[HDD_BUS_XTA].label = std::make_unique(); + d->hdds[HDD_BUS_XTA].setActive(false); + d->hdds[HDD_BUS_XTA].label->setToolTip(tr("Hard disk (%s)").replace("%s", "XTA")); + sbar->addWidget(d->hdds[HDD_BUS_XTA].label.get()); + } + if ((hasIDE() || hdc_name.left(5) == QStringLiteral("xtide") || hdc_name.left(3) == QStringLiteral("ide")) && c_ide > 0) { + d->hdds[HDD_BUS_IDE].label = std::make_unique(); + d->hdds[HDD_BUS_IDE].setActive(false); + d->hdds[HDD_BUS_IDE].label->setToolTip(tr("Hard disk (%s)").replace("%s", "IDE")); + sbar->addWidget(d->hdds[HDD_BUS_IDE].label.get()); + } + if ((hasSCSI() || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || + (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0)) && c_scsi > 0) { + d->hdds[HDD_BUS_SCSI].label = std::make_unique(); + d->hdds[HDD_BUS_SCSI].setActive(false); + d->hdds[HDD_BUS_SCSI].label->setToolTip(tr("Hard disk (%s)").replace("%s", "SCSI")); + sbar->addWidget(d->hdds[HDD_BUS_SCSI].label.get()); + } + + if (do_net) { + d->net.label = std::make_unique(); + d->net.setActive(false); + d->net.label->setToolTip(tr("Network")); + sbar->addWidget(d->net.label.get()); + } + d->sound = std::make_unique(); + d->sound->setPixmap(d->pixmaps.sound); + + connect(d->sound.get(), &ClickableLabel::doubleClicked, d->sound.get(), [this](QPoint pos) { + SoundGain gain(main_window); + gain.exec(); + }); + d->sound->setToolTip(tr("Sound")); + sbar->addWidget(d->sound.get()); + d->text = std::make_unique(); + sbar->addWidget(d->text.get()); +} + +void MachineStatus::setActivity(int tag, bool active) { + int category = tag & 0xfffffff0; + int item = tag & 0xf; + switch (category) { + case SB_CASSETTE: + break; + case SB_CARTRIDGE: + break; + case SB_FLOPPY: + d->fdd[item].setActive(active); + break; + case SB_CDROM: + d->cdrom[item].setActive(active); + break; + case SB_ZIP: + d->zip[item].setActive(active); + break; + case SB_MO: + d->mo[item].setActive(active); + break; + case SB_HDD: + d->hdds[item].setActive(active); + break; + case SB_NETWORK: + d->net.setActive(active); + break; + case SB_SOUND: + break; + case SB_TEXT: + break; + } +} + +void MachineStatus::setEmpty(int tag, bool empty) { + int category = tag & 0xfffffff0; + int item = tag & 0xf; + switch (category) { + case SB_CASSETTE: + d->cassette.setEmpty(empty); + break; + case SB_CARTRIDGE: + d->cartridge[item].setEmpty(empty); + break; + case SB_FLOPPY: + d->fdd[item].setEmpty(empty); + break; + case SB_CDROM: + d->cdrom[item].setEmpty(empty); + break; + case SB_ZIP: + d->zip[item].setEmpty(empty); + break; + case SB_MO: + d->mo[item].setEmpty(empty); + break; + case SB_HDD: + break; + case SB_NETWORK: + break; + case SB_SOUND: + break; + case SB_TEXT: + break; + } +} + +void MachineStatus::message(const QString &msg) { + d->text->setText(msg); +} + +QString MachineStatus::getMessage() { + return d->text->text(); +} + +void MachineStatus::updateTip(int tag) +{ + int category = tag & 0xfffffff0; + int item = tag & 0xf; + switch (category) { + case SB_CASSETTE: + d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title()); + break; + case SB_CARTRIDGE: + d->cartridge[item].label->setToolTip(MediaMenu::ptr->cartridgeMenus[item]->title()); + break; + case SB_FLOPPY: + d->fdd[item].label->setToolTip(MediaMenu::ptr->floppyMenus[item]->title()); + break; + case SB_CDROM: + d->cdrom[item].label->setToolTip(MediaMenu::ptr->cdromMenus[item]->title()); + break; + case SB_ZIP: + d->zip[item].label->setToolTip(MediaMenu::ptr->zipMenus[item]->title()); + break; + case SB_MO: + d->mo[item].label->setToolTip(MediaMenu::ptr->moMenus[item]->title()); + break; + case SB_HDD: + break; + case SB_NETWORK: + break; + case SB_SOUND: + break; + case SB_TEXT: + break; + } +} diff --git a/src/qt/qt_machinestatus.hpp b/src/qt/qt_machinestatus.hpp new file mode 100644 index 000000000..6f83234df --- /dev/null +++ b/src/qt/qt_machinestatus.hpp @@ -0,0 +1,57 @@ +#ifndef QT_MACHINESTATUS_HPP +#define QT_MACHINESTATUS_HPP + +#include +#include +#include + +#include + +class QStatusBar; + +class ClickableLabel : public QLabel { + Q_OBJECT; + public: + explicit ClickableLabel(QWidget* parent = nullptr) + : QLabel(parent) {} + ~ClickableLabel() {}; + + signals: + void clicked(QPoint); + void doubleClicked(QPoint); + + protected: + void mousePressEvent(QMouseEvent* event) override { emit clicked(event->globalPos()); } + void mouseDoubleClickEvent(QMouseEvent* event) override { emit doubleClicked(event->globalPos()); } +}; + +class MachineStatus : public QObject +{ + Q_OBJECT + +public: + explicit MachineStatus(QObject *parent = nullptr); + ~MachineStatus(); + + static bool hasCassette(); + static bool hasIDE(); + static bool hasSCSI(); + static void iterateFDD(const std::function& cb); + static void iterateCDROM(const std::function& cb); + static void iterateZIP(const std::function& cb); + static void iterateMO(const std::function& cb); + + QString getMessage(); +public slots: + void refresh(QStatusBar* sbar); + void setActivity(int tag, bool active); + void setEmpty(int tag, bool active); + void message(const QString& msg); + void updateTip(int tag); + +private: + struct States; + std::unique_ptr d; +}; + +#endif // QT_MACHINESTATUS_HPP diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp new file mode 100644 index 000000000..a6a999fa1 --- /dev/null +++ b/src/qt/qt_main.cpp @@ -0,0 +1,233 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef QT_STATIC +/* Static builds need plugin imports */ +#include +Q_IMPORT_PLUGIN(QICOPlugin) +#ifdef Q_OS_WINDOWS +Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) +Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin) +#endif +#endif + +#ifdef Q_OS_WINDOWS +#include "qt_winrawinputfilter.hpp" +#include "qt_winmanagerfilter.hpp" +#include <86box/win.h> +#endif + +extern "C" +{ +#include <86box/86box.h> +#include <86box/config.h> +#include <86box/plat.h> +#include <86box/ui.h> +#include <86box/video.h> +#include <86box/discord.h> +} + +#include +#include +#include + +#include "qt_mainwindow.hpp" +#include "qt_progsettings.hpp" +#include "qt_settings.hpp" +#include "cocoa_mouse.hpp" +#include "qt_styleoverride.hpp" + +// Void Cast +#define VC(x) const_cast(x) + +extern QElapsedTimer elapsed_timer; +extern MainWindow* main_window; + +extern "C" { +#include <86box/timer.h> +#include <86box/nvr.h> + extern int qt_nvr_save(void); +} + +void qt_set_sequence_auto_mnemonic(bool b); + +void +main_thread_fn() +{ + uint64_t old_time, new_time; + int drawits, frames; + + QThread::currentThread()->setPriority(QThread::HighestPriority); + framecountx = 0; + //title_update = 1; + old_time = elapsed_timer.elapsed(); + drawits = frames = 0; + while (!is_quit && cpu_thread_run) { + /* See if it is time to run a frame of code. */ + new_time = elapsed_timer.elapsed(); + drawits += (new_time - old_time); + old_time = new_time; + if (drawits > 0 && !dopause) { + /* Yes, so do one frame now. */ + drawits -= 10; + if (drawits > 50) + drawits = 0; + + /* Run a block of code. */ + pc_run(); + + /* Every 200 frames we save the machine status. */ + if (++frames >= 200 && nvr_dosave) { + qt_nvr_save(); + nvr_dosave = 0; + frames = 0; + } + } else { + /* Just so we dont overload the host OS. */ + if (drawits < -1) + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + else + std::this_thread::yield(); + } + + /* If needed, handle a screen resize. */ + if (!atomic_flag_test_and_set(&doresize) && !video_fullscreen && !is_quit) { + if (vid_resize & 2) + plat_resize(fixed_size_x, fixed_size_y); + else + plat_resize(scrnsz_x, scrnsz_y); + } + } + + is_quit = 1; +} + +int main(int argc, char* argv[]) { + QApplication app(argc, argv); + qt_set_sequence_auto_mnemonic(false); + Q_INIT_RESOURCE(qt_resources); + Q_INIT_RESOURCE(qt_translations); + QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); + fmt.setSwapInterval(0); + QSurfaceFormat::setDefaultFormat(fmt); + app.setStyle(new StyleOverride()); + +#ifdef __APPLE__ + CocoaEventFilter cocoafilter; + app.installNativeEventFilter(&cocoafilter); +#endif + elapsed_timer.start(); + + if (!pc_init(argc, argv)) + { + return 0; + } + ProgSettings::loadTranslators(&app); + if (! pc_init_modules()) { + ui_msgbox_header(MBX_FATAL, (void*)IDS_2120, (void*)IDS_2056); + return 6; + } + + if (settings_only) + { + Settings settings; + if (settings.exec() == QDialog::Accepted) + { + settings.save(); + config_save(); + } + return 0; + } + + discord_load(); + + main_window = new MainWindow(); + main_window->show(); + app.installEventFilter(main_window); + +#ifdef Q_OS_WINDOWS + /* Setup VM-manager messages */ + std::unique_ptr wmfilter; + if (source_hwnd) + { + HWND main_hwnd = (HWND)main_window->winId(); + + wmfilter.reset(new WindowsManagerFilter()); + QObject::connect(wmfilter.get(), &WindowsManagerFilter::showsettings, main_window, &MainWindow::showSettings); + QObject::connect(wmfilter.get(), &WindowsManagerFilter::pause, main_window, &MainWindow::togglePause); + QObject::connect(wmfilter.get(), &WindowsManagerFilter::reset, main_window, &MainWindow::hardReset); + QObject::connect(wmfilter.get(), &WindowsManagerFilter::shutdown, [](){ plat_power_off(); }); + QObject::connect(wmfilter.get(), &WindowsManagerFilter::ctrlaltdel, [](){ pc_send_cad(); }); + QObject::connect(wmfilter.get(), &WindowsManagerFilter::dialogstatus, [main_hwnd](bool open){ + PostMessage((HWND)(uintptr_t)source_hwnd, WM_SENDDLGSTATUS, (WPARAM)(open ? 1 : 0), (LPARAM)main_hwnd); + }); + + /* Native filter to catch VM-managers commands */ + app.installNativeEventFilter(wmfilter.get()); + + /* Filter to catch main window being blocked (by modal dialog) */ + main_window->installEventFilter(wmfilter.get()); + + /* Send main window HWND to manager */ + PostMessage((HWND)(uintptr_t)source_hwnd, WM_SENDHWND, (WPARAM)unique_id, (LPARAM)main_hwnd); + + /* Send shutdown message to manager */ + QObject::connect(&app, &QApplication::destroyed, [main_hwnd](QObject*) { + PostMessage((HWND)(uintptr_t)source_hwnd, WM_HAS_SHUTDOWN, (WPARAM)0, (LPARAM)main_hwnd); + }); + } + + /* Setup raw input */ + auto rawInputFilter = WindowsRawInputFilter::Register(main_window); + if (rawInputFilter) + { + app.installNativeEventFilter(rawInputFilter.get()); + QObject::disconnect(main_window, &MainWindow::pollMouse, 0, 0); + QObject::connect(main_window, &MainWindow::pollMouse, (WindowsRawInputFilter*)rawInputFilter.get(), &WindowsRawInputFilter::mousePoll, Qt::DirectConnection); + main_window->setSendKeyboardInput(false); + } +#endif + + pc_reset_hard_init(); + + /* Set the PAUSE mode depending on the renderer. */ + // plat_pause(0); + QTimer onesec; + QTimer discordupdate; + QObject::connect(&onesec, &QTimer::timeout, &app, [] { + pc_onesec(); + }); + onesec.setTimerType(Qt::PreciseTimer); + onesec.start(1000); + if (discord_loaded) { + QTimer::singleShot(1000, &app, [] { + if (enable_discord) { + discord_init(); + discord_update_activity(dopause); + } else + discord_close(); + }); + QObject::connect(&discordupdate, &QTimer::timeout, &app, [] { + discord_run_callbacks(); + }); + discordupdate.start(0); + } + + /* Initialize the rendering window, or fullscreen. */ + auto main_thread = std::thread([] { + main_thread_fn(); + }); + + auto ret = app.exec(); + cpu_thread_run = 0; + main_thread.join(); + + return ret; +} diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp new file mode 100644 index 000000000..881053cdc --- /dev/null +++ b/src/qt/qt_mainwindow.cpp @@ -0,0 +1,1577 @@ +#include "qt_mainwindow.hpp" +#include "ui_qt_mainwindow.h" + +#include "qt_specifydimensions.h" +#include "qt_soundgain.hpp" +#include "qt_progsettings.hpp" + +#include "qt_rendererstack.hpp" +#include "qt_renderercommon.hpp" + +extern "C" { +#include <86box/86box.h> +#include <86box/config.h> +#include <86box/keyboard.h> +#include <86box/plat.h> +#include <86box/discord.h> +#include <86box/video.h> +#include <86box/vid_ega.h> +#include <86box/version.h> + +#ifdef MTR_ENABLED +#include +#endif +}; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "qt_settings.hpp" +#include "qt_machinestatus.hpp" +#include "qt_mediamenu.hpp" + +#ifdef __unix__ +#ifdef WAYLAND +#include "wl_mouse.hpp" +#endif +#include +#include +#undef KeyPress +#undef KeyRelease +#endif + +extern void qt_mouse_capture(int); +extern "C" void qt_blit(int x, int y, int w, int h); + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ +#ifdef Q_OS_WINDOWS + auto font_name = tr("FONT_NAME"); + auto font_size = tr("FONT_SIZE"); + QApplication::setFont(QFont(font_name, font_size.toInt())); +#endif + + mm = std::make_shared(this); + MediaMenu::ptr = mm; + status = std::make_unique(this); + + setUnifiedTitleAndToolBarOnMac(true); + ui->setupUi(this); + ui->stackedWidget->setMouseTracking(true); + statusBar()->setVisible(!hide_status_bar); + statusBar()->setStyleSheet("QStatusBar::item {border: None; } QStatusBar QLabel { margin-right: 2px; margin-bottom: 1px; }"); + ui->toolBar->setVisible(!hide_tool_bar); + + auto toolbar_spacer = new QWidget(); + toolbar_spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + ui->toolBar->addWidget(toolbar_spacer); + + auto toolbar_label = new QLabel(); + ui->toolBar->addWidget(toolbar_label); + + this->setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); + this->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, vid_resize != 1); + this->setWindowFlag(Qt::WindowMaximizeButtonHint, vid_resize == 1); + + this->setWindowTitle(QString("%1 - %2 %3").arg(vm_name, EMU_NAME, EMU_VERSION_FULL)); + + connect(this, &MainWindow::showMessageForNonQtThread, this, &MainWindow::showMessage_, Qt::BlockingQueuedConnection); + + connect(this, &MainWindow::setTitle, this, [this,toolbar_label](const QString& title) { + if (!hide_tool_bar) +#ifdef _WIN32 + toolbar_label->setText(title); +#else + { + /* get the percentage and mouse message, TODO: refactor ui_window_title() */ + auto parts = title.split(" - "); + if (parts.size() >= 2) { + if (parts.size() < 5) + toolbar_label->setText(parts[1]); + else + toolbar_label->setText(QString("%1 - %2").arg(parts[1], parts.last())); + } + } +#endif + ui->actionPause->setChecked(dopause); + }); + connect(this, &MainWindow::getTitleForNonQtThread, this, &MainWindow::getTitle_, Qt::BlockingQueuedConnection); + + connect(this, &MainWindow::updateMenuResizeOptions, [this]() { + ui->actionResizable_window->setEnabled(vid_resize != 2); + ui->actionResizable_window->setChecked(vid_resize == 1); + ui->menuWindow_scale_factor->setEnabled(vid_resize == 0); + }); + + connect(this, &MainWindow::updateWindowRememberOption, [this]() { + ui->actionRemember_size_and_position->setChecked(window_remember); + }); + + emit updateMenuResizeOptions(); + + connect(this, &MainWindow::pollMouse, ui->stackedWidget, &RendererStack::mousePoll, Qt::DirectConnection); + + connect(this, &MainWindow::setMouseCapture, this, [this](bool state) { + mouse_capture = state ? 1 : 0; + qt_mouse_capture(mouse_capture); + if (mouse_capture) { + ui->stackedWidget->grabMouse(); + this->grabKeyboard(); +#ifdef WAYLAND + if (QGuiApplication::platformName().contains("wayland")) { + wl_mouse_capture(this->windowHandle()); + } +#endif + } else { + ui->stackedWidget->releaseMouse(); + this->releaseKeyboard(); +#ifdef WAYLAND + if (QGuiApplication::platformName().contains("wayland")) { + wl_mouse_uncapture(); + } +#endif + } + }); + + connect(this, &MainWindow::resizeContents, this, [this](int w, int h) { + if (!QApplication::platformName().contains("eglfs") && vid_resize == 0) { + w = w / (!dpi_scale ? this->screen()->devicePixelRatio() : 1); + + int modifiedHeight = (h / (!dpi_scale ? this->screen()->devicePixelRatio() : 1)) + + menuBar()->height() + + (statusBar()->height() * !hide_status_bar) + + (ui->toolBar->height() * !hide_tool_bar); + + ui->stackedWidget->resize(w, h); + if (vid_resize == 0) { + setFixedSize(w, modifiedHeight); + } else { + resize(w, modifiedHeight); + } + } + }); + + connect(ui->menubar, &QMenuBar::triggered, this, [this] { + config_save(); + if (QApplication::activeWindow() == this) + { + ui->stackedWidget->current->setFocus(); + } + }); + + connect(this, &MainWindow::updateStatusBarPanes, this, [this] { + refreshMediaMenu(); + }); + connect(this, &MainWindow::updateStatusBarPanes, this, &MainWindow::refreshMediaMenu); + connect(this, &MainWindow::updateStatusBarTip, status.get(), &MachineStatus::updateTip); + connect(this, &MainWindow::updateStatusBarActivity, status.get(), &MachineStatus::setActivity); + connect(this, &MainWindow::updateStatusBarEmpty, status.get(), &MachineStatus::setEmpty); + connect(this, &MainWindow::statusBarMessage, status.get(), &MachineStatus::message); + + ui->actionKeyboard_requires_capture->setChecked(kbd_req_capture); + ui->actionRight_CTRL_is_left_ALT->setChecked(rctrl_is_lalt); + ui->actionResizable_window->setChecked(vid_resize == 1); + ui->actionRemember_size_and_position->setChecked(window_remember); + ui->menuWindow_scale_factor->setEnabled(vid_resize == 0); + ui->actionHiDPI_scaling->setChecked(dpi_scale); + ui->actionHide_status_bar->setChecked(hide_status_bar); + ui->actionHide_tool_bar->setChecked(hide_tool_bar); + ui->actionUpdate_status_bar_icons->setChecked(update_icons); + ui->actionEnable_Discord_integration->setChecked(enable_discord); + +#if defined Q_OS_WINDOWS || defined Q_OS_MACOS + /* Make the option visible only if ANGLE is loaded. */ + ui->actionHardware_Renderer_OpenGL_ES->setVisible(QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES); + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES && vid_api == 2) vid_api = 1; +#endif + + if (QApplication::platformName().contains("eglfs") && vid_api >= 1) { + fprintf(stderr, "OpenGL renderers are unsupported on EGLFS.\n"); + vid_api = 0; + } + QActionGroup* actGroup = nullptr; + switch (vid_api) { + case 0: + ui->stackedWidget->switchRenderer(RendererStack::Renderer::Software); + ui->actionSoftware_Renderer->setChecked(true); + break; + case 1: + ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL); + ui->actionHardware_Renderer_OpenGL->setChecked(true); + break; + case 2: + ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGLES); + ui->actionHardware_Renderer_OpenGL_ES->setChecked(true); + break; + case 3: + ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL3); + ui->actionOpenGL_3_0_Core->setChecked(true); + break; + } + actGroup = new QActionGroup(this); + actGroup->addAction(ui->actionSoftware_Renderer); + actGroup->addAction(ui->actionHardware_Renderer_OpenGL); + actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES); + actGroup->addAction(ui->actionOpenGL_3_0_Core); + switch (scale) { + case 0: + ui->action0_5x->setChecked(true); + break; + case 1: + ui->action1x->setChecked(true); + break; + case 2: + ui->action1_5x->setChecked(true); + break; + case 3: + ui->action2x->setChecked(true); + break; + } + actGroup = new QActionGroup(this); + actGroup->addAction(ui->action0_5x); + actGroup->addAction(ui->action1x); + actGroup->addAction(ui->action1_5x); + actGroup->addAction(ui->action2x); + switch (video_filter_method) { + case 0: + ui->actionNearest->setChecked(true); + break; + case 1: + ui->actionLinear->setChecked(true); + break; + } + actGroup = new QActionGroup(this); + actGroup->addAction(ui->actionNearest); + actGroup->addAction(ui->actionLinear); + switch (video_fullscreen_scale) { + case FULLSCR_SCALE_FULL: + ui->actionFullScreen_stretch->setChecked(true); + break; + case FULLSCR_SCALE_43: + ui->actionFullScreen_43->setChecked(true); + break; + case FULLSCR_SCALE_KEEPRATIO: + ui->actionFullScreen_keepRatio->setChecked(true); + break; + case FULLSCR_SCALE_INT: + ui->actionFullScreen_int->setChecked(true); + break; + } + actGroup = new QActionGroup(this); + actGroup->addAction(ui->actionFullScreen_stretch); + actGroup->addAction(ui->actionFullScreen_43); + actGroup->addAction(ui->actionFullScreen_keepRatio); + actGroup->addAction(ui->actionFullScreen_int); + switch (video_grayscale) { + case 0: + ui->actionRGB_Color->setChecked(true); + break; + case 1: + ui->actionRGB_Grayscale->setChecked(true); + break; + case 2: + ui->actionAmber_monitor->setChecked(true); + break; + case 3: + ui->actionGreen_monitor->setChecked(true); + break; + case 4: + ui->actionWhite_monitor->setChecked(true); + break; + } + actGroup = new QActionGroup(this); + actGroup->addAction(ui->actionRGB_Grayscale); + actGroup->addAction(ui->actionAmber_monitor); + actGroup->addAction(ui->actionGreen_monitor); + actGroup->addAction(ui->actionWhite_monitor); + actGroup->addAction(ui->actionRGB_Color); + switch (video_graytype) { + case 0: + ui->actionBT601_NTSC_PAL->setChecked(true); + break; + case 1: + ui->actionBT709_HDTV->setChecked(true); + break; + case 2: + ui->actionAverage->setChecked(true); + break; + } + actGroup = new QActionGroup(this); + actGroup->addAction(ui->actionBT601_NTSC_PAL); + actGroup->addAction(ui->actionBT709_HDTV); + actGroup->addAction(ui->actionAverage); + if (force_43 > 0) { + ui->actionForce_4_3_display_ratio->setChecked(true); + } + if (enable_overscan > 0) { + ui->actionCGA_PCjr_Tandy_EGA_S_VGA_overscan->setChecked(true); + } + if (vid_cga_contrast > 0) { + ui->actionChange_contrast_for_monochrome_display->setChecked(true); + } + +#ifdef Q_OS_MACOS + ui->actionFullscreen->setShortcutVisibleInContextMenu(true); + ui->actionCtrl_Alt_Del->setShortcutVisibleInContextMenu(true); + ui->actionTake_screenshot->setShortcutVisibleInContextMenu(true); +#endif + video_setblit(qt_blit); + + if (start_in_fullscreen) { + connect(ui->stackedWidget, &RendererStack::blitToRenderer, this, [this] () { + if (start_in_fullscreen) { + QTimer::singleShot(100, ui->actionFullscreen, &QAction::trigger); + start_in_fullscreen = 0; + } + }); + } + +#ifdef MTR_ENABLED + { + ui->menuTools->addSeparator(); + ui->actionBegin_trace->setVisible(true); + ui->actionEnd_trace->setVisible(true); + ui->actionBegin_trace->setShortcut(QKeySequence(Qt::Key_Control + Qt::Key_T)); + ui->actionEnd_trace->setShortcut(QKeySequence(Qt::Key_Control + Qt::Key_T)); + ui->actionEnd_trace->setDisabled(true); + static auto init_trace = [&] + { + mtr_init("trace.json"); + mtr_start(); + }; + static auto shutdown_trace = [&] + { + mtr_stop(); + mtr_shutdown(); + }; +#ifdef Q_OS_MACOS + ui->actionBegin_trace->setShortcutVisibleInContextMenu(true); + ui->actionEnd_trace->setShortcutVisibleInContextMenu(true); +#endif + static bool trace = false; + connect(ui->actionBegin_trace, &QAction::triggered, this, [this] + { + if (trace) return; + ui->actionBegin_trace->setDisabled(true); + ui->actionEnd_trace->setDisabled(false); + init_trace(); + trace = true; + }); + connect(ui->actionEnd_trace, &QAction::triggered, this, [this] + { + if (!trace) return; + ui->actionBegin_trace->setDisabled(false); + ui->actionEnd_trace->setDisabled(true); + shutdown_trace(); + trace = false; + }); + } +#endif +} + +void MainWindow::closeEvent(QCloseEvent *event) { + if (confirm_exit && cpu_thread_run) + { + QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to exit 86Box?"), QMessageBox::Yes | QMessageBox::No, this); + QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + questionbox.setCheckBox(chkbox); + chkbox->setChecked(!confirm_exit); + bool confirm_exit_temp = false; + QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { + confirm_exit = (state == Qt::CheckState::Unchecked); + }); + questionbox.exec(); + if (questionbox.result() == QMessageBox::No) { + confirm_exit = true; + event->ignore(); + return; + } + } + if (window_remember) { + window_w = ui->stackedWidget->width(); + window_h = ui->stackedWidget->height(); + if (!QApplication::platformName().contains("wayland")) { + window_x = this->geometry().x(); + window_y = this->geometry().y(); + } + } + config_save(); + event->accept(); +} + +MainWindow::~MainWindow() { + delete ui; +} + +void MainWindow::showEvent(QShowEvent *event) { + if (shownonce) return; + shownonce = true; + if (window_remember && !QApplication::platformName().contains("wayland")) { + setGeometry(window_x, window_y, window_w, window_h + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height())); + } + if (vid_resize == 2) { + setFixedSize(fixed_size_x, fixed_size_y + + menuBar()->height() + + (hide_status_bar ? 0 : statusBar()->height()) + + (hide_tool_bar ? 0 : ui->toolBar->height())); + + scrnsz_x = fixed_size_x; + scrnsz_y = fixed_size_y; + } + else if (window_remember) { + emit resizeContents(window_w, window_h); + scrnsz_x = window_w; + scrnsz_y = window_h; + } +} + +void MainWindow::on_actionKeyboard_requires_capture_triggered() { + kbd_req_capture ^= 1; +} + +void MainWindow::on_actionRight_CTRL_is_left_ALT_triggered() { + rctrl_is_lalt ^= 1; +} + +void MainWindow::on_actionHard_Reset_triggered() { + if (confirm_reset) + { + QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to hard reset the emulated machine?"), QMessageBox::NoButton, this); + questionbox.addButton(tr("Don't reset"), QMessageBox::AcceptRole); + questionbox.addButton(tr("Reset"), QMessageBox::RejectRole); + QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + questionbox.setCheckBox(chkbox); + chkbox->setChecked(!confirm_reset); + bool confirm_exit_temp = false; + QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { + confirm_reset = (state == Qt::CheckState::Unchecked); + }); + questionbox.exec(); + if (questionbox.result() == QDialog::Rejected) + { + confirm_reset = true; + return; + } + } + config_changed = 2; + pc_reset_hard(); +} + +void MainWindow::on_actionCtrl_Alt_Del_triggered() { + pc_send_cad(); +} + +void MainWindow::on_actionCtrl_Alt_Esc_triggered() { + pc_send_cae(); +} + +void MainWindow::on_actionPause_triggered() { + plat_pause(dopause ^ 1); +} + +void MainWindow::on_actionExit_triggered() { + close(); +} + +void MainWindow::on_actionSettings_triggered() { + int currentPause = dopause; + plat_pause(1); + Settings settings(this); + settings.setModal(true); + settings.setWindowModality(Qt::WindowModal); + settings.exec(); + + switch (settings.result()) { + case QDialog::Accepted: + /* + pc_reset_hard_close(); + settings.save(); + config_changed = 2; + pc_reset_hard_init(); + */ + settings.save(); + config_changed = 2; + pc_reset_hard(); + + break; + case QDialog::Rejected: + break; + } + plat_pause(currentPause); +} + +std::array x11_to_xt_base +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0A, + 0x0B, + 0x0C, + 0x0D, + 0x0E, + 0x0F, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1A, + 0x1B, + 0x1C, + 0x1D, + 0x1E, + 0x1F, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2A, + 0x2B, + 0x2C, + 0x2D, + 0x2E, + 0x2F, + 0x30, + 0x31, + 0x32, + 0x33, + 0x34, + 0x35, + 0x36, + 0x37, + 0x38, + 0x39, + 0x3A, + 0x3B, + 0x3C, + 0x3D, + 0x3E, + 0x3F, + 0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4A, + 0x4B, + 0x4C, + 0x4D, + 0x4E, + 0x4F, + 0x50, + 0x51, + 0x52, + 0x53, + 0x54, + 0x55, + 0x56, + 0x57, + 0x58, + 0x147, + 0x148, + 0x149, + 0, + 0x14B, + 0, + 0x14D, + 0x14F, + 0x150, + 0x151, + 0x152, + 0x153, + 0x11C, + 0x11D, + 0, // Pause/Break key. + 0x137, + 0x135, + 0x138, + 0, // Ditto as above comment. + 0x15B, + 0x15C, + 0x15D, +}; + +std::array x11_to_xt_2 +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0A, + 0x0B, + 0x0C, + 0x0D, + 0x0E, + 0x0F, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1A, + 0x1B, + 0x1C, + 0x1D, + 0x1E, + 0x1F, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2A, + 0x2B, + 0x2C, + 0x2D, + 0x2E, + 0x2F, + 0x30, + 0x31, + 0x32, + 0x33, + 0x34, + 0x35, + 0x36, + 0x37, + 0x38, + 0x39, + 0x3A, + 0x3B, + 0x3C, + 0x3D, + 0x3E, + 0x3F, + 0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4A, + 0x4B, + 0x4C, + 0x4D, + 0x4E, + 0x4F, + 0x50, + 0x51, + 0x52, + 0x53, + 0x54, + 0x55, + 0x56, + 0x57, + 0x58, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0x11C, + 0x11D, + 0x135, + 0x137, + 0x138, + 0, + 0x147, + 0x148, + 0x149, + 0x14B, + 0x14D, + 0x14F, + 0x150, + 0x151, + 0x152, + 0x153 +}; + +std::array x11_to_xt_vnc +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0x1D, + 0x11D, + 0x2A, + 0x36, + 0, + 0, + 0x38, + 0x138, + 0x39, + 0x0B, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0A, + 0x0C, + 0x0D, + 0x1A, + 0x1B, + 0x27, + 0x28, + 0x29, + 0x33, + 0x34, + 0x35, + 0x2B, + 0x1E, + 0x30, + 0x2E, + 0x20, + 0x12, + 0x21, + 0x22, + 0x23, + 0x17, + 0x24, + 0x25, + 0x26, + 0x32, + 0x31, + 0x18, + 0x19, + 0x10, + 0x13, + 0x1F, + 0x14, + 0x16, + 0x2F, + 0x11, + 0x2D, + 0x15, + 0x2C, + 0x0E, + 0x1C, + 0x0F, + 0x01, + 0x153, + 0x147, + 0x14F, + 0x149, + 0x151, + 0x148, + 0x150, + 0x14B, + 0x14D, +}; + +std::array darwin_to_xt +{ + 0x1E, + 0x1F, + 0x20, + 0x21, + 0x23, + 0x22, + 0x2C, + 0x2D, + 0x2E, + 0x2F, + 0x2B, + 0x30, + 0x10, + 0x11, + 0x12, + 0x13, + 0x15, + 0x14, + 0x02, + 0x03, + 0x04, + 0x05, + 0x07, + 0x06, + 0x0D, + 0x0A, + 0x08, + 0x0C, + 0x09, + 0x0B, + 0x1B, + 0x18, + 0x16, + 0x1A, + 0x17, + 0x19, + 0x1C, + 0x26, + 0x24, + 0x28, + 0x25, + 0x27, + 0x2B, + 0x33, + 0x35, + 0x31, + 0x32, + 0x34, + 0x0F, + 0x39, + 0x29, + 0x0E, + 0x11C, + 0x01, + 0x15C, + 0x15B, + 0x2A, + 0x3A, + 0x38, + 0x1D, + 0x36, + 0x138, + 0x11D, + 0x15C, + 0, + 0x53, + 0, + 0x37, + 0, + 0x4E, + 0, + 0x45, + 0x130, + 0x12E, + 0x120, + 0x135, + 0x11C, + 0, + 0x4A, + 0, + 0, + 0, + 0x52, + 0x4F, + 0x50, + 0x51, + 0x4B, + 0x4C, + 0x4D, + 0x47, + 0, + 0x48, + 0x49, + 0, + 0, + 0, + 0x3F, + 0x40, + 0x41, + 0x3D, + 0x42, + 0x43, + 0, + 0x57, + 0, + 0x137, + 0, + 0x46, + 0, + 0x44, + 0x15D, + 0x58, + 0, + 0, // Pause/Break key. + 0x152, + 0x147, + 0x149, + 0x153, + 0x3E, + 0x14F, + 0x3C, + 0x151, + 0x3B, + 0x14B, + 0x14D, + 0x150, + 0x148, + 0, +}; + +static std::unordered_map evdev_to_xt = + { + {96, 0x11C}, + {97, 0x11D}, + {98, 0x135}, + {99, 0x71}, + {100, 0x138}, + {101, 0x1C}, + {102, 0x147}, + {103, 0x148}, + {104, 0x149}, + {105, 0x14B}, + {106, 0x14D}, + {107, 0x14F}, + {108, 0x150}, + {109, 0x151}, + {110, 0x152}, + {111, 0x153} +}; + +static std::array& selected_keycode = x11_to_xt_base; + +uint16_t x11_keycode_to_keysym(uint32_t keycode) +{ + uint16_t finalkeycode = 0; +#if defined(Q_OS_WINDOWS) + finalkeycode = (keycode & 0xFFFF); +#elif defined(__APPLE__) + finalkeycode = darwin_to_xt[keycode]; +#else + static Display* x11display = nullptr; + if (QApplication::platformName().contains("wayland")) + { + selected_keycode = x11_to_xt_2; + } + else if (QApplication::platformName().contains("eglfs")) + { + keycode -= 8; + if (keycode <= 88) finalkeycode = keycode; + else finalkeycode = evdev_to_xt[keycode]; + } + else if (!x11display) + { + x11display = XOpenDisplay(nullptr); + if (XKeysymToKeycode(x11display, XK_Home) == 110) + { + selected_keycode = x11_to_xt_2; + } + else if (XKeysymToKeycode(x11display, XK_Home) == 69) + { + selected_keycode = x11_to_xt_vnc; + } + } + if (!QApplication::platformName().contains("eglfs")) finalkeycode = selected_keycode[keycode]; +#endif + if (rctrl_is_lalt && finalkeycode == 0x11D) + { + finalkeycode = 0x38; + } + return finalkeycode; +} + +void MainWindow::on_actionFullscreen_triggered() { + if (video_fullscreen > 0) { + showNormal(); + ui->menubar->show(); + if (!hide_status_bar) ui->statusbar->show(); + if (!hide_tool_bar) ui->toolBar->show(); + video_fullscreen = 0; + if (vid_resize != 1) { + if (vid_resize == 2) setFixedSize(fixed_size_x, fixed_size_y + + menuBar()->height() + + (!hide_status_bar ? statusBar()->height() : 0) + + (!hide_tool_bar ? ui->toolBar->height() : 0)); + + emit resizeContents(scrnsz_x, scrnsz_y); + } + } else { + if (video_fullscreen_first) + { + QMessageBox questionbox(QMessageBox::Icon::Information, tr("Entering fullscreen mode"), tr("Press CTRL+ALT+PAGE DOWN to return to windowed mode."), QMessageBox::Ok, this); + QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + questionbox.setCheckBox(chkbox); + chkbox->setChecked(!video_fullscreen_first); + bool confirm_exit_temp = false; + QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { + video_fullscreen_first = (state == Qt::CheckState::Unchecked); + }); + questionbox.exec(); + config_save(); + } + setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + ui->menubar->hide(); + ui->statusbar->hide(); + ui->toolBar->hide(); + showFullScreen(); + video_fullscreen = 1; + } + ui->stackedWidget->rendererWindow->onResize(width(), height()); +} + +void MainWindow::getTitle_(wchar_t *title) +{ + this->windowTitle().toWCharArray(title); +} + +void MainWindow::getTitle(wchar_t *title) +{ + if (QThread::currentThread() == this->thread()) { + getTitle_(title); + } else { + emit getTitleForNonQtThread(title); + } +} + +bool MainWindow::eventFilter(QObject* receiver, QEvent* event) +{ + if (this->keyboardGrabber() == this) { + if (event->type() == QEvent::KeyPress) { + event->accept(); + this->keyPressEvent((QKeyEvent*)event); + return true; + } + if (event->type() == QEvent::KeyRelease) { + event->accept(); + this->keyReleaseEvent((QKeyEvent*)event); + return true; + } + } + + if (receiver == this) + { + static auto curdopause = dopause; + if (event->type() == QEvent::WindowBlocked) { curdopause = dopause; plat_pause(1); } + else if (event->type() == QEvent::WindowUnblocked) { plat_pause(curdopause); } + } + return QMainWindow::eventFilter(receiver, event); +} + +void MainWindow::refreshMediaMenu() { + mm->refresh(ui->menuMedia); + status->refresh(ui->statusbar); +} + +void MainWindow::showMessage(const QString& header, const QString& message) { + if (QThread::currentThread() == this->thread()) { + showMessage_(header, message); + } else { + emit showMessageForNonQtThread(header, message); + } +} + +void MainWindow::showMessage_(const QString &header, const QString &message) { + QMessageBox box(QMessageBox::Warning, header, message, QMessageBox::NoButton, this); + box.setTextFormat(Qt::TextFormat::RichText); + box.exec(); +} + +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())); +#else + keyboard_input(1, x11_keycode_to_keysym(event->nativeScanCode())); +#endif + } + + if ((video_fullscreen > 0) && keyboard_isfsexit()) { + ui->actionFullscreen->trigger(); + } + + if (keyboard_ismsexit()) { + plat_mouse_capture(0); + } + event->accept(); +} + +void MainWindow::blitToWidget(int x, int y, int w, int h) +{ + ui->stackedWidget->blit(x, y, w, h); +} + +void MainWindow::keyReleaseEvent(QKeyEvent* event) +{ + if (!send_keyboard_input) + return; + +#ifdef __APPLE__ + keyboard_input(0, x11_keycode_to_keysym(event->nativeVirtualKey())); +#else + keyboard_input(0, x11_keycode_to_keysym(event->nativeScanCode())); +#endif +} + +QSize MainWindow::getRenderWidgetSize() +{ + return ui->stackedWidget->size(); +} + +void MainWindow::on_actionSoftware_Renderer_triggered() { + ui->stackedWidget->switchRenderer(RendererStack::Renderer::Software); + ui->actionHardware_Renderer_OpenGL->setChecked(false); + ui->actionHardware_Renderer_OpenGL_ES->setChecked(false); + ui->actionOpenGL_3_0_Core->setChecked(false); + vid_api = 0; +} + +void MainWindow::on_actionHardware_Renderer_OpenGL_triggered() { + ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL); + ui->actionSoftware_Renderer->setChecked(false); + ui->actionHardware_Renderer_OpenGL_ES->setChecked(false); + ui->actionOpenGL_3_0_Core->setChecked(false); + vid_api = 1; +} + +void MainWindow::on_actionHardware_Renderer_OpenGL_ES_triggered() { + ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGLES); + ui->actionSoftware_Renderer->setChecked(false); + ui->actionHardware_Renderer_OpenGL->setChecked(false); + ui->actionOpenGL_3_0_Core->setChecked(false); + vid_api = 2; +} + +void MainWindow::focusInEvent(QFocusEvent* event) +{ + this->grabKeyboard(); +} + +void MainWindow::focusOutEvent(QFocusEvent* event) +{ + this->releaseKeyboard(); +} + +void MainWindow::on_actionResizable_window_triggered(bool checked) { + if (checked) { + vid_resize = 1; + setWindowFlag(Qt::WindowMaximizeButtonHint); + setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, false); + setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + } else { + vid_resize = 0; + setWindowFlag(Qt::WindowMaximizeButtonHint, false); + setWindowFlag(Qt::MSWindowsFixedSizeDialogHint); + } + show(); + ui->stackedWidget->switchRenderer((RendererStack::Renderer)vid_api); + + ui->menuWindow_scale_factor->setEnabled(! checked); + emit resizeContents(scrnsz_x, scrnsz_y); +} + +static void +video_toggle_option(QAction* action, int *val) +{ + startblit(); + *val ^= 1; + video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; + action->setChecked(*val > 0 ? true : false); + endblit(); + config_save(); + device_force_redraw(); +} + +void MainWindow::on_actionInverted_VGA_monitor_triggered() { + video_toggle_option(ui->actionInverted_VGA_monitor, &invert_display); +} + +static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) { + ui->action0_5x->setChecked(ui->action0_5x == selected); + ui->action1x->setChecked(ui->action1x == selected); + ui->action1_5x->setChecked(ui->action1_5x == selected); + ui->action2x->setChecked(ui->action2x == selected); + + reset_screen_size(); + device_force_redraw(); + video_force_resize_set(1); + atomic_flag_clear(&doresize); + config_save(); +} + +void MainWindow::on_action0_5x_triggered() { + scale = 0; + update_scaled_checkboxes(ui, ui->action0_5x); +} + +void MainWindow::on_action1x_triggered() { + scale = 1; + update_scaled_checkboxes(ui, ui->action1x); +} + +void MainWindow::on_action1_5x_triggered() { + scale = 2; + update_scaled_checkboxes(ui, ui->action1_5x); +} + +void MainWindow::on_action2x_triggered() { + scale = 3; + update_scaled_checkboxes(ui, ui->action2x); +} + +void MainWindow::on_actionNearest_triggered() { + video_filter_method = 0; + ui->actionLinear->setChecked(false); +} + +void MainWindow::on_actionLinear_triggered() { + video_filter_method = 1; + ui->actionNearest->setChecked(false); +} + +static void update_fullscreen_scale_checkboxes(Ui::MainWindow* ui, QAction* selected) { + ui->actionFullScreen_stretch->setChecked(ui->actionFullScreen_stretch == selected); + ui->actionFullScreen_43->setChecked(ui->actionFullScreen_43 == selected); + ui->actionFullScreen_keepRatio->setChecked(ui->actionFullScreen_keepRatio == selected); + ui->actionFullScreen_int->setChecked(ui->actionFullScreen_int == selected); + + if (video_fullscreen > 0) { + auto widget = ui->stackedWidget->currentWidget(); + auto rc = ui->stackedWidget->rendererWindow; + rc->onResize(widget->width(), widget->height()); + } + + device_force_redraw(); + config_save(); +} + +void MainWindow::on_actionFullScreen_stretch_triggered() { + video_fullscreen_scale = FULLSCR_SCALE_FULL; + update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_stretch); +} + +void MainWindow::on_actionFullScreen_43_triggered() { + video_fullscreen_scale = FULLSCR_SCALE_43; + update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_43); +} + +void MainWindow::on_actionFullScreen_keepRatio_triggered() { + video_fullscreen_scale = FULLSCR_SCALE_KEEPRATIO; + update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_keepRatio); +} + +void MainWindow::on_actionFullScreen_int_triggered() { + video_fullscreen_scale = FULLSCR_SCALE_INT; + update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_int); +} + +static void update_greyscale_checkboxes(Ui::MainWindow* ui, QAction* selected, int value) { + ui->actionRGB_Color->setChecked(ui->actionRGB_Color == selected); + ui->actionRGB_Grayscale->setChecked(ui->actionRGB_Grayscale == selected); + ui->actionAmber_monitor->setChecked(ui->actionAmber_monitor == selected); + ui->actionGreen_monitor->setChecked(ui->actionGreen_monitor == selected); + ui->actionWhite_monitor->setChecked(ui->actionWhite_monitor == selected); + + startblit(); + video_grayscale = value; + video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; + endblit(); + device_force_redraw(); + config_save(); +} + +void MainWindow::on_actionRGB_Color_triggered() { + update_greyscale_checkboxes(ui, ui->actionRGB_Color, 0); +} + +void MainWindow::on_actionRGB_Grayscale_triggered() { + update_greyscale_checkboxes(ui, ui->actionRGB_Grayscale, 1); +} + +void MainWindow::on_actionAmber_monitor_triggered() { + update_greyscale_checkboxes(ui, ui->actionAmber_monitor, 2); +} + +void MainWindow::on_actionGreen_monitor_triggered() { + update_greyscale_checkboxes(ui, ui->actionGreen_monitor, 3); +} + +void MainWindow::on_actionWhite_monitor_triggered() { + update_greyscale_checkboxes(ui, ui->actionWhite_monitor, 4); +} + +static void update_greyscale_type_checkboxes(Ui::MainWindow* ui, QAction* selected, int value) { + ui->actionBT601_NTSC_PAL->setChecked(ui->actionBT601_NTSC_PAL == selected); + ui->actionBT709_HDTV->setChecked(ui->actionBT709_HDTV == selected); + ui->actionAverage->setChecked(ui->actionAverage == selected); + + video_graytype = value; + device_force_redraw(); + config_save(); +} + +void MainWindow::on_actionBT601_NTSC_PAL_triggered() { + update_greyscale_type_checkboxes(ui, ui->actionBT601_NTSC_PAL, 0); +} + +void MainWindow::on_actionBT709_HDTV_triggered() { + update_greyscale_type_checkboxes(ui, ui->actionBT709_HDTV, 1); +} + +void MainWindow::on_actionAverage_triggered() { + update_greyscale_type_checkboxes(ui, ui->actionAverage, 2); +} + +void MainWindow::on_actionAbout_Qt_triggered() +{ + QApplication::aboutQt(); +} + +void MainWindow::on_actionAbout_86Box_triggered() +{ + QMessageBox msgBox; + msgBox.setTextFormat(Qt::RichText); + QString githash; +#ifdef EMU_GIT_HASH + githash = QString(" [%1]").arg(EMU_GIT_HASH); +#endif + msgBox.setText(QString("%3%1%2").arg(EMU_VERSION_FULL, githash, tr("86Box v"))); + msgBox.setInformativeText(tr("An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information.")); + msgBox.setWindowTitle("About 86Box"); + msgBox.addButton("OK", QMessageBox::ButtonRole::AcceptRole); + auto webSiteButton = msgBox.addButton("86box.net", QMessageBox::ButtonRole::HelpRole); + webSiteButton->connect(webSiteButton, &QPushButton::released, []() + { + QDesktopServices::openUrl(QUrl("https://86box.net/")); + }); + msgBox.setIconPixmap(QIcon(":/settings/win/icons/86Box-yellow.ico").pixmap(32, 32)); + msgBox.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); + msgBox.exec(); +} + +void MainWindow::on_actionDocumentation_triggered() +{ + QDesktopServices::openUrl(QUrl("https://86box.readthedocs.io")); +} + +void MainWindow::on_actionCGA_PCjr_Tandy_EGA_S_VGA_overscan_triggered() { + update_overscan = 1; + video_toggle_option(ui->actionCGA_PCjr_Tandy_EGA_S_VGA_overscan, &enable_overscan); +} + +void MainWindow::on_actionChange_contrast_for_monochrome_display_triggered() { + vid_cga_contrast ^= 1; + cgapal_rebuild(); + config_save(); +} + +void MainWindow::on_actionForce_4_3_display_ratio_triggered() { + video_toggle_option(ui->actionForce_4_3_display_ratio, &force_43); + video_force_resize_set(1); +} + +void MainWindow::on_actionRemember_size_and_position_triggered() +{ + window_remember ^= 1; + window_w = ui->stackedWidget->width(); + window_h = ui->stackedWidget->height(); + if (!QApplication::platformName().contains("wayland")) { + window_x = geometry().x(); + window_y = geometry().y(); + } + ui->actionRemember_size_and_position->setChecked(window_remember); +} + +void MainWindow::on_actionSpecify_dimensions_triggered() +{ + SpecifyDimensions dialog(this); + dialog.setWindowModality(Qt::WindowModal); + dialog.exec(); +} + +void MainWindow::on_actionHiDPI_scaling_triggered() +{ + dpi_scale ^= 1; + ui->actionHiDPI_scaling->setChecked(dpi_scale); + emit resizeContents(scrnsz_x, scrnsz_y); +} + +void MainWindow::on_actionHide_status_bar_triggered() +{ + hide_status_bar ^= 1; + ui->actionHide_status_bar->setChecked(hide_status_bar); + statusBar()->setVisible(!hide_status_bar); + if (vid_resize >= 2) { + setFixedSize(fixed_size_x, fixed_size_y + + menuBar()->height() + + (hide_status_bar ? 0 : statusBar()->height()) + + (hide_tool_bar ? 0 : ui->toolBar->height())); + } else { + int vid_resize_orig = vid_resize; + vid_resize = 0; + emit resizeContents(scrnsz_x, scrnsz_y); + vid_resize = vid_resize_orig; + } +} + +void MainWindow::on_actionHide_tool_bar_triggered() +{ + hide_tool_bar ^= 1; + ui->actionHide_tool_bar->setChecked(hide_tool_bar); + ui->toolBar->setVisible(!hide_tool_bar); + if (vid_resize >= 2) { + setFixedSize(fixed_size_x, fixed_size_y + + menuBar()->height() + + (hide_status_bar ? 0 : statusBar()->height()) + + (hide_tool_bar ? 0 : ui->toolBar->height())); + } else { + int vid_resize_orig = vid_resize; + vid_resize = 0; + emit resizeContents(scrnsz_x, scrnsz_y); + vid_resize = vid_resize_orig; + } +} + +void MainWindow::on_actionUpdate_status_bar_icons_triggered() +{ + update_icons ^= 1; + ui->actionUpdate_status_bar_icons->setChecked(update_icons); +} + +void MainWindow::on_actionTake_screenshot_triggered() +{ + startblit(); + screenshots++; + endblit(); + device_force_redraw(); +} + +void MainWindow::on_actionSound_gain_triggered() +{ + SoundGain gain(this); + gain.exec(); +} + +void MainWindow::setSendKeyboardInput(bool enabled) +{ + send_keyboard_input = enabled; +} + +void MainWindow::on_actionOpenGL_3_0_Core_triggered() +{ + ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL3); + ui->actionSoftware_Renderer->setChecked(false); + ui->actionHardware_Renderer_OpenGL->setChecked(false); + ui->actionHardware_Renderer_OpenGL_ES->setChecked(false); + ui->actionOpenGL_3_0_Core->setChecked(true); + vid_api = 3; +} + +void MainWindow::on_actionPreferences_triggered() +{ + ProgSettings progsettings(this); + progsettings.exec(); +} + + +void MainWindow::on_actionEnable_Discord_integration_triggered(bool checked) +{ + enable_discord = checked; + if(enable_discord) { + discord_init(); + discord_update_activity(dopause); + } else + discord_close(); +} + +void MainWindow::showSettings() +{ + if (findChild() == nullptr) + ui->actionSettings->trigger(); +} + +void MainWindow::hardReset() +{ + ui->actionHard_Reset->trigger(); +} + +void MainWindow::togglePause() +{ + ui->actionPause->trigger(); +} + +void MainWindow::changeEvent(QEvent* event) +{ +#ifdef Q_OS_WINDOWS + if (event->type() == QEvent::LanguageChange) + { + auto font_name = tr("FONT_NAME"); + auto font_size = tr("FONT_SIZE"); + QApplication::setFont(QFont(font_name, font_size.toInt())); + } +#endif + QWidget::changeEvent(event); +} diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp new file mode 100644 index 000000000..2d74af987 --- /dev/null +++ b/src/qt/qt_mainwindow.hpp @@ -0,0 +1,136 @@ +#ifndef QT_MAINWINDOW_HPP +#define QT_MAINWINDOW_HPP + +#include +#include +#include +#include + +#include + +class MediaMenu; + +namespace Ui { +class MainWindow; +} + +class MachineStatus; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + + void showMessage(const QString& header, const QString& message); + void getTitle(wchar_t* title); + void blitToWidget(int x, int y, int w, int h); + QSize getRenderWidgetSize(); + void setSendKeyboardInput(bool enabled); +signals: + void paint(const QImage& image); + void resizeContents(int w, int h); + void pollMouse(); + void statusBarMessage(const QString& msg); + void updateStatusBarPanes(); + void updateStatusBarActivity(int tag, bool active); + void updateStatusBarEmpty(int tag, bool empty); + void updateStatusBarTip(int tag); + void updateMenuResizeOptions(); + void updateWindowRememberOption(); + + void setTitle(const QString& title); + void setFullscreen(bool state); + void setMouseCapture(bool state); + + void showMessageForNonQtThread(const QString& header, const QString& message); + void getTitleForNonQtThread(wchar_t* title); +public slots: + void showSettings(); + void hardReset(); + void togglePause(); +private slots: + void on_actionFullscreen_triggered(); + void on_actionSettings_triggered(); + void on_actionExit_triggered(); + void on_actionPause_triggered(); + void on_actionCtrl_Alt_Del_triggered(); + void on_actionCtrl_Alt_Esc_triggered(); + void on_actionHard_Reset_triggered(); + void on_actionRight_CTRL_is_left_ALT_triggered(); + void on_actionKeyboard_requires_capture_triggered(); + void on_actionHardware_Renderer_OpenGL_ES_triggered(); + void on_actionHardware_Renderer_OpenGL_triggered(); + void on_actionSoftware_Renderer_triggered(); + void on_actionResizable_window_triggered(bool checked); + void on_actionInverted_VGA_monitor_triggered(); + void on_action0_5x_triggered(); + void on_action1x_triggered(); + void on_action1_5x_triggered(); + void on_action2x_triggered(); + void on_actionLinear_triggered(); + void on_actionNearest_triggered(); + void on_actionFullScreen_int_triggered(); + void on_actionFullScreen_keepRatio_triggered(); + void on_actionFullScreen_43_triggered(); + void on_actionFullScreen_stretch_triggered(); + void on_actionWhite_monitor_triggered(); + void on_actionGreen_monitor_triggered(); + void on_actionAmber_monitor_triggered(); + void on_actionRGB_Grayscale_triggered(); + void on_actionRGB_Color_triggered(); + void on_actionAverage_triggered(); + void on_actionBT709_HDTV_triggered(); + void on_actionBT601_NTSC_PAL_triggered(); + void on_actionDocumentation_triggered(); + void on_actionAbout_86Box_triggered(); + void on_actionAbout_Qt_triggered(); + void on_actionForce_4_3_display_ratio_triggered(); + void on_actionChange_contrast_for_monochrome_display_triggered(); + void on_actionCGA_PCjr_Tandy_EGA_S_VGA_overscan_triggered(); + void on_actionRemember_size_and_position_triggered(); + void on_actionSpecify_dimensions_triggered(); + void on_actionHiDPI_scaling_triggered(); + void on_actionHide_status_bar_triggered(); + void on_actionHide_tool_bar_triggered(); + void on_actionUpdate_status_bar_icons_triggered(); + + void refreshMediaMenu(); + void showMessage_(const QString& header, const QString& message); + void getTitle_(wchar_t* title); + void on_actionTake_screenshot_triggered(); + + void on_actionSound_gain_triggered(); + + void on_actionOpenGL_3_0_Core_triggered(); + + void on_actionPreferences_triggered(); + + void on_actionEnable_Discord_integration_triggered(bool checked); + +protected: + void keyPressEvent(QKeyEvent* event) override; + void keyReleaseEvent(QKeyEvent* event) override; + void focusInEvent(QFocusEvent* event) override; + void focusOutEvent(QFocusEvent* event) override; + bool eventFilter(QObject* receiver, QEvent* event) override; + void showEvent(QShowEvent* event) override; + void closeEvent(QCloseEvent* event) override; + void changeEvent(QEvent* event) override; + +private: + Ui::MainWindow *ui; + std::unique_ptr status; + std::shared_ptr mm; + + /* If main window should send keyboard input */ + bool send_keyboard_input = true; + bool shownonce = false; + + friend class SpecifyDimensions; + friend class ProgSettings; +}; + +#endif // QT_MAINWINDOW_HPP diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui new file mode 100644 index 000000000..787112399 --- /dev/null +++ b/src/qt/qt_mainwindow.ui @@ -0,0 +1,713 @@ + + + MainWindow + + + + 0 + 0 + 724 + 427 + + + + 86Box + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 0 + 0 + 724 + 22 + + + + + &Action + + + + + + + + + + + + + + + + &Tools + + + + + + + + + + + + + + + + + &View + + + + Re&nderer + + + + + + + + + &Window scale factor + + + + + + + + + Filter method + + + + + + + Fullscreen &stretch mode + + + + + + + + + E&GA/(S)VGA settings + + + + VGA screen &type + + + + + + + + + + Grayscale &conversion type + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + &Media + + + + + &Help + + + + + + + + + + + + + + + Qt::PreventContextMenu + + + toolBar + + + false + + + Qt::TopToolBarArea + + + + 16 + 16 + + + + Qt::ToolButtonIconOnly + + + false + + + TopToolBarArea + + + false + + + + + + + + + + + + + true + + + &Keyboard requires capture + + + + + true + + + &Right CTRL is left ALT + + + + + + :/menuicons/win/icons/hard_reset.ico:/menuicons/win/icons/hard_reset.ico + + + &Hard Reset... + + + false + + + + + + :/menuicons/win/icons/send_cad.ico:/menuicons/win/icons/send_cad.ico + + + &Ctrl+Alt+Del + + + Ctrl+Alt+Del + + + Ctrl+F12 + + + false + + + false + + + + + + :/menuicons/win/icons/send_cae.ico:/menuicons/win/icons/send_cae.ico + + + Ctrl+Alt+&Esc + + + false + + + + + true + + + + :/menuicons/win/icons/pause.ico:/menuicons/win/icons/pause.ico + + + &Pause + + + false + + + + + Exit + + + + + + :/menuicons/win/icons/settings.ico:/menuicons/win/icons/settings.ico + + + &Settings... + + + QAction::PreferencesRole + + + false + + + + + &Fullscreen + + + Ctrl+Alt+PgUp + + + false + + + + + true + + + &Qt (Software) + + + + + true + + + Qt (&OpenGL) + + + + + true + + + Qt (OpenGL &ES) + + + + + true + + + &Hide status bar + + + + + true + + + &Resizeable window + + + + + true + + + R&emember size && position + + + + + Specify dimensions... + + + + + true + + + F&orce 4:3 display ratio + + + + + true + + + Hi&DPI scaling + + + + + true + + + CGA/PCjr/Tandy/E&GA/(S)VGA overscan + + + + + true + + + Change contrast for &monochrome display + + + + + true + + + &0.5x + + + + + true + + + &1x + + + + + true + + + 1.&5x + + + + + true + + + &2x + + + + + true + + + &Nearest + + + + + true + + + &Linear + + + + + true + + + &Full screen stretch + + + + + true + + + &4:3 + + + + + true + + + &Square pixels (Keep ratio) + + + + + true + + + &Integer scale + + + + + true + + + &Inverted VGA monitor + + + + + true + + + RGB &Color + + + + + true + + + &RGB Grayscale + + + + + true + + + &Amber monitor + + + + + true + + + &Green monitor + + + + + true + + + &White monitor + + + + + true + + + BT&601 (NTSC/PAL) + + + + + true + + + BT&709 (HDTV) + + + + + true + + + &Average + + + + + About Qt + + + false + + + QAction::AboutQtRole + + + + + &About 86Box... + + + QAction::AboutRole + + + + + &Documentation... + + + + + true + + + &Update status bar icons + + + + + Take s&creenshot + + + Ctrl+F11 + + + false + + + + + Sound &gain... + + + + + true + + + Open&GL (3.0 Core) + + + + + &Preferences... + + + QAction::NoRole + + + + + true + + + Enable &Discord integration + + + + + true + + + Hide tool bar + + + Hide tool bar + + + + + false + + + + :/menuicons/win/icons/acpi_shutdown.ico:/menuicons/win/icons/acpi_shutdown.ico + + + ACPI Shutdown + + + ACPI Shutdown + + + + + Begin trace + + + Ctrl+T + + + false + + + false + + + + + End trace + + + Ctrl+T + + + false + + + false + + + + + + RendererStack + QStackedWidget +
qt_rendererstack.hpp
+ 1 +
+
+ + + + +
diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp new file mode 100644 index 000000000..2aabe04a8 --- /dev/null +++ b/src/qt/qt_mediamenu.cpp @@ -0,0 +1,636 @@ +#include "qt_mediamenu.hpp" + +#include "qt_machinestatus.hpp" + +#include +#include +#include +#include + +extern "C" { +#include <86box/config.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/plat.h> +#include <86box/cassette.h> +#include <86box/cartridge.h> +#include <86box/fdd.h> +#include <86box/fdd_86f.h> +#include <86box/cdrom.h> +#include <86box/scsi_device.h> +#include <86box/zip.h> +#include <86box/mo.h> +#include <86box/sound.h> +#include <86box/ui.h> +}; + +#include "qt_newfloppydialog.hpp" +#include "qt_util.hpp" + +std::shared_ptr MediaMenu::ptr; + +MediaMenu::MediaMenu(QWidget* parent) : QObject(parent) { + parentWidget = parent; +} + +void MediaMenu::refresh(QMenu *parentMenu) { + parentMenu->clear(); + + if(MachineStatus::hasCassette()) { + cassetteMenu = parentMenu->addMenu(""); + cassetteMenu->addAction(tr("&New image..."), [this]() { cassetteNewImage(); }); + cassetteMenu->addSeparator(); + cassetteMenu->addAction(tr("&Existing image..."), [this]() { cassetteSelectImage(false); }); + cassetteMenu->addAction(tr("Existing image (&Write-protected)..."), [this]() { cassetteSelectImage(true); }); + cassetteMenu->addSeparator(); + cassetteRecordPos = cassetteMenu->children().count(); + cassetteMenu->addAction(tr("&Record"), [this] { pc_cas_set_mode(cassette, 1); cassetteUpdateMenu(); })->setCheckable(true); + cassettePlayPos = cassetteMenu->children().count(); + cassetteMenu->addAction(tr("&Play"), [this] { pc_cas_set_mode(cassette, 0); cassetteUpdateMenu(); })->setCheckable(true); + cassetteRewindPos = cassetteMenu->children().count(); + cassetteMenu->addAction(tr("&Rewind to the beginning"), [] { pc_cas_rewind(cassette); }); + cassetteFastFwdPos = cassetteMenu->children().count(); + cassetteMenu->addAction(tr("&Fast forward to the end"), [] { pc_cas_append(cassette); }); + cassetteMenu->addSeparator(); + cassetteEjectPos = cassetteMenu->children().count(); + cassetteMenu->addAction(tr("E&ject"), [this]() { cassetteEject(); }); + cassetteUpdateMenu(); + } + + cartridgeMenus.clear(); + if (machine_has_cartridge(machine)) { + for(int i = 0; i < 2; i++) { + auto* menu = parentMenu->addMenu(""); + menu->addAction(tr("&Image..."), [this, i]() { cartridgeSelectImage(i); }); + menu->addSeparator(); + cartridgeEjectPos = menu->children().count(); + menu->addAction(tr("E&ject"), [this, i]() { cartridgeEject(i); }); + cartridgeMenus[i] = menu; + cartridgeUpdateMenu(i); + } + } + + floppyMenus.clear(); + MachineStatus::iterateFDD([this, parentMenu](int i) { + auto* menu = parentMenu->addMenu(""); + menu->addAction(tr("&New image..."), [this, i]() { floppyNewImage(i); }); + menu->addSeparator(); + menu->addAction(tr("&Existing image..."), [this, i]() { floppySelectImage(i, false); }); + menu->addAction(tr("Existing image (&Write-protected)..."), [this, i]() { floppySelectImage(i, true); }); + menu->addSeparator(); + floppyExportPos = menu->children().count(); + menu->addAction(tr("E&xport to 86F..."), [this, i]() { floppyExportTo86f(i); }); + menu->addSeparator(); + floppyEjectPos = menu->children().count(); + menu->addAction(tr("E&ject"), [this, i]() { floppyEject(i); }); + floppyMenus[i] = menu; + floppyUpdateMenu(i); + }); + + cdromMenus.clear(); + MachineStatus::iterateCDROM([this, parentMenu](int i) { + auto* menu = parentMenu->addMenu(""); + cdromMutePos = menu->children().count(); + menu->addAction(tr("&Mute"), [this, i]() { cdromMute(i); })->setCheckable(true); + menu->addSeparator(); + cdromEmptyPos = menu->children().count(); + menu->addAction(tr("E&mpty"), [this, i]() { cdromEject(i); })->setCheckable(true); + cdromReloadPos = menu->children().count(); + menu->addAction(tr("&Reload previous image"), [this, i]() { cdromReload(i); }); + menu->addSeparator(); + cdromImagePos = menu->children().count(); + menu->addAction(tr("&Image"), [this, i]() { cdromMount(i); })->setCheckable(true); + cdromMenus[i] = menu; + cdromUpdateMenu(i); + }); + + zipMenus.clear(); + MachineStatus::iterateZIP([this, parentMenu](int i) { + auto* menu = parentMenu->addMenu(""); + menu->addAction(tr("&New image..."), [this, i]() { zipNewImage(i); }); + menu->addSeparator(); + menu->addAction(tr("&Existing image..."), [this, i]() { zipSelectImage(i, false); }); + menu->addAction(tr("Existing image (&Write-protected)..."), [this, i]() { zipSelectImage(i, true); }); + menu->addSeparator(); + zipEjectPos = menu->children().count(); + menu->addAction(tr("E&ject"), [this, i]() { zipEject(i); }); + zipReloadPos = menu->children().count(); + menu->addAction(tr("&Reload previous image"), [this, i]() { zipReload(i); }); + zipMenus[i] = menu; + zipUpdateMenu(i); + }); + + moMenus.clear(); + MachineStatus::iterateMO([this, parentMenu](int i) { + auto* menu = parentMenu->addMenu(""); + menu->addAction(tr("&New image..."), [this, i]() { moNewImage(i); }); + menu->addSeparator(); + menu->addAction(tr("&Existing image..."), [this, i]() { moSelectImage(i, false); }); + menu->addAction(tr("Existing image (&Write-protected)..."), [this, i]() { moSelectImage(i, true); }); + menu->addSeparator(); + moEjectPos = menu->children().count(); + menu->addAction(tr("E&ject"), [this, i]() { moEject(i); }); + moReloadPos = menu->children().count(); + menu->addAction(tr("&Reload previous image"), [this, i]() { moReload(i); }); + moMenus[i] = menu; + moUpdateMenu(i); + }); +} + +void MediaMenu::cassetteNewImage() { + auto filename = QFileDialog::getSaveFileName(parentWidget, tr("Create...")); + QFileInfo fileinfo(filename); + if (fileinfo.suffix().isEmpty()) { + filename.append(".cas"); + } + if (!filename.isNull()) { + if (filename.isEmpty()) cassetteEject(); + else cassetteMount(filename, false); + } +} + +void MediaMenu::cassetteSelectImage(bool wp) { + auto filename = QFileDialog::getOpenFileName(parentWidget, + QString(), + QString(), + tr("Cassette images") % + util::DlgFilter({ "pcm","raw","wav","cas" }) % + tr("All files") % + util::DlgFilter({ "*" }, true)); + + if (!filename.isEmpty()) cassetteMount(filename, wp); +} + +void MediaMenu::cassetteMount(const QString& filename, bool wp) { + pc_cas_set_fname(cassette, nullptr); + memset(cassette_fname, 0, sizeof(cassette_fname)); + cassette_ui_writeprot = wp ? 1 : 0; + + if (! filename.isEmpty()) { + QByteArray filenameBytes = filename.toUtf8(); + strncpy(cassette_fname, filenameBytes.data(), sizeof(cassette_fname)); + pc_cas_set_fname(cassette, cassette_fname); + } + + ui_sb_update_icon_state(SB_CASSETTE, filename.isEmpty() ? 1 : 0); + cassetteUpdateMenu(); + ui_sb_update_tip(SB_CASSETTE); + config_save(); +} + +void MediaMenu::cassetteEject() { + pc_cas_set_fname(cassette, nullptr); + memset(cassette_fname, 0, sizeof(cassette_fname)); + ui_sb_update_icon_state(SB_CASSETTE, 1); + cassetteUpdateMenu(); + ui_sb_update_tip(SB_CASSETTE); + config_save(); +} + +void MediaMenu::cassetteUpdateMenu() { + QString name = cassette_fname; + QString mode = cassette_mode; + auto childs = cassetteMenu->children(); + auto* recordMenu = dynamic_cast(childs[cassetteRecordPos]); + auto* playMenu = dynamic_cast(childs[cassettePlayPos]); + auto* rewindMenu = dynamic_cast(childs[cassetteRewindPos]); + auto* fastFwdMenu = dynamic_cast(childs[cassetteFastFwdPos]); + auto* ejectMenu = dynamic_cast(childs[cassetteEjectPos]); + + recordMenu->setEnabled(!name.isEmpty()); + playMenu->setEnabled(!name.isEmpty()); + rewindMenu->setEnabled(!name.isEmpty()); + fastFwdMenu->setEnabled(!name.isEmpty()); + ejectMenu->setEnabled(!name.isEmpty()); + + bool isSaving = mode == QStringLiteral("save"); + recordMenu->setChecked(isSaving); + playMenu->setChecked(! isSaving); + + cassetteMenu->setTitle(QString::asprintf(tr("Cassette: %s").toUtf8().constData(), (name.isEmpty() ? tr("(empty)") : name).toUtf8().constData())); +} + +void MediaMenu::cartridgeSelectImage(int i) { + auto filename = QFileDialog::getOpenFileName( + parentWidget, + QString(), + QString(), + tr("Cartridge images") % + util::DlgFilter({ "a","b","jrc" }) % + tr("All files") % + util::DlgFilter({ "*" }, true)); + + if (filename.isEmpty()) { + return; + } + cart_close(i); + QByteArray filenameBytes = filename.toUtf8(); + cart_load(i, filenameBytes.data()); + + ui_sb_update_icon_state(SB_CARTRIDGE | i, filename.isEmpty() ? 1 : 0); + cartridgeUpdateMenu(i); + ui_sb_update_tip(SB_CARTRIDGE | i); + config_save(); +} + +void MediaMenu::cartridgeEject(int i) { + cart_close(i); + ui_sb_update_icon_state(SB_CARTRIDGE | i, 1); + cartridgeUpdateMenu(i); + ui_sb_update_tip(SB_CARTRIDGE | i); + config_save(); +} + +void MediaMenu::cartridgeUpdateMenu(int i) { + QString name = cart_fns[i]; + auto* menu = cartridgeMenus[i]; + auto childs = menu->children(); + auto* ejectMenu = dynamic_cast(childs[cartridgeEjectPos]); + ejectMenu->setEnabled(!name.isEmpty()); + //menu->setTitle(tr("Cartridge %1: %2").arg(QString::number(i+1), name.isEmpty() ? tr("(empty)") : name)); + menu->setTitle(QString::asprintf(tr("Cartridge %i: %ls").toUtf8().constData(), i + 1, name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); +} + +void MediaMenu::floppyNewImage(int i) { + NewFloppyDialog dialog(NewFloppyDialog::MediaType::Floppy, parentWidget); + switch (dialog.exec()) { + case QDialog::Accepted: + QByteArray filename = dialog.fileName().toUtf8(); + floppyMount(i, filename, false); + break; + } +} + +void MediaMenu::floppySelectImage(int i, bool wp) { + auto filename = QFileDialog::getOpenFileName( + parentWidget, + QString(), + QString(), + tr("All images") % + util::DlgFilter({ "0??","1??","??0","86f","bin","cq?","d??","flp","hdm","im?","json","td0","*fd?","mfm","xdf" }) % + tr("Advanced sector images") % + util::DlgFilter({ "imd","json","td0" }) % + tr("Basic sector images") % + util::DlgFilter({ "0??","1??","??0","bin","cq?","d??","flp","hdm","im?","xdf","*fd?" }) % + tr("Flux images") % + util::DlgFilter({ "fdi" }) % + tr("Surface images") % + util::DlgFilter({ "86f","mfm" }) % + tr("All files") % + util::DlgFilter({ "*" }, true)); + + if (!filename.isEmpty()) floppyMount(i, filename, wp); +} + +void MediaMenu::floppyMount(int i, const QString &filename, bool wp) { + fdd_close(i); + ui_writeprot[i] = wp ? 1 : 0; + if (! filename.isEmpty()) { + QByteArray filenameBytes = filename.toUtf8(); + fdd_load(i, filenameBytes.data()); + } + ui_sb_update_icon_state(SB_FLOPPY | i, filename.isEmpty() ? 1 : 0); + floppyUpdateMenu(i); + ui_sb_update_tip(SB_FLOPPY | i); + config_save(); +} + +void MediaMenu::floppyEject(int i) { + fdd_close(i); + ui_sb_update_icon_state(SB_FLOPPY | i, 1); + floppyUpdateMenu(i); + ui_sb_update_tip(SB_FLOPPY | i); + config_save(); +} + +void MediaMenu::floppyExportTo86f(int i) { + auto filename = QFileDialog::getSaveFileName(parentWidget, QString(), QString(), tr("Surface images") % util::DlgFilter({ "86f" }, true)); + if (! filename.isEmpty()) { + QByteArray filenameBytes = filename.toUtf8(); + plat_pause(1); + if (d86f_export(i, filenameBytes.data()) == 0) { + QMessageBox::critical(parentWidget, tr("Unable to write file"), tr("Make sure the file is being saved to a writable directory")); + } + plat_pause(0); + } +} + +void MediaMenu::floppyUpdateMenu(int i) { + QString name = floppyfns[i]; + + auto* menu = floppyMenus[i]; + auto childs = menu->children(); + + auto* ejectMenu = dynamic_cast(childs[floppyEjectPos]); + auto* exportMenu = dynamic_cast(childs[floppyExportPos]); + ejectMenu->setEnabled(!name.isEmpty()); + exportMenu->setEnabled(!name.isEmpty()); + + int type = fdd_get_type(i); + //floppyMenus[i]->setTitle(tr("Floppy %1 (%2): %3").arg(QString::number(i+1), fdd_getname(type), name.isEmpty() ? tr("(empty)") : name)); + floppyMenus[i]->setTitle(QString::asprintf(tr("Floppy %i (%s): %ls").toUtf8().constData(), i + 1, fdd_getname(type), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); +} + +void MediaMenu::cdromMute(int i) { + cdrom[i].sound_on ^= 1; + config_save(); + cdromUpdateMenu(i); + sound_cd_thread_reset(); +} + +void MediaMenu::cdromMount(int i) { + QString dir; + QFileInfo fi(cdrom[i].image_path); + + auto filename = QFileDialog::getOpenFileName( + parentWidget, + QString(), + QString(), + tr("CD-ROM images") % + util::DlgFilter({ "iso","cue" }) % + tr("All files") % + util::DlgFilter({ "*" }, true)); + + if (filename.isEmpty()) { + return; + } + QByteArray fn = filename.toUtf8().data(); + + cdrom[i].prev_host_drive = cdrom[i].host_drive; + strcpy(cdrom[i].prev_image_path, cdrom[i].image_path); + if (cdrom[i].ops && cdrom[i].ops->exit) + cdrom[i].ops->exit(&(cdrom[i])); + + cdrom[i].ops = nullptr; + memset(cdrom[i].image_path, 0, sizeof(cdrom[i].image_path)); + cdrom_image_open(&(cdrom[i]), fn.data()); + /* Signal media change to the emulated machine. */ + if (cdrom[i].insert) + cdrom[i].insert(cdrom[i].priv); + cdrom[i].host_drive = (strlen(cdrom[i].image_path) == 0) ? 0 : 200; + if (cdrom[i].host_drive == 200) { + ui_sb_update_icon_state(SB_CDROM | i, 0); + } else { + ui_sb_update_icon_state(SB_CDROM | i, 1); + } + cdromUpdateMenu(i); + ui_sb_update_tip(SB_CDROM | i); + config_save(); +} + +void MediaMenu::cdromEject(int i) { + cdrom_eject(i); + cdromUpdateMenu(i); + ui_sb_update_tip(SB_CDROM | i); +} + +void MediaMenu::cdromReload(int i) { + cdrom_reload(i); + cdromUpdateMenu(i); + ui_sb_update_tip(SB_CDROM | i); +} + +void MediaMenu::cdromUpdateMenu(int i) { + QString name = cdrom[i].image_path; + auto* menu = cdromMenus[i]; + auto childs = menu->children(); + + auto* muteMenu = dynamic_cast(childs[cdromMutePos]); + muteMenu->setChecked(cdrom[i].sound_on == 0); + + auto* imageMenu = dynamic_cast(childs[cdromImagePos]); + auto* emptyMenu = dynamic_cast(childs[cdromEmptyPos]); + imageMenu->setChecked(cdrom[i].host_drive == 200); + emptyMenu->setChecked(cdrom[i].host_drive != 200); + + auto* prevMenu = dynamic_cast(childs[cdromReloadPos]); + prevMenu->setEnabled(cdrom[i].prev_host_drive != 0); + + QString busName = tr("Unknown Bus"); + switch (cdrom[i].bus_type) { + case CDROM_BUS_ATAPI: + busName = "ATAPI"; + break; + case CDROM_BUS_SCSI: + busName = "SCSI"; + break; + } + + //menu->setTitle(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); + menu->setTitle(QString::asprintf(tr("CD-ROM %i (%s): %s").toUtf8().constData(), i + 1, busName.toUtf8().data(), name.isEmpty() ? tr("(empty)").toUtf8().data() : name.toUtf8().data())); +} + +void MediaMenu::zipNewImage(int i) { + NewFloppyDialog dialog(NewFloppyDialog::MediaType::Zip, parentWidget); + switch (dialog.exec()) { + case QDialog::Accepted: + QByteArray filename = dialog.fileName().toUtf8(); + zipMount(i, filename, false); + break; + } +} + +void MediaMenu::zipSelectImage(int i, bool wp) { + auto filename = QFileDialog::getOpenFileName( + parentWidget, + QString(), + QString(), + tr("ZIP images") % + util::DlgFilter({ "im?","zdi" }) % + tr("All files") % + util::DlgFilter({ "*" }, true)); + + if (!filename.isEmpty()) zipMount(i, filename, wp); +} + +void MediaMenu::zipMount(int i, const QString &filename, bool wp) { + zip_t *dev = (zip_t *) zip_drives[i].priv; + + zip_disk_close(dev); + zip_drives[i].read_only = wp; + if (! filename.isEmpty()) { + QByteArray filenameBytes = filename.toUtf8(); + zip_load(dev, filenameBytes.data()); + zip_insert(dev); + } + + ui_sb_update_icon_state(SB_ZIP | i, filename.isEmpty() ? 1 : 0); + zipUpdateMenu(i); + ui_sb_update_tip(SB_ZIP | i); + + config_save(); +} + +void MediaMenu::zipEject(int i) { + zip_t *dev = (zip_t *) zip_drives[i].priv; + + zip_disk_close(dev); + if (zip_drives[i].bus_type) { + /* Signal disk change to the emulated machine. */ + zip_insert(dev); + } + + ui_sb_update_icon_state(SB_ZIP | i, 1); + zipUpdateMenu(i); + ui_sb_update_tip(SB_ZIP | i); + config_save(); +} + +void MediaMenu::zipReload(int i) { + zip_t *dev = (zip_t *) zip_drives[i].priv; + + zip_disk_reload(dev); + if (strlen(zip_drives[i].image_path) == 0) { + ui_sb_update_icon_state(SB_ZIP|i, 1); + } else { + ui_sb_update_icon_state(SB_ZIP|i, 0); + } + + zipUpdateMenu(i); + ui_sb_update_tip(SB_ZIP|i); + + config_save(); +} + +void MediaMenu::zipUpdateMenu(int i) { + QString name = zip_drives[i].image_path; + QString prev_name = zip_drives[i].prev_image_path; + auto* menu = zipMenus[i]; + auto childs = menu->children(); + + auto* ejectMenu = dynamic_cast(childs[zipEjectPos]); + auto* reloadMenu = dynamic_cast(childs[zipReloadPos]); + ejectMenu->setEnabled(!name.isEmpty()); + reloadMenu->setEnabled(!prev_name.isEmpty()); + + QString busName = tr("Unknown Bus"); + switch (zip_drives[i].bus_type) { + case ZIP_BUS_ATAPI: + busName = "ATAPI"; + break; + case ZIP_BUS_SCSI: + busName = "SCSI"; + break; + } + + //menu->setTitle(tr("ZIP %1 %2 (%3): %4").arg((zip_drives[i].is_250 > 0) ? "250" : "100", QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); + menu->setTitle(QString::asprintf(tr("ZIP %03i %i (%s): %ls").toUtf8().constData(), (zip_drives[i].is_250 > 0) ? 250 : 100, i + 1, busName.toUtf8().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); +} + +void MediaMenu::moNewImage(int i) { + NewFloppyDialog dialog(NewFloppyDialog::MediaType::Mo, parentWidget); + switch (dialog.exec()) { + case QDialog::Accepted: + QByteArray filename = dialog.fileName().toUtf8(); + moMount(i, filename, false); + break; + } +} + +void MediaMenu::moSelectImage(int i, bool wp) { + auto filename = QFileDialog::getOpenFileName( + parentWidget, + QString(), + QString(), + tr("MO images") % + util::DlgFilter({ "im?", "mdi" }) % + tr("All files") % + util::DlgFilter({ "*", }, true)); + + if (!filename.isEmpty()) moMount(i, filename, wp); +} + +void MediaMenu::moMount(int i, const QString &filename, bool wp) { + mo_t *dev = (mo_t *) mo_drives[i].priv; + + mo_disk_close(dev); + mo_drives[i].read_only = wp; + if (! filename.isEmpty()) { + QByteArray filenameBytes = filename.toUtf8(); + mo_load(dev, filenameBytes.data()); + mo_insert(dev); + } + + ui_sb_update_icon_state(SB_MO | i, filename.isEmpty() ? 1 : 0); + moUpdateMenu(i); + ui_sb_update_tip(SB_MO | i); + + config_save(); +} + +void MediaMenu::moEject(int i) { + mo_t *dev = (mo_t *) mo_drives[i].priv; + + mo_disk_close(dev); + if (mo_drives[i].bus_type) { + /* Signal disk change to the emulated machine. */ + mo_insert(dev); + } + + ui_sb_update_icon_state(SB_MO | i, 1); + moUpdateMenu(i); + ui_sb_update_tip(SB_MO | i); + config_save(); +} + +void MediaMenu::moReload(int i) { + mo_t *dev = (mo_t *) mo_drives[i].priv; + + mo_disk_reload(dev); + if (strlen(mo_drives[i].image_path) == 0) { + ui_sb_update_icon_state(SB_MO|i, 1); + } else { + ui_sb_update_icon_state(SB_MO|i, 0); + } + + moUpdateMenu(i); + ui_sb_update_tip(SB_MO|i); + + config_save(); +} + +void MediaMenu::moUpdateMenu(int i) { + QString name = mo_drives[i].image_path; + QString prev_name = mo_drives[i].prev_image_path; + auto* menu = moMenus[i]; + auto childs = menu->children(); + + auto* ejectMenu = dynamic_cast(childs[moEjectPos]); + auto* reloadMenu = dynamic_cast(childs[moReloadPos]); + ejectMenu->setEnabled(!name.isEmpty()); + reloadMenu->setEnabled(!prev_name.isEmpty()); + + QString busName = tr("Unknown Bus"); + switch (mo_drives[i].bus_type) { + case MO_BUS_ATAPI: + busName = "ATAPI"; + break; + case MO_BUS_SCSI: + busName = "SCSI"; + break; + } + + menu->setTitle(QString::asprintf(tr("MO %i (%ls): %ls").toUtf8().constData(), i + 1, busName.toStdU16String().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); +} + + +// callbacks from 86box C code +extern "C" { + +void zip_eject(uint8_t id) { + MediaMenu::ptr->zipEject(id); +} + +void zip_reload(uint8_t id) { + MediaMenu::ptr->zipReload(id); +} + +void mo_eject(uint8_t id) { + MediaMenu::ptr->moEject(id); +} + +void mo_reload(uint8_t id) { + MediaMenu::ptr->moReload(id); +} + +} diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp new file mode 100644 index 000000000..3dc859fe9 --- /dev/null +++ b/src/qt/qt_mediamenu.hpp @@ -0,0 +1,90 @@ +#pragma once + +#include +#include +#include + +class QMenu; + +class MediaMenu : QObject +{ + Q_OBJECT +public: + MediaMenu(QWidget* parent); + + void refresh(QMenu* parentMenu); + + // because some 86box C-only code needs to call zip and + // mo eject directly + static std::shared_ptr ptr; + + void cassetteNewImage(); + void cassetteSelectImage(bool wp); + void cassetteMount(const QString& filename, bool wp); + void cassetteEject(); + void cassetteUpdateMenu(); + + void cartridgeSelectImage(int i); + void cartridgeEject(int i); + void cartridgeUpdateMenu(int i); + + void floppyNewImage(int i); + void floppySelectImage(int i, bool wp); + void floppyMount(int i, const QString& filename, bool wp); + void floppyEject(int i); + void floppyExportTo86f(int i); + void floppyUpdateMenu(int i); + + void cdromMute(int i); + void cdromMount(int i); + void cdromEject(int i); + void cdromReload(int i); + void cdromUpdateMenu(int i); + + void zipNewImage(int i); + void zipSelectImage(int i, bool wp); + void zipMount(int i, const QString& filename, bool wp); + void zipEject(int i); + void zipReload(int i); + void zipUpdateMenu(int i); + + void moNewImage(int i); + void moSelectImage(int i, bool wp); + void moMount(int i, const QString& filename, bool wp); + void moEject(int i); + void moReload(int i); + void moUpdateMenu(int i); +private: + QWidget* parentWidget = nullptr; + + QMenu* cassetteMenu = nullptr; + QMap cartridgeMenus; + QMap floppyMenus; + QMap cdromMenus; + QMap zipMenus; + QMap moMenus; + + int cassetteRecordPos; + int cassettePlayPos; + int cassetteRewindPos; + int cassetteFastFwdPos; + int cassetteEjectPos; + + int cartridgeEjectPos; + + int floppyExportPos; + int floppyEjectPos; + + int cdromMutePos; + int cdromEmptyPos; + int cdromReloadPos; + int cdromImagePos; + + int zipEjectPos; + int zipReloadPos; + + int moEjectPos; + int moReloadPos; + + friend class MachineStatus; +}; diff --git a/src/qt/qt_midi.cpp b/src/qt/qt_midi.cpp new file mode 100644 index 000000000..a9b741c9e --- /dev/null +++ b/src/qt/qt_midi.cpp @@ -0,0 +1,44 @@ +#include + +extern "C" { + +void plat_midi_play_msg(uint8_t *msg) +{} + +void plat_midi_play_sysex(uint8_t *sysex, unsigned int len) +{} + +void plat_midi_input_init(void) +{} + +void plat_midi_input_close(void) +{} + +int plat_midi_write(uint8_t val) +{ return 0; } + +void plat_midi_init() +{} + +void plat_midi_close() +{} + +int plat_midi_get_num_devs() +{ return 0; } + +int plat_midi_in_get_num_devs(void) +{ return 0; } + +void plat_midi_get_dev_name(int num, char *s) +{ + s[0] = ' '; + s[1] = 0; +} + +void plat_midi_in_get_dev_name(int num, char *s) +{ + s[0] = ' '; + s[1] = 0; +} + +} diff --git a/src/qt/qt_models_common.cpp b/src/qt/qt_models_common.cpp new file mode 100644 index 000000000..892048605 --- /dev/null +++ b/src/qt/qt_models_common.cpp @@ -0,0 +1,15 @@ +#include "qt_models_common.hpp" + +#include + +int Models::AddEntry(QAbstractItemModel *model, const QString& displayRole, int userRole) +{ + int row = model->rowCount(); + model->insertRow(row); + auto idx = model->index(row, 0); + + model->setData(idx, displayRole, Qt::DisplayRole); + model->setData(idx, userRole, Qt::UserRole); + + return row; +} diff --git a/src/qt/qt_models_common.hpp b/src/qt/qt_models_common.hpp new file mode 100644 index 000000000..91cda3836 --- /dev/null +++ b/src/qt/qt_models_common.hpp @@ -0,0 +1,8 @@ +#pragma once + +class QString; +class QAbstractItemModel; +namespace Models +{ + int AddEntry(QAbstractItemModel* model, const QString& displayRole, int userRole); +}; diff --git a/src/qt/qt_newfloppydialog.cpp b/src/qt/qt_newfloppydialog.cpp new file mode 100644 index 000000000..9450dfe1c --- /dev/null +++ b/src/qt/qt_newfloppydialog.cpp @@ -0,0 +1,664 @@ +#include "qt_newfloppydialog.hpp" +#include "ui_qt_newfloppydialog.h" + +#include "qt_models_common.hpp" +#include "qt_util.hpp" + +extern "C" { +#include <86box/random.h> +#include <86box/scsi_device.h> +#include <86box/zip.h> +#include <86box/mo.h> +} + +#include +#include +#include +#include +#include +#include + +struct disk_size_t { + int hole; + int sides; + int data_rate; + int encoding; + int rpm; + int tracks; + int sectors; /* For IMG and Japanese FDI only. */ + int sector_len; /* For IMG and Japanese FDI only. */ + int media_desc; + int spc; + int num_fats; + int spfat; + int root_dir_entries; +}; + +static const disk_size_t disk_sizes[14] = { { 0, 1, 2, 1, 0, 40, 8, 2, 0xfe, 2, 2, 1, 64 }, /* 160k */ + { 0, 1, 2, 1, 0, 40, 9, 2, 0xfc, 2, 2, 1, 64 }, /* 180k */ + { 0, 2, 2, 1, 0, 40, 8, 2, 0xff, 2, 2, 1, 112 }, /* 320k */ + { 0, 2, 2, 1, 0, 40, 9, 2, 0xfd, 2, 2, 2, 112 }, /* 360k */ + { 0, 2, 2, 1, 0, 80, 8, 2, 0xfb, 2, 2, 2, 112 }, /* 640k */ + { 0, 2, 2, 1, 0, 80, 9, 2, 0xf9, 2, 2, 3, 112 }, /* 720k */ + { 1, 2, 0, 1, 1, 80, 15, 2, 0xf9, 1, 2, 7, 224 }, /* 1.2M */ + { 1, 2, 0, 1, 1, 77, 8, 3, 0xfe, 1, 2, 2, 192 }, /* 1.25M */ + { 1, 2, 0, 1, 0, 80, 18, 2, 0xf0, 1, 2, 9, 224 }, /* 1.44M */ + { 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 2, 2, 5, 16 }, /* DMF cluster 1024 */ + { 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 4, 2, 3, 16 }, /* DMF cluster 2048 */ + { 2, 2, 3, 1, 0, 80, 36, 2, 0xf0, 2, 2, 9, 240 }, /* 2.88M */ + { 0, 64, 0, 0, 0, 96, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 100 */ + { 0, 64, 0, 0, 0, 239, 32, 2, 0, 0, 0, 0, 0 } }; /* ZIP 250 */ + +static const QStringList rpmModes = { + "Perfect RPM", + "1%% below perfect RPM", + "1.5%% below perfect RPM", + "2%% below perfect RPM", +}; + +static const QStringList floppyTypes = { + "160 kB", + "180 kB", + "320 kB", + "360 kB", + "640 kB", + "720 kB", + "1.2 MB", + "1.25 MB", + "1.44 MB", + "DMF (cluster 1024)", + "DMF (cluster 2048)", + "2.88 MB", +}; + +static const QStringList zipTypes = { + "ZIP 100", + "ZIP 250", +}; + +static const QStringList moTypes = { + "3.5\" 128Mb M.O. (ISO 10090)", + "3.5\" 230Mb M.O. (ISO 13963)", + "3.5\" 540Mb M.O. (ISO 15498)", + "3.5\" 640Mb M.O. (ISO 15498)", + "3.5\" 1.3Gb M.O. (GigaMO)", + "3.5\" 2.3Gb M.O. (GigaMO 2)", + "5.25\" 600Mb M.O.", + "5.25\" 650Mb M.O.", + "5.25\" 1Gb M.O.", + "5.25\" 1.3Gb M.O.", +}; + +NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent) : + QDialog(parent), + ui(new Ui::NewFloppyDialog), + mediaType_(type) +{ + ui->setupUi(this); + ui->fileField->setCreateFile(true); + + auto* model = ui->comboBoxSize->model(); + switch (type) { + case MediaType::Floppy: + for (int i = 0; i < floppyTypes.size(); ++i) { + Models::AddEntry(model, tr(floppyTypes[i].toUtf8().data()), i); + } + ui->fileField->setFilter( + tr("All images") % + util::DlgFilter({ "86f","dsk","flp","im?","*fd?" }) % + tr("Basic sector images") % + util::DlgFilter({ "dsk","flp","im?","img","*fd?" }) % + tr("Surface images") % + util::DlgFilter({ "86f" }, true)); + + break; + case MediaType::Zip: + for (int i = 0; i < zipTypes.size(); ++i) { + Models::AddEntry(model, tr(zipTypes[i].toUtf8().data()), i); + } + ui->fileField->setFilter(tr("ZIP images") % util::DlgFilter({ "im?","zdi" }, true)); + break; + case MediaType::Mo: + for (int i = 0; i < moTypes.size(); ++i) { + Models::AddEntry(model, tr(moTypes[i].toUtf8().data()), i); + } + ui->fileField->setFilter(tr("MO images") % util::DlgFilter({ "im?","mdi" }) % tr("All files") % util::DlgFilter({ "*" }, true)); + break; + } + + model = ui->comboBoxRpm->model(); + for (int i = 0; i < rpmModes.size(); ++i) { + Models::AddEntry(model, tr(rpmModes[i].toUtf8().data()).replace("%%", "%"), i); + } + + connect(ui->fileField, &FileField::fileSelected, this, [this](const QString& filename) { + bool hide = true; + if (mediaType_ == MediaType::Floppy) { + if (QFileInfo(filename).suffix().toLower() == QStringLiteral("86f")) { + hide = false; + } + } + + ui->labelRpm->setHidden(hide); + ui->comboBoxRpm->setHidden(hide); + }); + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &NewFloppyDialog::onCreate); + + ui->labelRpm->setHidden(true); + ui->comboBoxRpm->setHidden(true); +} + +NewFloppyDialog::~NewFloppyDialog() { + delete ui; +} + +QString NewFloppyDialog::fileName() const{ + return ui->fileField->fileName(); +} + +void NewFloppyDialog::onCreate() { + auto filename = ui->fileField->fileName(); + QFileInfo fi(filename); + FileType fileType; + + QProgressDialog progress("Creating floppy image", QString(), 0, 100, this); + connect(this, &NewFloppyDialog::fileProgress, &progress, &QProgressDialog::setValue); + switch (mediaType_) { + case MediaType::Floppy: + if (fi.suffix().toLower() == QStringLiteral("86f")) { + if (create86f(filename, disk_sizes[ui->comboBoxSize->currentIndex()], ui->comboBoxRpm->currentIndex())) { + return; + } + } else { + fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Fdi : FileType::Img; + if (createSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex()], fileType)) { + return; + } + } + break; + case MediaType::Zip: + { + fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Zdi: FileType::Img; + + std::atomic_bool res; + std::thread t([this, &res, filename, fileType, &progress] { + res = createZipSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex() + 12], fileType, progress); + }); + progress.exec(); + t.join(); + + if (res) { + return; + } + } + break; + case MediaType::Mo: + { + fileType = fi.suffix().toLower() == QStringLiteral("mdi") ? FileType::Mdi: FileType::Img; + + std::atomic_bool res; + std::thread t([this, &res, filename, fileType, &progress] { + res = createMoSectorImage(filename, ui->comboBoxSize->currentIndex(), fileType, progress); + }); + progress.exec(); + t.join(); + + if (res) { + return; + } + } + break; + } + + QMessageBox::critical(this, tr("Unable to write file"), tr("Make sure the file is being saved to a writable directory")); + reject(); +} + +bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk_size, uint8_t rpm_mode) +{ + uint32_t magic = 0x46423638; + uint16_t version = 0x020C; + uint16_t dflags = 0; + uint16_t tflags = 0; + uint32_t index_hole_pos = 0; + uint32_t tarray[512]; + uint32_t array_size; + uint32_t track_base, track_size; + int i; + uint32_t shift = 0; + + dflags = 0; /* Has surface data? - Assume no for now. */ + dflags |= (disk_size.hole << 1); /* Hole */ + dflags |= ((disk_size.sides - 1) << 3); /* Sides. */ + dflags |= (0 << 4); /* Write protect? - Assume no for now. */ + dflags |= (rpm_mode << 5); /* RPM mode. */ + dflags |= (0 << 7); /* Has extra bit cells? - Assume no for now. */ + + tflags = disk_size.data_rate; /* Data rate. */ + tflags |= (disk_size.encoding << 3); /* Encoding. */ + tflags |= (disk_size.rpm << 5); /* RPM. */ + + switch (disk_size.hole) { + case 0: + case 1: + default: + switch(rpm_mode) { + case 1: + array_size = 25250; + break; + case 2: + array_size = 25374; + break; + case 3: + array_size = 25750; + break; + default: + array_size = 25000; + break; + } + break; + case 2: + switch(rpm_mode) { + case 1: + array_size = 50500; + break; + case 2: + array_size = 50750; + break; + case 3: + array_size = 51000; + break; + default: + array_size = 50000; + break; + } + break; + } + + QByteArray bytes(array_size, 0); + memset(tarray, 0, 2048); + + QFile file(filename); + if (! file.open(QIODevice::WriteOnly)) { + return false; + } + QDataStream stream(&file); + stream.setByteOrder(QDataStream::LittleEndian); + + stream << magic; + stream << version; + stream << dflags; + + track_size = array_size + 6; + track_base = 8 + ((disk_size.sides == 2) ? 2048 : 1024); + + if (disk_size.tracks <= 43) + shift = 1; + + for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) + tarray[i] = track_base + (i * track_size); + + stream.writeRawData(reinterpret_cast(tarray), (disk_size.sides == 2) ? 2048 : 1024); + + int max = i < (disk_size.tracks * disk_size.sides) << shift; + for (i = 0; i < max; i++) { + stream << tflags; + stream << index_hole_pos; + stream.writeRawData(bytes, bytes.size()); + } + + return true; +} + +bool NewFloppyDialog::createSectorImage(const QString &filename, const disk_size_t& disk_size, FileType type) +{ + uint32_t total_size = 0; + uint32_t total_sectors = 0; + uint32_t sector_bytes = 0; + uint32_t root_dir_bytes = 0; + uint32_t fat_size = 0; + uint32_t fat1_offs = 0; + uint32_t fat2_offs = 0; + uint32_t zero_bytes = 0; + uint16_t base = 0x1000; + + QFile file(filename); + if (! file.open(QIODevice::WriteOnly)) { + return false; + } + QDataStream stream(&file); + stream.setByteOrder(QDataStream::LittleEndian); + + sector_bytes = (128 << disk_size.sector_len); + total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; + if (total_sectors > ZIP_SECTORS) + total_sectors = ZIP_250_SECTORS; + total_size = total_sectors * sector_bytes; + root_dir_bytes = (disk_size.root_dir_entries << 5); + fat_size = (disk_size.spfat * sector_bytes); + fat1_offs = sector_bytes; + fat2_offs = fat1_offs + fat_size; + zero_bytes = fat2_offs + fat_size + root_dir_bytes; + + if (type == FileType::Fdi) { + QByteArray bytes(base, 0); + auto empty = bytes.data(); + *(uint32_t *) &(empty[0x08]) = (uint32_t) base; + *(uint32_t *) &(empty[0x0C]) = total_size; + *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; + *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; + *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; + *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; + stream.writeRawData(empty, base); + } + + QByteArray bytes(total_size, 0); + auto empty = bytes.data(); + + memset(empty + zero_bytes, 0xF6, total_size - zero_bytes); + + empty[0x00] = 0xEB; /* Jump to make MS-DOS happy. */ + empty[0x01] = 0x58; + empty[0x02] = 0x90; + + empty[0x03] = 0x38; /* '86BOX5.0' OEM ID. */ + empty[0x04] = 0x36; + empty[0x05] = 0x42; + empty[0x06] = 0x4F; + empty[0x07] = 0x58; + empty[0x08] = 0x35; + empty[0x09] = 0x2E; + empty[0x0A] = 0x30; + + *(uint16_t *) &(empty[0x0B]) = (uint16_t) sector_bytes; + *(uint8_t *) &(empty[0x0D]) = (uint8_t) disk_size.spc; + *(uint16_t *) &(empty[0x0E]) = (uint16_t) 1; + *(uint8_t *) &(empty[0x10]) = (uint8_t) disk_size.num_fats; + *(uint16_t *) &(empty[0x11]) = (uint16_t) disk_size.root_dir_entries; + *(uint16_t *) &(empty[0x13]) = (uint16_t) total_sectors; + *(uint8_t *) &(empty[0x15]) = (uint8_t) disk_size.media_desc; + *(uint16_t *) &(empty[0x16]) = (uint16_t) disk_size.spfat; + *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sectors; + *(uint8_t *) &(empty[0x1A]) = (uint8_t) disk_size.sides; + + empty[0x26] = 0x29; /* ')' followed by randomly-generated volume serial number. */ + empty[0x27] = random_generate(); + empty[0x28] = random_generate(); + empty[0x29] = random_generate(); + empty[0x2A] = random_generate(); + + memset(&(empty[0x2B]), 0x20, 11); + + empty[0x36] = 'F'; + empty[0x37] = 'A'; + empty[0x38] = 'T'; + empty[0x39] = '1'; + empty[0x3A] = '2'; + memset(&(empty[0x3B]), 0x20, 0x0003); + + empty[0x1FE] = 0x55; + empty[0x1FF] = 0xAA; + + empty[fat1_offs + 0x00] = empty[fat2_offs + 0x00] = empty[0x15]; + empty[fat1_offs + 0x01] = empty[fat2_offs + 0x01] = 0xFF; + empty[fat1_offs + 0x02] = empty[fat2_offs + 0x02] = 0xFF; + + stream.writeRawData(empty, total_size); + return true; +} + +bool NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_size_t& disk_size, FileType type, QProgressDialog& pbar) +{ + uint32_t total_size = 0; + uint32_t total_sectors = 0; + uint32_t sector_bytes = 0; + uint32_t root_dir_bytes = 0; + uint32_t fat_size = 0; + uint32_t fat1_offs = 0; + uint32_t fat2_offs = 0; + uint32_t zero_bytes = 0; + uint16_t base = 0x1000; + uint32_t pbar_max = 0; + + QFile file(filename); + if (! file.open(QIODevice::WriteOnly)) { + return false; + } + QDataStream stream(&file); + stream.setByteOrder(QDataStream::LittleEndian); + + sector_bytes = (128 << disk_size.sector_len); + total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; + if (total_sectors > ZIP_SECTORS) + total_sectors = ZIP_250_SECTORS; + total_size = total_sectors * sector_bytes; + root_dir_bytes = (disk_size.root_dir_entries << 5); + fat_size = (disk_size.spfat * sector_bytes); + fat1_offs = sector_bytes; + fat2_offs = fat1_offs + fat_size; + zero_bytes = fat2_offs + fat_size + root_dir_bytes; + + pbar_max = total_size; + if (type == FileType::Zdi) { + pbar_max += base; + } + pbar_max >>= 11; + + if (type == FileType::Zdi) { + QByteArray data(base, 0); + auto empty = data.data(); + + *(uint32_t *) &(empty[0x08]) = (uint32_t) base; + *(uint32_t *) &(empty[0x0C]) = total_size; + *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; + *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; + *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; + *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; + + stream.writeRawData(empty, base); + pbar_max -= 2; + } + + QByteArray bytes(total_size, 0); + auto empty = bytes.data(); + + if (total_sectors == ZIP_SECTORS) { + /* ZIP 100 */ + /* MBR */ + *(uint64_t *) &(empty[0x0000]) = 0x2054524150492EEBLL; + *(uint64_t *) &(empty[0x0008]) = 0x3930302065646F63LL; + *(uint64_t *) &(empty[0x0010]) = 0x67656D6F49202D20LL; + *(uint64_t *) &(empty[0x0018]) = 0x726F70726F432061LL; + *(uint64_t *) &(empty[0x0020]) = 0x202D206E6F697461LL; + *(uint64_t *) &(empty[0x0028]) = 0x30392F33322F3131LL; + + *(uint64_t *) &(empty[0x01AE]) = 0x0116010100E90644LL; + *(uint64_t *) &(empty[0x01B6]) = 0xED08BBE5014E0135LL; + *(uint64_t *) &(empty[0x01BE]) = 0xFFFFFE06FFFFFE80LL; + *(uint64_t *) &(empty[0x01C6]) = 0x0002FFE000000020LL; + + *(uint16_t *) &(empty[0x01FE]) = 0xAA55; + + /* 31 sectors filled with 0x48 */ + memset(&(empty[0x0200]), 0x48, 0x3E00); + + /* Boot sector */ + *(uint64_t *) &(empty[0x4000]) = 0x584F4236389058EBLL; + *(uint64_t *) &(empty[0x4008]) = 0x0008040200302E35LL; + *(uint64_t *) &(empty[0x4010]) = 0x00C0F80000020002LL; + *(uint64_t *) &(empty[0x4018]) = 0x0000002000FF003FLL; + *(uint32_t *) &(empty[0x4020]) = 0x0002FFE0; + *(uint16_t *) &(empty[0x4024]) = 0x0080; + + empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ + empty[0x4027] = random_generate(); + empty[0x4028] = random_generate(); + empty[0x4029] = random_generate(); + empty[0x402A] = random_generate(); + + memset(&(empty[0x402B]), 0x00, 0x000B); + memset(&(empty[0x4036]), 0x20, 0x0008); + + empty[0x4036] = 'F'; + empty[0x4037] = 'A'; + empty[0x4038] = 'T'; + empty[0x4039] = '1'; + empty[0x403A] = '6'; + memset(&(empty[0x403B]), 0x20, 0x0003); + + empty[0x41FE] = 0x55; + empty[0x41FF] = 0xAA; + + empty[0x5000] = empty[0x1D000] = empty[0x4015]; + empty[0x5001] = empty[0x1D001] = 0xFF; + empty[0x5002] = empty[0x1D002] = 0xFF; + empty[0x5003] = empty[0x1D003] = 0xFF; + + /* Root directory = 0x35000 + Data = 0x39000 */ + } else { + /* ZIP 250 */ + /* MBR */ + *(uint64_t *) &(empty[0x0000]) = 0x2054524150492EEBLL; + *(uint64_t *) &(empty[0x0008]) = 0x3930302065646F63LL; + *(uint64_t *) &(empty[0x0010]) = 0x67656D6F49202D20LL; + *(uint64_t *) &(empty[0x0018]) = 0x726F70726F432061LL; + *(uint64_t *) &(empty[0x0020]) = 0x202D206E6F697461LL; + *(uint64_t *) &(empty[0x0028]) = 0x30392F33322F3131LL; + + *(uint64_t *) &(empty[0x01AE]) = 0x0116010100E900E9LL; + *(uint64_t *) &(empty[0x01B6]) = 0x2E32A7AC014E0135LL; + + *(uint64_t *) &(empty[0x01EE]) = 0xEE203F0600010180LL; + *(uint64_t *) &(empty[0x01F6]) = 0x000777E000000020LL; + *(uint16_t *) &(empty[0x01FE]) = 0xAA55; + + /* 31 sectors filled with 0x48 */ + memset(&(empty[0x0200]), 0x48, 0x3E00); + + /* The second sector begins with some strange data + in my reference image. */ + *(uint64_t *) &(empty[0x0200]) = 0x3831393230334409LL; + *(uint64_t *) &(empty[0x0208]) = 0x6A57766964483130LL; + *(uint64_t *) &(empty[0x0210]) = 0x3C3A34676063653FLL; + *(uint64_t *) &(empty[0x0218]) = 0x586A56A8502C4161LL; + *(uint64_t *) &(empty[0x0220]) = 0x6F2D702535673D6CLL; + *(uint64_t *) &(empty[0x0228]) = 0x255421B8602D3456LL; + *(uint64_t *) &(empty[0x0230]) = 0x577B22447B52603ELL; + *(uint64_t *) &(empty[0x0238]) = 0x46412CC871396170LL; + *(uint64_t *) &(empty[0x0240]) = 0x704F55237C5E2626LL; + *(uint64_t *) &(empty[0x0248]) = 0x6C7932C87D5C3C20LL; + *(uint64_t *) &(empty[0x0250]) = 0x2C50503E47543D6ELL; + *(uint64_t *) &(empty[0x0258]) = 0x46394E807721536ALL; + *(uint64_t *) &(empty[0x0260]) = 0x505823223F245325LL; + *(uint64_t *) &(empty[0x0268]) = 0x365C79B0393B5B6ELL; + + /* Boot sector */ + *(uint64_t *) &(empty[0x4000]) = 0x584F4236389058EBLL; + *(uint64_t *) &(empty[0x4008]) = 0x0001080200302E35LL; + *(uint64_t *) &(empty[0x4010]) = 0x00EFF80000020002LL; + *(uint64_t *) &(empty[0x4018]) = 0x0000002000400020LL; + *(uint32_t *) &(empty[0x4020]) = 0x000777E0; + *(uint16_t *) &(empty[0x4024]) = 0x0080; + + empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ + empty[0x4027] = random_generate(); + empty[0x4028] = random_generate(); + empty[0x4029] = random_generate(); + empty[0x402A] = random_generate(); + + memset(&(empty[0x402B]), 0x00, 0x000B); + memset(&(empty[0x4036]), 0x20, 0x0008); + + empty[0x4036] = 'F'; + empty[0x4037] = 'A'; + empty[0x4038] = 'T'; + empty[0x4039] = '1'; + empty[0x403A] = '6'; + memset(&(empty[0x403B]), 0x20, 0x0003); + + empty[0x41FE] = 0x55; + empty[0x41FF] = 0xAA; + + empty[0x4200] = empty[0x22000] = empty[0x4015]; + empty[0x4201] = empty[0x22001] = 0xFF; + empty[0x4202] = empty[0x22002] = 0xFF; + empty[0x4203] = empty[0x22003] = 0xFF; + + /* Root directory = 0x3FE00 + Data = 0x38200 */ + } + + pbar.setMaximum(pbar_max); + for (uint32_t i = 0; i < pbar_max; i++) { + stream.writeRawData(&empty[i << 11], 2048); + fileProgress(i); + } + fileProgress(pbar_max); + + return true; +} + + +bool NewFloppyDialog::createMoSectorImage(const QString& filename, int8_t disk_size, FileType type, QProgressDialog& pbar) +{ + const mo_type_t *dp = &mo_types[disk_size]; + uint32_t total_size = 0, total_size2; + uint32_t total_sectors = 0; + uint32_t sector_bytes = 0; + uint16_t base = 0x1000; + uint32_t pbar_max = 0, blocks_num; + + QFile file(filename); + if (! file.open(QIODevice::WriteOnly)) { + return false; + } + QDataStream stream(&file); + stream.setByteOrder(QDataStream::LittleEndian); + + sector_bytes = dp->bytes_per_sector; + total_sectors = dp->sectors; + total_size = total_sectors * sector_bytes; + + total_size2 = (total_size >> 20) << 20; + total_size2 = total_size - total_size2; + + pbar_max = total_size; + pbar_max >>= 20; + blocks_num = pbar_max; + if (type == FileType::Mdi) + pbar_max++; + if (total_size2 == 0) + pbar_max++; + + if (type == FileType::Mdi) { + QByteArray bytes(base, 0); + auto empty = bytes.data(); + + *(uint32_t *) &(empty[0x08]) = (uint32_t) base; + *(uint32_t *) &(empty[0x0C]) = total_size; + *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; + *(uint8_t *) &(empty[0x14]) = (uint8_t) 25; + *(uint8_t *) &(empty[0x18]) = (uint8_t) 64; + *(uint8_t *) &(empty[0x1C]) = (uint8_t) (dp->sectors / 64) / 25; + + stream.writeRawData(empty, base); + } + + QByteArray bytes(1048576, 0); + auto empty = bytes.data(); + + pbar.setMaximum(blocks_num); + for (uint32_t i = 0; i < blocks_num; i++) { + stream.writeRawData(empty, bytes.size()); + fileProgress(i); + } + + if (total_size2 > 0) { + QByteArray extra_bytes(total_size2, 0); + stream.writeRawData(extra_bytes.data(), total_size2); + } + fileProgress(blocks_num); + + return true; +} diff --git a/src/qt/qt_newfloppydialog.hpp b/src/qt/qt_newfloppydialog.hpp new file mode 100644 index 000000000..12e761cdf --- /dev/null +++ b/src/qt/qt_newfloppydialog.hpp @@ -0,0 +1,50 @@ +#ifndef QT_NEWFLOPPYDIALOG_HPP +#define QT_NEWFLOPPYDIALOG_HPP + +#include + +namespace Ui { +class NewFloppyDialog; +} + +struct disk_size_t; +class QProgressDialog; + +class NewFloppyDialog : public QDialog +{ + Q_OBJECT + +public: + enum class MediaType { + Floppy, + Zip, + Mo, + }; + enum class FileType { + Img, + Fdi, + Zdi, + Mdi, + }; + explicit NewFloppyDialog(MediaType type, QWidget *parent = nullptr); + ~NewFloppyDialog(); + + QString fileName() const; + +signals: + void fileProgress(int i); + +private slots: + void onCreate(); + +private: + Ui::NewFloppyDialog *ui; + MediaType mediaType_; + + bool create86f(const QString& filename, const disk_size_t& disk_size, uint8_t rpm_mode); + bool createSectorImage(const QString& filename, const disk_size_t& disk_size, FileType type); + bool createZipSectorImage(const QString& filename, const disk_size_t& disk_size, FileType type, QProgressDialog& pbar); + bool createMoSectorImage(const QString& filename, int8_t disk_size, FileType type, QProgressDialog& pbar); +}; + +#endif // QT_NEWFLOPPYDIALOG_HPP diff --git a/src/qt/qt_newfloppydialog.ui b/src/qt/qt_newfloppydialog.ui new file mode 100644 index 000000000..7fb044fcc --- /dev/null +++ b/src/qt/qt_newfloppydialog.ui @@ -0,0 +1,148 @@ + + + NewFloppyDialog + + + + 0 + 0 + 327 + 200 + + + + + 327 + 200 + + + + + 327 + 200 + + + + New Image + + + + + + File name: + + + + + + + + 0 + 0 + + + + + + + + Disk size: + + + + + + + + 0 + 0 + + + + + + + + RPM mode: + + + + + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + FileField + QWidget +
qt_filefield.hpp
+ 1 +
+
+ + + + buttonBox + accepted() + NewFloppyDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + NewFloppyDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp new file mode 100644 index 000000000..b13e2a877 --- /dev/null +++ b/src/qt/qt_platform.cpp @@ -0,0 +1,533 @@ +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "qt_mainwindow.hpp" +#include "qt_progsettings.hpp" + +#ifdef Q_OS_UNIX +#include +#endif + +// static QByteArray buf; +extern QElapsedTimer elapsed_timer; +extern MainWindow* main_window; +QElapsedTimer elapsed_timer; + +static std::atomic_int blitmx_contention = 0; +static std::mutex blitmx; + +class CharPointer { +public: + CharPointer(char* buf, int size) : b(buf), s(size) {} + CharPointer& operator=(const QByteArray &ba) { + if (s > 0) { + strncpy(b, ba.data(), s-1); + b[s] = 0; + } else { + // if we haven't been told the length of b, just assume enough + // because we didn't get it from emulator code + strcpy(b, ba.data()); + b[ba.size()] = 0; + } + return *this; + } +private: + char* b; + int s; +}; + +extern "C" { +#ifdef Q_OS_WINDOWS +#define NOMINMAX +#include +#include <86box/win.h> +#else +#include +#endif +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/gameport.h> +#include <86box/timer.h> +#include <86box/nvr.h> +#include <86box/plat_dynld.h> +#include <86box/config.h> +#include <86box/ui.h> +#include <86box/discord.h> + +#include "../cpu/cpu.h" +#include <86box/plat.h> + +volatile int cpu_thread_run = 1; +int mouse_capture = 0; +int fixed_size_x = 640; +int fixed_size_y = 480; +int rctrl_is_lalt = 0; +int update_icons = 0; +int kbd_req_capture = 0; +int hide_status_bar = 0; +int hide_tool_bar = 0; +uint32_t lang_id = 0x0409, lang_sys = 0x0409; // Multilangual UI variables, for now all set to LCID of en-US + +int stricmp(const char* s1, const char* s2) +{ +#ifdef Q_OS_WINDOWS + return _stricmp(s1, s2); +#else + return strcasecmp(s1, s2); +#endif +} + +int strnicmp(const char *s1, const char *s2, size_t n) +{ +#ifdef Q_OS_WINDOWS + return _strnicmp(s1, s2, n); +#else + return strncasecmp(s1, s2, n); +#endif +} + +void +do_stop(void) +{ + cpu_thread_run = 0; + //main_window->close(); +} + +void plat_get_exe_name(char *s, int size) +{ + QByteArray exepath_temp = QCoreApplication::applicationDirPath().toLocal8Bit(); + + memcpy(s, exepath_temp.data(), std::min((qsizetype)exepath_temp.size(),(qsizetype)size)); + + plat_path_slash(s); +} + +uint32_t +plat_get_ticks(void) +{ + return elapsed_timer.elapsed(); +} + +uint64_t +plat_timer_read(void) +{ + return elapsed_timer.elapsed(); +} + +FILE * +plat_fopen(const char *path, const char *mode) +{ + return fopen(QString::fromUtf8(path).toLocal8Bit(), mode); +} + +FILE * +plat_fopen64(const char *path, const char *mode) +{ + return fopen(path, mode); +} + +int +plat_dir_create(char *path) +{ + return QDir().mkdir(path) ? 0 : -1; +} + +int +plat_dir_check(char *path) +{ + QFileInfo fi(path); + return fi.isDir() ? 1 : 0; +} + +int +plat_getcwd(char *bufp, int max) +{ + CharPointer(bufp, max) = QDir::currentPath().toUtf8(); + return 0; +} + +void +plat_get_dirname(char *dest, const char *path) +{ + QFileInfo fi(path); + CharPointer(dest, -1) = fi.dir().path().toUtf8(); +} + +char * +plat_get_extension(char *s) +{ + auto len = strlen(s); + auto idx = QByteArray::fromRawData(s, len).lastIndexOf('.'); + if (idx >= 0) { + return s+idx+1; + } + return s+len; +} + +char * +plat_get_filename(char *s) +{ +#ifdef Q_OS_WINDOWS + int c = strlen(s) - 1; + + while (c > 0) { + if (s[c] == '/' || s[c] == '\\') + return(&s[c+1]); + c--; + } + + return(s); +#else + auto idx = QByteArray::fromRawData(s, strlen(s)).lastIndexOf(QDir::separator().toLatin1()); + if (idx >= 0) { + return s+idx+1; + } + return s; +#endif +} + +int +plat_path_abs(char *path) +{ + QFileInfo fi(path); + return fi.isAbsolute() ? 1 : 0; +} + +void +plat_path_slash(char *path) +{ + auto len = strlen(path); + auto separator = QDir::separator().toLatin1(); + if (path[len-1] != separator) { + path[len] = separator; + path[len+1] = 0; + } +} + +void +plat_append_filename(char *dest, const char *s1, const char *s2) +{ + strcpy(dest, s1); + plat_path_slash(dest); + strcat(dest, s2); +} + +void +plat_tempfile(char *bufp, char *prefix, char *suffix) +{ + QString name; + + if (prefix != nullptr) { + name.append(QString("%1-").arg(prefix)); + } + + name.append(QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss-zzzz")); + if (suffix) name.append(suffix); + sprintf(&bufp[strlen(bufp)], "%s", name.toUtf8().data()); +} + +void plat_remove(char* path) +{ + QFile(path).remove(); +} + +void * +plat_mmap(size_t size, uint8_t executable) +{ +#if defined Q_OS_WINDOWS + return VirtualAlloc(NULL, size, MEM_COMMIT, executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); +#elif defined Q_OS_UNIX +#if defined Q_OS_DARWIN && defined MAP_JIT + void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE | (executable ? MAP_JIT : 0), -1, 0); +#else + void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE, -1, 0); +#endif + return (ret == MAP_FAILED) ? nullptr : ret; +#endif +} + +void +plat_munmap(void *ptr, size_t size) +{ +#if defined Q_OS_WINDOWS + VirtualFree(ptr, 0, MEM_RELEASE); +#else + munmap(ptr, size); +#endif +} + +void +plat_pause(int p) +{ + static wchar_t oldtitle[512]; + wchar_t title[512]; + + if ((p == 0) && (time_sync & TIME_SYNC_ENABLED)) + nvr_time_sync(); + + dopause = p; + if (p) { + wcsncpy(oldtitle, ui_window_title(NULL), sizeof_w(oldtitle) - 1); + wcscpy(title, oldtitle); + wcscat(title, L" - PAUSED -"); + ui_window_title(title); + } else { + ui_window_title(oldtitle); + } + discord_update_activity(dopause); + +#ifdef Q_OS_WINDOWS + if (source_hwnd) + PostMessage((HWND)(uintptr_t)source_hwnd, WM_SENDSTATUS, (WPARAM)!!p, (LPARAM)(HWND)main_window->winId()); +#endif +} + +// because we can't include nvr.h because it's got fields named new +extern int nvr_save(void); + +void +plat_power_off(void) +{ + confirm_exit = 0; + nvr_save(); + config_save(); + + /* Deduct a sufficiently large number of cycles that no instructions will + run before the main thread is terminated */ + cycles -= 99999999; + + cpu_thread_run = 0; + main_window->close(); +} + +void set_language(uint32_t id) { + lang_id = id; +} + +extern "C++" +{ + QMap> ProgSettings::lcid_langcode = + { + {0x0405, {"cs-CZ", "Czech (Czech Republic)"} }, + {0x0407, {"de-DE", "German (Germany)"} }, + {0x0408, {"en-US", "English (United States)"} }, + {0x0809, {"en-GB", "English (United Kingdom)"} }, + {0x0C0A, {"es-ES", "Spanish (Spain)"} }, + {0x040B, {"fi-FI", "Finnish (Finland)"} }, + {0x040C, {"fr-FR", "French (France)"} }, + {0x041A, {"hr-HR", "Croatian (Croatia)"} }, + {0x040E, {"hu-HU", "Hungarian (Hungary)"} }, + {0x0410, {"it-IT", "Italian (Italy)"} }, + {0x0411, {"ja-JP", "Japanese (Japan)"} }, + {0x0412, {"ko-KR", "Korean (Korea)"} }, + {0x0415, {"pl-PL", "Polish (Poland)"} }, + {0x0416, {"pt-BR", "Portuguese (Brazil)"} }, + {0x0816, {"pt-PT", "Portuguese (Portugal)"} }, + {0x0419, {"ru-RU", "Russian (Russia)"} }, + {0x0424, {"sl-SI", "Slovenian (Slovenia)"} }, + {0x041F, {"tr-TR", "Turkish (Turkey)"} }, + {0x0422, {"uk-UA", "Ukrainian (Ukraine)"} }, + {0x0804, {"zh-CN", "Chinese (China)"} }, + {0xFFFF, {"system", "(System Default)"} }, + }; +} + +/* Sets up the program language before initialization. */ +uint32_t plat_language_code(char* langcode) { + for (auto& curKey : ProgSettings::lcid_langcode.keys()) + { + if (ProgSettings::lcid_langcode[curKey].first == langcode) + { + return curKey; + } + } + return 0xFFFF; +} + +/* Converts back the language code to LCID */ +void plat_language_code_r(uint32_t lcid, char* outbuf, int len) { + if (!ProgSettings::lcid_langcode.contains(lcid)) + { + qstrncpy(outbuf, "system", len); + return; + } + qstrncpy(outbuf, ProgSettings::lcid_langcode[lcid].first.toUtf8().constData(), len); + return; +} + +void* dynld_module(const char *name, dllimp_t *table) +{ + QString libraryName = name; + QFileInfo fi(libraryName); + QStringList removeSuffixes = {"dll", "dylib", "so"}; + if (removeSuffixes.contains(fi.suffix())) { + libraryName = fi.completeBaseName(); + } + + auto lib = std::unique_ptr(new QLibrary(libraryName)); + if (lib->load()) { + for (auto imp = table; imp->name != nullptr; imp++) + { + auto ptr = lib->resolve(imp->name); + if (ptr == nullptr) { + return nullptr; + } + auto imp_ptr = reinterpret_cast(imp->func); + *imp_ptr = reinterpret_cast(ptr); + } + } else { + return nullptr; + } + + return lib.release(); +} + +void dynld_close(void *handle) +{ + delete reinterpret_cast(handle); +} + +void startblit() +{ + blitmx_contention++; + if (blitmx.try_lock()) { + return; + } + + blitmx.lock(); +} + +void endblit() +{ + blitmx_contention--; + blitmx.unlock(); + if (blitmx_contention > 0) { + // a deadlock has been observed on linux when toggling via video_toggle_option + // because the mutex is typically unfair on linux + // => sleep if there's contention + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } +} + +} + +#ifdef Q_OS_WINDOWS +size_t mbstoc16s(uint16_t dst[], const char src[], int len) +{ + if (src == NULL) return 0; + if (len < 0) return 0; + + size_t ret = MultiByteToWideChar(CP_UTF8, 0, src, -1, reinterpret_cast(dst), dst == NULL ? 0 : len); + + if (!ret) { + return -1; + } + + return ret; +} + +size_t c16stombs(char dst[], const uint16_t src[], int len) +{ + if (src == NULL) return 0; + if (len < 0) return 0; + + size_t ret = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast(src), -1, dst, dst == NULL ? 0 : len, NULL, NULL); + + if (!ret) { + return -1; + } + + return ret; +} +#endif + +#ifdef _WIN32 +#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" +#define LIB_NAME_GS "gsdll32.dll" +#define LIB_NAME_FREETYPE "freetype.dll" +#define MOUSE_CAPTURE_KEYSEQ "F8+F12" +#else +#define LIB_NAME_FLUIDSYNTH "libfluidsynth" +#define LIB_NAME_GS "libgs" +#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 ProgSettings::translatedstrings; + +void ProgSettings::reloadStrings() +{ + translatedstrings.clear(); + translatedstrings[IDS_2077] = QCoreApplication::translate("", "Click to capture mouse").toStdWString(); + translatedstrings[IDS_2078] = QCoreApplication::translate("", "Press F8+F12 to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); + translatedstrings[IDS_2079] = QCoreApplication::translate("", "Press F8+F12 or middle button to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); + translatedstrings[IDS_2080] = QCoreApplication::translate("", "Failed to initialize FluidSynth").toStdWString(); + translatedstrings[IDS_4099] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); + translatedstrings[IDS_2093] = QCoreApplication::translate("", "Failed to set up PCap").toStdWString(); + translatedstrings[IDS_2094] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); + translatedstrings[IDS_2110] = QCoreApplication::translate("", "Unable to initialize FreeType").toStdWString(); + translatedstrings[IDS_2111] = QCoreApplication::translate("", "Unable to initialize SDL, libsdl2 is required").toStdWString(); + translatedstrings[IDS_2129] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); + translatedstrings[IDS_2114] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); + translatedstrings[IDS_2063] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); + translatedstrings[IDS_2064] = QCoreApplication::translate("", "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card.").toStdWString(); + translatedstrings[IDS_2128] = QCoreApplication::translate("", "Hardware not available").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 download a ROM set and extract it into the \"roms\" directory.").replace("roms", ROMDIR).toStdWString(); + + auto flsynthstr = QCoreApplication::translate("", " is required for FluidSynth MIDI output."); + if (flsynthstr.contains("libfluidsynth")) + { + flsynthstr.replace("libfluidsynth", LIB_NAME_FLUIDSYNTH); + } + else flsynthstr.prepend(LIB_NAME_FLUIDSYNTH); + translatedstrings[IDS_2133] = flsynthstr.toStdWString(); + auto gssynthstr = QCoreApplication::translate("", " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."); + if (gssynthstr.contains("libgs")) + { + gssynthstr.replace("libgs", LIB_NAME_GS); + } + else gssynthstr.prepend(LIB_NAME_GS); + translatedstrings[IDS_2132] = flsynthstr.toStdWString(); + auto ftsynthstr = QCoreApplication::translate("", " is required for ESC/P printer emulation."); + if (ftsynthstr.contains("libfreetype")) + { + ftsynthstr.replace("libfreetype", LIB_NAME_FREETYPE); + } + else ftsynthstr.prepend(LIB_NAME_FREETYPE); + translatedstrings[IDS_2131] = ftsynthstr.toStdWString(); +} + +wchar_t* plat_get_string(int i) +{ + if (ProgSettings::translatedstrings.empty()) ProgSettings::reloadStrings(); + return ProgSettings::translatedstrings[i].data(); +} + +int +plat_chdir(char *path) +{ + return QDir::setCurrent(QString(path)) ? 0 : -1; +} diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp new file mode 100644 index 000000000..f7fbd2ea6 --- /dev/null +++ b/src/qt/qt_progsettings.cpp @@ -0,0 +1,176 @@ +#include + +#include "qt_progsettings.hpp" +#include "ui_qt_progsettings.h" +#include "qt_mainwindow.hpp" +#include "ui_qt_mainwindow.h" +#include "qt_machinestatus.hpp" + +#include +#include +#include +#include + +extern "C" +{ +#include <86box/86box.h> +#include <86box/config.h> +#include <86box/plat.h> +} + + +static QMap iconset_to_qt; +extern MainWindow* main_window; + +ProgSettings::CustomTranslator* ProgSettings::translator = nullptr; +QTranslator* ProgSettings::qtTranslator = nullptr; +QString ProgSettings::getIconSetPath() +{ + QString roms_root; + if (rom_path[0]) + roms_root = rom_path; + else { + roms_root = QString("%1/roms").arg(exe_path); + } + + if (iconset_to_qt.isEmpty()) + { + iconset_to_qt.insert("", ":/settings/win/icons"); + QDir dir(roms_root + "/icons/"); + if (dir.isReadable()) + { + auto dirList = dir.entryList(QDir::AllDirs | QDir::Executable | QDir::Readable); + for (auto &curIconSet : dirList) + { + if (curIconSet == "." || curIconSet == "..") continue; + iconset_to_qt.insert(curIconSet, (dir.canonicalPath() + '/') + curIconSet); + } + } + } + return iconset_to_qt[icon_set]; +} + +QIcon ProgSettings::loadIcon(QString file) +{ + (void)getIconSetPath(); + if (!QFile::exists(iconset_to_qt[icon_set] + file)) return QIcon(iconset_to_qt[""] + file); + return QIcon(iconset_to_qt[icon_set] + file); +} + +ProgSettings::ProgSettings(QWidget *parent) : + QDialog(parent), + ui(new Ui::ProgSettings) +{ + ui->setupUi(this); + (void)getIconSetPath(); + ui->comboBox->setItemData(0, ""); + ui->comboBox->setCurrentIndex(0); + for (auto i = iconset_to_qt.begin(); i != iconset_to_qt.end(); i++) + { + if (i.key() == "") continue; + QFile iconfile(i.value() + "/iconinfo.txt"); + iconfile.open(QFile::ReadOnly); + QString friendlyName; + QString iconsetinfo(iconfile.readAll()); + iconfile.close(); + if (iconsetinfo.isEmpty()) friendlyName = i.key(); + else friendlyName = iconsetinfo.split('\n')[0]; + ui->comboBox->addItem(friendlyName, i.key()); + if (strcmp(icon_set, i.key().toUtf8().data()) == 0) + { + ui->comboBox->setCurrentIndex(ui->comboBox->findData(i.key())); + } + } + ui->comboBox->setItemData(0, '(' + tr("Default") + ')', Qt::DisplayRole); + + ui->comboBoxLanguage->setItemData(0, 0xFFFF); + for (auto i = lcid_langcode.begin(); i != lcid_langcode.end(); i++) + { + if (i.key() == 0xFFFF) continue; + ui->comboBoxLanguage->addItem(lcid_langcode[i.key()].second, i.key()); + if (i.key() == lang_id) + { + ui->comboBoxLanguage->setCurrentIndex(ui->comboBoxLanguage->findData(i.key())); + } + } +} + +void ProgSettings::accept() +{ + strcpy(icon_set, ui->comboBox->currentData().toString().toUtf8().data()); + lang_id = ui->comboBoxLanguage->currentData().toUInt(); + + loadTranslators(QCoreApplication::instance()); + reloadStrings(); + update_mouse_msg(); + main_window->ui->retranslateUi(main_window); + QString msg = main_window->status->getMessage(); + main_window->status.reset(new MachineStatus(main_window)); + main_window->refreshMediaMenu(); + main_window->status->message(msg); + connect(main_window, &MainWindow::updateStatusBarTip, main_window->status.get(), &MachineStatus::updateTip); + connect(main_window, &MainWindow::updateStatusBarActivity, main_window->status.get(), &MachineStatus::setActivity); + connect(main_window, &MainWindow::updateStatusBarEmpty, main_window->status.get(), &MachineStatus::setEmpty); + connect(main_window, &MainWindow::statusBarMessage, main_window->status.get(), &MachineStatus::message); + QDialog::accept(); +} + +ProgSettings::~ProgSettings() +{ + delete ui; +} + +void ProgSettings::on_pushButton_released() +{ + ui->comboBox->setCurrentIndex(0); +} + +void ProgSettings::loadTranslators(QObject *parent) +{ + if (qtTranslator) + { + QApplication::removeTranslator(qtTranslator); + qtTranslator = nullptr; + } + if (translator) + { + QApplication::removeTranslator(translator); + translator = nullptr; + } + qtTranslator = new QTranslator(parent); + translator = new CustomTranslator(parent); + QString localetofilename = ""; + if (lang_id == 0xFFFF || lcid_langcode.contains(lang_id) == false) + { + for (int i = 0; i < QLocale::system().uiLanguages().size(); i++) + { + localetofilename = QLocale::system().uiLanguages()[i]; + if (translator->load(QLatin1String("86box_") + localetofilename, QLatin1String(":/"))) + { + qDebug() << "Translations loaded.\n"; + QCoreApplication::installTranslator(translator); + if (!qtTranslator->load(QLatin1String("qtbase_") + localetofilename.replace('-', '_'), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + qtTranslator->load(QLatin1String("qt_") + localetofilename.replace('-', '_'), QApplication::applicationDirPath() + "/./translations/"); + if (QApplication::installTranslator(qtTranslator)) + { + qDebug() << "Qt translations loaded." << "\n"; + } + break; + } + } + } + else + { + translator->load(QLatin1String("86box_") + lcid_langcode[lang_id].first, QLatin1String(":/")); + QCoreApplication::installTranslator(translator); + if (!qtTranslator->load(QLatin1String("qtbase_") + QString(lcid_langcode[lang_id].first).replace('-', '_'), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + qtTranslator->load(QLatin1String("qt_") + QString(lcid_langcode[lang_id].first).replace('-', '_'), QApplication::applicationDirPath() + "/./translations/"); + QCoreApplication::installTranslator(qtTranslator); + } +} + +void ProgSettings::on_pushButtonLanguage_released() +{ + ui->comboBoxLanguage->setCurrentIndex(0); +} + diff --git a/src/qt/qt_progsettings.hpp b/src/qt/qt_progsettings.hpp new file mode 100644 index 000000000..39b3e6819 --- /dev/null +++ b/src/qt/qt_progsettings.hpp @@ -0,0 +1,67 @@ +#ifndef QT_PROGSETTINGS_HPP +#define QT_PROGSETTINGS_HPP + +#include +#include + +namespace Ui { +class ProgSettings; +} + +class ProgSettings : public QDialog +{ + Q_OBJECT + +public: + explicit ProgSettings(QWidget *parent = nullptr); + ~ProgSettings(); + static QString getIconSetPath(); + static QIcon loadIcon(QString file); + static void loadTranslators(QObject* parent = nullptr); + static void reloadStrings(); + class CustomTranslator : public QTranslator + { + public: + CustomTranslator(QObject* parent = nullptr) : QTranslator(parent) {}; + protected: + QString translate(const char *context, const char *sourceText, + const char *disambiguation = nullptr, int n = -1) const override + { + if (strcmp(sourceText, "&Fullscreen") == 0) sourceText = "&Fullscreen\tCtrl+Alt+PageUP"; + if (strcmp(sourceText, "&Ctrl+Alt+Del") == 0) sourceText = "&Ctrl+Alt+Del\tCtrl+F12"; + if (strcmp(sourceText, "Take s&creenshot") == 0) sourceText = "Take s&creenshot\tCtrl+F11"; + if (strcmp(sourceText, "Begin trace") == 0) sourceText = "Begin trace\tCtrl+T"; + if (strcmp(sourceText, "End trace") == 0) sourceText = "End trace\tCtrl+T"; + if (strcmp(sourceText, "Dump &video RAM") == 0) sourceText = "Dump &video RAM\tCtrl+F1"; + if (strcmp(sourceText, "&Qt (Software)") == 0) + { + QString finalstr = QTranslator::translate("", "&SDL (Software)", disambiguation, n); + finalstr.replace("SDL", "Qt"); + finalstr.replace("(&S)", "(&Q)"); + return finalstr; + } + QString finalstr = QTranslator::translate("", sourceText, disambiguation, n); +#ifdef Q_OS_MACOS + if (finalstr.contains('\t')) finalstr.truncate(finalstr.indexOf('\t')); +#endif + return finalstr; + } + }; + static CustomTranslator* translator; + static QTranslator* qtTranslator; + static QMap> lcid_langcode; + static QMap translatedstrings; + +protected slots: + void accept() override; +private slots: + void on_pushButton_released(); + void on_pushButtonLanguage_released(); + +private: + Ui::ProgSettings *ui; + + friend class MainWindow; +}; + +#endif // QT_PROGSETTINGS_HPP diff --git a/src/qt/qt_progsettings.ui b/src/qt/qt_progsettings.ui new file mode 100644 index 000000000..b64272f8b --- /dev/null +++ b/src/qt/qt_progsettings.ui @@ -0,0 +1,164 @@ + + + ProgSettings + + + + 0 + 0 + 370 + 228 + + + + + 370 + 228 + + + + + 370 + 228 + + + + Preferences + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + (System Default) + + + + + + + + Default + + + + + + + Language: + + + + + + + false + + + + (Default) + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Icon set: + + + + + + + Default + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + buttonBox + accepted() + ProgSettings + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ProgSettings + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp new file mode 100644 index 000000000..10cd72d8c --- /dev/null +++ b/src/qt/qt_renderercommon.cpp @@ -0,0 +1,107 @@ +#include "qt_renderercommon.hpp" +#include "qt_mainwindow.hpp" + +#include +#include +#include +#include + +#include + +extern "C" { +#include <86box/86box.h> +#include <86box/video.h> +} + +RendererCommon::RendererCommon() = default; + +extern MainWindow* main_window; + +static void integer_scale(double *d, double *g) { + double ratio; + + if (*d > *g) { + ratio = std::floor(*d / *g); + *d = *g * ratio; + } else { + ratio = std::ceil(*d / *g); + *d = *g / ratio; + } +} + +void RendererCommon::onResize(int width, int height) { + if (video_fullscreen == 0) { + destination.setRect(0, 0, width, height); + return; + } + double dx, dy, dw, dh, gsr; + + double hw = width; + double hh = height; + double gw = source.width(); + double gh = source.height(); + double hsr = hw / hh; + + switch (video_fullscreen_scale) { + case FULLSCR_SCALE_INT: + gsr = gw / gh; + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + integer_scale(&dw, &gw); + integer_scale(&dh, &gh); + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + destination.setRect(dx, dy, dw, dh); + break; + case FULLSCR_SCALE_43: + case FULLSCR_SCALE_KEEPRATIO: + if (video_fullscreen_scale == FULLSCR_SCALE_43) { + gsr = 4.0 / 3.0; + } else { + gsr = gw / gh; + } + + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + destination.setRect(dx, dy, dw, dh); + break; + case FULLSCR_SCALE_FULL: + default: + destination.setRect(0, 0, hw, hh); + break; + } +} + +bool RendererCommon::eventDelegate(QEvent *event, bool& result) +{ + switch (event->type()) + { + default: + return false; + case QEvent::KeyPress: + case QEvent::KeyRelease: + result = QApplication::sendEvent(main_window, event); + return true; + case QEvent::MouseButtonPress: + case QEvent::MouseMove: + case QEvent::MouseButtonRelease: + case QEvent::Wheel: + case QEvent::Enter: + case QEvent::Leave: + result = QApplication::sendEvent(parentWidget, event); + return true; + } + return false; +} diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp new file mode 100644 index 000000000..a62aa9aa2 --- /dev/null +++ b/src/qt/qt_renderercommon.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include + +class QWidget; + +class RendererCommon +{ +public: + RendererCommon(); + + void onResize(int width, int height); + virtual std::vector> getBuffers() = 0; +protected: + bool eventDelegate(QEvent* event, bool& result); + + QRect source, destination; + QWidget* parentWidget{nullptr}; + + std::vector buf_usage; +}; diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp new file mode 100644 index 000000000..b07ed34f7 --- /dev/null +++ b/src/qt/qt_rendererstack.cpp @@ -0,0 +1,255 @@ +#include "qt_rendererstack.hpp" +#include "ui_qt_rendererstack.h" + +#include "qt_softwarerenderer.hpp" +#include "qt_hardwarerenderer.hpp" + +#include "qt_mainwindow.hpp" + +#include "evdev_mouse.hpp" + +#include + +#ifdef __APPLE__ +#include +#endif + +extern "C" +{ +#include <86box/mouse.h> +#include <86box/plat.h> +#include <86box/video.h> +} + +extern MainWindow* main_window; +RendererStack::RendererStack(QWidget *parent) : + QStackedWidget(parent), + ui(new Ui::RendererStack) +{ + ui->setupUi(this); + +#ifdef WAYLAND + if (QApplication::platformName().contains("wayland")) { + wl_init(); + } +#endif +#ifdef EVDEV_INPUT + if (QApplication::platformName() == "xcb" || QApplication::platformName() == "eglfs") { + evdev_init(); + } +#endif +} + +RendererStack::~RendererStack() +{ + delete ui; +} + +extern "C" void macos_poll_mouse(); +void +qt_mouse_capture(int on) +{ + if (!on) + { + mouse_capture = 0; + QApplication::setOverrideCursor(Qt::ArrowCursor); +#ifdef __APPLE__ + CGAssociateMouseAndMouseCursorPosition(true); +#endif + return; + } + mouse_capture = 1; + QApplication::setOverrideCursor(Qt::BlankCursor); +#ifdef __APPLE__ + CGAssociateMouseAndMouseCursorPosition(false); +#endif + return; +} + +void RendererStack::mousePoll() +{ +#ifdef __APPLE__ + return macos_poll_mouse(); +#else + mouse_x = mousedata.deltax; + mouse_y = mousedata.deltay; + mouse_z = mousedata.deltaz; + mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; + mouse_buttons = mousedata.mousebuttons; +#ifdef WAYLAND + if (QApplication::platformName().contains("wayland")) + wl_mouse_poll(); +#endif +#ifdef EVDEV_INPUT + evdev_mouse_poll(); +#endif +#endif +} + +int ignoreNextMouseEvent = 1; +void RendererStack::mouseReleaseEvent(QMouseEvent *event) +{ + if (this->geometry().contains(event->pos()) && event->button() == Qt::LeftButton && !mouse_capture && (isMouseDown & 1)) + { + plat_mouse_capture(1); + this->setCursor(Qt::BlankCursor); + if (!ignoreNextMouseEvent) ignoreNextMouseEvent++; // Avoid jumping cursor when moved. + isMouseDown &= ~1; + return; + } + if (mouse_capture && event->button() == Qt::MiddleButton && mouse_get_buttons() < 3) + { + plat_mouse_capture(0); + this->setCursor(Qt::ArrowCursor); + isMouseDown &= ~1; + return; + } + if (mouse_capture) + { + mousedata.mousebuttons &= ~event->button(); + } + isMouseDown &= ~1; +} +void RendererStack::mousePressEvent(QMouseEvent *event) +{ + isMouseDown |= 1; + if (mouse_capture) + { + mousedata.mousebuttons |= event->button(); + } + if (main_window->frameGeometry().contains(event->pos()) && !geometry().contains(event->pos())) + { + main_window->windowHandle()->startSystemMove(); + } + event->accept(); +} +void RendererStack::wheelEvent(QWheelEvent *event) +{ + if (mouse_capture) + { + mousedata.deltaz += event->pixelDelta().y(); + } +} + +void RendererStack::mouseMoveEvent(QMouseEvent *event) +{ + if (QApplication::platformName().contains("wayland")) + { + event->accept(); + return; + } + if (!mouse_capture) { event->ignore(); return; } +#ifdef __APPLE__ + event->accept(); + return; +#else + static QPoint oldPos = QCursor::pos(); + if (ignoreNextMouseEvent) { oldPos = event->pos(); ignoreNextMouseEvent--; event->accept(); return; } + mousedata.deltax += event->pos().x() - oldPos.x(); + mousedata.deltay += event->pos().y() - oldPos.y(); + if (QApplication::platformName() == "eglfs") + { + leaveEvent((QEvent*)event); + ignoreNextMouseEvent--; + } + else if (event->globalPos().x() == 0 || event->globalPos().y() == 0) leaveEvent((QEvent*)event); + else if (event->globalPos().x() == (screen()->geometry().width() - 1) || event->globalPos().y() == (screen()->geometry().height() - 1)) leaveEvent((QEvent*)event); + oldPos = event->pos(); +#endif +} + +void RendererStack::leaveEvent(QEvent* event) +{ + if (QApplication::platformName().contains("wayland")) + { + event->accept(); + return; + } + if (!mouse_capture) return; + QCursor::setPos(mapToGlobal(QPoint(width() / 2, height() / 2))); + ignoreNextMouseEvent = 2; + event->accept(); +} + +void RendererStack::switchRenderer(Renderer renderer) { + startblit(); + if (current) { + removeWidget(current.get()); + } + + switch (renderer) { + case Renderer::Software: + { + auto sw = new SoftwareRenderer(this); + rendererWindow = sw; + connect(this, &RendererStack::blitToRenderer, sw, &SoftwareRenderer::onBlit, Qt::QueuedConnection); + current.reset(this->createWindowContainer(sw, this)); + } + break; + case Renderer::OpenGL: + { + this->createWinId(); + auto hw = new HardwareRenderer(this); + rendererWindow = hw; + connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection); + current.reset(this->createWindowContainer(hw, this)); + break; + } + case Renderer::OpenGLES: + { + this->createWinId(); + auto hw = new HardwareRenderer(this, HardwareRenderer::RenderType::OpenGLES); + rendererWindow = hw; + connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection); + current.reset(this->createWindowContainer(hw, this)); + break; + } + case Renderer::OpenGL3: + { + this->createWinId(); + auto hw = new HardwareRenderer(this, HardwareRenderer::RenderType::OpenGL3); + rendererWindow = hw; + connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection); + current.reset(this->createWindowContainer(hw, this)); + break; + } + } + + imagebufs = std::move(rendererWindow->getBuffers()); + + current->setFocusPolicy(Qt::NoFocus); + current->setFocusProxy(this); + addWidget(current.get()); + + this->setStyleSheet("background-color: black"); + + endblit(); +} + +// called from blitter thread +void RendererStack::blit(int x, int y, int w, int h) +{ + if ((w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || std::get(imagebufs[currentBuf])->test_and_set()) + { + video_blit_complete(); + return; + } + sx = x; + sy = y; + sw = this->w = w; + sh = this->h = h; + uint8_t* imagebits = std::get(imagebufs[currentBuf]); + for (int y1 = y; y1 < (y + h); y1++) + { + auto scanline = imagebits + (y1 * (2048) * 4) + (x * 4); + video_copy(scanline, &(buffer32->line[y1][x]), w * 4); + } + + if (screenshots) + { + video_screenshot((uint32_t *)imagebits, x, y, 2048); + } + video_blit_complete(); + emit blitToRenderer(currentBuf, sx, sy, sw, sh); + currentBuf = (currentBuf + 1) % imagebufs.size(); +} diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp new file mode 100644 index 000000000..9bff340f0 --- /dev/null +++ b/src/qt/qt_rendererstack.hpp @@ -0,0 +1,75 @@ +#ifndef QT_RENDERERCONTAINER_HPP +#define QT_RENDERERCONTAINER_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace Ui { +class RendererStack; +} + +class RendererCommon; +class RendererStack : public QStackedWidget +{ + Q_OBJECT + +public: + explicit RendererStack(QWidget *parent = nullptr); + ~RendererStack(); + + void mousePressEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void wheelEvent(QWheelEvent *event) override; + void leaveEvent(QEvent *event) override; + void keyPressEvent(QKeyEvent* event) override + { + event->ignore(); + } + void keyReleaseEvent(QKeyEvent* event) override + { + event->ignore(); + } + + enum class Renderer { + Software, + OpenGL, + OpenGLES, + OpenGL3 + }; + void switchRenderer(Renderer renderer); + + RendererCommon* rendererWindow{nullptr}; +signals: + void blitToRenderer(int buf_idx, int x, int y, int w, int h); + +public slots: + void blit(int x, int y, int w, int h); + void mousePoll(); + +private: + Ui::RendererStack *ui; + + struct mouseinputdata { + int deltax, deltay, deltaz; + int mousebuttons; + }; + mouseinputdata mousedata; + + int x, y, w, h, sx, sy, sw, sh; + + int currentBuf = 0; + int isMouseDown = 0; + std::vector> imagebufs; + + std::unique_ptr current; + + friend class MainWindow; +}; + +#endif // QT_RENDERERCONTAINER_HPP diff --git a/src/qt/qt_rendererstack.ui b/src/qt/qt_rendererstack.ui new file mode 100644 index 000000000..634784714 --- /dev/null +++ b/src/qt/qt_rendererstack.ui @@ -0,0 +1,19 @@ + + + RendererStack + + + + 0 + 0 + 400 + 300 + + + + StackedWidget + + + + + diff --git a/src/qt/qt_sdl.c b/src/qt/qt_sdl.c new file mode 100644 index 000000000..81a1311d1 --- /dev/null +++ b/src/qt/qt_sdl.c @@ -0,0 +1,732 @@ +/* + * 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. + * + * Rendering module for libSDL2 + * + * NOTE: Given all the problems reported with FULLSCREEN use of SDL, + * we will not use that, but, instead, use a new window which + * coverrs the entire desktop. + * + * + * + * Authors: Fred N. van Kempen, + * Michael Dr�ing, + * + * Copyright 2018-2020 Fred N. van Kempen. + * Copyright 2018-2020 Michael Dr�ing. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include + +#include +#include +#include +#include +/* This #undef is needed because a SDL include header redefines HAVE_STDARG_H. */ +#undef HAVE_STDARG_H +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/mouse.h> +#include <86box/keyboard.h> +#include <86box/device.h> +#include <86box/plat.h> +#include <86box/plat_dynld.h> +#include <86box/video.h> +#include <86box/ui.h> +#include <86box/version.h> + +#include "qt_sdl.h" + +#define RENDERER_FULL_SCREEN 1 +#define RENDERER_HARDWARE 2 +#define RENDERER_OPENGL 4 + + +static SDL_Window *sdl_win = NULL; +static SDL_Renderer *sdl_render = NULL; +static SDL_Texture *sdl_tex = NULL; +static int sdl_w, sdl_h; +static int sdl_fs, sdl_flags = -1; +static int cur_w, cur_h; +static int cur_ww = 0, cur_wh = 0; +static volatile int sdl_enabled = 0; +static SDL_mutex* sdl_mutex = NULL; + +static const uint16_t sdl_to_xt[0x200] = + { + [SDL_SCANCODE_ESCAPE] = 0x01, + [SDL_SCANCODE_1] = 0x02, + [SDL_SCANCODE_2] = 0x03, + [SDL_SCANCODE_3] = 0x04, + [SDL_SCANCODE_4] = 0x05, + [SDL_SCANCODE_5] = 0x06, + [SDL_SCANCODE_6] = 0x07, + [SDL_SCANCODE_7] = 0x08, + [SDL_SCANCODE_8] = 0x09, + [SDL_SCANCODE_9] = 0x0A, + [SDL_SCANCODE_0] = 0x0B, + [SDL_SCANCODE_MINUS] = 0x0C, + [SDL_SCANCODE_EQUALS] = 0x0D, + [SDL_SCANCODE_BACKSPACE] = 0x0E, + [SDL_SCANCODE_TAB] = 0x0F, + [SDL_SCANCODE_Q] = 0x10, + [SDL_SCANCODE_W] = 0x11, + [SDL_SCANCODE_E] = 0x12, + [SDL_SCANCODE_R] = 0x13, + [SDL_SCANCODE_T] = 0x14, + [SDL_SCANCODE_Y] = 0x15, + [SDL_SCANCODE_U] = 0x16, + [SDL_SCANCODE_I] = 0x17, + [SDL_SCANCODE_O] = 0x18, + [SDL_SCANCODE_P] = 0x19, + [SDL_SCANCODE_LEFTBRACKET] = 0x1A, + [SDL_SCANCODE_RIGHTBRACKET] = 0x1B, + [SDL_SCANCODE_RETURN] = 0x1C, + [SDL_SCANCODE_LCTRL] = 0x1D, + [SDL_SCANCODE_A] = 0x1E, + [SDL_SCANCODE_S] = 0x1F, + [SDL_SCANCODE_D] = 0x20, + [SDL_SCANCODE_F] = 0x21, + [SDL_SCANCODE_G] = 0x22, + [SDL_SCANCODE_H] = 0x23, + [SDL_SCANCODE_J] = 0x24, + [SDL_SCANCODE_K] = 0x25, + [SDL_SCANCODE_L] = 0x26, + [SDL_SCANCODE_SEMICOLON] = 0x27, + [SDL_SCANCODE_APOSTROPHE] = 0x28, + [SDL_SCANCODE_GRAVE] = 0x29, + [SDL_SCANCODE_LSHIFT] = 0x2A, + [SDL_SCANCODE_BACKSLASH] = 0x2B, + [SDL_SCANCODE_Z] = 0x2C, + [SDL_SCANCODE_X] = 0x2D, + [SDL_SCANCODE_C] = 0x2E, + [SDL_SCANCODE_V] = 0x2F, + [SDL_SCANCODE_B] = 0x30, + [SDL_SCANCODE_N] = 0x31, + [SDL_SCANCODE_M] = 0x32, + [SDL_SCANCODE_COMMA] = 0x33, + [SDL_SCANCODE_PERIOD] = 0x34, + [SDL_SCANCODE_SLASH] = 0x35, + [SDL_SCANCODE_RSHIFT] = 0x36, + [SDL_SCANCODE_KP_MULTIPLY] = 0x37, + [SDL_SCANCODE_LALT] = 0x38, + [SDL_SCANCODE_SPACE] = 0x39, + [SDL_SCANCODE_CAPSLOCK] = 0x3A, + [SDL_SCANCODE_F1] = 0x3B, + [SDL_SCANCODE_F2] = 0x3C, + [SDL_SCANCODE_F3] = 0x3D, + [SDL_SCANCODE_F4] = 0x3E, + [SDL_SCANCODE_F5] = 0x3F, + [SDL_SCANCODE_F6] = 0x40, + [SDL_SCANCODE_F7] = 0x41, + [SDL_SCANCODE_F8] = 0x42, + [SDL_SCANCODE_F9] = 0x43, + [SDL_SCANCODE_F10] = 0x44, + [SDL_SCANCODE_NUMLOCKCLEAR] = 0x45, + [SDL_SCANCODE_SCROLLLOCK] = 0x46, + [SDL_SCANCODE_HOME] = 0x147, + [SDL_SCANCODE_UP] = 0x148, + [SDL_SCANCODE_PAGEUP] = 0x149, + [SDL_SCANCODE_KP_MINUS] = 0x4A, + [SDL_SCANCODE_LEFT] = 0x14B, + [SDL_SCANCODE_KP_5] = 0x4C, + [SDL_SCANCODE_RIGHT] = 0x14D, + [SDL_SCANCODE_KP_PLUS] = 0x4E, + [SDL_SCANCODE_END] = 0x14F, + [SDL_SCANCODE_DOWN] = 0x150, + [SDL_SCANCODE_PAGEDOWN] = 0x151, + [SDL_SCANCODE_INSERT] = 0x152, + [SDL_SCANCODE_DELETE] = 0x153, + [SDL_SCANCODE_F11] = 0x57, + [SDL_SCANCODE_F12] = 0x58, + + [SDL_SCANCODE_KP_ENTER] = 0x11c, + [SDL_SCANCODE_RCTRL] = 0x11d, + [SDL_SCANCODE_KP_DIVIDE] = 0x135, + [SDL_SCANCODE_RALT] = 0x138, + [SDL_SCANCODE_KP_9] = 0x49, + [SDL_SCANCODE_KP_8] = 0x48, + [SDL_SCANCODE_KP_7] = 0x47, + [SDL_SCANCODE_KP_6] = 0x4D, + [SDL_SCANCODE_KP_4] = 0x4B, + [SDL_SCANCODE_KP_3] = 0x51, + [SDL_SCANCODE_KP_2] = 0x50, + [SDL_SCANCODE_KP_1] = 0x4F, + [SDL_SCANCODE_KP_0] = 0x52, + [SDL_SCANCODE_KP_PERIOD] = 0x53, + + [SDL_SCANCODE_LGUI] = 0x15B, + [SDL_SCANCODE_RGUI] = 0x15C, + [SDL_SCANCODE_APPLICATION] = 0x15D, + [SDL_SCANCODE_PRINTSCREEN] = 0x137, + [SDL_SCANCODE_NONUSBACKSLASH] = 0x56, +}; + +typedef struct mouseinputdata +{ + int deltax, deltay, deltaz; + int mousebuttons; +} mouseinputdata; +static mouseinputdata mousedata; + +// #define ENABLE_SDL_LOG 3 +#ifdef ENABLE_SDL_LOG +int sdl_do_log = ENABLE_SDL_LOG; + +static void +sdl_log(const char *fmt, ...) +{ + va_list ap; + + if (sdl_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define sdl_log(fmt, ...) +#endif + + +static void +sdl_integer_scale(double *d, double *g) +{ + double ratio; + + if (*d > *g) { + ratio = floor(*d / *g); + *d = *g * ratio; + } else { + ratio = ceil(*d / *g); + *d = *g / ratio; + } +} + + +static void +sdl_stretch(int *w, int *h, int *x, int *y) +{ + double hw, gw, hh, gh, dx, dy, dw, dh, gsr, hsr; + + hw = (double) sdl_w; + hh = (double) sdl_h; + gw = (double) *w; + gh = (double) *h; + hsr = hw / hh; + + switch (video_fullscreen_scale) { + case FULLSCR_SCALE_FULL: + default: + *w = sdl_w; + *h = sdl_h; + *x = 0; + *y = 0; + break; + case FULLSCR_SCALE_43: + case FULLSCR_SCALE_KEEPRATIO: + if (video_fullscreen_scale == FULLSCR_SCALE_43) + gsr = 4.0 / 3.0; + else + gsr = gw / gh; + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = (int) dy; + break; + case FULLSCR_SCALE_INT: + gsr = gw / gh; + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + sdl_integer_scale(&dw, &gw); + sdl_integer_scale(&dh, &gh); + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = (int) dy; + break; + } +} + +static void +sdl_blit(int x, int y, int w, int h) +{ + SDL_Rect r_src; + void *pixeldata; + int ret, pitch; + + if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) { + video_blit_complete(); + return; + } + + SDL_LockMutex(sdl_mutex); + SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch); + + video_copy(pixeldata, &(buffer32->line[y][x]), h * (2048) * sizeof(uint32_t)); + + if (screenshots) + video_screenshot((uint32_t *) pixeldata, 0, 0, (2048)); + + SDL_UnlockTexture(sdl_tex); + + video_blit_complete(); + + SDL_RenderClear(sdl_render); + + r_src.x = 0; + r_src.y = 0; + r_src.w = w; + r_src.h = h; + + ret = SDL_RenderCopy(sdl_render, sdl_tex, &r_src, 0); + if (ret) + sdl_log("SDL: unable to copy texture to renderer (%s)\n", sdl_GetError()); + + SDL_RenderPresent(sdl_render); + + SDL_UnlockMutex(sdl_mutex); +} + + +static void +sdl_destroy_window(void) +{ + if (sdl_win != NULL) { + SDL_DestroyWindow(sdl_win); + sdl_win = NULL; + } +} + + +static void +sdl_destroy_texture(void) +{ + if (sdl_tex != NULL) { + SDL_DestroyTexture(sdl_tex); + sdl_tex = NULL; + } + + /* SDL_DestroyRenderer also automatically destroys all associated textures. */ + if (sdl_render != NULL) { + SDL_DestroyRenderer(sdl_render); + sdl_render = NULL; + } +} + + +void +sdl_close(void) +{ + if (sdl_mutex != NULL) + SDL_LockMutex(sdl_mutex); + + /* Unregister our renderer! */ + video_setblit(NULL); + + if (sdl_enabled) + sdl_enabled = 0; + + if (sdl_mutex != NULL) { + SDL_DestroyMutex(sdl_mutex); + sdl_mutex = NULL; + } + + sdl_destroy_texture(); + sdl_destroy_window(); + + /* Quit. */ + SDL_Quit(); + sdl_flags = -1; +} + +static void sdl_select_best_hw_driver(void) { + int i; + SDL_RendererInfo renderInfo; + + for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { + SDL_GetRenderDriverInfo(i, &renderInfo); + if (renderInfo.flags & SDL_RENDERER_ACCELERATED) { + SDL_SetHint(SDL_HINT_RENDER_DRIVER, renderInfo.name); + return; + } + } +} + +static void +sdl_init_texture(void) +{ + if (sdl_flags & RENDERER_HARDWARE) { + sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED); + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); + } else { + sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); + } + + sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, (2048), (2048)); + + if (sdl_render == NULL) { + sdl_log("SDL: unable to SDL_CreateRenderer (%s)\n", SDL_GetError()); + } + if (sdl_tex == NULL) { + sdl_log("SDL: unable to SDL_CreateTexture (%s)\n", SDL_GetError()); + } +} + + +static void +sdl_reinit_texture(void) +{ + if (sdl_flags == -1) + return; + + sdl_destroy_texture(); + sdl_init_texture(); +} + + +void sdl_set_fs(int fs) { + SDL_SetWindowFullscreen(sdl_win, fs ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + SDL_SetRelativeMouseMode((SDL_bool)mouse_capture); + + sdl_fs = fs; + + if (fs) { + sdl_flags |= RENDERER_FULL_SCREEN; + } else { + sdl_flags &= ~RENDERER_FULL_SCREEN; + } + + sdl_reinit_texture(); +} + + +static int +sdl_init_common(void* win, int flags) +{ + wchar_t temp[128]; + SDL_version ver; + + sdl_log("SDL: init (fs=%d)\n", 0); + + /* Get and log the version of the DLL we are using. */ + SDL_GetVersion(&ver); + sdl_log("SDL: version %d.%d.%d\n", ver.major, ver.minor, ver.patch); + + /* Initialize the SDL system. */ + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + sdl_log("SDL: initialization failed (%s)\n", SDL_GetError()); + return(0); + } + + if (flags & RENDERER_HARDWARE) { + if (flags & RENDERER_OPENGL) + SDL_SetHint(SDL_HINT_RENDER_DRIVER, "OpenGL"); + else + sdl_select_best_hw_driver(); + } + + /* Get the size of the (current) desktop. */ + SDL_DisplayMode dm; + if (SDL_GetDesktopDisplayMode(0, &dm) != 0) { + sdl_log("SDL: SDL_GetDesktopDisplayMode failed (%s)\n", SDL_GetError()); + return(0); + } + sdl_w = dm.w; + sdl_h = dm.h; + sdl_flags = flags; + + sdl_win = SDL_CreateWindow("86Box renderer", 640, 480, 100, 100, sdl_flags); + if (sdl_win == NULL) { + sdl_log("SDL: unable to CreateWindowFrom (%s)\n", SDL_GetError()); + } + sdl_init_texture(); + sdl_set_fs(video_fullscreen & 1); + + /* Make sure we get a clean exit. */ + atexit(sdl_close); + + /* Register our renderer! */ + video_setblit(sdl_blit); + + sdl_enabled = 1; + sdl_mutex = SDL_CreateMutex(); + + return(1); +} + + +int +sdl_inits(void* win) +{ + return sdl_init_common(win, 0); +} + + +int +sdl_inith(void* win) +{ + return sdl_init_common(win, RENDERER_HARDWARE); +} + + +int +sdl_initho(void* win) +{ + return sdl_init_common(win, RENDERER_HARDWARE | RENDERER_OPENGL); +} + + +int +sdl_pause(void) +{ + return(0); +} + + +void +sdl_resize(int w, int h) +{ + int ww = 0, wh = 0; + + if (video_fullscreen & 2) + return; + + if ((w == cur_w) && (h == cur_h)) + return; + + SDL_LockMutex(sdl_mutex); + + ww = w; + wh = h; + + if (sdl_fs) { +// sdl_stretch(&ww, &wh, &wx, &wy); +// MoveWindow(hwndRender, wx, wy, ww, wh, TRUE); + } + + cur_w = w; + cur_h = h; + + cur_ww = ww; + cur_wh = wh; + + SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); + sdl_reinit_texture(); + + SDL_UnlockMutex(sdl_mutex); +} + + +void +sdl_enable(int enable) +{ + if (sdl_flags == -1) + return; + + SDL_LockMutex(sdl_mutex); + sdl_enabled = !!enable; + + if (enable == 1) { + SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); + sdl_reinit_texture(); + } + + SDL_UnlockMutex(sdl_mutex); +} + + +void +sdl_reload(void) +{ + if (sdl_flags & RENDERER_HARDWARE) { + SDL_LockMutex(sdl_mutex); + + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); + sdl_reinit_texture(); + + SDL_UnlockMutex(sdl_mutex); + } +} + +static int mouse_inside = 0; +enum sdl_main_status sdl_main() { + int ret = SdlMainOk; + SDL_Rect r_src; + SDL_Event event; + + while (SDL_PollEvent(&event)) + { + switch(event.type) + { + case SDL_QUIT: + ret = SdlMainQuit; + break; + case SDL_MOUSEWHEEL: + { + if (mouse_capture || video_fullscreen) + { + if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) + { + event.wheel.x *= -1; + event.wheel.y *= -1; + } + mousedata.deltaz = event.wheel.y; + } + break; + } + case SDL_MOUSEMOTION: + { + if (mouse_capture || video_fullscreen) + { + mousedata.deltax += event.motion.xrel; + mousedata.deltay += event.motion.yrel; + } + break; + } + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + { + if ((event.button.button == SDL_BUTTON_LEFT) + && !(mouse_capture || video_fullscreen) + && event.button.state == SDL_RELEASED + && mouse_inside) + { + plat_mouse_capture(1); + break; + } + if (mouse_get_buttons() < 3 && event.button.button == SDL_BUTTON_MIDDLE && !video_fullscreen) + { + plat_mouse_capture(0); + break; + } + if (mouse_capture || video_fullscreen) + { + int buttonmask = 0; + + switch(event.button.button) + { + case SDL_BUTTON_LEFT: + buttonmask = 1; + break; + case SDL_BUTTON_RIGHT: + buttonmask = 2; + break; + case SDL_BUTTON_MIDDLE: + buttonmask = 4; + break; + } + if (event.button.state == SDL_PRESSED) + { + mousedata.mousebuttons |= buttonmask; + } + else mousedata.mousebuttons &= ~buttonmask; + } + break; + } + case SDL_RENDER_DEVICE_RESET: + case SDL_RENDER_TARGETS_RESET: + { + sdl_reinit_texture(); + break; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + uint16_t xtkey = 0; + switch(event.key.keysym.scancode) + { + default: + xtkey = sdl_to_xt[event.key.keysym.scancode]; + break; + } + keyboard_input(event.key.state == SDL_PRESSED, xtkey); + } + break; + case SDL_WINDOWEVENT: + { + switch (event.window.event) + { + case SDL_WINDOWEVENT_ENTER: + mouse_inside = 1; + break; + case SDL_WINDOWEVENT_LEAVE: + mouse_inside = 0; + break; + } + } + } + } + + if (mouse_capture && keyboard_ismsexit()) { + plat_mouse_capture(0); + } + if (video_fullscreen && keyboard_isfsexit()) { + plat_setfullscreen(0); + } + + return ret; +} + +void sdl_mouse_capture(int on) { + SDL_SetRelativeMouseMode((SDL_bool)on); +} + +void sdl_mouse_poll() { + mouse_x = mousedata.deltax; + mouse_y = mousedata.deltay; + mouse_z = mousedata.deltaz; + mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; + mouse_buttons = mousedata.mousebuttons; +} diff --git a/src/qt/qt_sdl.h b/src/qt/qt_sdl.h new file mode 100644 index 000000000..02fd47ddf --- /dev/null +++ b/src/qt/qt_sdl.h @@ -0,0 +1,73 @@ +/* + * 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. + * + * Definitions for the libSDL2 rendering module. + * + * + * + * Authors: Fred N. van Kempen, + * Michael Drüing, + * + * Copyright 2018,2019 Fred N. van Kempen. + * Copyright 2018,2019 Michael Drüing. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef WIN_SDL_H +# define WIN_SDL_H + +extern void* sdl_win_handle; +extern void sdl_close(void); +extern int sdl_inits(); +extern int sdl_inith(); +extern int sdl_initho(); +extern int sdl_pause(void); +extern void sdl_resize(int w, int h); +extern void sdl_enable(int enable); +extern void sdl_set_fs(int fs); +extern void sdl_reload(void); + +enum sdl_main_status { + SdlMainOk, + SdlMainQuit, +}; + +extern enum sdl_main_status sdl_main(); + +extern void sdl_mouse_capture(int on); +extern void sdl_mouse_poll(); + +#endif /*WIN_SDL_H*/ diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp new file mode 100644 index 000000000..b7678bb8e --- /dev/null +++ b/src/qt/qt_settings.cpp @@ -0,0 +1,168 @@ +#include "qt_settings.hpp" +#include "ui_qt_settings.h" + +#include "qt_settingsmachine.hpp" +#include "qt_settingsdisplay.hpp" +#include "qt_settingsinput.hpp" +#include "qt_settingssound.hpp" +#include "qt_settingsnetwork.hpp" +#include "qt_settingsports.hpp" +#include "qt_settingsstoragecontrollers.hpp" +#include "qt_settingsharddisks.hpp" +#include "qt_settingsfloppycdrom.hpp" +#include "qt_settingsotherremovable.hpp" +#include "qt_settingsotherperipherals.hpp" + +#include "qt_progsettings.hpp" +#include "qt_harddrive_common.hpp" +#include "qt_settings_bus_tracking.hpp" + +extern "C" +{ +#include <86box/86box.h> +} + +#include +#include +#include + +class SettingsModel : public QAbstractListModel { +public: + SettingsModel(QObject* parent) : QAbstractListModel(parent) {} + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; +private: + QStringList pages = { + "Machine", + "Display", + "Input devices", + "Sound", + "Network", + "Ports (COM & LPT)", + "Storage controllers", + "Hard disks", + "Floppy & CD-ROM drives", + "Other removable devices", + "Other peripherals", + }; + QStringList page_icons = { + "machine", + "display", + "input_devices", + "sound", + "network", + "ports", + "storage_controllers", + "hard_disk", + "floppy_and_cdrom_drives", + "other_removable_devices", + "other_peripherals", + }; +}; + +QVariant SettingsModel::data(const QModelIndex &index, int role) const { + Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid | QAbstractItemModel::CheckIndexOption::ParentIsInvalid)); + + switch (role) { + case Qt::DisplayRole: + return tr(pages.at(index.row()).toUtf8().data()); + case Qt::DecorationRole: + return QIcon(QString("%1/%2.ico").arg(ProgSettings::getIconSetPath(), page_icons[index.row()])); + default: + return {}; + } +} + +int SettingsModel::rowCount(const QModelIndex &parent) const { + (void) parent; + return pages.size(); +} + +Settings::Settings(QWidget *parent) : + QDialog(parent), + ui(new Ui::Settings) +{ + ui->setupUi(this); + + ui->listView->setModel(new SettingsModel(this)); + + Harddrives::busTrackClass = new SettingsBusTracking; + machine = new SettingsMachine(this); + display = new SettingsDisplay(this); + input = new SettingsInput(this); + sound = new SettingsSound(this); + network = new SettingsNetwork(this); + ports = new SettingsPorts(this); + storageControllers = new SettingsStorageControllers(this); + harddisks = new SettingsHarddisks(this); + floppyCdrom = new SettingsFloppyCDROM(this); + otherRemovable = new SettingsOtherRemovable(this); + otherPeripherals = new SettingsOtherPeripherals(this); + + ui->stackedWidget->addWidget(machine); + ui->stackedWidget->addWidget(display); + ui->stackedWidget->addWidget(input); + ui->stackedWidget->addWidget(sound); + ui->stackedWidget->addWidget(network); + ui->stackedWidget->addWidget(ports); + ui->stackedWidget->addWidget(storageControllers); + ui->stackedWidget->addWidget(harddisks); + ui->stackedWidget->addWidget(floppyCdrom); + ui->stackedWidget->addWidget(otherRemovable); + ui->stackedWidget->addWidget(otherPeripherals); + + ui->listView->setFixedWidth(ui->listView->sizeHintForColumn(0) + 5); + + connect(machine, &SettingsMachine::currentMachineChanged, display, &SettingsDisplay::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, input, &SettingsInput::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, sound, &SettingsSound::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, network, &SettingsNetwork::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, storageControllers, &SettingsStorageControllers::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, otherPeripherals, &SettingsOtherPeripherals::onCurrentMachineChanged); + + connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex ¤t, const QModelIndex &previous) { + ui->stackedWidget->setCurrentIndex(current.row()); + }); +} + +Settings::~Settings() +{ + delete ui; + delete Harddrives::busTrackClass; + Harddrives::busTrackClass = nullptr; +} + +void Settings::save() { + machine->save(); + display->save(); + input->save(); + sound->save(); + network->save(); + ports->save(); + storageControllers->save(); + harddisks->save(); + floppyCdrom->save(); + otherRemovable->save(); + otherPeripherals->save(); +} + +void Settings::accept() +{ + if (confirm_save && !settings_only) + { + QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", QStringLiteral("%1\n\n%2").arg(tr("Do you want to save the settings?"), tr("This will hard reset the emulated machine.")), QMessageBox::Save | QMessageBox::Cancel, this); + QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + questionbox.setCheckBox(chkbox); + chkbox->setChecked(!confirm_save); + QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { + confirm_save = (state == Qt::CheckState::Unchecked); + }); + questionbox.exec(); + if (questionbox.result() == QMessageBox::Cancel) { + confirm_save = true; + return; + } + } + QDialog::accept(); +} diff --git a/src/qt/qt_settings.hpp b/src/qt/qt_settings.hpp new file mode 100644 index 000000000..49137b8b7 --- /dev/null +++ b/src/qt/qt_settings.hpp @@ -0,0 +1,49 @@ +#ifndef QT_SETTINGS_HPP +#define QT_SETTINGS_HPP + +#include + +namespace Ui { +class Settings; +} + +class SettingsMachine; +class SettingsDisplay; +class SettingsInput; +class SettingsSound; +class SettingsNetwork; +class SettingsPorts; +class SettingsStorageControllers; +class SettingsHarddisks; +class SettingsFloppyCDROM; +class SettingsOtherRemovable; +class SettingsOtherPeripherals; + +class Settings : public QDialog +{ + Q_OBJECT + +public: + explicit Settings(QWidget *parent = nullptr); + ~Settings(); + void save(); + +protected slots: + void accept() override; + +private: + Ui::Settings *ui; + SettingsMachine* machine; + SettingsDisplay* display; + SettingsInput* input; + SettingsSound* sound; + SettingsNetwork* network; + SettingsPorts* ports; + SettingsStorageControllers* storageControllers; + SettingsHarddisks* harddisks; + SettingsFloppyCDROM* floppyCdrom; + SettingsOtherRemovable* otherRemovable; + SettingsOtherPeripherals* otherPeripherals; +}; + +#endif // QT_SETTINGS_HPP diff --git a/src/qt/qt_settings.ui b/src/qt/qt_settings.ui new file mode 100644 index 000000000..66047cffd --- /dev/null +++ b/src/qt/qt_settings.ui @@ -0,0 +1,99 @@ + + + Settings + + + + 0 + 0 + 831 + 595 + + + + + 831 + 595 + + + + + 831 + 595 + + + + Settings + + + + + + + + + + + + -1 + + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Settings + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Settings + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/qt_settings_bus_tracking.cpp b/src/qt/qt_settings_bus_tracking.cpp new file mode 100644 index 000000000..3744c10c7 --- /dev/null +++ b/src/qt/qt_settings_bus_tracking.cpp @@ -0,0 +1,256 @@ +#include +#include +#include +#include + +#include "86box/hdd.h" +#include "qt_settings_bus_tracking.hpp" + + +SettingsBusTracking::SettingsBusTracking() +{ + int i; + + mfm_tracking = 0x0000000000000000ULL; + esdi_tracking = 0x0000000000000000ULL; + xta_tracking = 0x0000000000000000ULL; + + for (i = 0; i < 8; i++) { + if (i < 4) + ide_tracking[i] = 0x0000000000000000ULL; + + scsi_tracking[i] = 0x0000000000000000ULL; + } +} + + +uint8_t +SettingsBusTracking::next_free_mfm_channel() +{ + if ((mfm_tracking & 0xff00ULL) && !(mfm_tracking & 0x00ffULL)) + return 1; + + if (!(mfm_tracking & 0xff00ULL) && (mfm_tracking & 0x00ffULL)) + return 0; + + return CHANNEL_NONE; +} + + +uint8_t +SettingsBusTracking::next_free_esdi_channel() +{ + if ((esdi_tracking & 0xff00ULL) && !(esdi_tracking & 0x00ffULL)) + return 1; + + if (!(esdi_tracking & 0xff00ULL) && (esdi_tracking & 0x00ffULL)) + return 0; + + return CHANNEL_NONE; +} + + +uint8_t +SettingsBusTracking::next_free_xta_channel() +{ + if ((xta_tracking & 0xff00ULL) && !(xta_tracking & 0x00ffULL)) + return 1; + + if (!(xta_tracking & 0xff00ULL) && (xta_tracking & 0x00ffULL)) + return 0; + + return CHANNEL_NONE; +} + + +uint8_t +SettingsBusTracking::next_free_ide_channel() +{ + int i, element; + uint64_t mask; + uint8_t ret = CHANNEL_NONE; + + for (i = 0; i < 32; i++) { + element = ((i << 3) >> 6); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + + if (!(ide_tracking[element] & mask)) { + ret = (uint8_t) i; + break; + } + } + + return ret; +} + + +uint8_t +SettingsBusTracking::next_free_scsi_id() +{ + int i, element; + uint64_t mask; + uint8_t ret = CHANNEL_NONE; + + for (i = 0; i < 64; i++) { + element = ((i << 3) >> 6); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + + if (!(scsi_tracking[element] & mask)) { + ret = (uint8_t) i; + break; + } + } + + return ret; +} + + +int +SettingsBusTracking::mfm_bus_full() +{ + int i; + uint64_t mask; + uint8_t count = 0; + + for (i = 0; i < 2; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + + if (mfm_tracking & mask) + count++; + } + + return (count == 2); +} + + +int +SettingsBusTracking::esdi_bus_full() +{ + int i; + uint64_t mask; + uint8_t count = 0; + + for (i = 0; i < 2; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + + if (esdi_tracking & mask) + count++; + } + + return (count == 2); +} + + +int +SettingsBusTracking::xta_bus_full() +{ + int i; + uint64_t mask; + uint8_t count = 0; + + for (i = 0; i < 2; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + + if (xta_tracking & mask) + count++; + } + + return (count == 2); +} + + +int +SettingsBusTracking::ide_bus_full() +{ + int i, element; + uint64_t mask; + uint8_t count = 0; + + for (i = 0; i < 32; i++) { + element = ((i << 3) >> 6); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + + if (ide_tracking[element] & mask) + count++; + } + + return (count == 32); +} + + +int +SettingsBusTracking::scsi_bus_full() +{ + int i, element; + uint64_t mask; + uint8_t count = 0; + + for (i = 0; i < 64; i++) { + element = ((i << 3) >> 6); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + + if (scsi_tracking[element] & mask) + count++; + } + + return (count == 64); +} + + +void +SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channel) +{ + int i, element; + uint64_t mask; + uint8_t count = 0; + + switch (bus) { + case HDD_BUS_MFM: + mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); + + if (set) + mfm_tracking |= mask; + else + mfm_tracking &= ~mask; + break; + + case HDD_BUS_ESDI: + mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); + + if (set) + esdi_tracking |= mask; + else + esdi_tracking &= ~mask; + break; + + case HDD_BUS_XTA: + mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); + + if (set) + xta_tracking |= mask; + else + xta_tracking &= ~mask; + break; + + case HDD_BUS_IDE: + case HDD_BUS_ATAPI: + element = ((channel << 3) >> 6); + mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); + + if (set) + ide_tracking[element] |= mask; + else + ide_tracking[element] &= ~mask; + break; + + case HDD_BUS_SCSI: + element = ((channel << 3) >> 6); + mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); + + if (set) + scsi_tracking[element] |= mask; + else + scsi_tracking[element] &= ~mask; + break; + } +} diff --git a/src/qt/qt_settings_bus_tracking.hpp b/src/qt/qt_settings_bus_tracking.hpp new file mode 100644 index 000000000..0272b4359 --- /dev/null +++ b/src/qt/qt_settings_bus_tracking.hpp @@ -0,0 +1,63 @@ +#ifndef QT_SETTINGS_BUS_TRACKING_HPP +#define QT_SETTINGS_BUS_TRACKING_HPP + +#include + +#define TRACK_CLEAR 0 +#define TRACK_SET 1 + +#define DEV_HDD 0x01 +#define DEV_CDROM 0x02 +#define DEV_ZIP 0x04 +#define DEV_MO 0x08 + +#define BUS_MFM 0 +#define BUS_ESDI 1 +#define BUS_XTA 2 +#define BUS_IDE 3 +#define BUS_SCSI 4 + +#define CHANNEL_NONE 0xff + +namespace Ui { +class SettingsBusTracking; +} + +class SettingsBusTracking +{ +public: + explicit SettingsBusTracking(); + ~SettingsBusTracking() = default; + + /* These return 0xff is none is free. */ + uint8_t next_free_mfm_channel(); + uint8_t next_free_esdi_channel(); + uint8_t next_free_xta_channel(); + uint8_t next_free_ide_channel(); + uint8_t next_free_scsi_id(); + + int mfm_bus_full(); + int esdi_bus_full(); + int xta_bus_full(); + int ide_bus_full(); + int scsi_bus_full(); + + /* Set: 0 = Clear the device from the tracking, 1 = Set the device on the tracking. + Device type: 1 = Hard Disk, 2 = CD-ROM, 4 = ZIP, 8 = Magneto-Optical. + Bus: 0 = MFM, 1 = ESDI, 2 = XTA, 3 = IDE, 4 = SCSI. */ + void device_track(int set, uint8_t dev_type, int bus, int channel); + +private: + /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ + uint64_t mfm_tracking{0}; + /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ + uint64_t esdi_tracking{0}; + /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ + uint64_t xta_tracking{0}; + /* 16 channels (prepatation for that weird IDE card), 2 devices per channel, 8 bits per device = 256 bits. */ + uint64_t ide_tracking[4]{0, 0, 0, 0}; + /* 4 buses, 16 devices per bus, 8 bits per device (future-proofing) = 512 bits. */ + uint64_t scsi_tracking[8]{0, 0, 0, 0, 0, 0, 0, 0}; +}; + +#endif // QT_SETTINGS_BUS_TRACKING_HPP diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp new file mode 100644 index 000000000..4cd604305 --- /dev/null +++ b/src/qt/qt_settingsdisplay.cpp @@ -0,0 +1,104 @@ +#include "qt_settingsdisplay.hpp" +#include "ui_qt_settingsdisplay.h" + +#include + +extern "C" { +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/video.h> +} + +#include "qt_deviceconfig.hpp" +#include "qt_models_common.hpp" + +SettingsDisplay::SettingsDisplay(QWidget *parent) : + QWidget(parent), + ui(new Ui::SettingsDisplay) +{ + ui->setupUi(this); + + onCurrentMachineChanged(machine); +} + +SettingsDisplay::~SettingsDisplay() +{ + delete ui; +} + +void SettingsDisplay::save() { + gfxcard = ui->comboBoxVideo->currentData().toInt(); + voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0; +} + +void SettingsDisplay::onCurrentMachineChanged(int machineId) { + // win_settings_video_proc, WM_INITDIALOG + this->machineId = machineId; + + auto* model = ui->comboBoxVideo->model(); + auto removeRows = model->rowCount(); + + int c = 0; + int selectedRow = 0; + while (true) { + /* Skip "internal" if machine doesn't have it. */ + if ((c == 1) && (machine_has_flags(machineId, MACHINE_VIDEO) == 0)) { + c++; + continue; + } + + const device_t* video_dev = video_card_getdevice(c); + QString name = DeviceConfig::DeviceName(video_dev, video_get_internal_name(c), 1); + if (name.isEmpty()) { + break; + } + + if (video_card_available(c) && + device_is_valid(video_dev, machineId)) { + int row = Models::AddEntry(model, name, c); + if (c == gfxcard) { + selectedRow = row - removeRows; + } + } + + c++; + } + model->removeRows(0, removeRows); + + if (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0) { + ui->comboBoxVideo->setEnabled(false); + selectedRow = 1; + } else { + ui->comboBoxVideo->setEnabled(true); + } + ui->comboBoxVideo->setCurrentIndex(selectedRow); +} + +void SettingsDisplay::on_pushButtonConfigure_clicked() { + auto* device = video_card_getdevice(ui->comboBoxVideo->currentData().toInt()); + DeviceConfig::ConfigureDevice(device); +} + +void SettingsDisplay::on_pushButtonConfigureVoodoo_clicked() { + DeviceConfig::ConfigureDevice(&voodoo_device); +} + +void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) { + if (index < 0) { + return; + } + int videoCard = ui->comboBoxVideo->currentData().toInt(); + ui->pushButtonConfigure->setEnabled(video_card_has_config(videoCard) > 0); + + bool machineHasPci = machine_has_bus(machineId, MACHINE_BUS_PCI) > 0; + ui->checkBoxVoodoo->setEnabled(machineHasPci); + if (machineHasPci) { + ui->checkBoxVoodoo->setChecked(voodoo_enabled); + } + ui->pushButtonConfigureVoodoo->setEnabled(machineHasPci && ui->checkBoxVoodoo->isChecked()); +} + +void SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) { + ui->pushButtonConfigureVoodoo->setEnabled(state == Qt::Checked); +} diff --git a/src/qt/qt_settingsdisplay.hpp b/src/qt/qt_settingsdisplay.hpp new file mode 100644 index 000000000..768f40311 --- /dev/null +++ b/src/qt/qt_settingsdisplay.hpp @@ -0,0 +1,34 @@ +#ifndef QT_SETTINGSDISPLAY_HPP +#define QT_SETTINGSDISPLAY_HPP + +#include + +namespace Ui { +class SettingsDisplay; +} + +class SettingsDisplay : public QWidget +{ + Q_OBJECT + +public: + explicit SettingsDisplay(QWidget *parent = nullptr); + ~SettingsDisplay(); + + void save(); + +public slots: + void onCurrentMachineChanged(int machineId); + +private slots: + void on_checkBoxVoodoo_stateChanged(int state); + void on_comboBoxVideo_currentIndexChanged(int index); + void on_pushButtonConfigureVoodoo_clicked(); + void on_pushButtonConfigure_clicked(); + +private: + Ui::SettingsDisplay *ui; + int machineId = 0; +}; + +#endif // QT_SETTINGSDISPLAY_HPP diff --git a/src/qt/qt_settingsdisplay.ui b/src/qt/qt_settingsdisplay.ui new file mode 100644 index 000000000..58a2e6aef --- /dev/null +++ b/src/qt/qt_settingsdisplay.ui @@ -0,0 +1,77 @@ + + + SettingsDisplay + + + + 0 + 0 + 400 + 300 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Video: + + + + + + + Configure + + + + + + + Configure + + + + + + + Voodoo Graphics + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp new file mode 100644 index 000000000..0f4ede800 --- /dev/null +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -0,0 +1,235 @@ +#include "qt_settingsfloppycdrom.hpp" +#include "ui_qt_settingsfloppycdrom.h" + +extern "C" { +#include <86box/timer.h> +#include <86box/fdd.h> +#include <86box/cdrom.h> +} + +#include + +#include "qt_models_common.hpp" +#include "qt_harddrive_common.hpp" +#include "qt_settings_bus_tracking.hpp" +#include "qt_progsettings.hpp" + +static void setFloppyType(QAbstractItemModel* model, const QModelIndex& idx, int type) { + QIcon icon; + if (type == 0) { + icon = ProgSettings::loadIcon("/floppy_disabled.ico"); + } else if (type >= 1 && type <= 6) { + icon = ProgSettings::loadIcon("/floppy_525.ico"); + } else { + icon = ProgSettings::loadIcon("/floppy_35.ico"); + } + + model->setData(idx, QObject::tr(fdd_getname(type))); + model->setData(idx, type, Qt::UserRole); + model->setData(idx, icon, Qt::DecorationRole); +} + +static void setCDROMBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t bus, uint8_t channel) { + QIcon icon; + switch (bus) { + case CDROM_BUS_DISABLED: + icon = ProgSettings::loadIcon("/cdrom_disabled.ico"); + break; + case CDROM_BUS_ATAPI: + case CDROM_BUS_SCSI: + icon = ProgSettings::loadIcon("/cdrom.ico"); + break; + } + + auto i = idx.siblingAtColumn(0); + model->setData(i, Harddrives::BusChannelName(bus, channel)); + model->setData(i, bus, Qt::UserRole); + model->setData(i, channel, Qt::UserRole + 1); + model->setData(i, icon, Qt::DecorationRole); +} + +static void setCDROMSpeed(QAbstractItemModel* model, const QModelIndex& idx, uint8_t speed) { + auto i = idx.siblingAtColumn(1); + model->setData(i, QString("%1x").arg(speed)); + model->setData(i, speed, Qt::UserRole); +} + +SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) : + QWidget(parent), + ui(new Ui::SettingsFloppyCDROM) +{ + ui->setupUi(this); + + auto* model = ui->comboBoxFloppyType->model(); + int i = 0; + while (true) { + QString name = tr(fdd_getname(i)); + if (name.isEmpty()) { + break; + } + + Models::AddEntry(model, name, i); + ++i; + } + + model = new QStandardItemModel(0, 3, this); + ui->tableViewFloppy->setModel(model); + model->setHeaderData(0, Qt::Horizontal, tr("Type")); + model->setHeaderData(1, Qt::Horizontal, tr("Turbo")); + model->setHeaderData(2, Qt::Horizontal, tr("Check BPB")); + + model->insertRows(0, FDD_NUM); + /* Floppy drives category */ + for (int i = 0; i < FDD_NUM; i++) { + auto idx = model->index(i, 0); + int type = fdd_get_type(i); + setFloppyType(model, idx, type); + model->setData(idx.siblingAtColumn(1), fdd_get_turbo(i) > 0 ? tr("On") : tr("Off")); + model->setData(idx.siblingAtColumn(2), fdd_get_check_bpb(i) > 0 ? tr("On") : tr("Off")); + } + + ui->tableViewFloppy->resizeColumnsToContents(); + ui->tableViewFloppy->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + + connect(ui->tableViewFloppy->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsFloppyCDROM::onFloppyRowChanged); + ui->tableViewFloppy->setCurrentIndex(model->index(0, 0)); + + + Harddrives::populateRemovableBuses(ui->comboBoxBus->model()); + model = ui->comboBoxSpeed->model(); + for (int i = 0; i < 72; i++) { + Models::AddEntry(model, QString("%1x").arg(i + 1), i + 1); + } + + model = new QStandardItemModel(0, 2, this); + ui->tableViewCDROM->setModel(model); + model->setHeaderData(0, Qt::Horizontal, tr("Bus")); + model->setHeaderData(1, Qt::Horizontal, tr("Speed")); + model->insertRows(0, CDROM_NUM); + for (int i = 0; i < CDROM_NUM; i++) { + auto idx = model->index(i, 0); + setCDROMBus(model, idx, cdrom[i].bus_type, cdrom[i].res); + setCDROMSpeed(model, idx.siblingAtColumn(1), cdrom[i].speed); + Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, cdrom[i].bus_type == CDROM_BUS_ATAPI ? cdrom[i].ide_channel : cdrom[i].scsi_device_id); + } + ui->tableViewCDROM->resizeColumnsToContents(); + ui->tableViewCDROM->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + + connect(ui->tableViewCDROM->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsFloppyCDROM::onCDROMRowChanged); + ui->tableViewCDROM->setCurrentIndex(model->index(0, 0)); +} + +SettingsFloppyCDROM::~SettingsFloppyCDROM() +{ + delete ui; +} + +void SettingsFloppyCDROM::save() { + auto* model = ui->tableViewFloppy->model(); + for (int i = 0; i < FDD_NUM; i++) { + fdd_set_type(i, model->index(i, 0).data(Qt::UserRole).toInt()); + fdd_set_turbo(i, model->index(i, 1).data() == tr("On") ? 1 : 0); + fdd_set_check_bpb(i, model->index(i, 2).data() == tr("On") ? 1 : 0); + } + + /* Removable devices category */ + model = ui->tableViewCDROM->model(); + for (int i = 0; i < CDROM_NUM; i++) { + cdrom[i].img_fp = NULL; + cdrom[i].priv = NULL; + cdrom[i].ops = NULL; + cdrom[i].image = NULL; + cdrom[i].insert = NULL; + cdrom[i].close = NULL; + cdrom[i].get_volume = NULL; + cdrom[i].get_channel = NULL; + cdrom[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); + cdrom[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); + cdrom[i].speed = model->index(i, 1).data(Qt::UserRole).toUInt(); + } +} + +void SettingsFloppyCDROM::onFloppyRowChanged(const QModelIndex ¤t) { + int type = current.siblingAtColumn(0).data(Qt::UserRole).toInt(); + ui->comboBoxFloppyType->setCurrentIndex(type); + ui->checkBoxTurboTimings->setChecked(current.siblingAtColumn(1).data() == tr("On")); + ui->checkBoxCheckBPB->setChecked(current.siblingAtColumn(2).data() == tr("On")); +} + +void SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) { + uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); + uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt(); + uint8_t speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); + + ui->comboBoxBus->setCurrentIndex(-1); + auto* model = ui->comboBoxBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (! match.isEmpty()) { + ui->comboBoxBus->setCurrentIndex(match.first().row()); + } + + model = ui->comboBoxChannel->model(); + match = model->match(model->index(0, 0), Qt::UserRole, channel); + if (! match.isEmpty()) { + ui->comboBoxChannel->setCurrentIndex(match.first().row()); + } + else ui->comboBoxChannel->setCurrentIndex(8); + ui->comboBoxSpeed->setCurrentIndex(speed - 1); +} + +void SettingsFloppyCDROM::on_checkBoxTurboTimings_stateChanged(int arg1) { + auto idx = ui->tableViewFloppy->selectionModel()->currentIndex(); + ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(1), arg1 == Qt::Checked ? tr("On") : tr("Off")); +} + +void SettingsFloppyCDROM::on_checkBoxCheckBPB_stateChanged(int arg1) { + auto idx = ui->tableViewFloppy->selectionModel()->currentIndex(); + ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(2), arg1 == Qt::Checked ? tr("On") : tr("Off")); +} + +void SettingsFloppyCDROM::on_comboBoxFloppyType_activated(int index) { + setFloppyType(ui->tableViewFloppy->model(), ui->tableViewFloppy->selectionModel()->currentIndex(), index); +} + +void SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) { + if (index < 0) { + return; + } + + int bus = ui->comboBoxBus->currentData().toInt(); + bool enabled = (bus != CDROM_BUS_DISABLED); + ui->comboBoxChannel->setEnabled(enabled); + ui->comboBoxSpeed->setEnabled(enabled); + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), bus); +} + +void SettingsFloppyCDROM::on_comboBoxSpeed_activated(int index) { + auto idx = ui->tableViewCDROM->selectionModel()->currentIndex(); + setCDROMSpeed(ui->tableViewCDROM->model(), idx.siblingAtColumn(1), index + 1); +} + + +void SettingsFloppyCDROM::on_comboBoxBus_activated(int) { + auto i = ui->tableViewCDROM->selectionModel()->currentIndex().siblingAtColumn(0); + Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); + ui->comboBoxChannel->setCurrentIndex(ui->comboBoxBus->currentData().toUInt() == CDROM_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id()); + setCDROMBus( + ui->tableViewCDROM->model(), + ui->tableViewCDROM->selectionModel()->currentIndex(), + ui->comboBoxBus->currentData().toUInt(), + ui->comboBoxChannel->currentData().toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); +} + + +void SettingsFloppyCDROM::on_comboBoxChannel_activated(int) { + auto i = ui->tableViewCDROM->selectionModel()->currentIndex().siblingAtColumn(0); + Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); + setCDROMBus( + ui->tableViewCDROM->model(), + ui->tableViewCDROM->selectionModel()->currentIndex(), + ui->comboBoxBus->currentData().toUInt(), + ui->comboBoxChannel->currentData().toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); +} + diff --git a/src/qt/qt_settingsfloppycdrom.hpp b/src/qt/qt_settingsfloppycdrom.hpp new file mode 100644 index 000000000..f68646ab0 --- /dev/null +++ b/src/qt/qt_settingsfloppycdrom.hpp @@ -0,0 +1,35 @@ +#ifndef QT_SETTINGSFLOPPYCDROM_HPP +#define QT_SETTINGSFLOPPYCDROM_HPP + +#include + +namespace Ui { +class SettingsFloppyCDROM; +} + +class SettingsFloppyCDROM : public QWidget +{ + Q_OBJECT + +public: + explicit SettingsFloppyCDROM(QWidget *parent = nullptr); + ~SettingsFloppyCDROM(); + + void save(); + +private slots: + void on_comboBoxChannel_activated(int index); + void on_comboBoxBus_activated(int index); + void on_comboBoxSpeed_activated(int index); + void on_comboBoxBus_currentIndexChanged(int index); + void on_comboBoxFloppyType_activated(int index); + void on_checkBoxCheckBPB_stateChanged(int arg1); + void on_checkBoxTurboTimings_stateChanged(int arg1); + void onFloppyRowChanged(const QModelIndex ¤t); + void onCDROMRowChanged(const QModelIndex ¤t); + +private: + Ui::SettingsFloppyCDROM *ui; +}; + +#endif // QT_SETTINGSFLOPPYCDROM_HPP diff --git a/src/qt/qt_settingsfloppycdrom.ui b/src/qt/qt_settingsfloppycdrom.ui new file mode 100644 index 000000000..dfe8283ab --- /dev/null +++ b/src/qt/qt_settingsfloppycdrom.ui @@ -0,0 +1,148 @@ + + + SettingsFloppyCDROM + + + + 0 + 0 + 544 + 617 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Floppy drives: + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + + + + + + + Type: + + + + + + + + + + Turbo timings + + + + + + + Check BPB + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + CD-ROM drives: + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + + + + + + + Channel: + + + + + + + + + + Speed: + + + + + + + Bus: + + + + + + + + + + + + + + + + diff --git a/src/qt/qt_settingsharddisks.cpp b/src/qt/qt_settingsharddisks.cpp new file mode 100644 index 000000000..ac3ec67ca --- /dev/null +++ b/src/qt/qt_settingsharddisks.cpp @@ -0,0 +1,279 @@ +#include "qt_settingsharddisks.hpp" +#include "ui_qt_settingsharddisks.h" + +extern "C" { +#include <86box/86box.h> +#include <86box/hdd.h> +} + +#include + +#include "qt_harddiskdialog.hpp" +#include "qt_harddrive_common.hpp" +#include "qt_settings_bus_tracking.hpp" +#include "qt_progsettings.hpp" + +const int ColumnBus = 0; +const int ColumnFilename = 1; +const int ColumnCylinders = 2; +const int ColumnHeads = 3; +const int ColumnSectors = 4; +const int ColumnSize = 5; + +const int DataBus = Qt::UserRole; +const int DataBusChannel = Qt::UserRole + 1; +const int DataBusPrevious = Qt::UserRole + 2; +const int DataBusChannelPrevious = Qt::UserRole + 3; + +/* +static void +normalize_hd_list() +{ + hard_disk_t ihdd[HDD_NUM]; + int i, j; + + j = 0; + memset(ihdd, 0x00, HDD_NUM * sizeof(hard_disk_t)); + + for (i = 0; i < HDD_NUM; i++) { + if (temp_hdd[i].bus != HDD_BUS_DISABLED) { + memcpy(&(ihdd[j]), &(temp_hdd[i]), sizeof(hard_disk_t)); + j++; + } + } + + memcpy(temp_hdd, ihdd, HDD_NUM * sizeof(hard_disk_t)); +} +*/ + +static QString busChannelName(const QModelIndex& idx) { + return Harddrives::BusChannelName(idx.data(DataBus).toUInt(), idx.data(DataBusChannel).toUInt()); +} + +static void addRow(QAbstractItemModel* model, hard_disk_t* hd) { + const QString userPath = usr_path; + + int row = model->rowCount(); + model->insertRow(row); + + QString busName = Harddrives::BusChannelName(hd->bus, hd->channel); + model->setData(model->index(row, ColumnBus), busName); + model->setData(model->index(row, ColumnBus), ProgSettings::loadIcon( "/hard_disk.ico"), Qt::DecorationRole); + model->setData(model->index(row, ColumnBus), hd->bus, DataBus); + model->setData(model->index(row, ColumnBus), hd->bus, DataBusPrevious); + model->setData(model->index(row, ColumnBus), hd->channel, DataBusChannel); + model->setData(model->index(row, ColumnBus), hd->channel, DataBusChannelPrevious); + Harddrives::busTrackClass->device_track(1, DEV_HDD, hd->bus, hd->channel); + QString fileName = hd->fn; + if (fileName.startsWith(userPath, Qt::CaseInsensitive)) { + model->setData(model->index(row, ColumnFilename), fileName.mid(userPath.size())); + } else { + model->setData(model->index(row, ColumnFilename), fileName); + } + model->setData(model->index(row, ColumnFilename), fileName, Qt::UserRole); + + model->setData(model->index(row, ColumnCylinders), hd->tracks); + model->setData(model->index(row, ColumnHeads), hd->hpc); + model->setData(model->index(row, ColumnSectors), hd->spt); + model->setData(model->index(row, ColumnSize), (hd->tracks * hd->hpc * hd->spt) >> 11); +} + +SettingsHarddisks::SettingsHarddisks(QWidget *parent) : + QWidget(parent), + ui(new Ui::SettingsHarddisks) +{ + ui->setupUi(this); + + QAbstractItemModel* model = new QStandardItemModel(0, 6, this); + model->setHeaderData(ColumnBus, Qt::Horizontal, tr("Bus")); + model->setHeaderData(ColumnFilename, Qt::Horizontal, tr("File")); + model->setHeaderData(ColumnCylinders, Qt::Horizontal, tr("C")); + model->setHeaderData(ColumnHeads, Qt::Horizontal, tr("H")); + model->setHeaderData(ColumnSectors, Qt::Horizontal, tr("S")); + model->setHeaderData(ColumnSize, Qt::Horizontal, tr("MiB")); + ui->tableView->setModel(model); + + for (int i = 0; i < HDD_NUM; i++) { + if (hdd[i].bus > 0) { + addRow(model, &hdd[i]); + } + } + if (model->rowCount() == HDD_NUM) + { + ui->pushButtonNew->setEnabled(false); + ui->pushButtonExisting->setEnabled(false); + } + ui->tableView->resizeColumnsToContents(); + ui->tableView->horizontalHeader()->setSectionResizeMode(ColumnFilename, QHeaderView::Stretch); + + auto* tableSelectionModel = ui->tableView->selectionModel(); + connect(tableSelectionModel, &QItemSelectionModel::currentRowChanged, this, &SettingsHarddisks::onTableRowChanged); + onTableRowChanged(QModelIndex()); + + Harddrives::populateBuses(ui->comboBoxBus->model()); + on_comboBoxBus_currentIndexChanged(0); +} + +SettingsHarddisks::~SettingsHarddisks() +{ + delete ui; +} + +void SettingsHarddisks::save() { + memset(hdd, 0, sizeof(hdd)); + + auto* model = ui->tableView->model(); + int rows = model->rowCount(); + for (int i = 0; i < rows; ++i) { + auto idx = model->index(i, ColumnBus); + hdd[i].bus = idx.data(DataBus).toUInt(); + hdd[i].channel = idx.data(DataBusChannel).toUInt(); + hdd[i].tracks = idx.siblingAtColumn(ColumnCylinders).data().toUInt(); + hdd[i].hpc = idx.siblingAtColumn(ColumnHeads).data().toUInt(); + hdd[i].spt = idx.siblingAtColumn(ColumnSectors).data().toUInt(); + + QByteArray fileName = idx.siblingAtColumn(ColumnFilename).data(Qt::UserRole).toString().toUtf8(); + strncpy(hdd[i].fn, fileName.data(), sizeof(hdd[i].fn)); + hdd[i].priv = nullptr; + } +} + +void SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) { + if (index < 0) { + return; + } + + buschangeinprogress = true; + auto idx = ui->tableView->selectionModel()->currentIndex(); + if (idx.isValid()) { + auto* model = ui->tableView->model(); + auto col = idx.siblingAtColumn(ColumnBus); + model->setData(col, ui->comboBoxBus->currentData(Qt::UserRole), DataBus); + model->setData(col, busChannelName(col), Qt::DisplayRole); + Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBusPrevious).toInt(), model->data(col, DataBusChannelPrevious).toInt()); + model->setData(col, ui->comboBoxBus->currentData(Qt::UserRole), DataBusPrevious); + } + + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt()); + int chanIdx = 0; + + switch (ui->comboBoxBus->currentData().toInt()) + { + case HDD_BUS_MFM: + chanIdx = (Harddrives::busTrackClass->next_free_mfm_channel()); + break; + case HDD_BUS_XTA: + chanIdx = (Harddrives::busTrackClass->next_free_xta_channel()); + break; + case HDD_BUS_ESDI: + chanIdx = (Harddrives::busTrackClass->next_free_esdi_channel()); + break; + case HDD_BUS_ATAPI: + case HDD_BUS_IDE: + chanIdx = (Harddrives::busTrackClass->next_free_ide_channel()); + break; + case HDD_BUS_SCSI: + chanIdx = (Harddrives::busTrackClass->next_free_scsi_id()); + break; + } + + if (idx.isValid()) { + auto* model = ui->tableView->model(); + auto col = idx.siblingAtColumn(ColumnBus); + model->setData(col, chanIdx, DataBusChannelPrevious); + } + ui->comboBoxChannel->setCurrentIndex(chanIdx); + buschangeinprogress = false; +} + +void SettingsHarddisks::on_comboBoxChannel_currentIndexChanged(int index) { + if (index < 0) { + return; + } + + auto idx = ui->tableView->selectionModel()->currentIndex(); + if (idx.isValid()) { + auto* model = ui->tableView->model(); + auto col = idx.siblingAtColumn(ColumnBus); + model->setData(col, ui->comboBoxChannel->currentData(Qt::UserRole), DataBusChannel); + model->setData(col, busChannelName(col), Qt::DisplayRole); + if (!buschangeinprogress) Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannelPrevious).toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannel).toUInt()); + model->setData(col, ui->comboBoxChannel->currentData(Qt::UserRole), DataBusChannelPrevious); + } +} + +void SettingsHarddisks::onTableRowChanged(const QModelIndex ¤t) { + bool hidden = !current.isValid(); + ui->labelBus->setHidden(hidden); + ui->labelChannel->setHidden(hidden); + ui->comboBoxBus->setHidden(hidden); + ui->comboBoxChannel->setHidden(hidden); + + uint32_t bus = current.siblingAtColumn(ColumnBus).data(DataBus).toUInt(); + uint32_t busChannel = current.siblingAtColumn(ColumnBus).data(DataBusChannel).toUInt(); + + auto* model = ui->comboBoxBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (! match.isEmpty()) { + ui->comboBoxBus->setCurrentIndex(match.first().row()); + } + model = ui->comboBoxChannel->model(); + match = model->match(model->index(0, 0), Qt::UserRole, busChannel); + if (! match.isEmpty()) { + ui->comboBoxChannel->setCurrentIndex(match.first().row()); + } +} + +static void addDriveFromDialog(Ui::SettingsHarddisks* ui, const HarddiskDialog& dlg) { + QByteArray fn = dlg.fileName().toUtf8(); + + hard_disk_t hd; + hd.bus = dlg.bus(); + hd.channel = dlg.channel(); + hd.tracks = dlg.cylinders(); + hd.hpc = dlg.heads(); + hd.spt = dlg.sectors(); + strncpy(hd.fn, fn.data(), sizeof(hd.fn)); + + addRow(ui->tableView->model(), &hd); + ui->tableView->resizeColumnsToContents(); + ui->tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); + if (ui->tableView->model()->rowCount() == HDD_NUM) + { + ui->pushButtonNew->setEnabled(false); + ui->pushButtonExisting->setEnabled(false); + } +} + +void SettingsHarddisks::on_pushButtonNew_clicked() { + HarddiskDialog dialog(false, this); + switch (dialog.exec()) { + case QDialog::Accepted: + addDriveFromDialog(ui, dialog); + break; + } +} + + +void SettingsHarddisks::on_pushButtonExisting_clicked() { + HarddiskDialog dialog(true, this); + switch (dialog.exec()) { + case QDialog::Accepted: + addDriveFromDialog(ui, dialog); + break; + } +} + +void SettingsHarddisks::on_pushButtonRemove_clicked() { + auto idx = ui->tableView->selectionModel()->currentIndex(); + if (! idx.isValid()) { + return; + } + + auto* model = ui->tableView->model(); + model->removeRow(idx.row()); + ui->pushButtonNew->setEnabled(true); + ui->pushButtonExisting->setEnabled(true); +} + diff --git a/src/qt/qt_settingsharddisks.hpp b/src/qt/qt_settingsharddisks.hpp new file mode 100644 index 000000000..b10e79029 --- /dev/null +++ b/src/qt/qt_settingsharddisks.hpp @@ -0,0 +1,36 @@ +#ifndef QT_SETTINGSHARDDISKS_HPP +#define QT_SETTINGSHARDDISKS_HPP + +#include + +namespace Ui { +class SettingsHarddisks; +} + +class SettingsHarddisks : public QWidget +{ + Q_OBJECT + +public: + explicit SettingsHarddisks(QWidget *parent = nullptr); + ~SettingsHarddisks(); + + void save(); + +private slots: + void on_comboBoxChannel_currentIndexChanged(int index); + +private slots: + void on_pushButtonRemove_clicked(); + void on_pushButtonExisting_clicked(); + void on_pushButtonNew_clicked(); + void on_comboBoxBus_currentIndexChanged(int index); + + void onTableRowChanged(const QModelIndex& current); + +private: + Ui::SettingsHarddisks *ui; + bool buschangeinprogress = false; +}; + +#endif // QT_SETTINGSHARDDISKS_HPP diff --git a/src/qt/qt_settingsharddisks.ui b/src/qt/qt_settingsharddisks.ui new file mode 100644 index 000000000..b670dd512 --- /dev/null +++ b/src/qt/qt_settingsharddisks.ui @@ -0,0 +1,95 @@ + + + SettingsHarddisks + + + + 0 + 0 + 400 + 300 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + + + + + + + Bus: + + + + + + + + + + ID: + + + + + + + + + + + + + + &New... + + + + + + + &Existing... + + + + + + + &Remove + + + + + + + + + + diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp new file mode 100644 index 000000000..f9b99dd7a --- /dev/null +++ b/src/qt/qt_settingsinput.cpp @@ -0,0 +1,187 @@ +#include "qt_settingsinput.hpp" +#include "ui_qt_settingsinput.h" + +#include + +extern "C" { +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/mouse.h> +#include <86box/gameport.h> +} + +#include "qt_models_common.hpp" +#include "qt_deviceconfig.hpp" +#include "qt_joystickconfiguration.hpp" + +SettingsInput::SettingsInput(QWidget *parent) : + QWidget(parent), + ui(new Ui::SettingsInput) +{ + ui->setupUi(this); + + onCurrentMachineChanged(machine); +} + +SettingsInput::~SettingsInput() +{ + delete ui; +} + +void SettingsInput::save() { + mouse_type = ui->comboBoxMouse->currentData().toInt(); + joystick_type = ui->comboBoxJoystick->currentData().toInt(); +} + +void SettingsInput::onCurrentMachineChanged(int machineId) { + // win_settings_video_proc, WM_INITDIALOG + this->machineId = machineId; + + const auto* machine = &machines[machineId]; + auto* mouseModel = ui->comboBoxMouse->model(); + auto removeRows = mouseModel->rowCount(); + + int selectedRow = 0; + for (int i = 0; i < mouse_get_ndev(); ++i) { + const auto* dev = mouse_get_device(i); + if ((i == MOUSE_TYPE_INTERNAL) && (machine_has_flags(machineId, MACHINE_MOUSE) == 0)) { + continue; + } + + if (device_is_valid(dev, machineId) == 0) { + continue; + } + + QString name = DeviceConfig::DeviceName(dev, mouse_get_internal_name(i), 0); + int row = mouseModel->rowCount(); + mouseModel->insertRow(row); + auto idx = mouseModel->index(row, 0); + + mouseModel->setData(idx, name, Qt::DisplayRole); + mouseModel->setData(idx, i, Qt::UserRole); + + if (i == mouse_type) { + selectedRow = row - removeRows; + } + } + mouseModel->removeRows(0, removeRows); + ui->comboBoxMouse->setCurrentIndex(selectedRow); + + + int i = 0; + char* joyName = joystick_get_name(i); + auto* joystickModel = ui->comboBoxJoystick->model(); + removeRows = joystickModel->rowCount(); + selectedRow = 0; + while (joyName) { + int row = Models::AddEntry(joystickModel, tr(joyName).toUtf8().data(), i); + if (i == joystick_type) { + selectedRow = row - removeRows; + } + + ++i; + joyName = joystick_get_name(i); + } + joystickModel->removeRows(0, removeRows); + ui->comboBoxJoystick->setCurrentIndex(selectedRow); +} + +void SettingsInput::on_comboBoxMouse_currentIndexChanged(int index) { + int mouseId = ui->comboBoxMouse->currentData().toInt(); + ui->pushButtonConfigureMouse->setEnabled(mouse_has_config(mouseId) > 0); +} + + +void SettingsInput::on_comboBoxJoystick_currentIndexChanged(int index) { + int joystickId = ui->comboBoxJoystick->currentData().toInt(); + for (int i = 0; i < 4; ++i) { + auto* btn = findChild(QString("pushButtonJoystick%1").arg(i+1)); + if (btn == nullptr) { + continue; + } + btn->setEnabled(joystick_get_max_joysticks(joystickId) > i); + } +} + +void SettingsInput::on_pushButtonConfigureMouse_clicked() { + int mouseId = ui->comboBoxMouse->currentData().toInt(); + DeviceConfig::ConfigureDevice(mouse_get_device(mouseId)); +} + +static int get_axis(JoystickConfiguration& jc, int axis, int joystick_nr) { + int axis_sel = jc.selectedAxis(axis); + int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; + int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs; + + if (axis_sel < nr_axes) { + return axis_sel; + } + + axis_sel -= nr_axes; + if (axis_sel < nr_povs * 2) { + if (axis_sel & 1) + return POV_Y | (axis_sel >> 1); + else + return POV_X | (axis_sel >> 1); + } + axis_sel -= nr_povs; + + return SLIDER | (axis_sel >> 1); +} + +static int get_pov(JoystickConfiguration& jc, int pov, int joystick_nr) { + int pov_sel = jc.selectedPov(pov); + int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_povs*2; + + if (pov_sel < nr_povs) + { + if (pov_sel & 1) + return POV_Y | (pov_sel >> 1); + else + return POV_X | (pov_sel >> 1); + } + + return pov_sel - nr_povs; +} + +static void updateJoystickConfig(int type, int joystick_nr, QWidget* parent) { + JoystickConfiguration jc(type, joystick_nr, parent); + switch (jc.exec()) { + case QDialog::Rejected: + return; + case QDialog::Accepted: + break; + } + + joystick_state[joystick_nr].plat_joystick_nr = jc.selectedDevice(); + if (joystick_state[joystick_nr].plat_joystick_nr) { + for (int c = 0; c < joystick_get_axis_count(type); c++) { + joystick_state[joystick_nr].axis_mapping[c] = get_axis(jc, c, joystick_nr); + } + for (int c = 0; c < joystick_get_button_count(type); c++) { + joystick_state[joystick_nr].button_mapping[c] = jc.selectedButton(c); + } + for (int c = 0; c < joystick_get_button_count(type); c++) { + joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(jc, c, joystick_nr); + joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(jc, c, joystick_nr); + } + } +} + +void SettingsInput::on_pushButtonJoystick1_clicked() { + updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 0, this); +} + +void SettingsInput::on_pushButtonJoystick2_clicked() { + updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 1, this); +} + +void SettingsInput::on_pushButtonJoystick3_clicked() { + updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 2, this); +} + +void SettingsInput::on_pushButtonJoystick4_clicked() { + updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 3, this); +} + diff --git a/src/qt/qt_settingsinput.hpp b/src/qt/qt_settingsinput.hpp new file mode 100644 index 000000000..f9e44740d --- /dev/null +++ b/src/qt/qt_settingsinput.hpp @@ -0,0 +1,37 @@ +#ifndef QT_SETTINGSINPUT_HPP +#define QT_SETTINGSINPUT_HPP + +#include + +namespace Ui { +class SettingsInput; +} + +class SettingsInput : public QWidget +{ + Q_OBJECT + +public: + explicit SettingsInput(QWidget *parent = nullptr); + ~SettingsInput(); + + void save(); + +public slots: + void onCurrentMachineChanged(int machineId); + +private slots: + void on_pushButtonConfigureMouse_clicked(); + void on_comboBoxJoystick_currentIndexChanged(int index); + void on_comboBoxMouse_currentIndexChanged(int index); + void on_pushButtonJoystick1_clicked(); + void on_pushButtonJoystick2_clicked(); + void on_pushButtonJoystick3_clicked(); + void on_pushButtonJoystick4_clicked(); + +private: + Ui::SettingsInput *ui; + int machineId = 0; +}; + +#endif // QT_SETTINGSINPUT_HPP diff --git a/src/qt/qt_settingsinput.ui b/src/qt/qt_settingsinput.ui new file mode 100644 index 000000000..7332ad907 --- /dev/null +++ b/src/qt/qt_settingsinput.ui @@ -0,0 +1,134 @@ + + + SettingsInput + + + + 0 + 0 + 400 + 300 + + + + Form + + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Mouse: + + + + + + + + + + Configure + + + + + + + Joystick: + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Joystick 1... + + + + + + + Joystick 2... + + + + + + + Joystick 3... + + + + + + + Joystick 4... + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp new file mode 100644 index 000000000..8a1f12be2 --- /dev/null +++ b/src/qt/qt_settingsmachine.cpp @@ -0,0 +1,270 @@ +#include "qt_settingsmachine.hpp" +#include "ui_qt_settingsmachine.h" + +#include +#include +#include +#include +#include + +#include + +extern "C" { +#include "../cpu/cpu.h" + +#include <86box/86box.h> +#include <86box/config.h> +#include <86box/device.h> +#include <86box/machine.h> +} + +// from nvr.h, which we can't import into CPP code +#define TIME_SYNC_DISABLED 0 +#define TIME_SYNC_ENABLED 1 +#define TIME_SYNC_UTC 2 + +#include "qt_deviceconfig.hpp" +#include "qt_models_common.hpp" + +SettingsMachine::SettingsMachine(QWidget *parent) : + QWidget(parent), + ui(new Ui::SettingsMachine) +{ + ui->setupUi(this); + + switch (time_sync) { + case TIME_SYNC_ENABLED: + ui->radioButtonLocalTime->setChecked(true); + break; + case TIME_SYNC_ENABLED | TIME_SYNC_UTC: + ui->radioButtonUTC->setChecked(true); + break; + case TIME_SYNC_DISABLED: + default: + ui->radioButtonDisabled->setChecked(true); + break; + } + + auto* waitStatesModel = ui->comboBoxWaitStates->model(); + waitStatesModel->insertRows(0, 9); + auto idx = waitStatesModel->index(0, 0); + waitStatesModel->setData(idx, tr("Default"), Qt::DisplayRole); + waitStatesModel->setData(idx, 0, Qt::UserRole); + for (int i = 0; i < 8; ++i) { + idx = waitStatesModel->index(i+1, 0); + waitStatesModel->setData(idx, QString::asprintf(tr("%i Wait state(s)").toUtf8().constData(), i), Qt::DisplayRole); + waitStatesModel->setData(idx, i+1, Qt::UserRole); + } + + int selectedMachineType = 0; + auto* machineTypesModel = ui->comboBoxMachineType->model(); + for (int i = 0; i < MACHINE_TYPE_MAX; ++i) { + Models::AddEntry(machineTypesModel, machine_types[i].name, machine_types[i].id); + if (machine_types[i].id == machine_get_type(machine)) { + selectedMachineType = i; + } + } + ui->comboBoxMachineType->setCurrentIndex(selectedMachineType); +} + +SettingsMachine::~SettingsMachine() { + delete ui; +} + +void SettingsMachine::save() { + machine = ui->comboBoxMachine->currentData().toInt(); + cpu_f = const_cast(&cpu_families[ui->comboBoxCPU->currentData().toInt()]); + cpu = ui->comboBoxSpeed->currentData().toInt(); + fpu_type = ui->comboBoxFPU->currentData().toInt(); + cpu_use_dynarec = ui->checkBoxDynamicRecompiler->isChecked() ? 1 : 0; + int64_t temp_mem_size; + if (machine_get_ram_granularity(machine) < 1024) { + temp_mem_size = ui->spinBoxRAM->value(); + } else { + temp_mem_size = ui->spinBoxRAM->value() * 1024; + } + + temp_mem_size &= ~(machine_get_ram_granularity(machine) - 1); + if (temp_mem_size < machine_get_min_ram(machine)) { + temp_mem_size = machine_get_min_ram(machine); + } else if (temp_mem_size > machine_get_max_ram(machine)) { + temp_mem_size = machine_get_max_ram(machine); + } + mem_size = static_cast(temp_mem_size); + + if (ui->comboBoxWaitStates->isEnabled()) { + cpu_waitstates = ui->comboBoxWaitStates->currentData().toInt(); + } else { + cpu_waitstates = 0; + } + + time_sync = 0; + if (ui->radioButtonLocalTime->isChecked()) { + time_sync = TIME_SYNC_ENABLED; + } + if (ui->radioButtonUTC->isChecked()) { + time_sync = TIME_SYNC_ENABLED | TIME_SYNC_UTC; + } +} + +void SettingsMachine::on_comboBoxMachineType_currentIndexChanged(int index) { + auto* model = ui->comboBoxMachine->model(); + int removeRows = model->rowCount(); + + int selectedMachineRow = 0; + for (int i = 0; i < machine_count(); ++i) { + if ((machine_get_type(i) == index) && machine_available(i)) { + int row = Models::AddEntry(model, machines[i].name, i); + if (i == machine) { + selectedMachineRow = row - removeRows; + } + } + } + model->removeRows(0, removeRows); + + ui->comboBoxMachine->setCurrentIndex(-1); + ui->comboBoxMachine->setCurrentIndex(selectedMachineRow); +} + + +void SettingsMachine::on_comboBoxMachine_currentIndexChanged(int index) { + // win_settings_machine_recalc_machine + if (index < 0) { + return; + } + + int machineId = ui->comboBoxMachine->currentData().toInt(); + const auto* device = machine_getdevice(machineId); + ui->pushButtonConfigure->setEnabled((device != nullptr) && (device->config != nullptr)); + + auto* modelCpu = ui->comboBoxCPU->model(); + int removeRows = modelCpu->rowCount(); + + int i = 0; + int eligibleRows = 0; + int selectedCpuFamilyRow = 0; + while (cpu_families[i].package != 0) { + if (cpu_family_is_eligible(&cpu_families[i], machineId)) { + Models::AddEntry(modelCpu, QString("%1 %2").arg(cpu_families[i].manufacturer, cpu_families[i].name), i); + if (&cpu_families[i] == cpu_f) { + selectedCpuFamilyRow = eligibleRows; + } + ++eligibleRows; + } + ++i; + } + modelCpu->removeRows(0, removeRows); + ui->comboBoxCPU->setEnabled(eligibleRows > 1); + ui->comboBoxCPU->setCurrentIndex(-1); + ui->comboBoxCPU->setCurrentIndex(selectedCpuFamilyRow); + + int divisor; + if ((machine_get_ram_granularity(machineId) < 1024)) { + divisor = 1; + ui->spinBoxRAM->setSuffix(QCoreApplication::translate("", "KB").prepend(' ')); + } else { + divisor = 1024; + ui->spinBoxRAM->setSuffix(QCoreApplication::translate("", "MB").prepend(' ')); + } + ui->spinBoxRAM->setMinimum(machine_get_min_ram(machineId) / divisor); + ui->spinBoxRAM->setMaximum(machine_get_max_ram(machineId) / divisor); + ui->spinBoxRAM->setSingleStep(machine_get_ram_granularity(machineId) / divisor); + ui->spinBoxRAM->setValue(mem_size / divisor); + ui->spinBoxRAM->setEnabled(machine_get_min_ram(machineId) != machine_get_max_ram(machineId)); + + emit currentMachineChanged(machineId); +} + + +void SettingsMachine::on_comboBoxCPU_currentIndexChanged(int index) { + if (index < 0) { + return; + } + + int machineId = ui->comboBoxMachine->currentData().toInt(); + int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); + const auto* cpuFamily = &cpu_families[cpuFamilyId]; + + auto* modelSpeed = ui->comboBoxSpeed->model(); + int removeRows = modelSpeed->rowCount(); + + // win_settings_machine_recalc_cpu_m + int i = 0; + int eligibleRows = 0; + int selectedSpeedRow = 0; + while (cpuFamily->cpus[i].cpu_type != 0) { + if (cpu_is_eligible(cpuFamily, i, machineId)) { + Models::AddEntry(modelSpeed, QString("%1").arg(cpuFamily->cpus[i].name), i); + if (cpu == i) { + selectedSpeedRow = eligibleRows; + } + ++eligibleRows; + } + ++i; + } + modelSpeed->removeRows(0, removeRows); + ui->comboBoxSpeed->setEnabled(eligibleRows > 1); + ui->comboBoxSpeed->setCurrentIndex(-1); + ui->comboBoxSpeed->setCurrentIndex(selectedSpeedRow); +} + + +void SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) { + if (index < 0) { + return; + } + + // win_settings_machine_recalc_cpu + int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); + const auto* cpuFamily = &cpu_families[cpuFamilyId]; + int cpuId = ui->comboBoxSpeed->currentData().toInt(); + uint cpuType = cpuFamily->cpus[cpuId].cpu_type; + + if ((cpuType >= CPU_286) && (cpuType <= CPU_386DX)) { + ui->comboBoxWaitStates->setEnabled(true); + ui->comboBoxWaitStates->setCurrentIndex(cpu_waitstates); + } else { + ui->comboBoxWaitStates->setCurrentIndex(0); + ui->comboBoxWaitStates->setEnabled(false); + } + +#ifdef USE_DYNAREC + uint8_t flags = cpuFamily->cpus[cpuId].cpu_flags; + if (! (flags & CPU_SUPPORTS_DYNAREC)) { + ui->checkBoxDynamicRecompiler->setChecked(false); + ui->checkBoxDynamicRecompiler->setEnabled(false); + } else if (flags & CPU_REQUIRES_DYNAREC) { + ui->checkBoxDynamicRecompiler->setChecked(true); + ui->checkBoxDynamicRecompiler->setEnabled(false); + } else { + ui->checkBoxDynamicRecompiler->setChecked(cpu_use_dynarec); + ui->checkBoxDynamicRecompiler->setEnabled(true); + } +#endif + + // win_settings_machine_recalc_fpu + auto* modelFpu = ui->comboBoxFPU->model(); + int removeRows = modelFpu->rowCount(); + + int i = 0; + int selectedFpuRow = 0; + for (const char* fpuName = fpu_get_name_from_index(cpuFamily, cpuId, i); fpuName != nullptr; fpuName = fpu_get_name_from_index(cpuFamily, cpuId, ++i)) { + auto fpuType = fpu_get_type_from_index(cpuFamily, cpuId, i); + Models::AddEntry(modelFpu, QString("%1").arg(fpuName), fpuType); + if (fpu_type == fpuType) { + selectedFpuRow = i; + } + } + + modelFpu->removeRows(0, removeRows); + ui->comboBoxFPU->setEnabled(modelFpu->rowCount() > 1); + ui->comboBoxFPU->setCurrentIndex(-1); + ui->comboBoxFPU->setCurrentIndex(selectedFpuRow); +} + +void SettingsMachine::on_pushButtonConfigure_clicked() { + // deviceconfig_inst_open + int machineId = ui->comboBoxMachine->currentData().toInt(); + const auto* device = machine_getdevice(machineId); + DeviceConfig::ConfigureDevice(device); +} diff --git a/src/qt/qt_settingsmachine.hpp b/src/qt/qt_settingsmachine.hpp new file mode 100644 index 000000000..d0d4aabd2 --- /dev/null +++ b/src/qt/qt_settingsmachine.hpp @@ -0,0 +1,41 @@ +#ifndef QT_SETTINGSMACHINE_HPP +#define QT_SETTINGSMACHINE_HPP + +#include + +namespace Ui { +class SettingsMachine; +} + +class SettingsMachine : public QWidget +{ + Q_OBJECT + +public: + explicit SettingsMachine(QWidget *parent = nullptr); + ~SettingsMachine(); + + void save(); + +signals: + void currentMachineChanged(int machineId); +private slots: + void on_pushButtonConfigure_clicked(); + +private slots: + void on_comboBoxSpeed_currentIndexChanged(int index); + +private slots: + void on_comboBoxCPU_currentIndexChanged(int index); + +private slots: + void on_comboBoxMachine_currentIndexChanged(int index); + +private slots: + void on_comboBoxMachineType_currentIndexChanged(int index); + +private: + Ui::SettingsMachine *ui; +}; + +#endif // QT_SETTINGSMACHINE_HPP diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui new file mode 100644 index 000000000..e61eca023 --- /dev/null +++ b/src/qt/qt_settingsmachine.ui @@ -0,0 +1,229 @@ + + + SettingsMachine + + + + 0 + 0 + 458 + 390 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Machine type: + + + + + + + + + + Machine: + + + + + + + CPU type: + + + + + + + FPU: + + + + + + + Wait states: + + + + + + + Memory: + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Speed: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + 0 + + + + Configure + + + + + + + + + + + + + + 2 + 2 + + + + Dynamic Recompiler + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Time synchronization + + + + + + Disabled + + + + + + + Enabled (local time) + + + + + + + Enabled (UTC) + + + + + + + + + + + diff --git a/src/qt/qt_settingsnetwork.cpp b/src/qt/qt_settingsnetwork.cpp new file mode 100644 index 000000000..a8a6dd2fc --- /dev/null +++ b/src/qt/qt_settingsnetwork.cpp @@ -0,0 +1,113 @@ +#include "qt_settingsnetwork.hpp" +#include "ui_qt_settingsnetwork.h" + +extern "C" { +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/network.h> +} + +#include "qt_models_common.hpp" +#include "qt_deviceconfig.hpp" + +static void enableElements(Ui::SettingsNetwork *ui) { + int netType = ui->comboBoxNetwork->currentData().toInt(); + ui->comboBoxPcap->setEnabled(netType == NET_TYPE_PCAP); + + bool adaptersEnabled = netType == NET_TYPE_SLIRP || + (netType == NET_TYPE_PCAP && ui->comboBoxPcap->currentData().toInt() > 0); + ui->comboBoxAdapter->setEnabled(adaptersEnabled); + ui->pushButtonConfigure->setEnabled(adaptersEnabled && ui->comboBoxAdapter->currentIndex() > 0 && network_card_has_config(ui->comboBoxAdapter->currentData().toInt())); +} + +SettingsNetwork::SettingsNetwork(QWidget *parent) : + QWidget(parent), + ui(new Ui::SettingsNetwork) +{ + ui->setupUi(this); + + auto* model = ui->comboBoxNetwork->model(); + Models::AddEntry(model, tr("None"), NET_TYPE_NONE); + Models::AddEntry(model, "PCap", NET_TYPE_PCAP); + Models::AddEntry(model, "SLiRP", NET_TYPE_SLIRP); + ui->comboBoxNetwork->setCurrentIndex(network_type); + + int selectedRow = 0; + model = ui->comboBoxPcap->model(); + QString currentPcapDevice = network_host; + for (int c = 0; c < network_ndev; c++) { + + Models::AddEntry(model, tr(network_devs[c].description), c); + if (QString(network_devs[c].device) == currentPcapDevice) { + selectedRow = c; + } + } + ui->comboBoxPcap->setCurrentIndex(-1); + ui->comboBoxPcap->setCurrentIndex(selectedRow); + + onCurrentMachineChanged(machine); + enableElements(ui); +} + +SettingsNetwork::~SettingsNetwork() +{ + delete ui; +} + +void SettingsNetwork::save() { + network_type = ui->comboBoxNetwork->currentData().toInt(); + memset(network_host, '\0', sizeof(network_host)); + strcpy(network_host, network_devs[ui->comboBoxPcap->currentData().toInt()].device); + network_card = ui->comboBoxAdapter->currentData().toInt(); +} + +void SettingsNetwork::onCurrentMachineChanged(int machineId) { + this->machineId = machineId; + auto* machine = &machines[machineId]; + + auto* model = ui->comboBoxAdapter->model(); + auto removeRows = model->rowCount(); + int c = 0; + int selectedRow = 0; + while (true) { + auto name = DeviceConfig::DeviceName(network_card_getdevice(c), network_card_get_internal_name(c), 1); + if (name.isEmpty()) { + break; + } + + if (network_card_available(c) && device_is_valid(network_card_getdevice(c), machineId)) { + int row = Models::AddEntry(model, name, c); + if (c == network_card) { + selectedRow = row - removeRows; + } + } + + c++; + } + model->removeRows(0, removeRows); + ui->comboBoxAdapter->setEnabled(model->rowCount() > 0); + ui->comboBoxAdapter->setCurrentIndex(-1); + ui->comboBoxAdapter->setCurrentIndex(selectedRow); +} + +void SettingsNetwork::on_comboBoxNetwork_currentIndexChanged(int index) { + if (index < 0) { + return; + } + + enableElements(ui); +} + +void SettingsNetwork::on_comboBoxAdapter_currentIndexChanged(int index) { + if (index < 0) { + return; + } + + enableElements(ui); +} + +void SettingsNetwork::on_pushButtonConfigure_clicked() { + DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxAdapter->currentData().toInt())); +} + diff --git a/src/qt/qt_settingsnetwork.hpp b/src/qt/qt_settingsnetwork.hpp new file mode 100644 index 000000000..f17eb98f1 --- /dev/null +++ b/src/qt/qt_settingsnetwork.hpp @@ -0,0 +1,33 @@ +#ifndef QT_SETTINGSNETWORK_HPP +#define QT_SETTINGSNETWORK_HPP + +#include + +namespace Ui { +class SettingsNetwork; +} + +class SettingsNetwork : public QWidget +{ + Q_OBJECT + +public: + explicit SettingsNetwork(QWidget *parent = nullptr); + ~SettingsNetwork(); + + void save(); + +public slots: + void onCurrentMachineChanged(int machineId); + +private slots: + void on_pushButtonConfigure_clicked(); + void on_comboBoxAdapter_currentIndexChanged(int index); + void on_comboBoxNetwork_currentIndexChanged(int index); + +private: + Ui::SettingsNetwork *ui; + int machineId = 0; +}; + +#endif // QT_SETTINGSNETWORK_HPP diff --git a/src/qt/qt_settingsnetwork.ui b/src/qt/qt_settingsnetwork.ui new file mode 100644 index 000000000..0b99769a7 --- /dev/null +++ b/src/qt/qt_settingsnetwork.ui @@ -0,0 +1,101 @@ + + + SettingsNetwork + + + + 0 + 0 + 400 + 300 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + PCap device: + + + + + + + Network adapter: + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Network type: + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Configure + + + + + + + + + + + diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp new file mode 100644 index 000000000..7fa28f812 --- /dev/null +++ b/src/qt/qt_settingsotherperipherals.cpp @@ -0,0 +1,159 @@ +#include "qt_settingsotherperipherals.hpp" +#include "ui_qt_settingsotherperipherals.h" + +extern "C" { +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/isamem.h> +#include <86box/isartc.h> +} + +#include "qt_deviceconfig.hpp" +#include "qt_models_common.hpp" + +SettingsOtherPeripherals::SettingsOtherPeripherals(QWidget *parent) : + QWidget(parent), + ui(new Ui::SettingsOtherPeripherals) +{ + ui->setupUi(this); + onCurrentMachineChanged(machine); +} + +void SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) +{ + this->machineId = machineId; + + ui->checkBoxISABugger->setChecked(bugger_enabled > 0 ? true : false); + ui->checkBoxPOSTCard->setChecked(postcard_enabled > 0 ? true : false); + ui->checkBoxISABugger->setEnabled(machine_has_bus(machineId, MACHINE_BUS_ISA)); + ui->comboBoxRTC->setEnabled(machine_has_bus(machineId, MACHINE_BUS_ISA)); + ui->pushButtonConfigureRTC->setEnabled(machine_has_bus(machineId, MACHINE_BUS_ISA)); + + ui->comboBoxCard1->clear(); + ui->comboBoxCard2->clear(); + ui->comboBoxCard3->clear(); + ui->comboBoxCard4->clear(); + ui->comboBoxRTC->clear(); + + auto* model = ui->comboBoxRTC->model(); + int d = 0; + int selectedRow = 0; + while (true) { + QString name = DeviceConfig::DeviceName(isartc_get_device(d), isartc_get_internal_name(d), 0); + if (name.isEmpty()) { + break; + } + + if (!device_is_valid(isartc_get_device(d), machineId)) { + break; + } + + int row = Models::AddEntry(model, name, d); + if (d == isartc_type) { + selectedRow = row; + } + ++d; + } + ui->comboBoxRTC->setCurrentIndex(selectedRow); + + for (int c = 0; c < ISAMEM_MAX; c++) { + auto* cbox = findChild(QString("comboBoxCard%1").arg(c + 1)); + model = cbox->model(); + d = 0; + selectedRow = 0; + while (true) { + QString name = DeviceConfig::DeviceName(isamem_get_device(d), isamem_get_internal_name(d), 0); + if (name.isEmpty()) { + break; + } + + if (!device_is_valid(isamem_get_device(d), machineId)) { + break; + } + + int row = Models::AddEntry(model, name, d); + if (d == isamem_type[c]) { + selectedRow = row; + } + ++d; + } + cbox->setCurrentIndex(-1); + cbox->setCurrentIndex(selectedRow); + cbox->setEnabled(machine_has_bus(machineId, MACHINE_BUS_ISA)); + findChild(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled(isamem_type[c] != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); + } +} + +SettingsOtherPeripherals::~SettingsOtherPeripherals() +{ + delete ui; +} + +void SettingsOtherPeripherals::save() { + /* Other peripherals category */ + bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; + postcard_enabled = ui->checkBoxPOSTCard->isChecked() ? 1 : 0; + isartc_type = ui->comboBoxRTC->currentData().toInt(); + + /* ISA memory boards. */ + for (int i = 0; i < ISAMEM_MAX; i++) { + auto* cbox = findChild(QString("comboBoxCard%1").arg(i + 1)); + isamem_type[i] = cbox->currentData().toInt(); + } +} + +void SettingsOtherPeripherals::on_comboBoxRTC_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonConfigureRTC->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); +} + +void SettingsOtherPeripherals::on_pushButtonConfigureRTC_clicked() { + DeviceConfig::ConfigureDevice(isartc_get_device(ui->comboBoxRTC->currentData().toInt())); +} + +void SettingsOtherPeripherals::on_comboBoxCard1_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonConfigureCard1->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); +} + +void SettingsOtherPeripherals::on_pushButtonConfigureCard1_clicked() { + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard1->currentData().toInt()), 1); +} + +void SettingsOtherPeripherals::on_comboBoxCard2_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonConfigureCard2->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); +} + +void SettingsOtherPeripherals::on_pushButtonConfigureCard2_clicked() { + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard2->currentData().toInt()), 2); +} + +void SettingsOtherPeripherals::on_comboBoxCard3_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonConfigureCard3->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); +} + +void SettingsOtherPeripherals::on_pushButtonConfigureCard3_clicked() { + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard3->currentData().toInt()), 3); +} + +void SettingsOtherPeripherals::on_comboBoxCard4_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonConfigureCard4->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); +} + +void SettingsOtherPeripherals::on_pushButtonConfigureCard4_clicked() { + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard4->currentData().toInt()), 4); +} diff --git a/src/qt/qt_settingsotherperipherals.hpp b/src/qt/qt_settingsotherperipherals.hpp new file mode 100644 index 000000000..f8eed2c9e --- /dev/null +++ b/src/qt/qt_settingsotherperipherals.hpp @@ -0,0 +1,40 @@ +#ifndef QT_SETTINGSOTHERPERIPHERALS_HPP +#define QT_SETTINGSOTHERPERIPHERALS_HPP + +#include + +namespace Ui { +class SettingsOtherPeripherals; +} + +class SettingsOtherPeripherals : public QWidget +{ + Q_OBJECT + +public: + explicit SettingsOtherPeripherals(QWidget *parent = nullptr); + ~SettingsOtherPeripherals(); + + void save(); + +public slots: + void onCurrentMachineChanged(int machineId); + +private slots: + void on_pushButtonConfigureCard4_clicked(); + void on_comboBoxCard4_currentIndexChanged(int index); + void on_pushButtonConfigureCard3_clicked(); + void on_comboBoxCard3_currentIndexChanged(int index); + void on_pushButtonConfigureCard2_clicked(); + void on_comboBoxCard2_currentIndexChanged(int index); + void on_pushButtonConfigureCard1_clicked(); + void on_comboBoxCard1_currentIndexChanged(int index); + void on_pushButtonConfigureRTC_clicked(); + void on_comboBoxRTC_currentIndexChanged(int index); + +private: + Ui::SettingsOtherPeripherals *ui; + int machineId{0}; +}; + +#endif // QT_SETTINGSOTHERPERIPHERALS_HPP diff --git a/src/qt/qt_settingsotherperipherals.ui b/src/qt/qt_settingsotherperipherals.ui new file mode 100644 index 000000000..0a8d93efb --- /dev/null +++ b/src/qt/qt_settingsotherperipherals.ui @@ -0,0 +1,162 @@ + + + SettingsOtherPeripherals + + + + 0 + 0 + 421 + 458 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + ISA RTC: + + + + + + + + + + Configure + + + + + + + + + ISA Memory Expansion + + + + + + Configure + + + + + + + + + + Configure + + + + + + + Card 2: + + + + + + + Card 3: + + + + + + + Configure + + + + + + + + + + Card 1: + + + + + + + + + + + + + Configure + + + + + + + Card 4: + + + + + + + + + + + + ISABugger device + + + + + + + POST card + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/qt/qt_settingsotherremovable.cpp b/src/qt/qt_settingsotherremovable.cpp new file mode 100644 index 000000000..c6f089f80 --- /dev/null +++ b/src/qt/qt_settingsotherremovable.cpp @@ -0,0 +1,284 @@ +#include "qt_settingsotherremovable.hpp" +#include "ui_qt_settingsotherremovable.h" + +extern "C" { +#include <86box/timer.h> +#include <86box/scsi_device.h> +#include <86box/mo.h> +#include <86box/zip.h> +} + +#include + +#include "qt_models_common.hpp" +#include "qt_harddrive_common.hpp" +#include "qt_settings_bus_tracking.hpp" +#include "qt_progsettings.hpp" + +static QString moDriveTypeName(int i) { + return QString("%1 %2 %3").arg(mo_drive_types[i].vendor, mo_drive_types[i].model, mo_drive_types[i].revision); +} + +static void setMOBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t bus, uint8_t channel) { + QIcon icon; + switch (bus) { + case MO_BUS_DISABLED: + icon = ProgSettings::loadIcon("/mo_disabled.ico"); + break; + case MO_BUS_ATAPI: + case MO_BUS_SCSI: + icon = ProgSettings::loadIcon("/mo.ico"); + break; + } + + auto i = idx.siblingAtColumn(0); + model->setData(i, Harddrives::BusChannelName(bus, channel)); + model->setData(i, bus, Qt::UserRole); + model->setData(i, channel, Qt::UserRole + 1); + model->setData(i, icon, Qt::DecorationRole); +} + +static void setMOType(QAbstractItemModel* model, const QModelIndex& idx, uint32_t type) { + auto i = idx.siblingAtColumn(1); + if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() == MO_BUS_DISABLED) { + model->setData(i, QCoreApplication::translate("", "None")); + } else { + model->setData(i, moDriveTypeName(type)); + } + model->setData(i, type, Qt::UserRole); +} + +static void setZIPBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t bus, uint8_t channel) { + QIcon icon; + switch (bus) { + case ZIP_BUS_DISABLED: + icon = ProgSettings::loadIcon("/zip_disabled.ico"); + break; + case ZIP_BUS_ATAPI: + case ZIP_BUS_SCSI: + icon = ProgSettings::loadIcon("/zip.ico"); + break; + } + + auto i = idx.siblingAtColumn(0); + model->setData(i, Harddrives::BusChannelName(bus, channel)); + model->setData(i, bus, Qt::UserRole); + model->setData(i, channel, Qt::UserRole + 1); + model->setData(i, icon, Qt::DecorationRole); +} + +static void setZIPType(QAbstractItemModel* model, const QModelIndex& idx, bool is250) { + auto i = idx.siblingAtColumn(1); + model->setData(i, is250 ? "ZIP 250" : "ZIP 100"); + model->setData(i, is250, Qt::UserRole); +} + +SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) : + QWidget(parent), + ui(new Ui::SettingsOtherRemovable) +{ + ui->setupUi(this); + + Harddrives::populateRemovableBuses(ui->comboBoxMOBus->model()); + auto* model = ui->comboBoxMOType->model(); + for (uint32_t i = 0; i < KNOWN_MO_DRIVE_TYPES; i++) { + Models::AddEntry(model, moDriveTypeName(i), i); + } + + model = new QStandardItemModel(0, 2, this); + ui->tableViewMO->setModel(model); + model->setHeaderData(0, Qt::Horizontal, tr("Bus")); + model->setHeaderData(1, Qt::Horizontal, tr("Type")); + model->insertRows(0, MO_NUM); + for (int i = 0; i < MO_NUM; i++) { + auto idx = model->index(i, 0); + setMOBus(model, idx, mo_drives[i].bus_type, mo_drives[i].res); + setMOType(model, idx.siblingAtColumn(1), mo_drives[i].type); + Harddrives::busTrackClass->device_track(1, DEV_MO, mo_drives[i].bus_type, mo_drives[i].bus_type == MO_BUS_ATAPI ? mo_drives[i].ide_channel : mo_drives[i].scsi_device_id); + } + ui->tableViewMO->resizeColumnsToContents(); + ui->tableViewMO->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + + connect(ui->tableViewMO->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsOtherRemovable::onMORowChanged); + ui->tableViewMO->setCurrentIndex(model->index(0, 0)); + + + + + Harddrives::populateRemovableBuses(ui->comboBoxZIPBus->model()); + + model = new QStandardItemModel(0, 2, this); + ui->tableViewZIP->setModel(model); + model->setHeaderData(0, Qt::Horizontal, "Bus"); + model->setHeaderData(1, Qt::Horizontal, "Type"); + model->insertRows(0, ZIP_NUM); + for (int i = 0; i < ZIP_NUM; i++) { + auto idx = model->index(i, 0); + setZIPBus(model, idx, zip_drives[i].bus_type, zip_drives[i].res); + setZIPType(model, idx, zip_drives[i].is_250 > 0); + Harddrives::busTrackClass->device_track(1, DEV_ZIP, zip_drives[i].bus_type, zip_drives[i].bus_type == ZIP_BUS_ATAPI ? zip_drives[i].ide_channel : zip_drives[i].scsi_device_id); + } + ui->tableViewZIP->resizeColumnsToContents(); + ui->tableViewZIP->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + + connect(ui->tableViewZIP->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsOtherRemovable::onZIPRowChanged); + ui->tableViewZIP->setCurrentIndex(model->index(0, 0)); +} + +SettingsOtherRemovable::~SettingsOtherRemovable() +{ + delete ui; +} + +void SettingsOtherRemovable::save() { + auto* model = ui->tableViewMO->model(); + for (int i = 0; i < MO_NUM; i++) { + mo_drives[i].f = NULL; + mo_drives[i].priv = NULL; + mo_drives[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); + mo_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); + mo_drives[i].type = model->index(i, 1).data(Qt::UserRole).toUInt(); + } + + model = ui->tableViewZIP->model(); + for (int i = 0; i < ZIP_NUM; i++) { + zip_drives[i].f = NULL; + zip_drives[i].priv = NULL; + zip_drives[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); + zip_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); + zip_drives[i].is_250 = model->index(i, 1).data(Qt::UserRole).toBool() ? 1 : 0; + } +} + +void SettingsOtherRemovable::onMORowChanged(const QModelIndex ¤t) { + uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); + uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt(); + uint8_t type = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); + + ui->comboBoxMOBus->setCurrentIndex(-1); + auto* model = ui->comboBoxMOBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (! match.isEmpty()) { + ui->comboBoxMOBus->setCurrentIndex(match.first().row()); + } + + model = ui->comboBoxMOChannel->model(); + match = model->match(model->index(0, 0), Qt::UserRole, channel); + if (! match.isEmpty()) { + ui->comboBoxMOChannel->setCurrentIndex(match.first().row()); + } + ui->comboBoxMOType->setCurrentIndex(type); +} + +void SettingsOtherRemovable::onZIPRowChanged(const QModelIndex ¤t) { + uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); + uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt(); + bool is250 = current.siblingAtColumn(1).data(Qt::UserRole).toBool(); + + ui->comboBoxZIPBus->setCurrentIndex(-1); + auto* model = ui->comboBoxZIPBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (! match.isEmpty()) { + ui->comboBoxZIPBus->setCurrentIndex(match.first().row()); + } + + model = ui->comboBoxZIPChannel->model(); + match = model->match(model->index(0, 0), Qt::UserRole, channel); + if (! match.isEmpty()) { + ui->comboBoxZIPChannel->setCurrentIndex(match.first().row()); + } + ui->checkBoxZIP250->setChecked(is250); +} + +void SettingsOtherRemovable::on_comboBoxMOBus_currentIndexChanged(int index) { + if (index < 0) { + return; + } + + int bus = ui->comboBoxMOBus->currentData().toInt(); + bool enabled = (bus != MO_BUS_DISABLED); + ui->comboBoxMOChannel->setEnabled(enabled); + ui->comboBoxMOType->setEnabled(enabled); + Harddrives::populateBusChannels(ui->comboBoxMOChannel->model(), bus); +} + +void SettingsOtherRemovable::on_comboBoxMOBus_activated(int) { + auto i = ui->tableViewMO->selectionModel()->currentIndex().siblingAtColumn(0); + Harddrives::busTrackClass->device_track(0, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); + ui->comboBoxMOChannel->setCurrentIndex(ui->comboBoxMOBus->currentData().toUInt() == MO_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id()); + ui->tableViewMO->model()->data(i, Qt::UserRole + 1); + setMOBus( + ui->tableViewMO->model(), + ui->tableViewMO->selectionModel()->currentIndex(), + ui->comboBoxMOBus->currentData().toUInt(), + ui->comboBoxMOChannel->currentData().toUInt()); + setMOType( + ui->tableViewMO->model(), + ui->tableViewMO->selectionModel()->currentIndex(), + ui->comboBoxMOType->currentData().toUInt()); + ui->tableViewMO->resizeColumnsToContents(); + ui->tableViewMO->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); +} + +void SettingsOtherRemovable::on_comboBoxMOChannel_activated(int) { + auto i = ui->tableViewMO->selectionModel()->currentIndex().siblingAtColumn(0); + Harddrives::busTrackClass->device_track(0, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); + setMOBus( + ui->tableViewMO->model(), + ui->tableViewMO->selectionModel()->currentIndex(), + ui->comboBoxMOBus->currentData().toUInt(), + ui->comboBoxMOChannel->currentData().toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); +} + +void SettingsOtherRemovable::on_comboBoxMOType_activated(int) { + setMOType( + ui->tableViewMO->model(), + ui->tableViewMO->selectionModel()->currentIndex(), + ui->comboBoxMOType->currentData().toUInt()); + ui->tableViewMO->resizeColumnsToContents(); + ui->tableViewMO->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); +} + +void SettingsOtherRemovable::on_comboBoxZIPBus_currentIndexChanged(int index) { + if (index < 0) { + return; + } + + int bus = ui->comboBoxZIPBus->currentData().toInt(); + bool enabled = (bus != ZIP_BUS_DISABLED); + ui->comboBoxZIPChannel->setEnabled(enabled); + ui->checkBoxZIP250->setEnabled(enabled); + Harddrives::populateBusChannels(ui->comboBoxZIPChannel->model(), bus); +} + +void SettingsOtherRemovable::on_comboBoxZIPBus_activated(int) { + auto i = ui->tableViewZIP->selectionModel()->currentIndex().siblingAtColumn(0); + Harddrives::busTrackClass->device_track(0, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); + ui->comboBoxZIPChannel->setCurrentIndex(ui->comboBoxZIPBus->currentData().toUInt() == ZIP_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id()); + setZIPBus( + ui->tableViewZIP->model(), + ui->tableViewZIP->selectionModel()->currentIndex(), + ui->comboBoxZIPBus->currentData().toUInt(), + ui->comboBoxZIPChannel->currentData().toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); +} + +void SettingsOtherRemovable::on_comboBoxZIPChannel_activated(int) { + auto i = ui->tableViewZIP->selectionModel()->currentIndex().siblingAtColumn(0); + Harddrives::busTrackClass->device_track(0, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); + setZIPBus( + ui->tableViewZIP->model(), + ui->tableViewZIP->selectionModel()->currentIndex(), + ui->comboBoxZIPBus->currentData().toUInt(), + ui->comboBoxZIPChannel->currentData().toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); +} + +void SettingsOtherRemovable::on_checkBoxZIP250_stateChanged(int state) { + setZIPType( + ui->tableViewZIP->model(), + ui->tableViewZIP->selectionModel()->currentIndex(), + state == Qt::Checked); +} diff --git a/src/qt/qt_settingsotherremovable.hpp b/src/qt/qt_settingsotherremovable.hpp new file mode 100644 index 000000000..c48f6f819 --- /dev/null +++ b/src/qt/qt_settingsotherremovable.hpp @@ -0,0 +1,52 @@ +#ifndef QT_SETTINGSOTHERREMOVABLE_HPP +#define QT_SETTINGSOTHERREMOVABLE_HPP + +#include + +namespace Ui { +class SettingsOtherRemovable; +} + +class SettingsOtherRemovable : public QWidget +{ + Q_OBJECT + +public: + explicit SettingsOtherRemovable(QWidget *parent = nullptr); + ~SettingsOtherRemovable(); + + void save(); + +private slots: + void on_checkBoxZIP250_stateChanged(int arg1); + +private slots: + void on_comboBoxZIPChannel_activated(int index); + +private slots: + void on_comboBoxZIPBus_activated(int index); + +private slots: + void on_comboBoxZIPBus_currentIndexChanged(int index); + +private slots: + void on_comboBoxMOType_activated(int index); + +private slots: + void on_comboBoxMOChannel_activated(int index); + +private slots: + void on_comboBoxMOBus_activated(int index); + +private slots: + void on_comboBoxMOBus_currentIndexChanged(int index); + +private slots: + void onMORowChanged(const QModelIndex ¤t); + void onZIPRowChanged(const QModelIndex ¤t); + +private: + Ui::SettingsOtherRemovable *ui; +}; + +#endif // QT_SETTINGSOTHERREMOVABLE_HPP diff --git a/src/qt/qt_settingsotherremovable.ui b/src/qt/qt_settingsotherremovable.ui new file mode 100644 index 000000000..81b76f10a --- /dev/null +++ b/src/qt/qt_settingsotherremovable.ui @@ -0,0 +1,151 @@ + + + SettingsOtherRemovable + + + + 0 + 0 + 418 + 433 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + MO drives: + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + + + + + + + Bus: + + + + + + + Channel: + + + + + + + + + + + + + Type: + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + ZIP drives: + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + + + + + + + Bus: + + + + + + + + + + Channel: + + + + + + + + + + ZIP 250 + + + + + + + + + + diff --git a/src/qt/qt_settingsports.cpp b/src/qt/qt_settingsports.cpp new file mode 100644 index 000000000..e2a0a4fdc --- /dev/null +++ b/src/qt/qt_settingsports.cpp @@ -0,0 +1,81 @@ +#include "qt_settingsports.hpp" +#include "ui_qt_settingsports.h" + +extern "C" { +#include <86box/86box.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/lpt.h> +} + +#include "qt_deviceconfig.hpp" +#include "qt_models_common.hpp" + +SettingsPorts::SettingsPorts(QWidget *parent) : + QWidget(parent), + ui(new Ui::SettingsPorts) +{ + ui->setupUi(this); + + for (int i = 0; i < 3; i++) { + auto* cbox = findChild(QString("comboBoxLpt%1").arg(i+1)); + auto* model = cbox->model(); + int c = 0; + int selectedRow = 0; + while (true) { + const char* lptName = lpt_device_get_name(c); + if (lptName == nullptr) { + break; + } + + Models::AddEntry(model, tr(lptName), c); + if (c == lpt_ports[i].device) { + selectedRow = c; + } + c++; + } + cbox->setCurrentIndex(selectedRow); + + auto* checkBox = findChild(QString("checkBoxParallel%1").arg(i+1)); + checkBox->setChecked(lpt_ports[i].enabled > 0); + cbox->setEnabled(lpt_ports[i].enabled > 0); + } + + for (int i = 0; i < 4; i++) { + auto* checkBox = findChild(QString("checkBoxSerial%1").arg(i+1)); + checkBox->setChecked(serial_enabled[i] > 0); + } +} + +SettingsPorts::~SettingsPorts() +{ + delete ui; +} + +void SettingsPorts::save() { + for (int i = 0; i < 3; i++) { + auto* cbox = findChild(QString("comboBoxLpt%1").arg(i+1)); + auto* checkBox = findChild(QString("checkBoxParallel%1").arg(i+1)); + lpt_ports[i].device = cbox->currentData().toInt(); + lpt_ports[i].enabled = checkBox->isChecked() ? 1 : 0; + } + + for (int i = 0; i < 4; i++) { + auto* checkBox = findChild(QString("checkBoxSerial%1").arg(i+1)); + serial_enabled[i] = checkBox->isChecked() ? 1 : 0; + } +} + +void SettingsPorts::on_checkBoxParallel1_stateChanged(int state) { + ui->comboBoxLpt1->setEnabled(state == Qt::Checked); +} + +void SettingsPorts::on_checkBoxParallel2_stateChanged(int state) { + ui->comboBoxLpt2->setEnabled(state == Qt::Checked); +} + +void SettingsPorts::on_checkBoxParallel3_stateChanged(int state) { + ui->comboBoxLpt3->setEnabled(state == Qt::Checked); +} + diff --git a/src/qt/qt_settingsports.hpp b/src/qt/qt_settingsports.hpp new file mode 100644 index 000000000..e4a8a050a --- /dev/null +++ b/src/qt/qt_settingsports.hpp @@ -0,0 +1,28 @@ +#ifndef QT_SETTINGSPORTS_HPP +#define QT_SETTINGSPORTS_HPP + +#include + +namespace Ui { +class SettingsPorts; +} + +class SettingsPorts : public QWidget +{ + Q_OBJECT + +public: + explicit SettingsPorts(QWidget *parent = nullptr); + ~SettingsPorts(); + + void save(); +private slots: + void on_checkBoxParallel3_stateChanged(int arg1); + void on_checkBoxParallel2_stateChanged(int arg1); + void on_checkBoxParallel1_stateChanged(int arg1); + +private: + Ui::SettingsPorts *ui; +}; + +#endif // QT_SETTINGSPORTS_HPP diff --git a/src/qt/qt_settingsports.ui b/src/qt/qt_settingsports.ui new file mode 100644 index 000000000..0e52b4f3f --- /dev/null +++ b/src/qt/qt_settingsports.ui @@ -0,0 +1,133 @@ + + + SettingsPorts + + + + 0 + 0 + 398 + 341 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + LPT1 Device: + + + + + + + + + + LPT2 Device: + + + + + + + + + + LPT3 Device: + + + + + + + + + + + + + + Serial port 1 + + + + + + + Parallel port 1 + + + + + + + Serial port 2 + + + + + + + Parallel port 2 + + + + + + + Serial port 3 + + + + + + + Parallel port 3 + + + + + + + Serial port 4 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/qt/qt_settingssound.cpp b/src/qt/qt_settingssound.cpp new file mode 100644 index 000000000..fa8188567 --- /dev/null +++ b/src/qt/qt_settingssound.cpp @@ -0,0 +1,227 @@ +#include "qt_settingssound.hpp" +#include "ui_qt_settingssound.h" + +extern "C" { +#include <86box/86box.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/sound.h> +#include <86box/midi.h> +#include <86box/snd_mpu401.h> +} + +#include "qt_deviceconfig.hpp" +#include "qt_models_common.hpp" + +SettingsSound::SettingsSound(QWidget *parent) : + QWidget(parent), + ui(new Ui::SettingsSound) +{ + ui->setupUi(this); + onCurrentMachineChanged(machine); +} + +SettingsSound::~SettingsSound() +{ + delete ui; +} + +void SettingsSound::save() { + sound_card_current = ui->comboBoxSoundCard->currentData().toInt(); + midi_device_current = ui->comboBoxMidiOut->currentData().toInt(); + midi_input_device_current = ui->comboBoxMidiIn->currentData().toInt(); + mpu401_standalone_enable = ui->checkBoxMPU401->isChecked() ? 1 : 0; + SSI2001 = ui->checkBoxSSI2001->isChecked() ? 1 : 0;; + GAMEBLASTER = ui->checkBoxCMS->isChecked() ? 1 : 0; + GUS = ui->checkBoxGUS->isChecked() ? 1 : 0;; + sound_is_float = ui->checkBoxFloat32->isChecked() ? 1 : 0;; +} + +void SettingsSound::onCurrentMachineChanged(int machineId) { + this->machineId = machineId; + + auto* model = ui->comboBoxSoundCard->model(); + auto removeRows = model->rowCount(); + int c = 0; + int selectedRow = 0; + while (true) { + /* Skip "internal" if machine doesn't have it. */ + if ((c == 1) && (machine_has_flags(machineId, MACHINE_SOUND) == 0)) { + c++; + continue; + } + + auto* sound_dev = sound_card_getdevice(c); + QString name = DeviceConfig::DeviceName(sound_dev, sound_card_get_internal_name(c), 1); + if (name.isEmpty()) { + break; + } + + if (sound_card_available(c)) { + if (device_is_valid(sound_dev, machineId)) { + int row = Models::AddEntry(model, name, c); + if (c == sound_card_current) { + selectedRow = row - removeRows; + } + } + } + + c++; + } + model->removeRows(0, removeRows); + ui->comboBoxSoundCard->setEnabled(model->rowCount() > 0); + ui->comboBoxSoundCard->setCurrentIndex(-1); + ui->comboBoxSoundCard->setCurrentIndex(selectedRow); + + model = ui->comboBoxMidiOut->model(); + removeRows = model->rowCount(); + c = 0; + selectedRow = 0; + while (true) { + QString name = DeviceConfig::DeviceName(midi_device_getdevice(c), midi_device_get_internal_name(c), 0); + if (name.isEmpty()) { + break; + } + + if (midi_device_available(c)) { + int row = Models::AddEntry(model, name, c); + if (c == midi_device_current) { + selectedRow = row - removeRows; + } + } + c++; + } + model->removeRows(0, removeRows); + ui->comboBoxMidiOut->setEnabled(model->rowCount() > 0); + ui->comboBoxMidiOut->setCurrentIndex(-1); + ui->comboBoxMidiOut->setCurrentIndex(selectedRow); + + model = ui->comboBoxMidiIn->model(); + removeRows = model->rowCount(); + c = 0; + selectedRow = 0; + while (true) { + QString name = DeviceConfig::DeviceName(midi_in_device_getdevice(c), midi_device_get_internal_name(c), 0); + if (name.isEmpty()) { + break; + } + + if (midi_in_device_available(c)) { + int row = Models::AddEntry(model, name, c); + if (c == midi_input_device_current) { + selectedRow = row - removeRows; + } + } + + c++; + } + model->removeRows(0, removeRows); + ui->comboBoxMidiIn->setEnabled(model->rowCount() > 0); + ui->comboBoxMidiIn->setCurrentIndex(-1); + ui->comboBoxMidiIn->setCurrentIndex(selectedRow); + + ui->checkBoxMPU401->setChecked(mpu401_standalone_enable > 0); + ui->checkBoxSSI2001->setChecked(SSI2001 > 0); + ui->checkBoxCMS->setChecked(GAMEBLASTER > 0); + ui->checkBoxGUS->setChecked(GUS > 0); + ui->checkBoxFloat32->setChecked(sound_is_float > 0); + + bool hasIsa = machine_has_bus(machineId, MACHINE_BUS_ISA) > 0; + bool hasIsa16 = machine_has_bus(machineId, MACHINE_BUS_ISA) > 0; + ui->checkBoxCMS->setEnabled(hasIsa); + ui->pushButtonConfigureCMS->setEnabled((GAMEBLASTER > 0) && hasIsa); + ui->checkBoxGUS->setEnabled(hasIsa16); + ui->pushButtonConfigureGUS->setEnabled((GUS > 0) && hasIsa16); + ui->checkBoxSSI2001->setEnabled(hasIsa); + ui->pushButtonConfigureSSI2001->setEnabled((SSI2001 > 0) && hasIsa); +} + +static bool allowMpu401(Ui::SettingsSound *ui) { + QString midiOut = midi_device_get_internal_name(ui->comboBoxMidiOut->currentData().toInt()); + QString midiIn = midi_in_device_get_internal_name(ui->comboBoxMidiIn->currentData().toInt()); + + if (midiOut.isEmpty()) { + return false; + } + + if (midiOut == QStringLiteral("none") && midiIn == QStringLiteral("none")) { + return false; + } + + return true; +} + +void SettingsSound::on_comboBoxSoundCard_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonConfigureSoundCard->setEnabled(sound_card_has_config(ui->comboBoxSoundCard->currentData().toInt())); +} + + +void SettingsSound::on_pushButtonConfigureSoundCard_clicked() { + DeviceConfig::ConfigureDevice(sound_card_getdevice(ui->comboBoxSoundCard->currentData().toInt())); +} + +void SettingsSound::on_comboBoxMidiOut_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonConfigureMidiOut->setEnabled(midi_device_has_config(ui->comboBoxMidiOut->currentData().toInt())); + ui->checkBoxMPU401->setEnabled(allowMpu401(ui) && (machine_has_bus(machineId, MACHINE_BUS_ISA) || machine_has_bus(machineId, MACHINE_BUS_MCA))); + ui->pushButtonConfigureMPU401->setEnabled(allowMpu401(ui) && ui->checkBoxMPU401->isChecked()); +} + +void SettingsSound::on_pushButtonConfigureMidiOut_clicked() { + DeviceConfig::ConfigureDevice(midi_device_getdevice(ui->comboBoxMidiOut->currentData().toInt())); +} + +void SettingsSound::on_comboBoxMidiIn_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonConfigureMidiIn->setEnabled(midi_in_device_has_config(ui->comboBoxMidiIn->currentData().toInt())); + ui->checkBoxMPU401->setEnabled(allowMpu401(ui) && (machine_has_bus(machineId, MACHINE_BUS_ISA) || machine_has_bus(machineId, MACHINE_BUS_MCA))); + ui->pushButtonConfigureMPU401->setEnabled(allowMpu401(ui) && ui->checkBoxMPU401->isChecked()); +} + +void SettingsSound::on_pushButtonConfigureMidiIn_clicked() { + DeviceConfig::ConfigureDevice(midi_in_device_getdevice(ui->comboBoxMidiIn->currentData().toInt())); +} + +void SettingsSound::on_checkBoxMPU401_stateChanged(int state) { + ui->pushButtonConfigureMPU401->setEnabled(state == Qt::Checked); +} + +void SettingsSound::on_checkBoxSSI2001_stateChanged(int state) { + ui->pushButtonConfigureSSI2001->setEnabled(state == Qt::Checked); +} + +void SettingsSound::on_checkBoxCMS_stateChanged(int state) { + ui->pushButtonConfigureCMS->setEnabled(state == Qt::Checked); +} + +void SettingsSound::on_checkBoxGUS_stateChanged(int state) { + ui->pushButtonConfigureGUS->setEnabled(state == Qt::Checked); +} + +void SettingsSound::on_pushButtonConfigureMPU401_clicked() { + if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { + DeviceConfig::ConfigureDevice(&mpu401_mca_device); + } else { + DeviceConfig::ConfigureDevice(&mpu401_device); + } +} + +void SettingsSound::on_pushButtonConfigureSSI2001_clicked() { + DeviceConfig::ConfigureDevice(&ssi2001_device); +} + +void SettingsSound::on_pushButtonConfigureCMS_clicked() { + DeviceConfig::ConfigureDevice(&cms_device); +} + +void SettingsSound::on_pushButtonConfigureGUS_clicked() { + DeviceConfig::ConfigureDevice(&gus_device); +} diff --git a/src/qt/qt_settingssound.hpp b/src/qt/qt_settingssound.hpp new file mode 100644 index 000000000..c649eb2a2 --- /dev/null +++ b/src/qt/qt_settingssound.hpp @@ -0,0 +1,44 @@ +#ifndef QT_SETTINGSSOUND_HPP +#define QT_SETTINGSSOUND_HPP + +#include + +namespace Ui { +class SettingsSound; +} + +class SettingsSound : public QWidget +{ + Q_OBJECT + +public: + explicit SettingsSound(QWidget *parent = nullptr); + ~SettingsSound(); + + void save(); + +public slots: + void onCurrentMachineChanged(int machineId); + +private slots: + void on_pushButtonConfigureGUS_clicked(); + void on_pushButtonConfigureCMS_clicked(); + void on_pushButtonConfigureSSI2001_clicked(); + void on_pushButtonConfigureMPU401_clicked(); + void on_checkBoxGUS_stateChanged(int arg1); + void on_checkBoxCMS_stateChanged(int arg1); + void on_checkBoxSSI2001_stateChanged(int arg1); + void on_checkBoxMPU401_stateChanged(int arg1); + void on_pushButtonConfigureMidiIn_clicked(); + void on_pushButtonConfigureMidiOut_clicked(); + void on_comboBoxMidiIn_currentIndexChanged(int index); + void on_comboBoxMidiOut_currentIndexChanged(int index); + void on_pushButtonConfigureSoundCard_clicked(); + void on_comboBoxSoundCard_currentIndexChanged(int index); + +private: + Ui::SettingsSound *ui; + int machineId = 0; +}; + +#endif // QT_SETTINGSSOUND_HPP diff --git a/src/qt/qt_settingssound.ui b/src/qt/qt_settingssound.ui new file mode 100644 index 000000000..f8bad2c61 --- /dev/null +++ b/src/qt/qt_settingssound.ui @@ -0,0 +1,160 @@ + + + SettingsSound + + + + 0 + 0 + 387 + 332 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + MIDI In Device: + + + + + + + Innovation SSI-2001 + + + + + + + Gravis Ultrasound + + + + + + + Sound card: + + + + + + + Configure + + + + + + + + + + MIDI Out Device: + + + + + + + Standalone MPU-401 + + + + + + + Configure + + + + + + + Configure + + + + + + + Configure + + + + + + + CMS / Game Blaster + + + + + + + + + + + + + Configure + + + + + + + Use FLOAT32 sound + + + + + + + Configure + + + + + + + Configure + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp new file mode 100644 index 000000000..8432a300a --- /dev/null +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -0,0 +1,233 @@ +#include "qt_settingsstoragecontrollers.hpp" +#include "ui_qt_settingsstoragecontrollers.h" + +extern "C" { +#include <86box/86box.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/fdc_ext.h> +#include <86box/scsi.h> +#include <86box/scsi_device.h> +#include <86box/cassette.h> +} + +#include "qt_deviceconfig.hpp" +#include "qt_models_common.hpp" + +SettingsStorageControllers::SettingsStorageControllers(QWidget *parent) : + QWidget(parent), + ui(new Ui::SettingsStorageControllers) +{ + ui->setupUi(this); + + ui->checkBoxCassette->setChecked(cassette_enable > 0); + + onCurrentMachineChanged(machine); +} + +SettingsStorageControllers::~SettingsStorageControllers() +{ + delete ui; +} + +void SettingsStorageControllers::save() { + /* Storage devices category */ + for (int i = 0; i < SCSI_BUS_MAX; ++i) { + auto* cbox = findChild(QString("comboBoxSCSI%1").arg(i+1)); + scsi_card_current[i] = cbox->currentData().toInt(); + } + hdc_current = ui->comboBoxHD->currentData().toInt(); + fdc_type = ui->comboBoxFD->currentData().toInt(); + ide_ter_enabled = ui->checkBoxTertiaryIDE->isChecked() ? 1 : 0; + ide_qua_enabled = ui->checkBoxQuaternaryIDE->isChecked() ? 1 : 0; + cassette_enable = ui->checkBoxCassette->isChecked() ? 1 : 0; +} + +void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { + this->machineId = machineId; + auto* machine = &machines[machineId]; + + /*HD controller config*/ + auto* model = ui->comboBoxHD->model(); + auto removeRows = model->rowCount(); + int c = 0; + int selectedRow = 0; + while (true) { + /* Skip "internal" if machine doesn't have it. */ + if ((c == 1) && (machine_has_flags(machineId, MACHINE_HDC) == 0)) { + c++; + continue; + } + + QString name = DeviceConfig::DeviceName(hdc_get_device(c), hdc_get_internal_name(c), 1); + if (name.isEmpty()) { + break; + } + + if (hdc_available(c)) { + auto* hdc_dev = hdc_get_device(c); + + if (device_is_valid(hdc_dev, machineId)) { + int row = Models::AddEntry(model, name, c); + if (c == hdc_current) { + selectedRow = row - removeRows; + } + } + } + c++; + } + model->removeRows(0, removeRows); + ui->comboBoxHD->setEnabled(model->rowCount() > 0); + ui->comboBoxHD->setCurrentIndex(-1); + ui->comboBoxHD->setCurrentIndex(selectedRow); + + /*FD controller config*/ + model = ui->comboBoxFD->model(); + removeRows = model->rowCount(); + c = 0; + selectedRow = 0; + while (true) { + QString name = DeviceConfig::DeviceName(fdc_card_getdevice(c), fdc_card_get_internal_name(c), 1); + if (name.isEmpty()) { + break; + } + + if (fdc_card_available(c)) { + auto* fdc_dev = fdc_card_getdevice(c); + + if (device_is_valid(fdc_dev, machineId)) { + int row = Models::AddEntry(model, name, c); + if (c == fdc_type) { + selectedRow = row - removeRows; + } + } + } + c++; + } + model->removeRows(0, removeRows); + ui->comboBoxFD->setEnabled(model->rowCount() > 0); + ui->comboBoxFD->setCurrentIndex(-1); + ui->comboBoxFD->setCurrentIndex(selectedRow); + + for (int i = 0; i < SCSI_BUS_MAX; ++i) { + auto* cbox = findChild(QString("comboBoxSCSI%1").arg(i+1)); + model = cbox->model(); + removeRows = model->rowCount(); + c = 0; + selectedRow = 0; + + while (true) { + auto name = DeviceConfig::DeviceName(scsi_card_getdevice(c), scsi_card_get_internal_name(c), 1); + if (name.isEmpty()) { + break; + } + + if (scsi_card_available(c)) { + auto* scsi_dev = scsi_card_getdevice(c); + if (device_is_valid(scsi_dev, machineId)) { + int row = Models::AddEntry(model, name, c); + if (c == scsi_card_current[i]) { + selectedRow = row - removeRows; + } + } + } + c++; + } + + model->removeRows(0, removeRows); + cbox->setEnabled(model->rowCount() > 0); + cbox->setCurrentIndex(-1); + cbox->setCurrentIndex(selectedRow); + } + + int is_at = IS_AT(machineId); + ui->checkBoxTertiaryIDE->setEnabled(is_at > 0); + ui->checkBoxQuaternaryIDE->setEnabled(is_at > 0); +} + +void SettingsStorageControllers::on_comboBoxHD_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonHD->setEnabled(hdc_has_config(ui->comboBoxHD->currentData().toInt()) > 0); +} + +void SettingsStorageControllers::on_comboBoxFD_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonFD->setEnabled(hdc_has_config(ui->comboBoxFD->currentData().toInt()) > 0); +} + +void SettingsStorageControllers::on_checkBoxTertiaryIDE_stateChanged(int arg1) { + ui->pushButtonTertiaryIDE->setEnabled(arg1 == Qt::Checked); +} + + +void SettingsStorageControllers::on_checkBoxQuaternaryIDE_stateChanged(int arg1) { + ui->pushButtonQuaternaryIDE->setEnabled(arg1 == Qt::Checked); +} + +void SettingsStorageControllers::on_pushButtonHD_clicked() { + DeviceConfig::ConfigureDevice(hdc_get_device(ui->comboBoxHD->currentData().toInt())); +} + +void SettingsStorageControllers::on_pushButtonFD_clicked() { + DeviceConfig::ConfigureDevice(fdc_card_getdevice(ui->comboBoxFD->currentData().toInt())); +} + +void SettingsStorageControllers::on_pushButtonTertiaryIDE_clicked() { + DeviceConfig::ConfigureDevice(&ide_ter_device); +} + +void SettingsStorageControllers::on_pushButtonQuaternaryIDE_clicked() { + DeviceConfig::ConfigureDevice(&ide_qua_device); +} + +void SettingsStorageControllers::on_comboBoxSCSI1_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonSCSI1->setEnabled(scsi_card_has_config(ui->comboBoxSCSI1->currentData().toInt()) > 0); +} + +void SettingsStorageControllers::on_comboBoxSCSI2_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonSCSI2->setEnabled(scsi_card_has_config(ui->comboBoxSCSI2->currentData().toInt()) > 0); +} + +void SettingsStorageControllers::on_comboBoxSCSI3_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonSCSI3->setEnabled(scsi_card_has_config(ui->comboBoxSCSI3->currentData().toInt()) > 0); +} + +void SettingsStorageControllers::on_comboBoxSCSI4_currentIndexChanged(int index) { + if (index < 0) { + return; + } + ui->pushButtonSCSI4->setEnabled(scsi_card_has_config(ui->comboBoxSCSI4->currentData().toInt()) > 0); +} + + +void SettingsStorageControllers::on_pushButtonSCSI1_clicked() { + DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI1->currentData().toInt()), 1); +} + +void SettingsStorageControllers::on_pushButtonSCSI2_clicked() { + DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI2->currentData().toInt()), 2); +} + +void SettingsStorageControllers::on_pushButtonSCSI3_clicked() { + DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI3->currentData().toInt()), 3); +} + +void SettingsStorageControllers::on_pushButtonSCSI4_clicked() { + DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI4->currentData().toInt()), 4); +} diff --git a/src/qt/qt_settingsstoragecontrollers.hpp b/src/qt/qt_settingsstoragecontrollers.hpp new file mode 100644 index 000000000..e4596b567 --- /dev/null +++ b/src/qt/qt_settingsstoragecontrollers.hpp @@ -0,0 +1,46 @@ +#ifndef QT_SETTINGSSTORAGECONTROLLERS_HPP +#define QT_SETTINGSSTORAGECONTROLLERS_HPP + +#include + +namespace Ui { +class SettingsStorageControllers; +} + +class SettingsStorageControllers : public QWidget +{ + Q_OBJECT + +public: + explicit SettingsStorageControllers(QWidget *parent = nullptr); + ~SettingsStorageControllers(); + + void save(); + +public slots: + void onCurrentMachineChanged(int machineId); + +private slots: + void on_pushButtonSCSI4_clicked(); + void on_pushButtonSCSI3_clicked(); + void on_pushButtonSCSI2_clicked(); + void on_pushButtonSCSI1_clicked(); + void on_comboBoxSCSI4_currentIndexChanged(int index); + void on_comboBoxSCSI3_currentIndexChanged(int index); + void on_comboBoxSCSI2_currentIndexChanged(int index); + void on_comboBoxSCSI1_currentIndexChanged(int index); + void on_pushButtonQuaternaryIDE_clicked(); + void on_pushButtonTertiaryIDE_clicked(); + void on_pushButtonFD_clicked(); + void on_pushButtonHD_clicked(); + void on_checkBoxQuaternaryIDE_stateChanged(int arg1); + void on_checkBoxTertiaryIDE_stateChanged(int arg1); + void on_comboBoxFD_currentIndexChanged(int index); + void on_comboBoxHD_currentIndexChanged(int index); + +private: + Ui::SettingsStorageControllers *ui; + int machineId = 0; +}; + +#endif // QT_SETTINGSSTORAGECONTROLLERS_HPP diff --git a/src/qt/qt_settingsstoragecontrollers.ui b/src/qt/qt_settingsstoragecontrollers.ui new file mode 100644 index 000000000..00f7c9619 --- /dev/null +++ b/src/qt/qt_settingsstoragecontrollers.ui @@ -0,0 +1,202 @@ + + + SettingsStorageControllers + + + + 0 + 0 + 496 + 449 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + HD Controller: + + + + + + + Configure + + + + + + + FD Controller: + + + + + + + + + + Configure + + + + + + + + + + Tertiary IDE Controller + + + + + + + Quaternary IDE Controller + + + + + + + false + + + Configure + + + + + + + false + + + Configure + + + + + + + + + SCSI + + + + + + + + + Configure + + + + + + + Controller 1: + + + + + + + + + + + + + Controller 4: + + + + + + + Controller 2: + + + + + + + Configure + + + + + + + Configure + + + + + + + Controller 3: + + + + + + + + + + Configure + + + + + + + + + + Cassette + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp new file mode 100644 index 000000000..6a935a7a5 --- /dev/null +++ b/src/qt/qt_softwarerenderer.cpp @@ -0,0 +1,72 @@ +#include "qt_softwarerenderer.hpp" +#include +#include + +extern "C" { +#include <86box/86box.h> +#include <86box/video.h> +} + +SoftwareRenderer::SoftwareRenderer(QWidget *parent) + : QRasterWindow(parent->windowHandle()) +{ + parentWidget = parent; + + images[0] = std::make_unique(QSize(2048, 2048), QImage::Format_RGB32); + images[1] = std::make_unique(QSize(2048, 2048), QImage::Format_RGB32); + + buf_usage = std::vector(2); + buf_usage[0].clear(); + buf_usage[1].clear(); +} + +void SoftwareRenderer::paintEvent(QPaintEvent* event) { + (void)event; + onPaint(this); +} + +void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { + /* TODO: should look into deleteLater() */ + auto tval = this; + void* nuldata = 0; + if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; + + cur_image = buf_idx; + buf_usage[(buf_idx + 1) % 2].clear(); + + source.setRect(x, y, w, h), + update(); +} + +void SoftwareRenderer::resizeEvent(QResizeEvent *event) { + onResize(width(), height()); + QRasterWindow::resizeEvent(event); +} + +bool SoftwareRenderer::event(QEvent *event) +{ + bool res = false; + if (!eventDelegate(event, res)) return QRasterWindow::event(event); + return res; +} + +void SoftwareRenderer::onPaint(QPaintDevice* device) { + if (cur_image == -1) + return; + + QPainter painter(device); + painter.setRenderHint(QPainter::SmoothPixmapTransform, video_filter_method > 0 ? true : false); + painter.fillRect(0, 0, device->width(), device->height(), QColorConstants::Black); + painter.setCompositionMode(QPainter::CompositionMode_Plus); + painter.drawImage(destination, *images[cur_image], source); +} + +std::vector> SoftwareRenderer::getBuffers() +{ + std::vector> buffers; + + buffers.push_back(std::make_tuple(images[0]->bits(), &buf_usage[0])); + buffers.push_back(std::make_tuple(images[1]->bits(), &buf_usage[1])); + + return buffers; +} diff --git a/src/qt/qt_softwarerenderer.hpp b/src/qt/qt_softwarerenderer.hpp new file mode 100644 index 000000000..8e646c14d --- /dev/null +++ b/src/qt/qt_softwarerenderer.hpp @@ -0,0 +1,33 @@ +#ifndef SOFTWARERENDERER_HPP +#define SOFTWARERENDERER_HPP + +#include +#include +#include +#include +#include +#include "qt_renderercommon.hpp" + +class SoftwareRenderer : public QRasterWindow, public RendererCommon +{ + Q_OBJECT +public: + explicit SoftwareRenderer(QWidget *parent = nullptr); + + void paintEvent(QPaintEvent* event) override; + + std::vector> getBuffers() override; + +public slots: + void onBlit(int buf_idx, int x, int y, int w, int h); + +protected: + std::array, 2> images; + int cur_image = -1; + + void onPaint(QPaintDevice* device); + void resizeEvent(QResizeEvent *event) override; + bool event(QEvent *event) override; +}; + +#endif // SOFTWARERENDERER_HPP diff --git a/src/qt/qt_soundgain.cpp b/src/qt/qt_soundgain.cpp new file mode 100644 index 000000000..9f02608e7 --- /dev/null +++ b/src/qt/qt_soundgain.cpp @@ -0,0 +1,35 @@ +#include "qt_soundgain.hpp" +#include "ui_qt_soundgain.h" + +extern "C" +{ +#include <86box/86box.h> +#include <86box/plat.h> +#include <86box/sound.h> +} + +SoundGain::SoundGain(QWidget *parent) : + QDialog(parent), + ui(new Ui::SoundGain) +{ + ui->setupUi(this); + ui->verticalSlider->setValue(sound_gain); + sound_gain_orig = sound_gain; +} + +SoundGain::~SoundGain() +{ + delete ui; +} + +void SoundGain::on_verticalSlider_valueChanged(int value) +{ + sound_gain = value; +} + + +void SoundGain::on_SoundGain_rejected() +{ + sound_gain = sound_gain_orig; +} + diff --git a/src/qt/qt_soundgain.hpp b/src/qt/qt_soundgain.hpp new file mode 100644 index 000000000..0e19bab53 --- /dev/null +++ b/src/qt/qt_soundgain.hpp @@ -0,0 +1,28 @@ +#ifndef QT_SOUNDGAIN_HPP +#define QT_SOUNDGAIN_HPP + +#include + +namespace Ui { +class SoundGain; +} + +class SoundGain : public QDialog +{ + Q_OBJECT + +public: + explicit SoundGain(QWidget *parent = nullptr); + ~SoundGain(); + +private slots: + void on_verticalSlider_valueChanged(int value); + + void on_SoundGain_rejected(); + +private: + Ui::SoundGain *ui; + int sound_gain_orig; +}; + +#endif // QT_SOUNDGAIN_HPP diff --git a/src/qt/qt_soundgain.ui b/src/qt/qt_soundgain.ui new file mode 100644 index 000000000..8d3f2c3f6 --- /dev/null +++ b/src/qt/qt_soundgain.ui @@ -0,0 +1,126 @@ + + + SoundGain + + + + 0 + 0 + 200 + 250 + + + + + 0 + 0 + + + + + 200 + 250 + + + + + 200 + 250 + + + + Sound Gain + + + + + + + 0 + 0 + + + + Gain + + + Qt::AlignCenter + + + + + + + 18 + + + 2 + + + 4 + + + Qt::Vertical + + + false + + + QSlider::TicksBothSides + + + + + + + + 0 + 0 + + + + Qt::Vertical + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + SoundGain + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SoundGain + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/qt_specifydimensions.cpp b/src/qt/qt_specifydimensions.cpp new file mode 100644 index 000000000..4a5b0ea0f --- /dev/null +++ b/src/qt/qt_specifydimensions.cpp @@ -0,0 +1,76 @@ +#include "qt_specifydimensions.h" +#include "ui_qt_specifydimensions.h" + +#include "qt_mainwindow.hpp" +#include "ui_qt_mainwindow.h" + +#include +#include +#include + +extern "C" +{ +#include <86box/86box.h> +#include <86box/plat.h> +#include <86box/ui.h> +#include <86box/video.h> +} + +extern MainWindow* main_window; + +SpecifyDimensions::SpecifyDimensions(QWidget *parent) : + QDialog(parent), + ui(new Ui::SpecifyDimensions) +{ + ui->setupUi(this); + ui->checkBox->setChecked(vid_resize == 2); + ui->spinBoxWidth->setRange(16, 2048); + ui->spinBoxWidth->setValue(main_window->getRenderWidgetSize().width()); + ui->spinBoxHeight->setRange(16, 2048); + ui->spinBoxHeight->setValue(main_window->getRenderWidgetSize().height()); +} + +SpecifyDimensions::~SpecifyDimensions() +{ + delete ui; +} + +void SpecifyDimensions::on_SpecifyDimensions_accepted() +{ + if (ui->checkBox->isChecked()) + { + vid_resize = 2; + main_window->setWindowFlag(Qt::WindowMaximizeButtonHint, false); + main_window->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint); + window_remember = 0; + fixed_size_x = ui->spinBoxWidth->value(); + fixed_size_y = ui->spinBoxHeight->value(); + + main_window->setFixedSize(ui->spinBoxWidth->value(), + ui->spinBoxHeight->value() + + (!hide_status_bar ? main_window->statusBar()->height() : 0) + + (!hide_tool_bar ? main_window->ui->toolBar->height() : 0) + + main_window->menuBar()->height()); + + emit main_window->updateMenuResizeOptions(); + main_window->show(); + main_window->ui->stackedWidget->switchRenderer((RendererStack::Renderer)vid_api); + } + else + { + main_window->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + main_window->ui->actionResizable_window->setChecked(false); + vid_resize = 0; + main_window->ui->actionResizable_window->trigger(); + window_remember = 1; + window_w = ui->spinBoxWidth->value(); + window_h = ui->spinBoxHeight->value(); + main_window->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + emit main_window->resizeContents(ui->spinBoxWidth->value(), ui->spinBoxHeight->value()); + vid_resize = 1; + emit main_window->updateMenuResizeOptions(); + } + main_window->show(); + emit main_window->updateWindowRememberOption(); +} + diff --git a/src/qt/qt_specifydimensions.h b/src/qt/qt_specifydimensions.h new file mode 100644 index 000000000..2aa820455 --- /dev/null +++ b/src/qt/qt_specifydimensions.h @@ -0,0 +1,25 @@ +#ifndef QT_SPECIFYDIMENSIONS_H +#define QT_SPECIFYDIMENSIONS_H + +#include + +namespace Ui { +class SpecifyDimensions; +} + +class SpecifyDimensions : public QDialog +{ + Q_OBJECT + +public: + explicit SpecifyDimensions(QWidget *parent = nullptr); + ~SpecifyDimensions(); + +private slots: + void on_SpecifyDimensions_accepted(); + +private: + Ui::SpecifyDimensions *ui; +}; + +#endif // QT_SPECIFYDIMENSIONS_H diff --git a/src/qt/qt_specifydimensions.ui b/src/qt/qt_specifydimensions.ui new file mode 100644 index 000000000..855b9f3b7 --- /dev/null +++ b/src/qt/qt_specifydimensions.ui @@ -0,0 +1,127 @@ + + + SpecifyDimensions + + + + 0 + 0 + 388 + 158 + + + + Specify Main Window Dimensions + + + + + 20 + 110 + 361 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 70 + 50 + 81 + 21 + + + + + + + 30 + 50 + 41 + 21 + + + + Width: + + + + + + 20 + 90 + 131 + 23 + + + + Lock to this size + + + + + + 200 + 50 + 51 + 21 + + + + Height: + + + + + + 250 + 50 + 81 + 21 + + + + + + + + buttonBox + accepted() + SpecifyDimensions + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SpecifyDimensions + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/qt_styleoverride.cpp b/src/qt/qt_styleoverride.cpp new file mode 100644 index 000000000..449b167aa --- /dev/null +++ b/src/qt/qt_styleoverride.cpp @@ -0,0 +1,21 @@ +#include "qt_styleoverride.hpp" + +int StyleOverride::styleHint( + StyleHint hint, + const QStyleOption *option, + const QWidget *widget, + QStyleHintReturn *returnData) const +{ + /* Disable using menu with alt key */ + if (hint == QStyle::SH_MenuBar_AltKeyNavigation) + return 0; + + return QProxyStyle::styleHint(hint, option, widget, returnData); +} + +void StyleOverride::polish(QWidget* widget) +{ + /* Disable title bar context help buttons globally as they are unused. */ + if (widget->isWindow()) + widget->setWindowFlag(Qt::WindowContextHelpButtonHint, false); +} \ No newline at end of file diff --git a/src/qt/qt_styleoverride.hpp b/src/qt/qt_styleoverride.hpp new file mode 100644 index 000000000..fa365d946 --- /dev/null +++ b/src/qt/qt_styleoverride.hpp @@ -0,0 +1,19 @@ +#ifndef QT_STYLEOVERRIDE_HPP +#define QT_STYLEOVERRIDE_HPP + +#include +#include + +class StyleOverride : public QProxyStyle +{ +public: + int styleHint( + StyleHint hint, + const QStyleOption *option = nullptr, + const QWidget *widget = nullptr, + QStyleHintReturn *returnData = nullptr) const override; + + void polish(QWidget* widget) override; +}; + +#endif \ No newline at end of file diff --git a/src/qt/qt_translations.qrc b/src/qt/qt_translations.qrc new file mode 100644 index 000000000..1de212273 --- /dev/null +++ b/src/qt/qt_translations.qrc @@ -0,0 +1,24 @@ + + + 86box_cs-CZ.qm + 86box_de-DE.qm + 86box_en-US.qm + 86box_en-GB.qm + 86box_es-ES.qm + 86box_fi-FI.qm + 86box_fr-FR.qm + 86box_hr-HR.qm + 86box_hu-HU.qm + 86box_it-IT.qm + 86box_ja-JP.qm + 86box_ko-KR.qm + 86box_pl-PL.qm + 86box_pt-BR.qm + 86box_pt-PT.qm + 86box_ru-RU.qm + 86box_sl-SI.qm + 86box_tr-TR.qm + 86box_uk-UA.qm + 86box_zh-CN.qm + + diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp new file mode 100644 index 000000000..d45fb889b --- /dev/null +++ b/src/qt/qt_ui.cpp @@ -0,0 +1,117 @@ +#include + +#include +#include +#include + +#include + +#include "qt_mainwindow.hpp" + +MainWindow* main_window = nullptr; + +extern "C" { + +#include <86box/plat.h> +#include <86box/ui.h> + +void +plat_delay_ms(uint32_t count) +{ + QThread::msleep(count); +} + +wchar_t* ui_window_title(wchar_t* str) +{ + if (str == nullptr) { + static wchar_t title[512]; + memset(title, 0, sizeof(title)); + main_window->getTitle(title); + str = title; + } else { + emit main_window->setTitle(QString::fromWCharArray(str)); + } + return str; +} + +extern "C" void qt_blit(int x, int y, int w, int h) +{ + main_window->blitToWidget(x, y, w, h); +} + +void mouse_poll() { + main_window->pollMouse(); +} + +void plat_resize(int w, int h) { + main_window->resizeContents(w, h); +} + +void plat_setfullscreen(int on) { + main_window->setFullscreen(on > 0 ? true : false); +} + +void plat_mouse_capture(int on) { + main_window->setMouseCapture(on > 0 ? true : false); +} + +int ui_msgbox_header(int flags, void *header, void* message) { + if (header <= (void*)7168) header = plat_get_string((uintptr_t)header); + if (message <= (void*)7168) message = plat_get_string((uintptr_t)message); + + auto hdr = (flags & MBX_ANSI) ? QString((char*)header) : QString::fromWCharArray(reinterpret_cast(header)); + auto msg = (flags & MBX_ANSI) ? QString((char*)message) : QString::fromWCharArray(reinterpret_cast(message)); + + // any error in early init + if (main_window == nullptr) { + QMessageBox msgBox(QMessageBox::Icon::Critical, hdr, msg); + msgBox.setTextFormat(Qt::TextFormat::RichText); + msgBox.exec(); + } else { + // else scope it to main_window + main_window->showMessage(hdr, msg); + } + return 0; +} + +int ui_msgbox(int flags, void *message) { + return ui_msgbox_header(flags, nullptr, message); +} + +void ui_sb_set_text_w(wchar_t *wstr) { + main_window->statusBar()->showMessage(QString::fromWCharArray(wstr)); +} + +void +ui_sb_update_tip(int arg) { + main_window->updateStatusBarTip(arg); +} + +void +ui_sb_update_panes() { + main_window->updateStatusBarPanes(); +} + +void ui_sb_bugui(char *str) { + main_window->statusBarMessage(str); +} + +void ui_sb_set_ready(int ready) { + qDebug() << Q_FUNC_INFO << ready; +} + +void +ui_sb_update_icon_state(int tag, int state) { + if (main_window == nullptr) { + return; + } + main_window->updateStatusBarEmpty(tag, state > 0 ? true : false); +} + +void +ui_sb_update_icon(int tag, int active) { + if (!update_icons) return; + main_window->updateStatusBarActivity(tag, active > 0 ? true : false); +} + +} diff --git a/src/qt/qt_util.cpp b/src/qt/qt_util.cpp new file mode 100644 index 000000000..3c41d6745 --- /dev/null +++ b/src/qt/qt_util.cpp @@ -0,0 +1,31 @@ +#include +#include +#include "qt_util.hpp" + +namespace util +{ + + QString DlgFilter(std::initializer_list extensions, bool last) + { + QStringList temp; + + for (auto ext : extensions) + { +#ifdef Q_OS_UNIX + if (ext == "*") + { + temp.append("*"); + continue; + } + temp.append("*." % ext.toUpper()); +#endif + temp.append("*." % ext); + } + +#ifdef Q_OS_UNIX + temp.removeDuplicates(); +#endif + return " (" % temp.join(' ') % ")" % (!last ? ";;" : ""); + } + +} \ No newline at end of file diff --git a/src/qt/qt_util.hpp b/src/qt/qt_util.hpp new file mode 100644 index 000000000..ab2284e4b --- /dev/null +++ b/src/qt/qt_util.hpp @@ -0,0 +1,14 @@ +#ifndef QT_UTIL_HPP +#define QT_UTIL_HPP + +#include + +#include + +namespace util +{ + /* Creates extension list for qt filedialog */ + QString DlgFilter(std::initializer_list extensions, bool last = false); +}; + +#endif \ No newline at end of file diff --git a/src/qt/qt_winmanagerfilter.cpp b/src/qt/qt_winmanagerfilter.cpp new file mode 100644 index 000000000..cdaa6734e --- /dev/null +++ b/src/qt/qt_winmanagerfilter.cpp @@ -0,0 +1,77 @@ +/* + * 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. + * + * Windows VM-managers native messages filter + * + * Authors: + * Teemu Korhonen + * + * Copyright 2022 Teemu Korhonen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "qt_winmanagerfilter.hpp" + +#include +#include <86box/win.h> + +bool WindowsManagerFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result) +{ + if (eventType == "windows_generic_MSG") + { + MSG *msg = static_cast(message); + + switch (msg->message) + { + case WM_SHOWSETTINGS: + emit showsettings(); + return true; + case WM_PAUSE: + emit pause(); + return true; + case WM_HARDRESET: + emit reset(); + return true; + case WM_SHUTDOWN: + emit shutdown(); + return true; + case WM_CTRLALTDEL: + emit ctrlaltdel(); + return true; + } + } + + return false; +} + +bool WindowsManagerFilter::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::WindowBlocked) + { + emit dialogstatus(1); + } + else if (event->type() == QEvent::WindowUnblocked) + { + emit dialogstatus(0); + } + + return QObject::eventFilter(obj, event); +} \ No newline at end of file diff --git a/src/qt/qt_winmanagerfilter.hpp b/src/qt/qt_winmanagerfilter.hpp new file mode 100644 index 000000000..405d84aed --- /dev/null +++ b/src/qt/qt_winmanagerfilter.hpp @@ -0,0 +1,68 @@ +/* + * 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. + * + * Header file for Windows VM-managers native messages filter + * + * Authors: + * Teemu Korhonen + * + * Copyright 2022 Teemu Korhonen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef QT_WINDOWSMANAGERFILTER_HPP +#define QT_WINDOWSMANAGERFILTER_HPP + +#include +#include +#include +#include + +#if QT_VERSION_MAJOR >= 6 +#define result_t qintptr +#else +#define result_t long +#endif + +/* + * Filters native events for messages from VM-manager and + * window blocked events to notify about open modal dialogs. + */ +class WindowsManagerFilter : public QObject, public QAbstractNativeEventFilter +{ + Q_OBJECT + +public: + bool nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) override; + +signals: + void pause(); + void ctrlaltdel(); + void showsettings(); + void reset(); + void shutdown(); + void dialogstatus(bool open); + +protected: + bool eventFilter(QObject *obj, QEvent *event) override; +}; + +#endif diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp new file mode 100644 index 000000000..59a808065 --- /dev/null +++ b/src/qt/qt_winrawinputfilter.cpp @@ -0,0 +1,423 @@ +/* + * 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. + * + * Windows raw input native filter for QT + * + * Authors: + * Teemu Korhonen + * Miran Grca, + * + * Copyright 2021 Teemu Korhonen + * Copyright 2016-2018 Miran Grca. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "qt_winrawinputfilter.hpp" + +#include + +#include + +#include <86box/keyboard.h> +#include <86box/mouse.h> +#include <86box/plat.h> +#include <86box/86box.h> + +#include +#include + +extern "C" void win_joystick_handle(PRAWINPUT); +std::unique_ptr WindowsRawInputFilter::Register(QMainWindow *window) +{ + HWND wnd = (HWND)window->winId(); + + RAWINPUTDEVICE rid[2] = + { + { + .usUsagePage = 0x01, + .usUsage = 0x06, + .dwFlags = RIDEV_NOHOTKEYS, + .hwndTarget = wnd + }, + { + .usUsagePage = 0x01, + .usUsage = 0x02, + .dwFlags = 0, + .hwndTarget = wnd + } + }; + + if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE) + return std::unique_ptr(nullptr); + + std::unique_ptr inputfilter(new WindowsRawInputFilter(window)); + + return inputfilter; +} + +WindowsRawInputFilter::WindowsRawInputFilter(QMainWindow *window) +{ + this->window = window; + + for (auto menu : window->findChildren()) + { + connect(menu, &QMenu::aboutToShow, this, [=]() { menus_open++; }); + connect(menu, &QMenu::aboutToHide, this, [=]() { menus_open--; }); + } + + for (size_t i = 0; i < sizeof(scancode_map) / sizeof(scancode_map[0]); i++) + scancode_map[i] = i; + + keyboard_getkeymap(); +} + +WindowsRawInputFilter::~WindowsRawInputFilter() +{ + RAWINPUTDEVICE rid[2] = + { + { + .usUsagePage = 0x01, + .usUsage = 0x06, + .dwFlags = RIDEV_REMOVE, + .hwndTarget = NULL + }, + { + .usUsagePage = 0x01, + .usUsage = 0x02, + .dwFlags = RIDEV_REMOVE, + .hwndTarget = NULL + } + }; + + RegisterRawInputDevices(rid, 2, sizeof(rid[0])); +} + +bool WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result) +{ + if (eventType == "windows_generic_MSG") + { + MSG *msg = static_cast(message); + + if (msg->message == WM_INPUT) + { + if (window->isActiveWindow() && menus_open == 0) + handle_input((HRAWINPUT)msg->lParam); + + return true; + } + } + + return false; +} + +void WindowsRawInputFilter::handle_input(HRAWINPUT input) +{ + UINT size = 0; + + GetRawInputData(input, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); + + std::vector buf(size); + + if (GetRawInputData(input, RID_INPUT, buf.data(), &size, sizeof(RAWINPUTHEADER)) == size) + { + PRAWINPUT raw = (PRAWINPUT)buf.data(); + + switch(raw->header.dwType) + { + case RIM_TYPEKEYBOARD: + keyboard_handle(raw); + break; + case RIM_TYPEMOUSE: + if (mouse_capture) + mouse_handle(raw); + break; + case RIM_TYPEHID: + { + win_joystick_handle(raw); + break; + } + } + } +} + +/* The following is more or less a direct copy of the old WIN32 implementation */ + +void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) +{ + USHORT scancode; + static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0; + + RAWKEYBOARD rawKB = raw->data.keyboard; + scancode = rawKB.MakeCode; + + if (kbd_req_capture && !mouse_capture && !video_fullscreen) + return; + + /* If it's not a scan code that starts with 0xE1 */ + if (!(rawKB.Flags & RI_KEY_E1)) + { + if (rawKB.Flags & RI_KEY_E0) + scancode |= 0x100; + + /* Translate the scan code to 9-bit */ + scancode = convert_scan_code(scancode); + + /* Remap it according to the list from the Registry */ + if (scancode != scancode_map[scancode]) + pclog("Scan code remap: %03X -> %03X\n", scancode, scancode); + scancode = scancode_map[scancode]; + + /* If it's not 0xFFFF, send it to the emulated + keyboard. + We use scan code 0xFFFF to mean a mapping that + has a prefix other than E0 and that is not E1 1D, + which is, for our purposes, invalid. */ + if ((scancode == 0x00F) && + !(rawKB.Flags & RI_KEY_BREAK) && + (recv_lalt || recv_ralt) && + !mouse_capture) + { + /* We received a TAB while ALT was pressed, while the mouse + is not captured, suppress the TAB and send an ALT key up. */ + if (recv_lalt) + { + keyboard_input(0, 0x038); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x038); + keyboard_input(0, 0x038); + recv_lalt = 0; + } + if (recv_ralt) + { + keyboard_input(0, 0x138); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x138); + keyboard_input(0, 0x138); + recv_ralt = 0; + } + } + else if (((scancode == 0x038) || (scancode == 0x138)) && + !(rawKB.Flags & RI_KEY_BREAK) && + recv_tab && + !mouse_capture) + { + /* We received an ALT while TAB was pressed, while the mouse + is not captured, suppress the ALT and send a TAB key up. */ + keyboard_input(0, 0x00F); + recv_tab = 0; + } + else + { + switch (scancode) + { + case 0x00F: + recv_tab = !(rawKB.Flags & RI_KEY_BREAK); + break; + case 0x038: + recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); + break; + case 0x138: + recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); + break; + } + + /* Translate right CTRL to left ALT if the user has so + chosen. */ + if ((scancode == 0x11D) && rctrl_is_lalt) + scancode = 0x038; + + /* Normal scan code pass through, pass it through as is if + it's not an invalid scan code. */ + if (scancode != 0xFFFF) + keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); + } + } + else + { + if (rawKB.MakeCode == 0x1D) + { + scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would + otherwise be E0 00 but that is invalid + anyway). + Also, take a potential mapping into + account. */ + } + else + scancode = 0xFFFF; + if (scancode != 0xFFFF) + keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); + } +} + +/* This is so we can disambiguate scan codes that would otherwise conflict and get + passed on incorrectly. */ +UINT16 WindowsRawInputFilter::convert_scan_code(UINT16 scan_code) +{ + if ((scan_code & 0xff00) == 0xe000) + scan_code = (scan_code & 0xff) | 0x0100; + + if (scan_code == 0xE11D) + scan_code = 0x0100; + /* E0 00 is sent by some USB keyboards for their special keys, as it is an + invalid scan code (it has no untranslated set 2 equivalent), we mark it + appropriately so it does not get passed through. */ + else if ((scan_code > 0x01FF) || (scan_code == 0x0100)) + scan_code = 0xFFFF; + + return scan_code; +} + +void WindowsRawInputFilter::keyboard_getkeymap() +{ + const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + const LPCSTR valueName = "Scancode Map"; + unsigned char buf[32768]; + DWORD bufSize; + HKEY hKey; + int j; + UINT32 *bufEx2; + int scMapCount; + UINT16 *bufEx; + int scancode_unmapped; + int scancode_mapped; + + /* First, prepare the default scan code map list which is 1:1. + * Remappings will be inserted directly into it. + * 512 bytes so this takes less memory, bit 9 set means E0 + * prefix. + */ + for (j = 0; j < 512; j++) + scancode_map[j] = j; + + /* Get the scan code remappings from: + HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ + bufSize = 32768; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) + { + if (RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) + { + bufEx2 = (UINT32 *)buf; + scMapCount = bufEx2[2]; + if ((bufSize != 0) && (scMapCount != 0)) + { + bufEx = (UINT16 *)(buf + 12); + for (j = 0; j < scMapCount * 2; j += 2) + { + /* Each scan code is 32-bit: 16 bits of remapped scan code, + and 16 bits of original scan code. */ + scancode_unmapped = bufEx[j + 1]; + scancode_mapped = bufEx[j]; + + scancode_unmapped = convert_scan_code(scancode_unmapped); + scancode_mapped = convert_scan_code(scancode_mapped); + + /* Ignore source scan codes with prefixes other than E1 + that are not E1 1D. */ + if (scancode_unmapped != 0xFFFF) + scancode_map[scancode_unmapped] = scancode_mapped; + } + } + } + RegCloseKey(hKey); + } +} + +void WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) +{ + RAWMOUSE state = raw->data.mouse; + static int x, y; + + /* read mouse buttons and wheel */ + if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) + buttons |= 1; + else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) + buttons &= ~1; + + if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) + buttons |= 4; + else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) + buttons &= ~4; + + if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) + buttons |= 2; + else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) + buttons &= ~2; + + if (state.usButtonFlags & RI_MOUSE_WHEEL) + { + dwheel += (SHORT)state.usButtonData / 120; + } + + if (state.usFlags & MOUSE_MOVE_ABSOLUTE) + { + /* absolute mouse, i.e. RDP or VNC + * seems to work fine for RDP on Windows 10 + * Not sure about other environments. + */ + dx += (state.lLastX - x) / 25; + dy += (state.lLastY - y) / 25; + x = state.lLastX; + y = state.lLastY; + } + else + { + /* relative mouse, i.e. regular mouse */ + dx += state.lLastX; + dy += state.lLastY; + } + HWND wnd = (HWND)window->winId(); + + RECT rect; + + GetWindowRect(wnd, &rect); + + int left = rect.left + (rect.right - rect.left) / 2; + int top = rect.top + (rect.bottom - rect.top) / 2; + + SetCursorPos(left, top); +} + +void WindowsRawInputFilter::mousePoll() +{ + if (mouse_capture || video_fullscreen) + { + static int b = 0; + + if (dx != 0 || dy != 0 || dwheel != 0) + { + mouse_x += dx; + mouse_y += dy; + mouse_z = dwheel; + + dx = 0; + dy = 0; + dwheel = 0; + } + + if (b != buttons) + { + mouse_buttons = buttons; + b = buttons; + } + } +} diff --git a/src/qt/qt_winrawinputfilter.hpp b/src/qt/qt_winrawinputfilter.hpp new file mode 100644 index 000000000..7a73a2eca --- /dev/null +++ b/src/qt/qt_winrawinputfilter.hpp @@ -0,0 +1,82 @@ +/* + * 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. + * + * Header file for windows raw input native filter for QT + * + * Authors: + * Teemu Korhonen + * + * Copyright 2021 Teemu Korhonen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef QT_WINDOWSRAWINPUTFILTER_HPP +#define QT_WINDOWSRAWINPUTFILTER_HPP + +#include +#include +#include +#include + +#include + +#include + +#if QT_VERSION_MAJOR >= 6 +#define result_t qintptr +#else +#define result_t long +#endif + + +class WindowsRawInputFilter : public QObject, public QAbstractNativeEventFilter +{ + Q_OBJECT + +public: + static std::unique_ptr Register(QMainWindow *window); + + bool nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) override; + + ~WindowsRawInputFilter(); + +public slots: + void mousePoll(); + +private: + QMainWindow *window; + uint16_t scancode_map[768]; + int buttons = 0; + int dx = 0; + int dy = 0; + int dwheel = 0; + int menus_open = 0; + + WindowsRawInputFilter(QMainWindow *window); + + void handle_input(HRAWINPUT input); + void keyboard_handle(PRAWINPUT raw); + void mouse_handle(PRAWINPUT raw); + static UINT16 convert_scan_code(UINT16 scan_code); + void keyboard_getkeymap(); +}; + +#endif diff --git a/src/qt/sdl_joystick.cpp b/src/qt/sdl_joystick.cpp new file mode 100644 index 000000000..0e7bfd619 --- /dev/null +++ b/src/qt/sdl_joystick.cpp @@ -0,0 +1,167 @@ +// Lifted from wx-sdl2-joystick.c in PCem + +#include + +#include + +extern "C" { +#include <86box/device.h> +#include <86box/gameport.h> + +int joysticks_present; +joystick_t joystick_state[MAX_JOYSTICKS]; +plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS]; +} + +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +void joystick_init() { + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) { + return; + } + joysticks_present = SDL_NumJoysticks(); + + memset(sdl_joy, 0, sizeof(sdl_joy)); + for (int c = 0; c < joysticks_present; c++) + { + sdl_joy[c] = SDL_JoystickOpen(c); + + if (sdl_joy[c]) + { + int d; + + strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64); + plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]); + plat_joystick_state[c].nr_buttons = SDL_JoystickNumButtons(sdl_joy[c]); + plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); + + for (d = 0; d < std::min(plat_joystick_state[c].nr_axes, 8); d++) + { + sprintf(plat_joystick_state[c].axis[d].name, "Axis %i", d); + plat_joystick_state[c].axis[d].id = d; + } + for (d = 0; d < std::min(plat_joystick_state[c].nr_buttons, 8); d++) + { + sprintf(plat_joystick_state[c].button[d].name, "Button %i", d); + plat_joystick_state[c].button[d].id = d; + } + for (d = 0; d < std::min(plat_joystick_state[c].nr_povs, 4); d++) + { + sprintf(plat_joystick_state[c].pov[d].name, "POV %i", d); + plat_joystick_state[c].pov[d].id = d; + } + } + } +} + +void joystick_close() +{ + int c; + + for (c = 0; c < joysticks_present; c++) + { + if (sdl_joy[c]) + SDL_JoystickClose(sdl_joy[c]); + } +} + +static int joystick_get_axis(int joystick_nr, int mapping) +{ + if (mapping & POV_X) + { + switch (plat_joystick_state[joystick_nr].p[mapping & 3]) + { + case SDL_HAT_LEFTUP: case SDL_HAT_LEFT: case SDL_HAT_LEFTDOWN: + return -32767; + + case SDL_HAT_RIGHTUP: case SDL_HAT_RIGHT: case SDL_HAT_RIGHTDOWN: + return 32767; + + default: + return 0; + } + } + else if (mapping & POV_Y) + { + switch (plat_joystick_state[joystick_nr].p[mapping & 3]) + { + case SDL_HAT_LEFTUP: case SDL_HAT_UP: case SDL_HAT_RIGHTUP: + return -32767; + + case SDL_HAT_LEFTDOWN: case SDL_HAT_DOWN: case SDL_HAT_RIGHTDOWN: + return 32767; + + default: + return 0; + } + } + else + return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; +} +void joystick_process() +{ + int c, d; + + SDL_JoystickUpdate(); + for (c = 0; c < joysticks_present; c++) + { + int b; + + plat_joystick_state[c].a[0] = SDL_JoystickGetAxis(sdl_joy[c], 0); + plat_joystick_state[c].a[1] = SDL_JoystickGetAxis(sdl_joy[c], 1); + plat_joystick_state[c].a[2] = SDL_JoystickGetAxis(sdl_joy[c], 2); + plat_joystick_state[c].a[3] = SDL_JoystickGetAxis(sdl_joy[c], 3); + plat_joystick_state[c].a[4] = SDL_JoystickGetAxis(sdl_joy[c], 4); + plat_joystick_state[c].a[5] = SDL_JoystickGetAxis(sdl_joy[c], 5); + + for (b = 0; b < 16; b++) + plat_joystick_state[c].b[b] = SDL_JoystickGetButton(sdl_joy[c], b); + + for (b = 0; b < 4; b++) + plat_joystick_state[c].p[b] = SDL_JoystickGetHat(sdl_joy[c], b); + // pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); + } + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + if (joystick_state[c].plat_joystick_nr) + { + int joystick_nr = joystick_state[c].plat_joystick_nr - 1; + + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + int x, y; + double angle, magnitude; + + x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); + y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); + + angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI); + magnitude = sqrt((double)x*(double)x + (double)y*(double)y); + + if (magnitude < 16384) + joystick_state[c].pov[d] = -1; + else + joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360; + } + } + else + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = 0; + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = 0; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + joystick_state[c].pov[d] = -1; + } + } +} diff --git a/src/qt/win_joystick_rawinput.c b/src/qt/win_joystick_rawinput.c new file mode 100644 index 000000000..be808fc47 --- /dev/null +++ b/src/qt/win_joystick_rawinput.c @@ -0,0 +1,471 @@ +/* + * 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. + * + * RawInput joystick interface. + * + * Authors: Sarah Walker, + * Miran Grca, + * GH Cao, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * Copyright 2020 GH Cao. + */ +#include +#include +#include +#include +#include +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/plat.h> +#include <86box/gameport.h> +#include <86box/win.h> + +#ifdef ENABLE_JOYSTICK_LOG +int joystick_do_log = ENABLE_JOYSTICK_LOG; + + +static void +joystick_log(const char *fmt, ...) +{ + va_list ap; + + if (joystick_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define joystick_log(fmt, ...) +#endif + +typedef struct { + HANDLE hdevice; + PHIDP_PREPARSED_DATA data; + + USAGE usage_button[256]; + + struct raw_axis_t { + USAGE usage; + USHORT link; + USHORT bitsize; + LONG max; + LONG min; + } axis[8]; + + struct raw_pov_t { + USAGE usage; + USHORT link; + LONG max; + LONG min; + } pov[4]; +} raw_joystick_t; + +plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +joystick_t joystick_state[MAX_JOYSTICKS]; +int joysticks_present = 0; + +raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; + +/* We only use the first 32 buttons reported, from Usage ID 1-128 */ +void joystick_add_button(raw_joystick_t* rawjoy, plat_joystick_t* joy, USAGE usage) { + if (joy->nr_buttons >= 32) return; + if (usage < 1 || usage > 128) return; + + rawjoy->usage_button[usage] = joy->nr_buttons; + sprintf(joy->button[joy->nr_buttons].name, "Button %d", usage); + joy->nr_buttons++; +} + +void joystick_add_axis(raw_joystick_t* rawjoy, plat_joystick_t* joy, PHIDP_VALUE_CAPS prop) { + if (joy->nr_axes >= 8) return; + + switch (prop->Range.UsageMin) { + case HID_USAGE_GENERIC_X: + sprintf(joy->axis[joy->nr_axes].name, "X"); + break; + case HID_USAGE_GENERIC_Y: + sprintf(joy->axis[joy->nr_axes].name, "Y"); + break; + case HID_USAGE_GENERIC_Z: + sprintf(joy->axis[joy->nr_axes].name, "Z"); + break; + case HID_USAGE_GENERIC_RX: + sprintf(joy->axis[joy->nr_axes].name, "RX"); + break; + case HID_USAGE_GENERIC_RY: + sprintf(joy->axis[joy->nr_axes].name, "RY"); + break; + case HID_USAGE_GENERIC_RZ: + sprintf(joy->axis[joy->nr_axes].name, "RZ"); + break; + default: + return; + } + + joy->axis[joy->nr_axes].id = joy->nr_axes; + rawjoy->axis[joy->nr_axes].usage = prop->Range.UsageMin; + rawjoy->axis[joy->nr_axes].link = prop->LinkCollection; + rawjoy->axis[joy->nr_axes].bitsize = prop->BitSize; + + /* Assume unsigned when min >= 0 */ + if (prop->LogicalMin < 0) { + rawjoy->axis[joy->nr_axes].max = prop->LogicalMax; + } else { + /* + * Some joysticks will send -1 in LogicalMax, like Xbox Controllers + * so we need to mask that to appropriate value (instead of 0xFFFFFFFF) + */ + rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1 << prop->BitSize) - 1); + } + rawjoy->axis[joy->nr_axes].min = prop->LogicalMin; + + joy->nr_axes++; +} + +void joystick_add_pov(raw_joystick_t* rawjoy, plat_joystick_t* joy, PHIDP_VALUE_CAPS prop) { + if (joy->nr_povs >= 4) return; + + sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs+1); + rawjoy->pov[joy->nr_povs].usage = prop->Range.UsageMin; + rawjoy->pov[joy->nr_povs].link = prop->LinkCollection; + rawjoy->pov[joy->nr_povs].min = prop->LogicalMin; + rawjoy->pov[joy->nr_povs].max = prop->LogicalMax; + + joy->nr_povs++; +} + +void joystick_get_capabilities(raw_joystick_t* rawjoy, plat_joystick_t* joy) { + UINT size = 0; + PHIDP_BUTTON_CAPS btn_caps = NULL; + PHIDP_VALUE_CAPS val_caps = NULL; + + /* Get preparsed data (HID data format) */ + GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, NULL, &size); + rawjoy->data = malloc(size); + if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, rawjoy->data, &size) <= 0) + fatal("joystick_get_capabilities: Failed to get preparsed data.\n"); + + HIDP_CAPS caps; + HidP_GetCaps(rawjoy->data, &caps); + + /* Buttons */ + if (caps.NumberInputButtonCaps > 0) { + btn_caps = calloc(caps.NumberInputButtonCaps, sizeof(HIDP_BUTTON_CAPS)); + if (HidP_GetButtonCaps(HidP_Input, btn_caps, &caps.NumberInputButtonCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { + joystick_log("joystick_get_capabilities: Failed to query input buttons.\n"); + goto end; + } + /* We only detect generic stuff */ + for (int c=0; c 0) { + val_caps = calloc(caps.NumberInputValueCaps, sizeof(HIDP_VALUE_CAPS)); + if (HidP_GetValueCaps(HidP_Input, val_caps, &caps.NumberInputValueCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { + joystick_log("joystick_get_capabilities: Failed to query axes and povs.\n"); + goto end; + } + /* We only detect generic stuff */ + for (int c=0; chdevice, RIDI_DEVICENAME, device_name, &size); + device_name = calloc(size, sizeof(char)); + if (GetRawInputDeviceInfoA(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size) <= 0) + fatal("joystick_get_capabilities: Failed to get device name.\n"); + + HANDLE hDevObj = CreateFile(device_name, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (hDevObj) { + HidD_GetProductString(hDevObj, device_desc_wide, sizeof(WCHAR) * 200); + CloseHandle(hDevObj); + } + free(device_name); + + int result = WideCharToMultiByte(CP_ACP, 0, device_desc_wide, 200, joy->name, 260, NULL, NULL); + if (result == 0 || strlen(joy->name) == 0) + sprintf(joy->name, + "RawInput %s, VID:%04lX PID:%04lX", + info->hid.usUsage == HID_USAGE_GENERIC_JOYSTICK ? "Joystick" : "Gamepad", + info->hid.dwVendorId, + info->hid.dwProductId); +} + +void joystick_init() +{ + UINT size = 0; + atexit(joystick_close); + + joysticks_present = 0; + memset(raw_joystick_state, 0, sizeof(raw_joystick_t) * MAX_PLAT_JOYSTICKS); + + /* Get a list of raw input devices from Windows */ + UINT raw_devices = 0; + GetRawInputDeviceList(NULL, &raw_devices, sizeof(RAWINPUTDEVICELIST)); + PRAWINPUTDEVICELIST deviceList = calloc(raw_devices, sizeof(RAWINPUTDEVICELIST)); + GetRawInputDeviceList(deviceList, &raw_devices, sizeof(RAWINPUTDEVICELIST)); + + for (int i=0; i= MAX_PLAT_JOYSTICKS) break; + if (deviceList[i].dwType != RIM_TYPEHID) continue; + + /* Get device info: hardware IDs and usage IDs */ + GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, NULL, &size); + info = malloc(size); + info->cbSize = sizeof(RID_DEVICE_INFO); + if (GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, info, &size) <= 0) + goto end_loop; + + /* If this is not a joystick/gamepad, skip */ + if (info->hid.usUsagePage != HID_USAGE_PAGE_GENERIC) goto end_loop; + if (info->hid.usUsage != HID_USAGE_GENERIC_JOYSTICK && + info->hid.usUsage != HID_USAGE_GENERIC_GAMEPAD) goto end_loop; + + plat_joystick_t *joy = &plat_joystick_state[joysticks_present]; + raw_joystick_t *rawjoy = &raw_joystick_state[joysticks_present]; + rawjoy->hdevice = deviceList[i].hDevice; + + joystick_get_capabilities(rawjoy, joy); + joystick_get_device_name(rawjoy, joy, info); + + joystick_log("joystick_init: %s - %d buttons, %d axes, %d POVs\n", + joy->name, joy->nr_buttons, joy->nr_axes, joy->nr_povs); + + joysticks_present++; + + end_loop: + free(info); + } + + joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present); + + /* Initialize the RawInput (joystick and gamepad) module. */ + RAWINPUTDEVICE ridev[2]; + ridev[0].dwFlags = 0; + ridev[0].hwndTarget = NULL; + ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; + ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; + + ridev[1].dwFlags = 0; + ridev[1].hwndTarget = NULL; + ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; + ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; + + if (!RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE))) + fatal("plat_joystick_init: RegisterRawInputDevices failed\n"); +} + +void joystick_close() +{ + RAWINPUTDEVICE ridev[2]; + ridev[0].dwFlags = RIDEV_REMOVE; + ridev[0].hwndTarget = NULL; + ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; + ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; + + ridev[1].dwFlags = RIDEV_REMOVE; + ridev[1].hwndTarget = NULL; + ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; + ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; + + RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE)); +} + + +void win_joystick_handle(PRAWINPUT raw) +{ + HRESULT r; + int j = -1; /* current joystick index, -1 when not found */ + + /* If the input is not from a known device, we ignore it */ + for (int i=0; iheader.hDevice) { + j = i; + break; + } + } + if (j == -1) return; + + /* Read buttons */ + USAGE usage_list[128] = {0}; + ULONG usage_length = plat_joystick_state[j].nr_buttons; + memset(plat_joystick_state[j].b, 0, 32 * sizeof(int)); + + r = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usage_list, &usage_length, + raw_joystick_state[j].data, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid); + + if (r == HIDP_STATUS_SUCCESS) { + for (int i=0; imax - axis->min + 1) / 2; + + r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue, + raw_joystick_state[j].data, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid); + + if (r == HIDP_STATUS_SUCCESS) { + if (axis->min < 0) { + /* extend signed uvalue to LONG */ + if (uvalue & (1 << (axis->bitsize-1))) { + ULONG mask = (1 << axis->bitsize) - 1; + value = -1U ^ mask; + value |= uvalue; + } else { + value = uvalue; + } + } else { + /* Assume unsigned when min >= 0, convert to a signed value */ + value = (LONG)uvalue - center; + } + if (abs(value) == 1) value = 0; + value = value * 32768 / center; + } + + plat_joystick_state[j].a[a] = value; + //joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); + } + + /* read povs */ + for (int p=0; plink, pov->usage, &uvalue, + raw_joystick_state[j].data, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid); + + if (r == HIDP_STATUS_SUCCESS && (uvalue >= pov->min && uvalue <= pov->max)) { + value = (uvalue - pov->min) * 36000; + value /= (pov->max - pov->min + 1); + value %= 36000; + } + + plat_joystick_state[j].p[p] = value; + + //joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); + + } + //joystick_log("\n"); +} + + +static int joystick_get_axis(int joystick_nr, int mapping) +{ + if (mapping & POV_X) + { + int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + if (LOWORD(pov) == 0xFFFF) + return 0; + else + return sin((2*M_PI * (double)pov) / 36000.0) * 32767; + } + else if (mapping & POV_Y) + { + int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + + if (LOWORD(pov) == 0xFFFF) + return 0; + else + return -cos((2*M_PI * (double)pov) / 36000.0) * 32767; + } + else + return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; + +} + + +void joystick_process(void) +{ + int c, d; + + if (joystick_type == 7) return; + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + if (joystick_state[c].plat_joystick_nr) + { + int joystick_nr = joystick_state[c].plat_joystick_nr - 1; + + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; + + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + int x, y; + double angle, magnitude; + + x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); + y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); + + angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI); + magnitude = sqrt((double)x*(double)x + (double)y*(double)y); + + if (magnitude < 16384) + joystick_state[c].pov[d] = -1; + else + joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360; + } + } + else + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = 0; + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = 0; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + joystick_state[c].pov[d] = -1; + } + } +} + diff --git a/src/qt/wl_mouse.cpp b/src/qt/wl_mouse.cpp new file mode 100644 index 000000000..b399dafd7 --- /dev/null +++ b/src/qt/wl_mouse.cpp @@ -0,0 +1,89 @@ +#include "wl_mouse.hpp" +#include +#include +#include +#include +#include + +#include +#include +#include + +static zwp_relative_pointer_manager_v1* rel_manager = nullptr; +static zwp_relative_pointer_v1* rel_pointer = nullptr; +static zwp_pointer_constraints_v1* conf_pointer_interface = nullptr; +static zwp_locked_pointer_v1* conf_pointer = nullptr; + +static int rel_mouse_x = 0, rel_mouse_y = 0; + +void rel_mouse_event(void* data, zwp_relative_pointer_v1* zwp_relative_pointer_v1, uint32_t tstmp, uint32_t tstmpl, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_real, wl_fixed_t dy_real) +{ + rel_mouse_x += wl_fixed_to_int(dx_real); + rel_mouse_y += wl_fixed_to_int(dy_real); +} + +extern "C" +{ + extern int mouse_x, mouse_y; +} + +void wl_mouse_poll() +{ + mouse_x = rel_mouse_x; + mouse_y = rel_mouse_y; + rel_mouse_x = 0; + rel_mouse_y = 0; +} + +static struct zwp_relative_pointer_v1_listener rel_listener = +{ + rel_mouse_event +}; + +static void +display_handle_global(void *data, struct wl_registry *registry, uint32_t id, + const char *interface, uint32_t version) +{ + if (!strcmp(interface, "zwp_relative_pointer_manager_v1")) + { + rel_manager = (zwp_relative_pointer_manager_v1*)wl_registry_bind(registry, id, &zwp_relative_pointer_manager_v1_interface, version); + } + if (!strcmp(interface, "zwp_pointer_constraints_v1")) + { + conf_pointer_interface = (zwp_pointer_constraints_v1*)wl_registry_bind(registry, id, &zwp_pointer_constraints_v1_interface, version); + } +} + +static const struct wl_registry_listener registry_listener = { + display_handle_global, + nullptr +}; + +void wl_init() +{ + wl_display* display = (wl_display*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display"); + if (display) + { + auto registry = wl_display_get_registry(display); + if (registry) + { + wl_registry_add_listener(registry, ®istry_listener, nullptr); + wl_display_roundtrip(display); + } + } +} + +void wl_mouse_capture(QWindow *window) +{ + rel_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(rel_manager, (wl_pointer*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer")); + zwp_relative_pointer_v1_add_listener(rel_pointer, &rel_listener, nullptr); + conf_pointer = zwp_pointer_constraints_v1_lock_pointer(conf_pointer_interface, (wl_surface*)QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window), (wl_pointer*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer"), nullptr, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); +} + +void wl_mouse_uncapture() +{ + zwp_locked_pointer_v1_destroy(conf_pointer); + zwp_relative_pointer_v1_destroy(rel_pointer); + rel_pointer = nullptr; + conf_pointer = nullptr; +} \ No newline at end of file diff --git a/src/qt/wl_mouse.hpp b/src/qt/wl_mouse.hpp new file mode 100644 index 000000000..73e81c208 --- /dev/null +++ b/src/qt/wl_mouse.hpp @@ -0,0 +1,5 @@ +class QWindow; +void wl_mouse_capture(QWindow* window); +void wl_mouse_uncapture(); +void wl_mouse_poll(); +void wl_init(); \ No newline at end of file diff --git a/src/qt_resources.qrc b/src/qt_resources.qrc new file mode 100644 index 000000000..045c3659d --- /dev/null +++ b/src/qt_resources.qrc @@ -0,0 +1,60 @@ + + + win/icons/cartridge.ico + win/icons/cartridge_empty.ico + win/icons/cassette.ico + win/icons/cassette_active.ico + win/icons/cassette_empty.ico + win/icons/cassette_empty_active.ico + win/icons/cdrom.ico + win/icons/cdrom_active.ico + win/icons/cdrom_disabled.ico + win/icons/cdrom_empty.ico + win/icons/cdrom_empty_active.ico + win/icons/display.ico + win/icons/floppy_35.ico + win/icons/floppy_35_active.ico + win/icons/floppy_35_empty.ico + win/icons/floppy_35_empty_active.ico + win/icons/floppy_525.ico + win/icons/floppy_525_active.ico + win/icons/floppy_525_empty.ico + win/icons/floppy_525_empty_active.ico + win/icons/floppy_and_cdrom_drives.ico + win/icons/floppy_disabled.ico + win/icons/hard_disk.ico + win/icons/hard_disk_active.ico + win/icons/input_devices.ico + win/icons/machine.ico + win/icons/mo.ico + win/icons/mo_active.ico + win/icons/mo_disabled.ico + win/icons/mo_empty.ico + win/icons/mo_empty_active.ico + win/icons/network.ico + win/icons/network_active.ico + win/icons/other_peripherals.ico + win/icons/other_removable_devices.ico + win/icons/ports.ico + win/icons/sound.ico + win/icons/storage_controllers.ico + win/icons/zip.ico + win/icons/zip_active.ico + win/icons/zip_disabled.ico + win/icons/zip_empty.ico + win/icons/zip_empty_active.ico + win/icons/86Box-gray.ico + win/icons/86Box-green.ico + win/icons/86Box-red.ico + win/icons/86Box-yellow.ico + + + win/icons/acpi_shutdown.ico + win/icons/hard_reset.ico + win/icons/pause.ico + win/icons/run.ico + win/icons/send_cad.ico + win/icons/send_cae.ico + win/icons/settings.ico + + diff --git a/src/win/86Box-qt.rc b/src/win/86Box-qt.rc new file mode 100644 index 000000000..0d4d8158f --- /dev/null +++ b/src/win/86Box-qt.rc @@ -0,0 +1,123 @@ +/* + * 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. + * + * Application resource script for Windows. + * + * Authors: Miran Grca, + * Fred N. van Kempen, + * David Hrdlička, + * + * Copyright 2016-2019 Miran Grca. + * Copyright 2018,2019 David Hrdlička. + * Copyright 2021 Laci bá' + */ +#define IN_RESOURCE_H +#include <86box/version.h> +#undef IN_RESOURCE_H + +#define APSTUDIO_READONLY_SYMBOLS +#define APSTUDIO_HIDDEN_SYMBOLS +#include +#undef APSTUDIO_HIDDEN_SYMBOLS +#undef APSTUDIO_READONLY_SYMBOLS + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) + +#ifndef NO_INCLUDE_MANIFEST +///////////////////////////////////////////////////////////////////////////// +// +// 24 +// + +1 24 MOVEABLE PURE "86Box.manifest" +#endif + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +#ifdef CMAKE +#define ICON_PATH +#else +#define ICON_PATH "win/" +#endif + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +// defining the icons depending on the build status +#ifdef RELEASE_BUILD +/* Icon by OBattler and laciba96 (green for release builds)*/ + 10 ICON DISCARDABLE ICON_PATH "icons/86Box-green.ico" +#elif BETA_BUILD +/* Icon by OBattler and laciba96 (yellow for beta builds done by Jenkins)*/ + 10 ICON DISCARDABLE ICON_PATH "icons/86Box-yellow.ico" +#elif ALPHA_BUILD +/* Icon by OBattler and laciba96 (red for alpha builds done by Jenkins)*/ + 10 ICON DISCARDABLE ICON_PATH "icons/86Box-red.ico" +#else +/* Icon by OBattler and laciba96 (gray for builds of branches and from the git master)*/ + 10 ICON DISCARDABLE ICON_PATH "icons/86Box-gray.ico" +#endif + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION EMU_VERSION_MAJ,EMU_VERSION_MIN,EMU_VERSION_PATCH,EMU_BUILD_NUM + PRODUCTVERSION EMU_VERSION_MAJ,EMU_VERSION_MIN,EMU_VERSION_PATCH,EMU_BUILD_NUM + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", EMU_NAME "\0" + VALUE "FileDescription", EMU_NAME "\0" + VALUE "FileVersion", EMU_VERSION "\0" + VALUE "InternalName", EMU_NAME "\0" + VALUE "LegalCopyright", "Copyright \xa9 2007-" COPYRIGHT_YEAR " " EMU_NAME " contributors\0" + VALUE "OriginalFilename", EMU_NAME ".exe\0" + VALUE "ProductName", EMU_NAME "\0" + VALUE "ProductVersion", EMU_VERSION "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +#endif + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index 0d1fb00cc..0e8300946 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -20,7 +20,7 @@ add_library(plat OBJECT win.c win_dynld.c win_cdrom.c win_keyboard.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 - win_jsconf.c win_media_menu.c win_preferences.c win_discord.c glad.c win_opengl.c + win_jsconf.c win_media_menu.c win_preferences.c glad.c win_opengl.c win_opengl_glslp.c win_toolbar.c 86Box.rc) if(NOT CPPTHREADS) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index cfcef28ab..4362273e7 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -717,7 +717,7 @@ PLATOBJ := win.o \ win_crashdump.o \ win_mouse.o -UIOBJ := win_ui.o win_icon.o win_stbar.o win_discord.o \ +UIOBJ := win_ui.o win_icon.o win_stbar.o discord.o \ win_sdl.o win_opengl.o win_opengl_glslp.o glad.o \ win_dialog.o win_about.o \ win_settings.o win_devconf.o win_snd_gain.o win_specify_dim.o win_preferences.o \ diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc index 6d5907bcc..cc1f9aebb 100644 --- a/src/win/languages/hu-HU.rc +++ b/src/win/languages/hu-HU.rc @@ -4,7 +4,7 @@ // Translated by Laci bá', 2021 // -#define TRANSLATORS_NAME "Laci bá'" +//#define TRANSLATORS_NAME "Laci bá'" #ifdef _WIN32 LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 92fccd1c3..701a306e3 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -43,7 +43,7 @@ #include <86box/ui.h> #include <86box/win.h> #include <86box/version.h> -# include <86box/win_discord.h> +#include <86box/discord.h> #ifdef MTR_ENABLED #include diff --git a/vcpkg.json b/vcpkg.json index cbd8a31ca..f4e78d8e7 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -3,12 +3,21 @@ "version-string": "3.1", "homepage": "https://86box.net/", "documentation": "http://86box.readthedocs.io/", - "license": "GPL-2.0-only", + "license": "GPL-2.0-or-later", "dependencies": [ "freetype", "libpng", "openal-soft", "sdl2", "rtmidi" - ] -} \ No newline at end of file + ], + "features": { + "qt-ui": { + "description": "Qt User Interface", + "dependencies": [ + "qt5-base", + "qt5-translations" + ] + } + } +} diff --git a/wl_protocols/pointer-constraints-unstable-v1.xml b/wl_protocols/pointer-constraints-unstable-v1.xml new file mode 100644 index 000000000..efd64b660 --- /dev/null +++ b/wl_protocols/pointer-constraints-unstable-v1.xml @@ -0,0 +1,339 @@ + + + + + Copyright © 2014 Jonas Ådahl + Copyright © 2015 Red Hat Inc. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol specifies a set of interfaces used for adding constraints to + the motion of a pointer. Possible constraints include confining pointer + motions to a given region, or locking it to its current position. + + In order to constrain the pointer, a client must first bind the global + interface "wp_pointer_constraints" which, if a compositor supports pointer + constraints, is exposed by the registry. Using the bound global object, the + client uses the request that corresponds to the type of constraint it wants + to make. See wp_pointer_constraints for more details. + + Warning! The protocol described in this file is experimental and backward + incompatible changes may be made. Backward compatible changes may be added + together with the corresponding interface version bump. Backward + incompatible changes are done by bumping the version number in the protocol + and interface names and resetting the interface version. Once the protocol + is to be declared stable, the 'z' prefix and the version number in the + protocol and interface names are removed and the interface version number is + reset. + + + + + The global interface exposing pointer constraining functionality. It + exposes two requests: lock_pointer for locking the pointer to its + position, and confine_pointer for locking the pointer to a region. + + The lock_pointer and confine_pointer requests create the objects + wp_locked_pointer and wp_confined_pointer respectively, and the client can + use these objects to interact with the lock. + + For any surface, only one lock or confinement may be active across all + wl_pointer objects of the same seat. If a lock or confinement is requested + when another lock or confinement is active or requested on the same surface + and with any of the wl_pointer objects of the same seat, an + 'already_constrained' error will be raised. + + + + + These errors can be emitted in response to wp_pointer_constraints + requests. + + + + + + + These values represent different lifetime semantics. They are passed + as arguments to the factory requests to specify how the constraint + lifetimes should be managed. + + + + A oneshot pointer constraint will never reactivate once it has been + deactivated. See the corresponding deactivation event + (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for + details. + + + + + A persistent pointer constraint may again reactivate once it has + been deactivated. See the corresponding deactivation event + (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for + details. + + + + + + + Used by the client to notify the server that it will no longer use this + pointer constraints object. + + + + + + The lock_pointer request lets the client request to disable movements of + the virtual pointer (i.e. the cursor), effectively locking the pointer + to a position. This request may not take effect immediately; in the + future, when the compositor deems implementation-specific constraints + are satisfied, the pointer lock will be activated and the compositor + sends a locked event. + + The protocol provides no guarantee that the constraints are ever + satisfied, and does not require the compositor to send an error if the + constraints cannot ever be satisfied. It is thus possible to request a + lock that will never activate. + + There may not be another pointer constraint of any kind requested or + active on the surface for any of the wl_pointer objects of the seat of + the passed pointer when requesting a lock. If there is, an error will be + raised. See general pointer lock documentation for more details. + + The intersection of the region passed with this request and the input + region of the surface is used to determine where the pointer must be + in order for the lock to activate. It is up to the compositor whether to + warp the pointer or require some kind of user interaction for the lock + to activate. If the region is null the surface input region is used. + + A surface may receive pointer focus without the lock being activated. + + The request creates a new object wp_locked_pointer which is used to + interact with the lock as well as receive updates about its state. See + the the description of wp_locked_pointer for further information. + + Note that while a pointer is locked, the wl_pointer objects of the + corresponding seat will not emit any wl_pointer.motion events, but + relative motion events will still be emitted via wp_relative_pointer + objects of the same seat. wl_pointer.axis and wl_pointer.button events + are unaffected. + + + + + + + + + + + The confine_pointer request lets the client request to confine the + pointer cursor to a given region. This request may not take effect + immediately; in the future, when the compositor deems implementation- + specific constraints are satisfied, the pointer confinement will be + activated and the compositor sends a confined event. + + The intersection of the region passed with this request and the input + region of the surface is used to determine where the pointer must be + in order for the confinement to activate. It is up to the compositor + whether to warp the pointer or require some kind of user interaction for + the confinement to activate. If the region is null the surface input + region is used. + + The request will create a new object wp_confined_pointer which is used + to interact with the confinement as well as receive updates about its + state. See the the description of wp_confined_pointer for further + information. + + + + + + + + + + + + The wp_locked_pointer interface represents a locked pointer state. + + While the lock of this object is active, the wl_pointer objects of the + associated seat will not emit any wl_pointer.motion events. + + This object will send the event 'locked' when the lock is activated. + Whenever the lock is activated, it is guaranteed that the locked surface + will already have received pointer focus and that the pointer will be + within the region passed to the request creating this object. + + To unlock the pointer, send the destroy request. This will also destroy + the wp_locked_pointer object. + + If the compositor decides to unlock the pointer the unlocked event is + sent. See wp_locked_pointer.unlock for details. + + When unlocking, the compositor may warp the cursor position to the set + cursor position hint. If it does, it will not result in any relative + motion events emitted via wp_relative_pointer. + + If the surface the lock was requested on is destroyed and the lock is not + yet activated, the wp_locked_pointer object is now defunct and must be + destroyed. + + + + + Destroy the locked pointer object. If applicable, the compositor will + unlock the pointer. + + + + + + Set the cursor position hint relative to the top left corner of the + surface. + + If the client is drawing its own cursor, it should update the position + hint to the position of its own cursor. A compositor may use this + information to warp the pointer upon unlock in order to avoid pointer + jumps. + + The cursor position hint is double buffered. The new hint will only take + effect when the associated surface gets it pending state applied. See + wl_surface.commit for details. + + + + + + + + Set a new region used to lock the pointer. + + The new lock region is double-buffered. The new lock region will + only take effect when the associated surface gets its pending state + applied. See wl_surface.commit for details. + + For details about the lock region, see wp_locked_pointer. + + + + + + + Notification that the pointer lock of the seat's pointer is activated. + + + + + + Notification that the pointer lock of the seat's pointer is no longer + active. If this is a oneshot pointer lock (see + wp_pointer_constraints.lifetime) this object is now defunct and should + be destroyed. If this is a persistent pointer lock (see + wp_pointer_constraints.lifetime) this pointer lock may again + reactivate in the future. + + + + + + + The wp_confined_pointer interface represents a confined pointer state. + + This object will send the event 'confined' when the confinement is + activated. Whenever the confinement is activated, it is guaranteed that + the surface the pointer is confined to will already have received pointer + focus and that the pointer will be within the region passed to the request + creating this object. It is up to the compositor to decide whether this + requires some user interaction and if the pointer will warp to within the + passed region if outside. + + To unconfine the pointer, send the destroy request. This will also destroy + the wp_confined_pointer object. + + If the compositor decides to unconfine the pointer the unconfined event is + sent. The wp_confined_pointer object is at this point defunct and should + be destroyed. + + + + + Destroy the confined pointer object. If applicable, the compositor will + unconfine the pointer. + + + + + + Set a new region used to confine the pointer. + + The new confine region is double-buffered. The new confine region will + only take effect when the associated surface gets its pending state + applied. See wl_surface.commit for details. + + If the confinement is active when the new confinement region is applied + and the pointer ends up outside of newly applied region, the pointer may + warped to a position within the new confinement region. If warped, a + wl_pointer.motion event will be emitted, but no + wp_relative_pointer.relative_motion event. + + The compositor may also, instead of using the new region, unconfine the + pointer. + + For details about the confine region, see wp_confined_pointer. + + + + + + + Notification that the pointer confinement of the seat's pointer is + activated. + + + + + + Notification that the pointer confinement of the seat's pointer is no + longer active. If this is a oneshot pointer confinement (see + wp_pointer_constraints.lifetime) this object is now defunct and should + be destroyed. If this is a persistent pointer confinement (see + wp_pointer_constraints.lifetime) this pointer confinement may again + reactivate in the future. + + + + + diff --git a/wl_protocols/relative-pointer-unstable-v1.xml b/wl_protocols/relative-pointer-unstable-v1.xml new file mode 100644 index 000000000..ca6f81d12 --- /dev/null +++ b/wl_protocols/relative-pointer-unstable-v1.xml @@ -0,0 +1,136 @@ + + + + + Copyright © 2014 Jonas Ådahl + Copyright © 2015 Red Hat Inc. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol specifies a set of interfaces used for making clients able to + receive relative pointer events not obstructed by barriers (such as the + monitor edge or other pointer barriers). + + To start receiving relative pointer events, a client must first bind the + global interface "wp_relative_pointer_manager" which, if a compositor + supports relative pointer motion events, is exposed by the registry. After + having created the relative pointer manager proxy object, the client uses + it to create the actual relative pointer object using the + "get_relative_pointer" request given a wl_pointer. The relative pointer + motion events will then, when applicable, be transmitted via the proxy of + the newly created relative pointer object. See the documentation of the + relative pointer interface for more details. + + Warning! The protocol described in this file is experimental and backward + incompatible changes may be made. Backward compatible changes may be added + together with the corresponding interface version bump. Backward + incompatible changes are done by bumping the version number in the protocol + and interface names and resetting the interface version. Once the protocol + is to be declared stable, the 'z' prefix and the version number in the + protocol and interface names are removed and the interface version number is + reset. + + + + + A global interface used for getting the relative pointer object for a + given pointer. + + + + + Used by the client to notify the server that it will no longer use this + relative pointer manager object. + + + + + + Create a relative pointer interface given a wl_pointer object. See the + wp_relative_pointer interface for more details. + + + + + + + + + A wp_relative_pointer object is an extension to the wl_pointer interface + used for emitting relative pointer events. It shares the same focus as + wl_pointer objects of the same seat and will only emit events when it has + focus. + + + + + + + + + Relative x/y pointer motion from the pointer of the seat associated with + this object. + + A relative motion is in the same dimension as regular wl_pointer motion + events, except they do not represent an absolute position. For example, + moving a pointer from (x, y) to (x', y') would have the equivalent + relative motion (x' - x, y' - y). If a pointer motion caused the + absolute pointer position to be clipped by for example the edge of the + monitor, the relative motion is unaffected by the clipping and will + represent the unclipped motion. + + This event also contains non-accelerated motion deltas. The + non-accelerated delta is, when applicable, the regular pointer motion + delta as it was before having applied motion acceleration and other + transformations such as normalization. + + Note that the non-accelerated delta does not represent 'raw' events as + they were read from some device. Pointer motion acceleration is device- + and configuration-specific and non-accelerated deltas and accelerated + deltas may have the same value on some devices. + + Relative motions are not coupled to wl_pointer.motion events, and can be + sent in combination with such events, but also independently. There may + also be scenarios where wl_pointer.motion is sent, but there is no + relative motion. The order of an absolute and relative motion event + originating from the same physical motion is not guaranteed. + + If the client needs button events or focus state, it can receive them + from a wl_pointer object of the same seat that the wp_relative_pointer + object is associated with. + + + + + + + + + + +